對應原題(Common ‧ Agents and Tool Use)

  • How do you make an agent’s actions reversible, or at least auditable, in a production system? — Asked at: Palantir
  • Design human-in-the-loop approval for an agent that takes consequential actions. — Asked at: OpenAI, Palantir

🎯 什麼情境該想到我

當你「要把 agent 放進會產生真實後果的系統」的時候——它能發信、能改資料、能付錢、能部署。
★ 這一頁的核心命題:不可逆的動作只能靠事前把關,事後補救不存在。所以設計的第一步是「把動作分級」。

⚙️ Part 1:可逆性

★ 動作分級(所有設計的起點)

級別例子策略
L0 唯讀查詢、搜尋、讀檔自動執行,只記錄
L1 可逆寫入建草稿、加標籤、寫暫存檔自動執行 + undo 能力
L2 難逆改生產資料、合併 PR、調整設定需要 dry-run + 核准,並備妥補償動作
L3 不可逆寄出 email、轉帳、刪除、對外發布、呼叫第三方 API必須人工核准,且要有延遲視窗

★ 面試的第一句話應該是「我會先把工具按可逆性分級」,而不是直接講技術。
沒有分級,你要嘛什麼都擋(agent 沒用)、要嘛什麼都放(遲早出事)。

讓動作變可逆的七種技術

技術說明
★ Plan / Apply 兩段式先產出具體的變更計畫(像 terraform plan),核准後才 apply。最好用的一招——把「模型的意圖」變成「可審查的具體 diff」
沙箱 / 影子執行在資料副本或隔離環境執行,驗證無誤再套用到真實環境
軟刪除 + 版本永遠不硬刪。標記 deleted_at,保留版本鏈
事務包裹一組動作在同一個交易內,要嘛全成要嘛全退
補償交易(Saga)本質不可逆的,預先定義補償動作(退款、發更正信)
★ 延遲執行 + 撤回視窗email 排程 5 分鐘後才真的送出,期間可撤回。成本極低、效果極好,把 L3 降成準 L2
事件溯源所有變更是 append-only 事件,可重放、可回捲到任一時點

設計技巧:想辦法把 L3 降級成 L2。
「寄信」不可逆,但「排程 5 分鐘後寄信」在那 5 分鐘內是可逆的。很多不可逆性是可以用時間換掉的。

⚙️ Part 2:審計

審計要能回答六個問題

誰 · 什麼時候 · 以什麼身分 · 做了什麼 · 為什麼 · 依據什麼

所以每個動作至少要記:

trace_id:        關聯整條 agent 軌跡
timestamp:       時間
actor:
  agent_id:      哪個 agent
  agent_version: 版本(程式碼 + prompt + 工具集)
  model:         模型與版本
  on_behalf_of:  ★ 代表哪個使用者在行動
action:
  tool:          工具名
  args:          完整參數
  result:        完整回傳(或指標)
  status:        成功 / 失敗 / 被拒絕
rationale:       ★ 模型當時的推理輸出
inputs:          完整 prompt(含檢索到的文件 ID 與版本)
approval:        核准人、核准時間、核准時看到的內容

三個容易漏掉但關鍵的欄位:

  1. rationale(模型的推理) —— 事後要回答「它為什麼覺得該這麼做」,沒有這欄就只能猜
  2. inputs 含檢索文件的 ID 與版本 —— 錯誤答案的根因常常在「它讀到了什麼」
  3. approval 要記「核准人當時看到什麼」 —— 而不只是「有人按了同意」。否則出事時無法判斷是人看錯還是介面顯示錯

不可篡改與身分

  • Append-only,不可編輯不可刪除;高合規環境要加簽章或雜湊鏈
  • ★ Agent 必須有自己的身分,而不是共用一把 admin key
    • agent 的權限是代理使用者的權限(on-behalf-of / 委派憑證),不是 superuser
    • agent 能做的,不應該超過發起它的那個人能做的 —— 這一條是權限設計的基石
    • 每個 agent 實例/每次任務發短期憑證,範圍最小化
  • 日誌本身要分級與保護 —— 它包含了所有原始資料(見 權限感知檢索與引用歸因)

⚙️ Part 3:人類把關(HITL)

★ 分級核准矩陣

不要「每件事都問」。 這是這題最重要的設計判斷。

模型信心高模型信心低
L0–L1 低風險自動執行自動執行 + 事後通知
L2 中風險自動執行 + 事後通知(可撤銷)事前核准
L3 高風險事前核准事前核准 + 升級到更高層
超出範圍拒絕拒絕

其他該納入的維度:金額門檻、影響筆數、對象是否為外部、是否在營業時間。

好的核准介面要件

要件❌ 反例✅ 正例
顯示具體變更,不是意圖「agent 想更新客戶資料,同意嗎?」顯示 diff:客戶 #4821 的 email: a@x.com → b@y.com
顯示依據—「因為工單 #993 中客戶要求更改」+ 可點開原文
顯示影響範圍「批次更新」「將影響 1,247 筆記錄」 ← 這個數字常常就是救命的那一眼
預設拒絕逾時自動放行★ 逾時 = 拒絕(fail-closed)
可修改後執行只有「同意 / 拒絕」允許人類調整參數再執行
可追問—「為什麼你認為要這樣改?」

★ 核准疲勞:最大的失敗模式

低風險的核准請求太多 → 人類開始盲按 → 真正高風險的那一個也被盲按。

一個會送出 200 個核准請求的系統,等於沒有核准。

對策:

  1. 提高自動化門檻 —— 把低風險的改成事後通知,不要事前打斷
  2. ★ 聚合相似請求 —— 但聚合不等於批次盲核。聚合要顯示「共 12 筆,全部都是同一類型,這是其中的代表樣本與完整清單」
  3. 量核准指標 —— ★ 追蹤「拒絕率」和「核准所花的秒數」
    • 拒絕率趨近 0% + 核准秒數趨近 0 → 人類已經在盲按了,這是系統失效的訊號
  4. 逐步放寬 —— 新 agent 先全部核准,累積出可信的拒絕率統計後再自動化低風險類別

升級與逾時

  • 升級路徑:一般核准者 → 主管 → 安全團隊。依風險等級決定起點
  • 逾時行為必須明確:L3 逾時 = 拒絕並回報;L2 逾時 = 拒絕或降級為草稿
  • 離線/半夜怎麼辦 —— 設計時就要決定,不要讓它變成生產事故

⚠️ 注意 / 什麼時候不適用

  • ★ 人類核准不是萬靈丹。人會累、會信任 agent、會被說服。核准是最後一道防線,不是第一道——前面還要有權限最小化、工具分級、輸入驗證。
  • agent 可能繞過核准。用一連串「個別看起來低風險」的動作達成高風險結果(例如分 100 次各轉一小筆)。→ 要有累積額度與速率限制,不只單次判斷。
  • 模型的「信心」不可靠。用它當自動化門檻要先校準,或改用可客觀判定的規則(金額、筆數、對象類型)。
  • 資料外洩是另一條路。能讀資料 + 能對外呼叫 = 可外洩,即使每個動作都「合法」。見 工具集設計 與批次 3 的提示注入。
  • 審計日誌會很大。要有保存期限政策與成本規劃;但高風險動作的日誌不能因為省錢而縮短保存。
  • 別事後才加。可逆性與審計要在工具設計時就決定,否則之後每個工具都要改。

🧪 我實際套用的紀錄

  • 2026-09-20:從面試題庫展開。待辦:把現有 agent 的工具照 L0–L3 分級一次,並確認 L3 有沒有延遲視窗。

🔗 相關