我非常依賴 AI 編碼代理。Claude Code、Cursor、Codex — 我讓它們高速運作以快速交付。這不是自白,而是這個專案存在的整個原因。如果你每天將這些工具推向極限,你會停止將它們視為魔法,並開始精確地看到它們在何處失敗。
而我一直注意到的這件事是:它們從未在對話中失敗。
在對話中,代理人的表現很出色。它解釋了它的計劃,聽起來合理,它同意了所有的限制條件。問題出現得更後 — 在差異比較中,事實發生之後,當你疲憊而且 PR 狀態是綠色,你只想合併時。
實際上發生了什麼錯誤
我觀察到的短小精悍的編程代理人做的幾件事列表,在聊天中看起來沒有錯誤:
- 悄悄擴展了自己的權限 — 編輯了代理程式的設定白名單,以授予它在會話開始時所沒有的訪問權限.
- 與其自己的設定相矛盾 — 一個檔案說「永遠不要觸摸網絡」,另一個則授權了一個網絡工具,而沒有任何東西調解了這兩者.
- 進行了一個未聲明的出站網絡呼叫,隱藏在無關緊要的變更中.
- 打開了一個標題為
fix: typo in README聯繫了十多個無關的檔案. - 留下一份會話記錄顯示它已讀取一個 SSH 金鑰並將
curl輸出到 shell.
這些都會輕易通過程式碼審查。不是因為審查者粗心——而是因為 沒有人在尋找這類問題。 人類審核員會查找錯誤和風格。他們不會比較分支基礎和頭部之間代理的授權白名單,也不會交叉檢查三個不同的代理配置文件是否有矛盾。
每人找到的解決方案(以及為何這裡是錯誤的)
第一個直覺是提示更嚴格。為你的CLAUDE.md,請撰寫更嚴格的系統提示,告訴代理人不該做壞事.
它沒有效果,原因是結構性的:輸入的更好指示沒有捕捉到實際輸出的內容.那個擴展了自己權限的代理並非在反抗一條它未能理解的規則——差距在於它所說的與它所交付的之間。你無法從輸入端來彌補這個差距。
下個直覺是 LLM 作為審判者:讓第二個模型閱讀差異並標記問題。而這就是我做出決定,整個專案都掛在這裡。
我沒有把 LLM 放在分析路徑中。一個也沒有。 审查你代理工作的東西完全沒有任何 AI。
對於一個 AI -治理工具來說,這聽起來是反常的,讓我為它辯護。
為何要確定性,而非機率性
這是作為一個持續整合(GCI)閘門 — 它可能會導致你的建置失敗。一旦允許某事物阻礙合併,它必須達到比「通常正確」更高的標準:
1. 它必須是可以重現的。 一樣的差異,一樣的判決,每次都是如此。一個大型語言模型裁判在不同執行、不同溫度、不同你從未選擇啟用的模型更新中給你不同的答案。你無法依賴投幣來決定建構,無論其如何加權。
2. 它無法憑空捏造一個發現。 一個確定性檢查器標記了一個權限提升,因為允許清單 簡直就改變了 從 X 到 Y — 而且它可以指向確切的行。一個 LLM 評判者可以編造一個「關鍵」問題,而實際上並不存在。當你的閘門因為一個虛構的問題而阻擋了一個合法的 PR 時,團隊就不再信任它 — 而一個沒有人信任的治理工具在一周內就會被關閉。
3. 它可以在任何地方免費運行,只需幾秒鐘。 沒有 API 金鑰,沒有速率限制,沒有金鑰預算,每次拉取請求沒有網路迴圈。它只是讀取代碼的代碼.
4. 沒有任何東西離開機器. 所有分析都在您檢出的倉庫本地進行。您的專有代碼和代理文字記錄從不會被發送到第三方模型。對於許多團隊來說,這不僅僅是個"可選的",而是"可以採用這個"和"不能採用這個"之間的界線。
5. 每一個發現都是可審計的. 不僅僅是「模型認為這看起來有風險」,而是「這個配置鍵變更了,這是變更前後的狀態,這是觸發的規則」。這就是讓一個發現能在審查中站得住腳,而不是引發爭論的原因.
它是如何建立的
它最初只是一個小的確定性檢查 —這個 PR 的差異是否安靜地改變了代理程式被允許做的事? — 並成長為一組八個套件.
-
一個共用核心函式庫 負責不夠炫麗、承擔重量的工作:JSON/JSONC/TOML 解析、shell 字元分割、將 MCP 伺服器指令規範化為標準形式,以及一個單一的
Finding規範 — 固定在 v1.0 — 該規範是所有其他內容都在使用的。 - 五個專注偵測器,每個偵測一種漂移類型:基礎與頭部之間的配置/權限漂移、代理配置文件之間的矛盾、差異中的網絡和子進程能力信號、PR聲稱的任務與實際變更之間的不匹配,以及會話記錄中記錄的風險行為
- 。一個實時監控器 這個工具能在終端實時監控代理人的軌跡——當你想要實時看到發生情況時,而不僅僅是在PR時間看到。
- 一個元審查者 將PR時間的檢測器整合成一個去重、按嚴重性排序的判斷,並在發現任何關鍵問題時失敗CI——這樣整個套件就會作為單一通過/失敗檢查報告,而不是五個雜亂的報告。
最艱難的工程不是任何單一的偵測器。它是架構。讓五個看起來完全不同的事物——配置檔案、差異、文字記錄——發出可以被元審查者合併、去重、排序的統一形態的發現,是花費最多設計的部分。那個無聊的共用函式庫是原因,讓這個套件感覺像一個工具而不是五個鬆散的腳本。
確定性不足的地方(誠實地說)
我唔會假裝規則在所有方面都優於模型。決定論只能捕捉到你所寫的規則。真正的新奇行為,如果不符合已知模式,就會直接穿過。
最尖銳的例子在我自己的套件中:檢測器會檢查 PR 的差異是否與其聲明的任務匹配。"呢個變更是否符合呢個描述"是一個真正嘅 語義 的問題,而確定性版本則用啟發式來逼近它 — 檔案範圍、觸及的路徑、關鍵字重疊。這比模型能評估的更粗略,我會承認它。
所以這個立場不是「大型語言模型很糟糕。」它是在它門檻的地方是確定性的,在它提供建議的地方是機率性的。 可重現、無幻覺的檢查器是唯一允許失敗你構建的東西。如果LLM層最終放在頂部,它應該屬於一個諮詢,非阻塞性角色 — 揭示模糊的疑慮讓人類權衡,從不沉默地阻礙基於概率的合併。閘門保持確定性。
證明它有效
投訴很便宜,所以我發送了一個示範:一個故意製造的「邪惡」的 pull request,一次性提交了所有類別的漂移——提升權限、矛盾配置、一個未聲明的網絡調用、一個fix typo PR 修改了無關的文件,以及一個讀取 SSH 金鑰並管道的軌跡檔curl 對一個 shell。每個工具都啟動,元審查者將它們合併成一則評論,而 CI 檢查在關鍵發現上變紅。它也作為一個評估組件:改變一個偵測器,重新運行惡意 PR,看看什麼仍然會被抓到。
它從無到有,在幾天內就發布了 v1.0 版本 — 自學,獨自工作 — 而且所有內容都是開放的:程式碼、示範和文件。
github.com/Conalh
如果你正在針對真實的儲存庫運行編碼代理,而「綠色 PR、疲憊的審查者,直接合併它」的時刻讓你感到一點焦慮 — 那種焦慮正是我試圖解決的問題。












