技術札記

冪等:一次簽批,怎樣才不會變成兩次寫入

寫給 Agent 已經在寫入生產系統的工程與營運團隊:要回答逾時、重啟或模型重新規劃,對一筆退款、一次付款或一個帳戶停用會造成甚麼。

GembaOS 是企業 AI Agent 的治理執行平台:以政策判定權限、以綁定參數的單次放行令授權每一個動作、以可追責的簽署鏈記錄人的審批,部署於企業本地機房或私有 VPC。這篇講的是 Agent 造成實質損失之中最不起眼的一條路:把對的事做了兩次。

甚麼是冪等,Agent 為甚麼需要它

一個操作重複執行與只執行一次的結果相同,就叫冪等 (Idempotency)。Agent 需要它,是因為重試是日常而不是意外。呼叫逾時,用戶端重送;流量限制拒絕了這次嘗試,有東西把它重試;寫入已經送出、回應未到,程序就重啟了;模型收到含糊的工具結果,把同一步再規劃一次。

以上沒有一項是 Agent 行為不當,也沒有一項會被權限判定攔下。這個 Agent 本來就可以發出那個呼叫,它只是發了兩次。

觸發情況Agent 看見的沒有冪等鍵時業務端看見的
逾時沒有回應兩筆退款
寫入途中重啟這一步沒有完成重複記錄,或帳戶被停用兩次
流量限制後重試先錯誤,後成功一筆扣款,還是兩筆
模型重新規劃上一次的結果不清楚第二張工單、第二封電郵

冪等鍵應該從哪裡來

來自授權,不是來自這一次嘗試。整個設計決定就在這一句,而常見的錯誤是在呼叫之內產生這把鍵,例如用 UUID 或時間戳:重試時產生的是另一個值,目標系統當作新請求,於是寫下重複的一筆。這把鍵在兩次嘗試中必須相同,也就是說,它必須由比兩次嘗試都更早存在的東西推導出來。

鍵的來源重試時是否相同由誰決定
呼叫時產生的 UUID否Agent
只用參數相同,但兩筆合理的同額退款會撞在一起Agent
審批單與工單是GembaOS 治理內核

GembaOS 採用第三種。這把鍵由 GembaOS 治理內核依審批單與工單組成,Agent 既不能選也不能改;而兩筆金額相同但批准不同的動作,因為批准不同,鍵也不同,不會互相吞掉。

受治理的執行實際保證了甚麼

「一次批准,最多一次寫入」這句話背後,是三個處於不同層次的機制。在 GembaOS 之內,放行令只能用一次:執行已批准的動作就會把它消耗掉,同一張放行令的第二次嘗試會被拒絕並記錄在案。在目標系統之內,冪等鍵令重送落地為同一筆寫入。至於兩者都沒有的系統,則由 Adapter 聲明自己的寫入靠甚麼保護:版本號、條件寫入,或在動作執行期間鎖住該筆記錄。

示例退款的時間線:受理、提交審批、發出工單編號與初步回覆、各級簽章、按簽署內容重新核對、消耗放行令後執行、寫入後回讀、發出正式回覆、完成
示例退款的時間線:受理、提交審批、發出工單編號與初步回覆、各級簽章、按簽署內容重新核對、消耗放行令後執行、寫入後回讀、發出正式回覆、完成

記錄上的那一行報告同時點名了兩樣東西:這次寫入是在哪一張放行令之下發生的,以及由審批單與工單推導出來的執行鍵是甚麼。日後讀這份記錄的審計人員,不需要相信「重送應該處理好了」——令它安全的那把鍵,就寫在記錄上。

批次處理呢

重複最貴的地方是批次,因為部分失敗之後,人的第一反應就是整批重跑。在 GembaOS 裡,一個批准可以覆蓋一張清單,但每一行在該批准之下仍然是自己的工單、自己的記錄。

GembaOS 批次工單畫面:四行帳戶停用之中三行正常、一行錯誤,每行各自連到自己的子工單與同一張審批單,失敗那行寫明目標系統回覆找不到該帳戶,因此沒有執行任何動作
GembaOS 批次工單畫面:四行帳戶停用之中三行正常、一行錯誤,每行各自連到自己的子工單與同一張審批單,失敗那行寫明目標系統回覆找不到該帳戶,因此沒有執行任何動作

三行成功,一行因為目標系統回覆該帳戶不存在而失敗,而該行明確寫著沒有執行任何動作。總數、逐行狀態與共用的批准都在記錄上,所以「到底哪幾行真的做了」這個問題,不必翻日誌就有答案。

小結

冪等不是 HTTP 用戶端的實作細節。對一個會寫入生產系統的 Agent 而言,它是授權的一部分:一個人簽了一次的決定,無論中間網絡發生甚麼,都應該變成一次寫入。判別任何 Agent 平台的實用問題很短——問它冪等鍵從哪裡來。如果答案是「由 Agent 產生」,那個平台沒有解決這個問題,只是把它移了位置。

本文回答的問題

AI Agent 的冪等是甚麼意思?

一個操作執行多次與執行一次的結果相同,就是冪等。對 Agent 而言,這件事在寫入那一刻才重要:退款、付款、開單或停用帳戶,即使呼叫送了兩次,也應該只落地一次。

為甚麼不可以由 Agent 產生冪等鍵?

因為第二次嘗試就是第二次產生。在嘗試之內產生的鍵,重送時會變成另一個值,目標系統會當作新的請求,寫下第二筆記錄。這把鍵必須來自兩次嘗試共有的、穩定的東西——那是批准,不是嘗試。

如果目標系統根本不支援冪等鍵呢?

那就要改為在寫入前核對記錄本身:條件寫入、版本號,或在動作執行期間鎖住該筆記錄。每個 Adapter 都要聲明自己用哪一種,所以執行平台在放行一次寫入之前,已經知道這次寫入受甚麼保護。

批次處理之中有一行失敗會怎樣?

每一行都是同一個批准之下獨立的工單,分別記錄,所以某一行失敗就顯示為該行失敗。重跑整個批次時,已經成功的行不會再執行一次。

資料來源

截至 2026 年 9 月,GembaOS 未取得任何第三方認證;本站的控制對應表為自評,未經審計。GembaOS 處於 Design Partner 階段。 了解 Design Partner 計劃。

最後更新: · GembaOS v0.2