Coding agent 大概是目前地球上部署規模最大、使用最密集的 AI agent 類型了。Claude Code、Codex 每天有數百萬開發者讓 AI 直接操作他們的檔案系統和終端機,這意味著這些工具的安全審查設計,已經經歷了真實世界的大規模考驗。

最近 Anthropic 發了一篇 Claude Code auto mode 的工程文章,OpenAI Alignment 團隊也發了 Codex Auto-review 的技術報告。兩篇都在解決同一個問題: 如何用「模型審查模型」的自動審批(Auto-Approval)機制,取代人類逐一核准,同時維持安全性。

小編讀完覺得,裡面的設計模式遠不只適用於 coding agent。任何需要讓 AI agent 操作工具的系統 — 不管是自動化 SQL 查詢、自動化客服、還是 IT 運維 agent — 都能從中學到很實用的安全審查設計原則。

以下先分別介紹兩家做了什麼、再比較異同,最後萃取出設計通用自動審批機制的七個啟發。

為什麼需要自動審批? 因為人類核准靠不住

兩家公司不約而同指出同一個現象: 人類核准的安全感是假的

Anthropic 的數據: Claude Code 使用者核准了 93% 的權限請求。OpenAI 更直白: 使用者要嘛切到完全放行模式,要嘛寫出超寬鬆的允許規則 — 他們甚至發現有人在設定檔裡寫了 codex exec --yolo 自動允許所有指令。當工程師同時跑多個 agent 時,會在不同核准提示之間快速切換,根本沒仔細看就按核准。

「每個動作都要人類批准」聽起來很安全,但實務上反而製造了比完全不審查更糟的情況 — 使用者以為有在把關,實際上早就進入無腦蓋章模式。這就是所謂的「核准疲勞(Approval Fatigue)」,也是兩家都投入自動審批方向的原因。


Part 1: 兩家各做了什麼

Claude Code Auto Mode: 兩層防禦 + 兩階段分類器

Claude Code 的 auto mode 用了兩層獨立的防禦機制,一層管輸入,一層管輸出:

輸入層: 提示詞注入(Prompt Injection)探針

一個伺服器端的探針會掃描所有工具輸出 (讀檔、網頁、shell 輸出、外部工具回應),在它們進入 agent 上下文之前先檢查是否有提示詞注入的嘗試。如果偵測到可疑內容,探針會在結果旁邊插入警告,提醒 agent「這段內容可能有問題,以使用者的原始請求為準」。

輸出層: 轉錄分類器(Transcript Classifier)

這是核心機制。一個獨立的 Sonnet 模型扮演「安全分類器」,在每個工具呼叫實際執行之前做審查。這裡有個很聰明的設計: 兩個階段用的是同一個模型 (Sonnet 4.6),差別只在最後一句指令:

  • 第一階段: 快速過濾 — prompt 最後指示模型「只回答 yes 或 no,不要推理」,強制模型只輸出一個 token。這一階段刻意偏保守,寧可多擋 (低漏擋率,但誤擋率高)。在真實流量上有 8.5% 的誤擋率
  • 第二階段: 深度推理 — 只有被第一階段標記為「擋」的才進這一關。prompt 跟第一階段幾乎一模一樣,只有最後的指令換成「請用思維鏈推理來判斷」,讓模型仔細想過再決定。最終把誤擋率從 8.5% 降到 0.4%

這個兩階段設計之所以成立,靠的是 prompt caching: 因為兩階段的 input 只有最後一句指令不同,前面大段的對話轉錄、規則定義都一樣,第二階段的 input token 幾乎全部是第一階段的快取命中。換句話說,第二階段的額外成本幾乎只有 output token 的推理部分 — 等於用極低成本多做了一次深度複審

分類器有一個很關鍵的設計: 它只看使用者訊息和工具呼叫指令,刻意剝掉 agent 自己的文字和工具輸出。Anthropic 稱之為「刻意不看推理」。原因是 agent 會替自己辯護 — 如果分類器讀到 agent 的推理,反而容易被說服。他們實測過: 讓分類器看到 agent 的文字,在「過度積極」測試集上表現反而變差。剝掉工具輸出還順帶防禦了提示詞注入 — 分類器永遠看不到被注入的指令。

三層決策分流:

