AI 工作實務 · 故障情境+狀態機與驗收矩陣
自動化通知寄了兩次:重試、冪等鍵與結果對帳怎麼設計
以業務意圖定唯一鍵、原子鎖與狀態台帳;不明結果先對帳,不能盲目補寄

客戶只填了一次詢價表,卻收到兩封相同的確認信。排程顯示「重試成功」,工程師說 API 沒報錯,客服卻要處理客訴。這不是多加一個「傳送前檢查」就能解決:只要系統遇到逾時、排程重跑、Webhook 重送或人工補跑,就可能同一件業務動作被再次執行。
要避免「同一件事做兩次」,不能只依靠觸發器的成功狀態;必須先定義唯一的業務動作、保留執行紀錄,對不確定的外部結果進行查證。 本文以虛構的「企業詢價回覆」示範重試矩陣與狀態表。這是設計規格和沙盒案例,不是已在 WordPress、Gmail 或 CRM 部署的保證方案。
重試正常,副作用不一定正常
AWS 的 Amazon SQS 文件說明,標準佇列採用至少一次(at-least-once)傳送語意,消費端可能收到同一訊息的副本,設計時應考慮冪等處理。S01 這項官方說明針對 SQS 標準佇列,不是「所有自動化服務一定重複寄送」的證據。
微軟的 Power Automate 文件也描述流程動作可採用重試原則,重試次數與條件受設定、授權層級及流程型態影響。S02 它能說明「失敗後可能自動重試」的機制,不表示任何特定 Gmail 或 Outlook 發信連接器天然具備業務層去重。
所謂冪等性(idempotency),是同一個業務請求重複送達,不再產生額外不希望發生的副作用。Stripe 的 API 以 idempotency key 配合請求參數做重試識別,並對相同鍵回傳已紀錄結果;AWS Builders’ Library 也討論「同一個客戶要求」與「後來的新意圖」不可混同。S03 S04 但這是架構借鑑,不代表自行在 Excel 加一欄請求 ID,就能保證外部 Email 只寄一次。
先決定:什麼才是同一件業務動作?
在教學例子中,一份詢價的 ID 是 INQ-001,第一次客戶確認通知版本是 v1。設計 business_key = inquiry_id + action_type + approved_version,例如 INQ-001:confirmation:v1。這表示「針對同一詢價、同一通知用途、同一核准內容版本的寄送」才視為同一操作。不同客戶詢價、不同用途、或經核准的新版通知,不能被粗暴阻擋。
必要欄位可分三類:
| 類別 | 建議欄位 | 用途 |
|---|---|---|
| 身分 | business_key、payload_fingerprint | 區分同一業務動作與內容被改寫 |
| 狀態 | state、attempt_count、locked_at | 防止並行重跑,追蹤是否仍在處理 |
| 外部證據 | provider_message_id、last_error、verified_at | 對帳寄送結果,不能只信流程標示成功 |
資料庫應有唯一索引或具原子性的鎖定機制,不能採「先查沒有,再插入」兩個彼此獨立的操作;否則兩個執行個體可能同時查到空白而都寄出。若只用共享試算表,未先驗證鎖定、權限及併發限制,不應拿來保證付款、發信等具副作用的正式交易。
四種結果,不是「有錯就重跑」
這份情境的狀態表採 PENDING、SENDING、SENT、UNKNOWN、FAILED_FINAL。先寫入 PENDING,取到唯一執行資格才進入 SENDING;外部提供者確認成功且回傳可追溯 ID 後記 SENT。收到明確不可重試錯誤可以記 FAILED_FINAL;逾時或連線中斷不能直接等同「沒寄出」,先記 UNKNOWN。
| 情況 | 不可靠的做法 | 建議操作 |
|---|---|---|
重送相同鍵、已是 SENT | 再寄一次 | 回傳既有處理結果及外部 ID |
| 相同鍵、內容指紋不同 | 直接覆蓋舊資料 | 停止,確認是否為新版且另建版本鍵 |
SENDING 被另一執行緒看到 | 兩邊一起執行 | 依交易鎖與租約規則等待或排隊 |
| 呼叫逾時、提供者回覆不明 | 當失敗重新送 | UNKNOWN,查提供者紀錄與寄件資料 |
| 提供者明確拒絕且可確定無副作用 | 永遠禁止再試 | 依錯誤類型、退避及批准政策重試 |
下載的 retry_scenarios.csv 是 8 種虛構事件;dedupe_ledger_example.csv 是示範台帳,不含真人地址與真實發信結果。把兩表當規格討論素材,而不是直接匯入寄件工具的運作腳本。
一次教學推演:流程成功不等於業務成功
假設上午 09:00,第一次處理 INQ-003:confirmation:v1;提供者收到請求,但工作流等待逾時。平台上午 09:02 重新觸發相同工作。若程序只看上一輪「逾時」,就可能重寄;如果沿用業務鍵,第二輪會看到第一輪 UNKNOWN 而進入對帳。
- 輸入:同一筆詢價與同一通知版本,觸發事件發生 2 次。
- 檢查:依
business_key與內容指紋查台帳,辨識第二次是重試而非新通知。 - 動作:第一次保留
UNKNOWN;第二次不直接外寄,交給具權限人員或安全可追溯的系統比對 provider log。 - 判斷:若取得已寄出的可驗證證據,標為
SENT;若明確證實未處理,再按正式規則重新排入佇列;查不出來時維持待決,避免把未知寫成成功。 - 驗收:業務台帳保留兩次觸發與一次預期副作用的映射;重複觸發不自動增加寄件紀錄。
請注意:以上流程是應有行為規格,不是「在特定 Gmail API 已測得只寄一封」。外部服務可能沒有可查的交易查詢介面,也可能缺少支援業務鍵的 API,此時就必須增加人工核對、可撤回設計,或調整產品需求。永遠不能靠補填一個 SENT 假裝對帳完成。
上線前必做的 8 個驗收情境
在獨立測試環境跑完以下條件:相同訊息連送、不同內容重用同鍵、兩個程序同時取得相同鍵、連線逾時後結果不明、明確 4xx 驗證失敗、明確可重試故障、超過業務鍵保存期限的晚到請求,以及已核准新版。retry_scenarios.csv 為每一項附上「預期狀態/應保留的證據」。涉及金流、法定通知或正式客戶寄送,應增加經授權的整合測試與風險審核。
本文與既有的AI Agent 寄報價前人工核准流程分工不同:舊文回答「誰可以核准寄送」,本篇回答「核准後重試如何不重做副作用、結果不明怎麼對帳」。想練習 n8n、Dify 的工作流、錯誤處理與日誌追蹤,可查看AI Agent 自動化實戰課;公開課綱未明列本篇完整的交易式冪等實作,不能把它當成該課必教保證。
資料來源與方法
[S01] AWS:SQS at-least-once delivery,官方產品文件;僅證明其標準佇列語意。查閱:2026-10-20。
[S02] Microsoft:Power Automate limits and retry policy,官方產品文件;支持重試原則存在,實際連接器行為仍需逐一驗證。查閱:2026-10-20。
[S03] Stripe:Idempotent requests,官方 API 文件;支持供應商自身鍵與重試契約,不是對其他平台的承諾。查閱:2026-10-20。
[S04] AWS Builders’ Library:Making retries safe with idempotent APIs,架構分析;支持意圖、重試與業務鍵的設計思路,本文流程是編輯推演。查閱:2026-10-20。
帶回工作使用
下載教學資料與空白表
免費下載,不需留下聯絡資料。檔案內均為教學合成資料,請依實際工作條件調整。
本文由 TARAISG(TIANDIREN AI SOLUTION GROUP)使用 AI 模型產生正文、整理來源並設計實務工具。方法依據與限制列於文末;案例為明確標示的教學假設。未有具名紀錄時,不宣稱經人工或專家審核。
查看內容製作與更正說明