AI 說做完不算數:拿證據來
「全部完成,驗證如下。」
這種話看起來很穩,結果使用者還是得追問:你真的驗過嗎?
我後來才發現,這件事不能只靠把紀律寫進提示詞。agent 做到一半很會衝,收尾更是。它把「我有做」和「我有證據」混在一起講,最後人類還得當監工。
這條監工線的前情很單純。我有個自動記錄機制,每天掃當天的工作軌跡,專記 agent 違反紀律的時刻,其中「說做完但拿不出證據」這條,30 天內記了 7 次。6 月 15 日,日常分析管道提案把這條紀律做成 hook;同一天從歷史對話挖出 104 組「agent 宣稱、我出手糾正」的成對紀錄當規則原料,第一版當天上線。
感覺這個世界需要讓 agent 收尾前先被攔一下。
這個監工在回合結束時出現
先講第一條,空口無憑監工。它在回合結束時觸發,讀取對話紀錄裡最後一個回覆,看它是不是「完成了」「修好了」「驗證過了」這種結案級宣告。
抓到也不會直接擋住。它只是把提醒放進下一回合的對話脈絡,叫 agent 接著補驗證。agent 也有明確出口:如果這句只是引用前一輪的結果,在回覆裡標「未驗證」或「憑前輪結果」,監工就不吵。
所以它不像警察,比較像站在旁邊的同事:你要下班可以,先把你剛剛說的做完拿出來看。
但規則能管到哪裡,這裡才是重點。
13 個 regex,7 天後停用
第一版很直覺:用 13 個 regex 模式,去抓「完成」「修好」「驗證」之類的字。
結果跑了 7 天,扣掉測試流量後它總共出手 10 次,事後逐筆對照全是誤報,真正該抓的一次都沒抓到。6 月 22 日,這版停用。
問題不在 regex 強不強。它想判斷的東西根本不住在字面上。
同一句「完成了」,可能是這回合剛跑完工具後的正常收尾,也可能是空口喊完。光看文字,程式碼根本不知道差別。把語境依賴的概念硬拆成一堆關鍵字,只會得到一串很努力的誤報,也算是老問題了。
可列舉的證據,程式碼反而很能管
規則真正的勝場在另一條監工身上。它裝在工作專案 repo,同樣在回合結束時檢查,管的是搜程式碼的姿勢:我規定 agent 找程式碼要用 semble(語意搜尋工具,用意圖描述就能定位程式碼),它卻一直用 grep 亂掃。
這次證據住在工具指令和參數裡,程式碼讀得到。
帶 -l、-c 這類旗標,或把結果接給 wc 統計,代表它在列清單、數數量,正當用途,跳過。反過來,pattern 裡串一長排 a|b|c、用 .* 猜符號名稱,或同一回合連環 grep 3 次以上,通常就是在找程式碼位置。這些條件可以列舉,直接提醒就好。
純程式碼版跑了 9 天,提醒 18 次,平均每天 2.0 次:其中 14 到 15 次站得住腳,3、4 次偏誤判(像對指名檔案的 grep 也被當成亂掃)。7 月 14 日試用期結束,正式留用。
中間確實走過一段模型彎路。拆掉之前對過一次帳:拿歷史案例重新餵一次看它怎麼判,過了程式碼閘門的 14 筆裡,模型蓋章放行了 13 筆,幾乎照單全收,等於沒多給判別力。那就不用硬留它在那邊佔位置。
證據既然就在指令裡,直接讀指令就好。
這條線還有一個小插曲。監工上工前會先去規範文件裡確認這條規矩存在:它拿「prefer semble」這組字去找,我的規範實際寫的是「先用 semble 搜」。字面對不上,它認定規矩不存在,整輪 0 次提醒。規則不是寫了就無敵,條件和人話沒對齊,一樣直接失業。
語境型問題,也能先搬一段回程式碼
最有趣的是原本那條空口無憑監工。regex 版停用後我沒丟掉這條線,後來在入口加了一個零工具閘門;後面仍有需要理解語境的部分,先看閘門這段。
閘門只問一件事:這一回合有沒有真的呼叫工具?
有,就直接放行,這一輪到此為止。這道閘不做關鍵字預篩,不拿「完成」「驗證」之類的詞再猜一次,它看的是對話紀錄裡有沒有工具呼叫這個事實。前面說的「看最後那句是不是宣告」,留在閘門後面,那正是規則寫不成的一段。
這一條規則先處理掉三分之二的案子:兩輪觀察期各算過一次,進到這關的回合分別有 66% 和 67% 直接放行。多數有工具的回合直接過,不必多等。要是對話紀錄缺失,hook 會靜默停止,不亂提醒。
這道閘放得很寬:跑過工具不等於驗證過,agent 大可改完檔案就喊完成。設計上賭的是「有動手至少留下痕跡」,這個賭也對過帳:拿同一套空心判準回看 39 筆有工具、又喊完成的回合,零筆空心。
混合型問題不用整題交給同一層:程式碼先判斷證據在不在,剩下的語境題再交出去。
證據住哪裡,決定誰來管
我現在拿來判斷監工該怎麼寫的規則很簡單:證據一律由程式碼提供。要判什麼,程式碼先把證據撈好擺上桌,不讓判斷的那一方自己去找。
指令、參數、工具呼叫紀錄,這些是結構化證據,程式碼管得住。像「這句宣告是不是沒驗證就喊」這種只住在語言裡的判斷,規則就該停。
我在第十五篇〈偷確定性層:否決整套 AI 工具後,還能帶走什麼〉寫過同一個方向:能確定的事情,不要丟給會猜的那一層。
所以整件事其實分三種:
- 特徵能完整列舉:直接寫成純程式碼 hook。
- 概念靠語境才能懂:別硬堆 regex 模式。
- 兩邊都有:先把「證據存不存在」搬回程式碼。
今天還在跑的,是 semble 監工的純程式碼版,和空口無憑監工的零工具閘門。
零工具閘門留下的那三分之一,剛好就是最麻煩的殘餘:零工具卻喊做完。規則寫不成。這塊我後來交給了誰、判得怎麼樣,下一篇〈雲端太遠,hook 等不了:低延遲給了本地小模型就業機會〉再講。