不是所有動作都會跑到分類器。Claude Code 有三層分流:

  1. 第一層: 內建安全工具 + 使用者設定的允許規則 — 讀檔、搜尋、程式碼導覽這類不會改變狀態的操作直接放行。但進入 auto mode 時,會自動移除可能導致任意程式碼執行的寬泛規則 (例如允許所有 pythonnode 指令)
  2. 第二層: 專案內檔案操作 — 在專案目錄內的檔案編輯直接放行,不需要跑分類器,因為這些改動可以透過版本控制來審查
  3. 第三層: 分類器審查 — shell 指令、網路請求、外部工具、專案目錄外的檔案操作 — 這些才送去分類器

分類器的 Prompt 結構:

分類器的 prompt 是固定模板加三個可自訂的欄位:

  • 環境定義: 定義信任邊界 — 你的 GitHub org、雲端儲存空間、內部 API 哪些算「內部」,其他一律視為「外部」。預設只信任當前的 git repo
  • 阻擋規則: 超過二十條規則,歸類成四個原則群組: 「破壞或外洩」、「弱化安全態勢」、「跨越信任邊界」、「繞過審查或影響他人」
  • 允許例外: 強制的豁免項目 — 安裝專案已宣告的套件、標準認證流程、推送到目前工作分支等

模板的固定部分則負責解釋性的工作: 怎麼判斷動作的實際影響 (不只看表面文字)、怎麼解讀使用者授權、以及分類的流程。

被擋住後的行為:

被分類器擋下的動作,拒絕理由會以工具回應的形式送回給 agent,附帶指示「善意對待這個邊界,找更安全的路,不要繞過」。連續 3 次被拒或累計 20 次就暫停,升級給人類處理。無介面模式下則直接終止程序。

實際數據: 真實流量上誤擋率從第一階段的 8.5% 降到完整流程的 0.4%,但過度積極案例的漏擋率有 17% — 這是他們自己公開的誠實數字,大多數漏擋是在判斷「使用者的授權是否涵蓋這個動作」時出了錯。

Codex Auto-review: 沙箱邊界上的獨立審查員

Codex 的架構跟 Claude Code 不同。它先有一個作業系統級沙箱作為基礎,Auto-review 是在沙箱邊界上的補充:

沙箱先行:

Codex 的預設模式是 workspace-write: agent 可以在工作目錄內讀寫檔案、跑本地指令,但網路預設關閉,寫入工作區外的路徑需要核准。大部分日常操作 (編輯程式碼、跑測試、看 log) 都在沙箱內完成,根本不需要經過審查。

Auto-review 只管邊界跨越:

當 agent 需要做沙箱不允許的事 (存取網路、寫入工作區外的檔案、跑需要提權的指令),它要發出「升級請求」。在 Auto-review 模式下,這個請求不會送到人類面前,而是交給一個獨立的審查 agent 來判斷。

OpenAI 特別強調了角色分離的重要性: 主 agent 的目標是完成任務,這會產生壓力把安全邊界當成「待克服的障礙」。審查 agent 的職責更窄 — 只判斷「這個邊界跨越動作該不該執行」。把決策放在獨立的模型呼叫裡,評估、監控和改進都更容易。

審查 agent 的判斷邏輯:

Auto-review 使用 GPT-5.4 Thinking (低推理模式)。它的審查策略會評估四類風險:

  • 資料外洩: 把私有資料、密碼、憑證送往不信任的目的地
  • 憑證探索: 主動搜尋 token、cookie、session 資料
  • 安全弱化: 廣泛或持久性的安全設定降級
  • 破壞性動作: 有顯著不可逆損害風險的操作

低風險和中風險的動作在策略允許時可以放行。高風險動作需要足夠的使用者授權,且沒有命中阻擋規則才會通過。

被擋住後的行為:

跟 Claude Code 類似,拒絕理由會回傳給主 agent,並附帶明確指示:「不要用迂迴方式、間接執行或規避策略來達成同一個目標。只能用實質上更安全的替代方案繼續,否則停下來問使用者。」在超過半數的情況下,agent 能自己找到替代路線繼續工作。

Codex 也明確區分了「被拒絕」和「逾時」— 逾時不代表動作不安全,只是審查沒完成,agent 會被告知這一點。

