部落格
可靠性與正式環境

發布於 更新於

Anshu 和 Shouryamaan

AI 代理失敗復原:重試、檢查點與人類核准

以 Markdown 閱讀

AI 代理失敗復原會依錯誤類別及外部副作用是否可能已經完成,決定失敗步驟應停止、重試、對應結果、等待核准、補償,還是從檢查點繼續。

只有操作合約能保證重複執行安全時,自動重試才安全。逾時並不能證明失敗。

回應前先分類失敗

失敗 預設回應
輸入或結構描述無效 停止並修正請求
身分驗證或授權失敗 停止並要求有效存取權
政策拒絕 停止或要求指定的核准
速率限制附重試時間 等待後,在操作預算內重試
暫時性讀取失敗 使用有限 backoff 重試
寫入逾時且結果未知 重試前先對應結果
永久供應商失敗 失敗,或使用有文件的替代路徑
Worker 當機 從持久狀態繼續
多系統部分完成 依政策繼續、補償或升級處理

工具應公開穩定錯誤碼。不要要求模型從「發生錯誤」之類文字推斷重試是否安全。

一個邏輯寫入只使用一個操作 ID

影響重大的呼叫前先建立操作記錄,保存動作、租戶、資源、正規化輸入雜湊、冪等鍵、狀態、嘗試次數、供應商參照及結果。

同一邏輯副作用的每次重試都重用相同冪等鍵,並拒絕以不同參數重用。Stripe 的冪等請求文件示範伺服器端合約如何針對重複的鍵回傳已保存結果。其保留規則是供應商特有的,因此你的時間窗應涵蓋最長的實際恢復路徑。

如果供應商不支援冪等性,操作資料表能防止兩個本機 worker 刻意啟動同一動作,但無法判定供應商執行後遺失的回應。此時應加入供應商查詢、webhook 或人類對應步驟。

為已驗證進度建立檢查點

應在系統驗證外部副作用後建立檢查點,而不是在模型聲稱完成後建立。保存供應商識別碼或操作參照。恢復執行時,先載入檢查點及權威後端狀態,再次呼叫模型。

持久執行指南說明工作流程歷史、確定性重播及持久等待。失敗復原則補上每個狀態的操作選擇。

指定一個重試擁有者

HTTP 用戶端、佇列、工作流程引擎、模型 SDK、工具及供應商都可能重試。每種失敗類別只指定一個擁有者,並將每次嘗試計入同一操作。

設定最大嘗試次數、經過時間、backoff 及終止結果。驗證、授權及政策失敗時停止。對模型呼叫,應決定重試會使用相同的提示詞與工具,還是建立新決策。這項差異會改變評估,因此必須記錄。

對應未知結果

寫入逾時時:

  1. 將操作標記為 unknown,而不是 failed;
  2. 以冪等鍵、供應商參照或預期業務狀態查詢;
  3. 如果副作用存在,就標記為完成;
  4. 只有供應商確認未發生時才重試;
  5. 兩種結果都無法確定時,要求人類審查。

不要用成功訊息隱藏未知狀態。對應仍在進行時,使用者可能需要避免重複發出請求。

在高影響嘗試前加入核准

核准應綁定動作、資源、參數、執行者及到期時間。恢復執行時重新檢查授權。「繼續」這類廣泛核准不應涵蓋已修改的付款或刪除參數。

Railway 的代理刪除事故促使其將 API 刪除改成保留 48 小時的軟刪除。可復原副作用能降低復原壓力,但仍需要範圍受限的身分與稽核記錄。

區分取消與補償

取消會阻止未來工作,但無法復原已寄出的電子郵件、已完成付款或已公開的內容。補償是另一項動作,例如將發票作廢或還原軟刪除資源。

補償需要自己的授權、冪等性、操作記錄及失敗路徑。多個外部系統沒有共用 transaction 時,不要把它稱為自動 rollback。

撰寫人類能執行的 runbook

每個高影響工作流程都應記載:

  • 如何停止新執行與作用中的 worker;
  • 要撤銷哪一份憑證;
  • 如何找出範圍內的工作與操作;
  • 如何分類未知結果;
  • 哪些重試安全;
  • 哪些副作用可以補償;
  • 誰負責核准復原,以及如何驗證完成。

將 runbook 連接到追蹤與操作查詢。可觀察性指南列出從頭到尾追蹤事故所需的識別碼。

在各個時間點演練失敗

分別在呼叫前、供應商收到後、成功但回應抵達前、檢查點後、核准期間及取消期間注入失敗。使用沒有本機狀態的新 worker 繼續,再驗證副作用次數與最終業務狀態。

下方提示詞會在不碰觸正式環境的情況下,設計最能揭露問題的演練。如果 runbook 無法區分「失敗」與「可能已成功」,應先修正這個分支,再提高自主程度。