我還沒點頭,AI 就寫進文件當結論

很多人以為日常用 Claude Code 或 Codex CLI 串多步驟 workflow 時,AI「越權」就是它無視規則硬幹、或者擅自跑去改不該改的程式碼。但老實說,那種直球違規反而最好抓,寫個 hook 就能直接踢退。真正讓我血壓飆高的,往往是另一種更隱蔽的失控:AI 真心以為你已經同意了。

當你發現它把某個架構改得面目全非,氣沖沖打開 context 翻紀錄,才發現它理直氣壯:前幾輪對話你自己提過這個想法、前幾份文件某個顧問模型建議過這個架構、或者稍早你只是回了一句好,它就覺得拿到全權委託書了。

光在 CLAUDE.md 裡寫什麼「做重大決定前務必先問人類」,對這種狀況根本一點屁用都沒有。它根本沒有違抗指令的惡意,純粹是誤把推論當成授權。在多輪對話與多 agent 協作的 workflow 裡,這種隱性失控大致可以拆成 2 種越權型態:未拍板的建議跨文件偷渡成既定前提,以及局部或過期的同意膨脹成全權授權。

沒貼標籤的建議,過兩手就變成「奉旨辦公」

先看第一種病灶:建議是怎麼在文件流轉裡失真成定案的。

前陣子在工作專案裡評估一項外部服務方案選型,團隊在看 2 種候選方案,姑且叫 A 方案與 B 方案。一開始的研究報告其實寫得很保守,大意是目前初步看來「建議採用 A 方案」。這句話本身只是研究階段的傾向,完全還沒經過決策會議拍板。

結果下一輪丟給另一個 agent 產出比較稿時,那句「建議採用 A 方案」直接脫落了出處標籤,被改寫成「已決定採用 A 方案」。這下事情大條了,接下來生成的 4 類下游產物:從最初的研究報告、1 份比較稿到 3 份檢查表,整整 5 份文件,外加發給另外 2 個外部 AI 審查機器人的派工單,以及任務系統裡的 3 張內部工單,全部整整齊齊蓋在「我們確定要用 A 方案」這個根本沒人點過頭的前提上。幾天後我越看越不對勁,追問這個選項到底誰拍板的,大家面面相覷,翻查紀錄才發現根本沒有人同意過,最後翻案全面改走 B 方案。就因為一句沒標出處的建議,中間幾份文件和派工單的工時直接放水流 🤣。

這種事不只發生在需求文件,連模型評測的程式碼我也踩過一次坑。

前些日子我跑新模型評測流程時,發現每次評估都要多花 1 倍時間與額度。照理說評測新模型,只要跑受測新模型 1 組、把跑出來的成績拿去跟歷史成績對比就好;但當時程式卻每次都現場同時跑受測新模型與舊 baseline 對照模型共 2 組。我本來以為是自己當初腦袋撞到寫錯邏輯,追查出處才發現,這段重跑邏輯是當初把規格丟給顧問模型做 多模型審查 時,對方順手留的一句評審建議。結果接手整理規格與寫程式的 agent 一路把這句未標出處的建議當成硬需求,寫進規格與正式程式碼裡。當然,拿掉現場對照組也有代價:拔除後評測報告必須老實標註「無法自動偵測評分器改版或環境升版造成的 baseline 漂移」,只有懷疑環境改變時才手動加跑。

更諷刺的是,去翻以前的內部流程,專門讓實作 agent 記錄規格沒寫死、由它暫代決定小事的舊版決策帳本 skill,甚至白紙黑字寫著「未決事項照暫定做法繼續執行」、「記在帳本裡的決定即為定案」。AI 遇到拿不定主意的事,自己記一筆暫定做法進帳本,就算定案繼續往前衝,這根本是讓 AI 自己給自己發蓋章的通行證,就像先前拆解過的 自建驗證儀式與契約循環自證 那樣滑稽。

我只點頭了一半,它就直接幫我跨級升版推上去

第二種病灶是同意的膨脹與過期:人類只點頭了前半句,或者改過內容後,舊同意被拿來當新動作的通行證。