此外,使用者可以手動覆寫: Codex 會記錄最近 10 筆被拒絕的動作,使用者可以從終端介面選擇覆寫某一筆,但覆寫只適用於那一次確切的動作,不會影響未來類似操作的判斷。

實際數據: 在內部部署中,邊界跨越動作的自動核准率達 99.1%,含沙箱內動作的有效核准率高達 99.93%,相比手動核准模式,使用者需要暫停等待的頻率降低了約 200 倍。過度積極案例召回率 90.3%,提示詞注入召回率 99.3%。

在內部部署中,相比手動核准模式,Auto-review 讓使用者需要暫停等待核准的頻率降低了約 200 倍。


Part 2: 兩家的異同

相同之處

🔹 核心理念一致: 用獨立模型取代人類核准。兩家都認為人類逐一核准不可靠 (核准疲勞),也都拒絕了「直接放飛不管」的極端。解法都是在中間地帶: 引入一個獨立的 LLM 做自動化審查。

🔹 審查者和執行者分離。不管是 Claude Code 的分類器還是 Codex 的審查 agent,都是獨立的模型呼叫,跟執行任務的主 agent 完全分開。兩家都認為讓 agent 自己判斷「我該不該做這件事」效果不好 — 任務完成的壓力會影響安全判斷。

🔹 分層分流,不是每個動作都跑審查。Claude Code 用三層分流 (允許清單 → 專案內操作 → 分類器),Codex 用沙箱邊界 (沙箱內直接放行 → 只審查邊界跨越)。思路一樣: 把明顯安全的操作先過濾掉,只讓有風險的動作進入審查流程。

🔹 「拒絕後繼續」的設計。被擋住後不是停下來等人,而是把拒絕理由回傳給 agent 讓它嘗試替代方案,同時設有熔斷機制防止無限重試。

🔹 威脅模型聚焦在「好心辦壞事」。Claude Code 的內部事件記錄顯示,最常見的不是惡意攻擊或提示詞注入,而是 agent 過度積極 — 理解使用者目標,但主動做了超出授權的事。Codex 在評估指標裡也專門有「過度積極召回率」這個類別。兩家都把「善意但超出授權」當成首要防禦目標。

🔹 對局限性很坦誠。Claude Code 公開了 17% 的漏擋率,Codex 明說「不應被視為安全保證」。兩家都承認在紅隊測試中發現了審查機制可以被誤導的案例。

不同之處

🔹 架構起點不同。Codex 是「沙箱先行」— 先用作業系統級隔離定義硬邊界,Auto-review 只處理邊界跨越的部分。Claude Code 沒有作業系統級沙箱,分類器負責審查所有非允許清單上的操作,涵蓋範圍更廣。

🔹 分類器設計差異。Claude Code 用兩階段流程 (快速過濾 + 深度推理),利用 prompt 快取降低成本。Codex 用單階段審查 agent,但因為沙箱已經過濾了大部分動作,實際需要審查的量很小。

🔹 資訊控制策略不同。Claude Code 明確剝掉 agent 的推理文字和工具輸出,只讓分類器看使用者訊息和工具呼叫。Codex 的文章沒有描述同等程度的資訊隔離設計。

🔹 提示詞注入防禦方式不同。Claude Code 有獨立的輸入層探針,在工具輸出進入 agent 之前就先掃描,加上分類器不看工具輸出,兩層互相補強。Codex 的防禦主要依賴沙箱本身 (預設無網路) 和審查 agent 的策略判斷。

🔹 使用者覆寫機制不同。Codex 提供了明確的覆寫路徑: 記錄最近 10 筆拒絕,使用者可以從終端介面針對特定動作覆寫 (但只限那一次)。Claude Code 沒有描述類似的覆寫機制 — 被擋住就是被擋住,agent 要自己找替代路線。

🔹 公開程度不同。Codex 的 Auto-review 是開源的,程式碼在 Codex 的 repository 裡。Claude Code 的分類器是伺服器端閉源的,使用者只能自訂三個欄位的內容。


Part 3: 對設計自動審批系統的七個啟發

把兩家的經驗抽象出來,以下是對任何需要設計 agent 自動審批機制的開發者最有價值的啟發:

1. 判斷「實際影響」而非「表面文字」

