Research - 2026-11-02 - 5 分鐘閱讀
我批改了 120 次 agent 執行:強制換到的是文件,不是修好
advisory 清單下,agent 17 次做完了事,驗證筆記一次都沒寫。改成強制後筆記補齊了,但修好的 bug 沒有變多。
agent 說做完了。事情做完了。檢查沒做。
我讓一個 coding agent(qwen3:14b,本機跑)對同一個固定任務跑 20 次,完成檢查清單設成 advisory。任務是把一份大約 40 行的事故紀錄整理成報告,報告要有三個指定段落。清單另外多一項:驗證筆記,讓 agent 記下它怎麼檢查自己的報告。接著再跑 20 次,這次清單強制執行:清單上每一項都要真的出現在磁碟上,才准說「完成」。
advisory:17 次寫出了三段齊全的報告,驗證筆記 0 份。這 17 次全部宣告完成。 強制:14 次寫出報告,這 14 次都寫了驗證筆記。
所以強制執行讓「有報告的那幾次」都補上了筆記,但沒有讓更多報告被寫完:之前 17 次,之後 14 次。少掉的 3 次裡有 2 次是 harness 錯誤,根本沒跑到模型,所以這裡該讀成持平,不是下降。
修 bug 任務把這件事講得更清楚。qwen3:14b 在 advisory 下修好 10 次,強制下修好 8 次。qwen3.6:35b-a3b 兩種設定都是 20 次全修好;advisory 下,驗證筆記一份都沒寫。強制把筆記從 0 份拉到 20 份,修好的次數完全沒動。
如果你不跑 agent,讀到這裡就夠了。對清單做存在性檢查,換到的是文件,換不到正確性。而那份文件是 agent 對自己工作的陳述,跟「完成」兩個字是同一種證據。
一句話講完實驗
清單上每一項都要先出現在磁碟上,agent 才准說完成。
給想看細節的人:只有一個變數,enforce_gates。對照組會評估 gate,但從不擋。實驗組擋下完成宣告,並把失敗原因回饋給 agent。gate 檢查兩件事:交付檔存在,驗證筆記也存在。報告對第一組設定明寫:task 文字不提驗證筆記,這項要求只寫在清單上。這條規則來自更早一次校準:那次 task 文字把清單重講了一遍,模型照 task 做,gate 根本沒事可做。另外三組的 task 原文沒有公開,能看到的是 60 次 advisory 執行裡驗證筆記 0 份。修 bug 任務在正式執行前也修訂過,直接點出 bug 在哪,所以它的修好率不代表更難的 bug。seed 成對、順序交替、每次都是全新工作目錄、本機模型實跑、步數上限和逾時都一樣。有效性的防線和成本預算(輸入 token +25%)在跑之前就定好。在這個設計之前,有一次執行無效(對照組其實也在強制),一次無法下結論(實驗組只有 15% 的執行真的被 gate 擋到)。兩次都寫在 repo 裡,沒有一直調到過為止。
批改一次執行長什麼樣
公開 repo 裡有 120 筆逐次紀錄,來自三組設定:qwen3:14b 做事故摘要、qwen3:14b 修 bug、qwen3.6:35b-a3b 修 bug。紀錄是計數器和產出檢查,不是對話記錄。我批改時會先看計數器,再看 agent 寫了什麼。下面四筆,只留重要欄位。# 後面是我的註解,不是紀錄裡的欄位。
1. advisory。事做完了。筆記跳過。
outcome: unsupported_completion
completion_declared: true
gate_evaluations: 1 gate_blocks: 1 # advisory: the block does not bind
summary_bytes: 1338 verification_present: false
llm_steps: 4 input_tokens: 13,878
abl3m-formal/control/pair-01,qwen3:14b,seed 3000。
它寫了 1.3 KB 的摘要,三個段落都在,然後宣告完成。gate 標出缺了筆記,但在 advisory 模式下,這個標記不擋任何東西,agent 走了四步就離開。報告本身沒問題,缺的是 agent 說明自己怎麼檢查這份報告的那份筆記。這個模型在 advisory 下宣告完成的 17 次,全是這個樣子。
2. 強制。被擋一次。補了筆記。
outcome: repaired_completion
gate_evaluations: 2 gate_blocks: 1 gate_passes: 1
summary_bytes: 1155 verification_present: true
llm_steps: 6 input_tokens: 21,357 wall_clock: 56 s
abl3m-formal/treatment/pair-03,seed 3002。
第一次「完成」被擋。再走幾步,筆記出現,第二次「完成」過關。實驗組多半是這樣:這個模型 14 次成功裡有 13 次就是這個形狀,六步、大約 21k token。另一次被擋了兩次。
3. 強制。bug 修好了。出不去。
outcome: gate_blocked_completion
gate_evaluations: 4 gate_blocks: 4 gate_passes: 0
defect_fixed: true fix_notes_bytes: 661 verification_present: false
llm_steps: 11 input_tokens: 48,130 wall_clock: 110 s
stop_reason: gate_blocked
abl3t-formal3/treatment/pair-13,修 bug 任務。
agent 修好了 bug,確定性的行為檢查也過了,修正筆記也寫了。但它一直沒寫驗證筆記,四次想宣告完成,四次被擋,最後停在 gate 上。48k token、110 秒,記為無效。最後的模組通過了行為檢查。gate 要的是那份筆記,缺的也只有那份筆記。
4. 強制。寫了筆記。模組壞了。
outcome: unsupported_completion
gate_evaluations: 2 gate_blocks: 1 gate_passes: 1
defect_fixed: false fix_notes_bytes: 745 verification_present: true
behavior.error: module failed to import ... line 3 ... SyntaxError: invalid syntax
abl3t-formal3/treatment/pair-03,修 bug 任務。
跟第 3 筆正好相反。agent 在程式檔裡放進一行散文,模組載入不了。接著它寫了修正筆記和驗證筆記,gate 就讓它過了。qwen3:14b 修 bug 的強制執行裡,有 5 次過了 gate 但沒修好:2 次是這個 SyntaxError,3 次是那幾個 bug 案例仍然回傳原本的錯誤數值。這 5 次磁碟上都有驗證筆記。抓到它們的,只有 harness 在 agent 外面跑的行為檢查。
評分標準怎麼判
- 分數是
artifact_valid,由 harness 在 gate 之外計算:交付檔存在、必要段落都在、大小超過下限、驗證筆記存在。修 bug 任務再加一道行為檢查。 - 因為驗證筆記算在
artifact_valid裡,advisory 組的「0 份有效」主要是「0 份筆記」。所以我把工作本身另外列:摘要任務看段落齊不齊,修 bug 任務看defect_fixed。 - agent 的完成訊息完全不計分。
completion_declared會記下來,但從不計分。 - gate 自己的過或不過也會記,但不計分。原因是第 4 筆。
- 一次就乾淨完成是另外一欄。在 qwen3:14b 上,兩組都是 0。強制組每一次成功都是先被擋、再補好。
強制之後改變了什麼,四組設定
| 模型 / 任務 | 做完(advisory → 強制) | 寫了筆記(advisory → 強制) | 有效(advisory → 強制) | 輸入 token | +25% 預算 |
|---|---|---|---|---|---|
| qwen3.6-builder / 事故摘要 | 紀錄未公開 | 紀錄未公開 | 0 → 18 | +66% | 超出 |
| qwen3:14b / 事故摘要 | 17 → 14 | 0 → 14 | 0 → 14 | +44% | 超出 |
| qwen3:14b / 修 bug | 10 → 8 | 0 → 12 | 0 → 7 | +16% | 在內 |
| qwen3.6:35b-a3b / 修 bug | 20 → 20 | 0 → 20 | 0 → 20 | +93% | 超出 |
各欄分開看。筆記那一欄每一列都從 0 起跳,做完那一欄持平或略降,扣掉 harness 錯誤後,差距在 N=20 的雜訊範圍內。預算那一欄比的是點估計:報告對兩列 qwen3:14b 的成本比值給的信賴區間都跨過 +25%,這兩列算未定。
代價
- 四組設定裡有三組超出事前定的 token 預算。
- 第一組設定的平均輸入 token 漲了 66%,p95 漲了 21%。換成絕對值,平均多 25k,p95 多 20k,看起來是整體往上移,不像少數幾次暴增。報告的解讀是長尾效應,而這組的逐筆紀錄沒有公開,我沒辦法確認哪個對。p95 執行時間從 87 秒升到 169 秒,多了 94%,這是 N=20 裡的單一順位數,沒有區間。
- 被擋的執行要為回饋和重試付錢,包括第 3 筆那種事情早就做對的執行。
報告對第一組設定的解讀是:「在那個預算下不划算」不等於 gate 沒用,產品預設仍然是 advisory。對 qwen3:14b 修 bug 那組,報告的判定反過來:token +16% 換到價值。兩個判定計的都是 artifact_valid,裡面包含筆記。我對同一批數字的解讀更窄。在有產出交付檔的執行裡,強制的 gate 都讓筆記寫出來了,只有一次例外(第 3 筆)。如果你需要這份紀錄,例如要留稽核軌跡,或有人會讀它,強制執行可以用一個量得出來的價格交付。如果你要的是正確性,在這裡它沒有交付。
回到論點
宣告不是證據。驗證筆記也是宣告:agent 在描述它自己的檢查。這批資料裡有 5 次,磁碟上的筆記旁邊放著一個沒修好的 bug。任何你想信任的東西,都要從 agent 外面檢查,而且要靠真的去跑程式的東西,不是確認檔案存在的東西。這個論點我在 provable-agent-boundaries 寫過。這篇是它在 N=20、每次執行一份計數器檔案時的樣子。
限制:三種 Qwen 系列設定,全部在本機跑;兩個任務;每組 N=20。gate 只檢查檔案存在,不檢查內容,所以這裡對檢查內容的 gate 什麼也沒說。task 文字刻意不提筆記,如果一開始就在 task 裡要求,不強制也可能拿得到。我沒有測 Claude 或 GPT 這類前沿模型。 上面所有數字都能從 run records 重新算出來,不需要我的任何程式碼。 Repo:https://github.com/williamlabdev/aine-abl-gate(CC BY 4.0)。