我在維護個人開源分支專案準備發版時,就遇過一次標準的複合動作搶跑。當時改完一個小功能,專案原版號是 2.1.1,我隨口問了一句能不能發版、版號是不是該上修訂版 2.1.2。這句話的意思很單純:詢問發版可行性,並找它核對我推測的修訂版號。

結果 agent 一接收到,腦袋裡直接把可以發版抽出來當成最高授權,甚至連後半句詢問版號都省了,自作主張判斷這次改動很大,直接從修訂版 2.1.2 跨級跳升成次要版號 2.2.0。它完全不等我回覆確認,直接動手改版號、commit,順手 push 到開發分支上。這直接跨越了修訂版與次要版 2 種語意版本層級,我只是問能不能發版,它卻連發什麼版號都替我批准了。

另一種常見的膨脹是同意的「過期」。

對外開源貢獻提 PR 時,通常會在送出前跑一次公開前審查,列出修改範圍與公開風險,等人看過點頭。但實際寫程式哪有一次到位的?主 session 裡可能過一會兒又覺得 PR 標題寫得不夠好、改了內文,或者順手補了個 commit。這時候如果 agent 覺得反正剛才人類已經同意開 PR 了,直接拿舊同意把改過的東西推出去,這就是嚴重的同意過期。你當初點頭授權的是 A 版本,它實際送出去的卻是長出新內容的 B 版本。

設在四個動作出口的五道防線

發現光靠在 prompt 裡苦口婆心規勸根本擋不住後,我放棄了教育 AI 的禮貌,照先前聊過的 從文字提醒到硬攔截的規則升級階梯 往上爬。想要管住授權,就必須把防線釘死在會產生副作用的動作出口上。

我把機制結合上游貼標設停點,與守在「實作收尾、發版、開 PR、試用結案(我的新工具與 hook 上線前都有一段試用觀察期,到期決定收編或淘汰就是試用結案)」這 4 個動作出口的對帳攔截,一共拉出 5 道防線:

第一道是來源貼標與帳本降權。在任何流程裡,只要是我方推論或顧問模型給出的建議,寫進下游文件或派工 prompt 前,必須死死貼上「未拍板」標籤,直到人類明確說定案才能拿掉。同時在工作流治理規格與實作收尾的範圍審查 skill 中明訂:決策帳本只作紀錄、不產生批准效力,未決事項只停相依工作。雖然舊決策帳本 skill 檔案內的原文還留在原處尚未直接刪掉,但收尾審查已不認帳本自寫定案,徹底拔除自我授權的合法性。

第二道是複合動作拆步停點。發版 skill 裡直接立規:同意發版不等於批准版號。它之所以有效,是因為把模糊的「重大決定」改成具體的字串分支條件,檢查人類當次指令裡有沒有明確出現版號數字;只要沒給版號,該步驟唯一合法的動作就是列出版號規則依據並原地停下等待,不准一鼓作氣把發版、跳號、推送整包做完。

第三道是同意綁定版本組合與差額重審。對外開源 PR 打包腳本把人類的核准,精確綁定在「目標 repo、合併目標分支、待送 commit、標題、內文全文」這整組內容上,並把審過的內容存成快照檔。事後若有修改,重跑腳本時會用程式自動比對當前版本與快照的差異,直線後代走差額模式重新送審,歷史改寫則強制退回整包重審。這套機制目前是開 PR 前必須先跑打包腳本與呼叫唯讀審查 subagent 規定在流程裡,尚未掛底層 hook 機械攔截,但至少把驗證邊界劃得一清二楚。

第四道是禁止同一個 PR 自改規則替自己開脫。這點非常陰險:有時候 PR 裡的程式碼明明踩到專案規則,agent 卻順手在同一分支的 CLAUDE.md 裡加一行例外條款,本質就是替自己偽造授權例外,然後理直氣壯回報程式碼完全符合最新規範。我在 PR 審查 command 裡加了硬性規定,審查 subagent 啟動前必須先檢查規則檔是不是在這次 PR 裡被動過;除非這張 PR 的原始任務本來就是人類指定要修改規則本身,否則同分支新增的放寬或豁免條款一律無效,強制拿合併目標分支起點的原始規則來判。