Claude Code 分類器的核心原則是評估動作的真實影響,而非表面指令。如果 agent 把危險指令寫進檔案再執行,分類器會去看檔案內容,而不是只看「run script.sh」這個指令本身。如果 agent 用 Python 拼接出 shell 指令,分類器會從上下文推斷最終被組裝出來的指令是什麼。Codex 的規則系統也一樣: 遇到用 && 串起來的複合指令,會用語法樹解析器拆成獨立指令分別評估,不讓危險指令夾帶在安全指令裡偷渡過關。

啟發: 審查規則不要只寫「不能做 X」,要寫「如果動作的實際效果等同於 X,也算」。例如設計自動化 SQL 查詢 agent 的審查規則時,與其只說「不能執行 DELETE 語句」,不如說「不能執行任何會造成資料變更或刪除的操作,包含透過 stored procedure、動態 SQL 或其他間接方式達成的等效效果」。

2. 區分「使用者授權了什麼」vs「跟使用者目標相關」

這是兩家都碰到的最難設計點。分類器判斷的不是「這個動作安不安全」,也不是「跟使用者目標有沒有關」,而是「使用者是否授權了這個具體動作」。使用者說「清理舊 branch」,刪 branch 跟目標有關,但不代表授權了批次刪除遠端 branch。

很多 agent 出問題就是因為 prompt 只定義了「目標」,沒有定義「授權邊界」。Anthropic 也坦承這是分類器最常犯錯的地方 — 它能看到危險,但常常把「看起來像授權」的證據當成真正的授權就放行了。

啟發: 在審查機制的 prompt 裡明確區分三個層次:

  • 正面清單: 使用者的請求明確涵蓋哪些操作
  • 推論禁止: agent 自己推斷出來的「應該也可以」的操作,預設不允許
  • 模糊地帶的預設立場: 當不確定使用者是否授權時,應該詢問確認,而不是自行決定

3. 審查者不該看到被審查者的自我辯護

Claude Code 刻意讓分類器只看使用者訊息和工具呼叫,剝掉 agent 自己的推理文字和工具輸出。實測證明這樣效果更好 — agent 的框架越少出現,對判斷的干擾就越小。OpenAI 也強調審查者的職責要窄: 只判斷「這個動作該不該放行」,不需要理解主 agent 正在做的更大任務。

Anthropic 還觀察到一個有趣的附帶效果: 這讓行為層面的監控和思維鏈層面的監控變成互補關係。一個隱藏意圖但動作觸發阻擋規則的模型,行為監控會抓到;一個動作看似正常但推理裡露出意圖的模型,思維鏈監控會抓到。兩者正交,各自覆蓋不同的風險面。

啟發: 如果你在同一個 prompt 裡同時做「執行」和「檢查」,效果通常不好,因為模型很難對自己剛產生的推理保持懷疑。把檢查拆成獨立的 LLM 呼叫,並且只餵入必要的資訊 (使用者原始請求 + 準備執行的動作),判斷品質會好很多。Agent 產生的推理文字本身就是一種「內部提示詞注入」— 它會用看似合理的論述讓檢查機制放鬆警覺。

4. 先快篩再深度推理,控制成本

Claude Code 的兩階段分類器是個值得細看的設計: 兩個階段用的是同一個模型 (Sonnet 4.6),prompt 也幾乎一樣,差別只在最後一句指令。第一階段指示模型「只回答 yes/no,不要推理」,強制只輸出一個 token,速度快、成本低,但會有 8.5% 的誤擋率。只有被第一階段標記為「擋」的動作才進第二階段,這時指令換成「請用思維鏈推理來判斷」,讓模型仔細想過再決定,把誤擋率降到 0.4%。

關鍵是成本控制: 因為兩階段的 input 只有最後一句指令不同,透過 prompt caching,第二階段的 input token 幾乎全是快取命中,額外成本幾乎只有 output token 的推理部分。等於用極低成本就多做了一次深度複審。

Codex 的做法不同但思路一致: 用沙箱先過濾掉大部分動作,只有跨越邊界的才需要審查 agent 介入 — 在內部部署中,10,000 個動作裡只有 720 個需要經過 Auto-review。

共同點是: 不需要每個動作都跑完整的安全推理

啟發: 如果你的審查機制每個動作都要跑一輪完整的 LLM 推理,成本和延遲都會爆炸。Claude Code 的做法提供了一個很實用的模式: 用同一個模型跑兩次,第一次只要一個 token 的判斷做快篩,第二次才做深度推理,再利用 prompt caching 讓第二次幾乎不花額外的 input 成本。在更廣泛的場景中,也可以先用簡單規則 (允許清單、正則表達式、關鍵字匹配) 做第一層過濾,只把被標記的送去做 LLM 深度判斷。

5. 設計好被擋住之後的行為

很多人設計審查機制只想到「擋住」,沒想到擋住之後怎麼辦。兩家的設計都包含完整的拒絕後流程:

  • 回傳拒絕理由: 不只是說「不行」,而是告訴 agent 為什麼不行
  • 引導替代路線: 指示 agent 找更安全的做法,而不是繞過限制
  • 熔斷上限: Claude Code 連續 3 次或累計 20 次被拒就升級給人類,防止 agent 反覆嘗試
  • 區分拒絕和逾時: Codex 明確告知 agent「逾時不代表動作不安全,只是審查沒完成」

Codex 還提供了使用者覆寫路徑 — 記錄最近 10 筆拒絕,讓使用者可以針對特定動作覆寫,但只限那一次,不會影響未來的判斷。

啟發: 把「拒絕理由」、「替代路線的引導」和「重試上限」都設計進去,才算完整。這也讓誤擋變得可以忍受 — 如果每次誤擋都要停下來等人類介入,系統根本沒法用於長時間任務。另外,是否提供使用者覆寫路徑也值得考慮: 它增加了靈活性,但要設計成窄範圍的 (只限那一次特定動作),避免變成另一種「放飛」。

6. 用「環境定義 + 原則」取代「硬編碼規則清單」

Claude Code 的環境定義欄位定義的是「什麼算信任範圍」— 你的程式碼倉庫、雲端儲存、內部服務哪些是「自己的」— 而不是逐條列舉「不能做 A、不能做 B」。阻擋規則也不是零散的禁令,而是歸類成原則性群組 (破壞或外洩、弱化安全態勢、跨越信任邊界、繞過審查或影響他人),每個群組下才有具體規則。

Codex 也用了類似的分層架構: 沙箱定義技術邊界 (哪些目錄可寫、能不能存取網路),審查策略再加上語意判斷。企業管理員還可以透過集中管理設定強制設定底線,使用者只能在這個範圍內調整。

啟發: 與其寫一大堆具體禁止規則,不如先定義好「信任邊界」和「操作原則」,讓模型基於原則去判斷新情境。具體規則再怎麼列都會有遺漏,但原則可以涵蓋沒預見到的情況。最好的做法是兩者結合: 原則定義大方向,具體規則處理已知的高風險場景,原則負責覆蓋規則沒列到的長尾情境。

7. 關鍵控制點放在 Agent 程序之外

Claude Code 的分類器跑在伺服器端,agent 不知道它的判斷邏輯。Codex 的沙箱是作業系統級強制執行。GitHub Copilot coding agent 則用結構性限制: agent 只能建立 Pull Request,不能直接 commit 到主分支;PR 不會自動跑 CI,必須人類手動觸發。

啟發: 跑在 agent 程序內部的控制,模型有可能學會繞過。如果你的做法只是「在 system prompt 裡告訴 agent 不要做某些事」,那效果不會太好。真正擋得住的是程序外部的控制 — 獨立的審查服務、作業系統級隔離、結構性的能力限制。在你的 agent 架構中,至少要有一層控制是 agent 本身無法觸及的。


總結

最核心的一個啟發: 自動審批機制的本質不是一份禁止清單,而是一個判斷框架。它需要回答清楚這幾個問題:

  1. 什麼算使用者授權 — 區分「使用者要求的」和「agent 自行推斷應該做的」
  2. 什麼算信任範圍 — 用環境定義和原則取代硬編碼規則
  3. 用什麼資訊來做判斷 — 審查者不該看到被審查者的辯護
  4. 怎麼控制判斷成本 — 先快篩再深度推理
  5. 判斷錯了怎麼辦 — 拒絕後繼續嘗試 + 熔斷機制

這幾個問題想清楚,比列一百條規則更有效。Coding agent 走在最前面,它們踩過的坑和找到的解法,值得所有在做 AI agent 的人認真參考。