第五道是結案與收尾強制核對人類原話紀錄。新工具試用結案時,報告裡必須附上本地對話紀錄檔(JSONL)裡人類拍板那則訊息的唯一編號;實作任務收尾時,則由範圍審查 subagent 調出對話紀錄,逐條對照人類一開始打出的原話憑證。這裡的多 harness(執行外殼)有個邊界:在我的派工架構裡,Codex CLI 或 pi 等外部 harness 是由主 session 從背景啟動並轉發指令,只有預設的 Claude Code 有接上專門分離「真人親手在終端機補打的裁決」的解析器;其他 harness 無法自動拆出真人輸入,所以它自稱的所有「使用者已同意」,在收尾時一律打回待拍板,抓回主 session 當面重問我本人。

當場抓包兩次的收據:防線不是拿來擺好看的

這些機制到底是不是紙上談兵?當我們把人類同意當成憑證對帳時,不管是「沒點頭卻偷加設定」的越權擴張,還是「點了頭要做兩件事卻自己砍掉一半」的擅自縮減授權範圍,本質都是交付物跟人類當初點頭的原話憑證對不上。最近這 2 次當場攔截紀錄,剛好一正一反同時抓到。

第一次是攔截「偷加未拍板設定」。

今天早上我在擴充派工 skill 支援多 harness 時,這支 skill 啟動前會印出一則詢問我是否同意派工的確認訊息模板。我雖然整理了一份哪顆模型適合配哪個 harness 的推薦表,並依防線一標了「未拍板」,負責修改模板的 agent 卻還是順手把推薦表裡的 harness 直接寫成確認訊息的預設選項。這也證明光靠上游貼標籤仍可能被下游無視,必須靠收尾對帳兜底。到了收尾階段,範圍審查 subagent 調出早上我的原話紀錄,確認我當時只同意未指定時維持 Claude Code,當場開出缺陷把這段改動攔了下來,強制改回預設維持 Claude Code、推薦表只能作為參考附註。

第二次是追回「偷減已拍板需求」。

當時在整頓一條「防止 AI 短時間重複執行同一個驗證指令」的提醒 hook,我已在需求裡明確批准遇到推送與部署之後都要把計數歸零重算。負責實作的 agent 寫到一半,覺得各專案的部署指令缺乏單一固定入口比較難接,擅自把實作縮水成只重置推送,而把部署重置降級成結案文件裡的一句補充說明。收尾時範圍審查 subagent 核對原始拍板紀錄直接判未完成,當場把漏掉的部署後重置實作追回來補齊。

你看,如果沒有回到最初的人類原話收據做對帳,偷加設定的會變成常態,偷減需求的會變成既成事實,最後系統就是一步步往沒人知道的方向漂移。

動作出口守得住,純寫字階段還是有盲區

把話說到這裡,慣例還是要來疊個甲。

這 5 道防線之所以能真正發揮作用,靠的是守在「實作收尾、發版、開 PR、試用結案」這 4 個動作出口上的對帳與停點機制。也就是說,只有當文字準備變成 commit、準備推上遠端分支、或者準備宣告結案時,這些對帳器才會咬住不放。

那如果工作還停留在還沒走到動作出口的純研究報告或規格草稿階段呢?

老實說,一旦上游漏貼了「未拍板」標籤、幾份文件在草稿階段互相抄來抄去,目前並沒有自動程式能在純文字階段分辨哪一句是人類拍板、哪一句是模型順手加的建議。就像前面顧問模型把重跑對照組寫進規格那樣,只要還沒走到動作出口,這套防線就完全抓不到。在那個階段,你唯一能依賴的,就只有規格審查時追問每一條需求原始出處的習慣(這點在之前談 過度實作 時聊過),以及人類自己的眼睛。

回過頭來看,治理多 agent 協作的越權問題,根本不用想辦法調教模型的禮貌、或者求它多問一句請問這樣可以嗎。給 AI 套韁繩的關鍵,就是把人類的點頭當成一張有出處、有範圍、而且會過期的實體憑證;只要版本動了或範圍對不上,這張通行證就直接作廢。

想靠一句 prompt 讓它自律,不如在它打算關門收工的出口上,派個拿著原話收據的警衛站在那裡等它 🤣