AI 工作流 / 規則治理

AI 規則檔裝了攔截器,52 天一條都沒擋下來|AGENTS.md 優化,36,000 字的主檔瘦回 26,000

提示型的攔截裝了 52 天,一次都沒擋下來。我把 36,000 字的規則主檔瘦回 26,000,並且讓它這次真的胖不回去。

封面:Agent.md 精簡過又復胖?小心白白浪費 Token,咪卡拿著剪刀站在長長的紙捲軸旁

如果你跟 AI 講過的規矩,它下次就忘記,你大概會想再多寫一點、講得更清楚一點。我也是這樣,寫到 36,000 字。 我有一份寫給 AI 看的規則檔,它是我所有 AI 助手每次對話都會先讀一遍的東西。兩個月前我把它從 25,036 字砍到 15,822 字,還裝了一個防止它再變胖的攔截器。9 月 12 日我去量,它 35,960 字。攔截器裝了 52 天,檔案漲了 47%,一次都沒擋下來。 這篇記錄我怎麼找出真正的原因,以及最後怎麼把它瘦回 25,969 字,還讓它這次真的胖不回去。中間被另一家 AI 退回兩次,兩次都退在我以為已經做完的地方。

適合誰
  • 你寫了一大份規則給 AI,每次它出錯你就再補一條,但同樣的錯還是一直發生。
  • 你有一份文件越長越長,你知道該精簡,但每一條看起來都很重要,不知道砍哪裡。
  • 你幫團隊或客戶整理過工作規範,寫的時候大家都說好,三個月後沒人照做。
  • 你聽過「給 AI 寫規則」,但沒想過規則本身也會出問題。
你可以帶走什麼
  • 一個判斷方法:怎麼看出你寫的規則到底有沒有在生效。
  • 一個反直覺的結論:提醒式的攔截,效果跟沒有攔截一樣,我有 52 天的數據。
  • 一組可以直接套用的做法:把預設值從「想加就加」翻成「想加就先搬走等量」。
  • 一個檢查題:你手上有哪份資料正在被維護兩次。這通常才是文件失控的真正原因。

一份沒人讀完的規則檔,每次對話都要重讀一遍

先說清楚這份檔案是什麼,因為它跟一般的文件不一樣。

我用 AI 工作的方式,是把我所有的規矩寫成一份檔案,放在知識庫最上層。它的檔名叫 AGENTS.md,如果你用的是 Claude Code,同一個角色的檔案叫 CLAUDE.md,兩者作用一樣。每次我開一個新對話,不管是 Claude、Codex 還是 Gemini,它都會先把整份讀進去,然後才看我要它做什麼。裡面有安全規則(哪些指令絕對不准跑)、有工作習慣(檔名怎麼取、標籤怎麼掛)、有路由(遇到什麼情況該去讀哪個技能包)。

這份檔案有個特性:它不是給人讀的。沒有人會從頭讀完它。它的唯一讀者是 AI,而 AI 每一輪對話都要重讀一次。

所以它每長一個字,我每次對話都要多付一次。36,000 字的中文,大概是三萬個 token(AI 計費與計算長度的單位,一個中文字差不多一個 token)。我問一句「今天天氣如何」,也要先付這三萬。

但真正的代價不是錢。是注意力被稀釋

一條寫在第 200 字的規則和一條寫在第 22,000 字的規則,AI 遵守的程度不一樣。這件事我沒有嚴謹的實驗數據,但我有一個很說明問題的現象:我的規則檔裡有整整 600 字在講「急件流程要留下紀錄」,那段的最後一句是我自己寫的誠實標註,寫著「這條目前靠自律生效,沒有機械保證」。

600 個字,講一條靠自律的規則。而那 600 字擺在第 22,000 字的位置。

我兩個月前就裝了防復胖的攔截器,它一次都沒擋下來

7 月 4 日我做過一次瘦身,25,036 砍到 15,822,砍掉 37%。

砍完我就知道會復胖,因為之前發生過。所以 7 月 22 日我加了一道攔截:每次有人要改這份規則檔,就跳出三個問題問他。

1. 這條「每輪對話」都需要載入嗎?(不是「重不重要」,是「每輪都要嗎」)
2. 既有規則或工具已經涵蓋了嗎?
3. 掛在哪個執行器上?純靠自覺的話,違反的代價是什麼?

這三題我現在看還是覺得問得很好。問題在於它只是跳出來問,問完就放行。

我同時裝了第二個東西:一支自動記錄字數的程式,每次檔案被改就記一筆。當時我在程式的註解裡寫給未來的自己:「2026-08-22 評估要不要把提示升成硬攔時,讀這條曲線判斷有沒有止漲。」

8 月 22 日那天過了。沒有人去評估。

9 月 12 日我把那條曲線叫出來:

日期字數發生什麼
7 月 4 日25,036 → 15,822人工瘦身,砍掉 37%
7 月 22 日24,451裝攔截器。18 天就胖回來了
8 月 24 日33,039單日 +2,221
9 月 12 日35,960比裝攔截器那天多了 47%

攔截器裝了 52 天,檔案從 24,451 長到 35,960。

它每次都有跳出來。三個問題每次都有問。然後每次都被放行。

因為那三個問題,是問給一個已經決定要加的人聽的。

人(或 AI)在那個當下的心理狀態是「我剛踩到一個坑,我要補一條規則不要再踩」。這時候跳出三個問題,答案早就準備好了:重要、還沒涵蓋、靠自覺但代價很高。三題全過,加。

規則長太長只是症狀,真正的病是同一份資料維護兩次

我本來以為問題是「條文寫得太囉嗦」,準備逐條精簡。量完各段字數之後,發現不是。

段落字數該不該常駐
憲法(硬規則、安全紅線)7,346該。每輪都要
路由(遇到什麼情況去讀哪個技能包)22,638問題在這
其他5,976

路由段佔了六成。而我自己在這份檔案的開頭就寫著一句話:

操作細節一律放技能包,這裡只放路由。

結果路由段裡面,「網頁部署」那一塊 4,856 字,完整寫著 C 網怎麼部署、指令要帶什麼參數、驗收要看什麼、哪些能力還沒補上。那些內容在技能包裡本來就有一份

再往下挖,挖到真正的問題。

我有 114 個技能包,每一個都有一份 SKILL.md。我去數了一下:其中 108 個,檔案最上方都寫了一段 description,內容是「什麼情況該用我、什麼情況不該用我」。

那就是路由資訊。我早就寫好了,108 份。

而我在規則檔裡,另外手寫了一張 6,506 字的表格,內容也是「什麼情況該用哪個技能包」。

同一件事,維護了兩次。一次是自動可讀的(每個技能包自己帶著),一次是手寫的(塞在常駐檔案裡,每次新增技能包都要記得回來改)。

我自己的規則裡有一條叫「真相分身禁令」,寫的就是禁止同一份事實在多處人工重複維護。我違反了自己寫的規則,而且違反的地點就在那條規則的下面兩千字。

這件事還有一個外部證據。我派 Codex 幫我做跨家審查的時候,它的執行紀錄裡跳出一行警告:

Skill descriptions were shortened to fit the 2% skills context budget.

翻成白話:Codex 這套系統本來就有「技能包描述最多佔 2% 上下文」的預算限制,而我那 108 份描述已經肥到被它自動截短了。

我那 108 份描述加起來 39,736 字。比整份規則檔還大。

所以這件事有兩層:我維護了兩份路由,而且那份自動的,本身也太肥。

延伸閱讀

提醒型的攔截等於沒有攔截

把三個現象放在一起看,問題就清楚了。

第一,規則沒有執行引擎。

我在 7 月做過一次盤點:規則檔裡大約 220 條規則,只有 24 條有機械執行器(也就是真的有程式會擋)。剩下的靠自覺。而那些「違反了代價很高」的規則裡,有 48 條是純靠自覺。

我筆記裡有一條自己寫給自己的話:規則有寫卻沒擋住,缺的是引擎不是文字。 我知道這件事,還是又犯了一次。

第二,提醒沒有改變預設值。

提醒型的攔截,預設值還是「可以加」。它只是在加之前多問一句。而人在要加東西的當下,對「多問一句」是免疫的。

要改變行為,預設值本身必須翻轉:從「想加就加」變成「想加就先搬走等量」。

第三,同一件事維護兩次,遲早有一份過期。

而且過期的那份不會報錯。手寫的路由表和 108 份描述,哪一份是對的?沒人知道,因為兩份都沒有標記自己是不是最新。

這三點我認為可以離開我的例子,套用到任何「寫了規範但沒人照做」的場合。團隊的工作守則、客戶的 SOP、你給 AI 的提示詞,都一樣。

把「想加就加」翻成「想加就先搬走等量」

先講最有效的那一刀,因為它最簡單。

我把原本那個「跳出三個問題」的攔截器,改成字數預算

  • 設一個上限,就設成瘦身後的實際字數,不留餘裕。
  • 每次要改這份檔案時,算「改完之後會是幾個字」。
  • 超過上限,而且這次改動不會讓它變短,就直接擋下來,不讓改
  • 被擋的時候給三個出路:這條規則放去技能包、先搬走等量的文字再回來加、或是當次明確授權(授權要在工作日記留一筆為什麼)。

關鍵在「不留餘裕」這四個字。上限就等於現況,意思是這份檔案從今天起是零和的:你想加一條新規則,就得先找出一條舊的搬走。

這一刀之所以有效,是因為它不需要判斷「這條規則重不重要」。重要性是主觀的,每個人在當下都覺得自己要加的那條很重要。字數是客觀的,機器數得出來。

實作上有兩個細節是被 Codex 抓出來才補的,我原本都寫錯:

第一,要算改完之後的字數,不是改之前。我原本寫的是「現在已經超過上限就擋」,Codex 指出:那樣的話,檔案在 25,999 字的時候,可以一次寫進 5,000 字,因為寫之前還沒超過。

第二,要涵蓋所有的修改方式。我原本只擋了兩種寫入方式,Codex 指出還有第三種可以整批修改的方式沒擋,從那邊進去就繞過去了。

讓路由自己長出來,不要手寫第二份

第二刀處理「維護兩次」。

做法是寫一支小程式,去讀那 108 個技能包各自的描述,加上我從舊表格轉出來的關鍵詞,自動產生一份機器可讀的索引檔(一份 JSON)。

重點在三件事:

  1. 不改任何一個技能包。 那 108 份描述保持原樣,程式只是去讀它。
  2. 索引是生成物,不是手寫物。 任何人改了技能包的描述,索引自動重生,不需要記得回來改規則檔。
  3. 所有 AI 都讀得到。 它是純 JSON,Claude 有專屬的程式去讀它,Codex 和 Gemini 用一行搜尋指令也能查。

然後規則檔裡那張 6,506 字的表格就退場了,換成一段大約 500 字的協議:說明索引在哪裡、怎麼查、查不到的時候去哪裡找備援。

我另外保留了一份領域地圖,只有二十行,寫「寫作類找哪個包、部署類找哪個包」。這是 Codex 堅持要留的,理由我後面會講。

每輪對話只注入路標,不注入內容

第三刀回答的是我自己最初的問題:能不能不要全部常駐(常駐=不管你問什麼,它每次都先整份載入),改成遇到情境才把對應的技能包找出來。

可以,但有一個前提要先講清楚,否則會出事。

我做的版本是這樣:每次你送出一句話,一支小程式會先攔下來,拿你的話去比對那份索引。命中了就在你的訊息上方插一行提示,長這樣:

🧭 情境路由(關鍵字命中,會漏;動手前先讀 SKILL.md,判斷不合就不用):
- spring-editor ← 命中「深度文章」「文章」 → \_agent/skills/spring-editor/SKILL.md

它只給路標,不把技能包內容塞進來。要不要真的去讀,AI 自己判斷。

另外兩個設計:

  • 碰到高風險的字(部署、刪除、金鑰、發文、改規則)就多插一行安全提示,這一行不靠猜,只要字出現就一定插。因為這幾件事猜錯的代價太高。
  • 沒有命中也要印一行,告訴 AI 「沒找到,需要的話自己去查索引」。這一行是 Codex 要求加的,原因下一段講。

換掉手寫表格最危險的地方,是沒命中就安靜

這是整篇最重要的一段,也是我原本想錯的地方。

我一開始的設計是:命中就提示,沒命中就安靜。聽起來很合理,不要吵。

Codex 第一輪審查把它退回來,理由是:

刪掉手寫的語意表之後,hook 漏詞就靜默,Codex、Gemini 更沒有 hook,「與現況等價」不成立。

它說的是這件事:關鍵字比對一定會漏。讀者問「幫我把這段錄音轉成文字」,我的索引裡寫的是「轉錄」「逐字稿」,字面上沒有一個對得上,就漏了。這不是假設,是我自己寫的測試第一次跑就踩到的,補了別名才過。

而原本那張手寫的表格,雖然肥,但它一直在那裡。AI 讀得到全文,就算沒有任何提示,它掃過去也可能想起來「喔這件事有個技能包」。

把表格拿掉又讓提示靜默,等於從「看得到但被稀釋」變成「完全看不到」。那是退步,不是進步。

所以最後的版本有三層保底:

做什麼蓋到誰
路由提示命中就給路標只有 Claude
無命中提示印一行「自己去查索引」只有 Claude
領域地圖規則檔裡留二十行的領域對照所有 AI,包含沒有 hook 的

動態載入不能取代常駐,只能當加速器。 這句話是這次最大的收穫。

跨家審三輪退回,兩輪都退在我以為做完的地方

我的規則裡有一條:改規則主檔、改攔截程式,屬於最高風險等級,必須找另一家公司的 AI 來審。同一家的模型審自己,等於沒審。

這次的分工是 Claude 提案與施工,Codex 審查。三輪。

第一輪,退回。

最重要的一項是這個:我原本打算把搬出來的條文,放進一個新建的檔案裡。Codex 指出那會製造第三份真相:新檔案一份、原本的技能包一份、規則檔指向新檔案又是一份。我在解決真相分身的過程中,正在製造一個新的真相分身。

改法是把那 24 段條文逐字併回它們原本該在的 14 個檔案,每一段標記「這是從規則檔搬進來的,跟本檔既有內容重複的地方待去重」。

第二輪,還是退回。

這輪三項全部是同一種錯:我寫好了程式,但沒有真的掛上去

  • 攔截程式的提示訊息裡,還留著第一輪已經被否決的檔案名字。
  • 新的路由程式寫好了,但沒有註冊進設定檔,所以它根本不會被執行。
  • 攔截範圍漏了一種修改方式,從那邊進去可以繞過。

我在第一輪之後跟江江回報「已經改好了」。那個「改好了」是真的改了程式碼,但沒有接上電源。

第三輪,通過。

我另外做了一件規則要求但很容易跳過的事:真的演練一次退回。把三個檔案還原回瘦身前,量字數確認回到 35,960,再復原回 25,969。不是登記一條「出事可以還原」就算,是真的跑一遍。

我的規則裡寫著一句話:沒跑過演練,不准說退得回去。

延伸閱讀

字數預算擋得住總量,擋不住品質

這套做完之後,我要誠實講它保證什麼、不保證什麼。

保證得了的:

  • 這份檔案不會再默默變胖。想加就得先搬走等量,機器擋著。
  • 路由資訊不會再有兩份。表格退場了,索引是生成的。
  • 高風險的字一定會觸發安全提示,不靠猜。

保證不了的:

  • 字數預算擋的是總量,不是品質。 我可以在預算內寫一堆廢話。品質那層還是靠自問三題跟跨家審查。
  • 關鍵字路由會漏。 漏了就退回領域地圖跟 AI 自己找,跟瘦身前一樣,不會更差,但也沒有更好。
  • 只有 Claude 有這支程式。 Codex 跟 Gemini 靠的是規則檔裡那段文字約定,它們可以選擇不照做。這是我整套系統的共同限制,不是這次才有的。
  • 有一段路是我還沒走完的。 那 24 段搬進去的條文,跟原檔案既有的內容有重複,我這次刻意沒改寫(怕改出失真),排在兩個星期後處理。

還有一件事我想特別標出來,因為它跟這篇的主題直接有關。

這套機制是 9 月 12 日晚上做完的。我是 9 月 13 日凌晨,自己再去驗一次的時候,才發現用量紀錄裡混進了五筆測試資料。我每跑一次測試,就會灌進十筆「必然命中」的假紀錄,兩個星期後我要拿那份數據算「漏掉多少」的時候,數字會是假的。

做完不等於做對。 這是第四次驗收才抓到的東西。

延伸閱讀

OpenAI 說規則檔可以為新模型升級,改之前先看你主力跑哪個模型

就在我做完這次瘦身的同一週,OpenAI 發了一篇文章:Rethinking skills and prompts for GPT-6 Astra ↗,提醒大家:換到 GPT-6 Astra,很多人的 AGENTS.md 跟技能包都可以升級了。GPT-6 Astra 是 OpenAI 這次推出的新模型。

它提的幾個重點,跟這篇前面講的事情對得上:

  • 技能包的描述太長、裝太多,Codex 會自動把描述縮短,模型看到的變少,反而更難選對。我在前面貼的那行 Codex 警告,就是這件事。
  • 技能包的主檔寫成路標就好,細節放在分頁,用到才讀。
  • 不要寫「每次動手前都先讀這幾份文件」,改成「做哪件事的時候讀哪一份」。
  • 以前因為舊模型沒經過同意就代你做事,而寫得很硬的邊界,換成 Astra 之後可能要放軟,不然它會停在你其實希望它繼續做的地方。

我覺得概念很好。但務實來看,我是 100 的訂閱額度,其實不太可能全部都用 Astra 去跑,我的主力還是 Sol(GPT-5.6 Sol)。這篇文章裡的三輪跨家審,也都是用 Sol 跑的。

所以這件事要斟酌。那篇是在提醒大家可以針對 Astra 優化,其實每個模型都可以優化,但不是每個人都可以一直跑。大家不要無腦去改,還是要先評估自己實際的工作環境跟狀況。

OpenAI 那篇自己也提到一點:放在專案裡的規則,也會被其他人的 AI 讀到,那些 AI 用的不一定是同一個模型,對 Sol 有幫助的寫法,可能會把 Astra 綁得太緊。而我的規則檔,本來就同時給 Claude、Codex、Gemini 三家讀。

今天就能開始:找出你手上維護兩次的那份資料

如果你手邊有一份越長越長的文件(給 AI 的規則、團隊的守則、客戶的 SOP),三個步驟:

第一步,量一下各段字數,不要憑印象。

我本來以為要逐條精簡,量完才發現六成集中在一段,而那一段的內容技能包裡本來就有。憑印象你會砍錯地方。

第二步,問這一題:這份文件裡,有哪一段的內容在別的地方也有一份?

這題比「這條重不重要」好用太多。重要性人人都覺得自己那條重要,重複是客觀事實。找到重複的,決定哪一份是正本,另一份改成指向它。

第三步,給它一個零和的上限。

上限就設成你整理完之後的實際字數,不留餘裕。從今天起要加新的,就得先搬走舊的。

這三步不用自己動手,可以直接複製下面這段,貼給你平常在用的那個 AI(ChatGPT、Claude 都可以),把你的文件一起丟給它:

幫我做三件事。第一,把這份文件每一個大段落的字數列出來,由多到少排。第二,逐段告訴我,這一段的內容有沒有在我其他的檔案裡也存在一份,有的話指出是哪一份。第三,假設這份文件從今天起不准再變長,只能等量替換,你會建議我先把哪一段搬走,搬去哪裡。

最後一句話,是我這次真正學到的:

你寫了規則卻沒人照做,通常不是規則寫得不好,是那條規則沒有掛在任何一個會動的東西上面。

先去找出你那條「寫了但沒有引擎」的規則。比再多寫一條有用。

給 AI 讀的備忘(不懂技術的讀者可以跳過這段)

這段是寫給你的 AI 看的。如果你想做同一套,把這段連同你的檔案一起貼給它。

字數預算閘門的判斷式

攔截條件 = (現有字數 + 這次的增量 > 預算上限) AND (這次增量 >= 0)

三個實作要點:

  1. 算的是寫入後的字數,不是寫入前。判寫入前的話,檔案在上限邊緣時可以一次寫進大量內容,因為寫之前還沒超過。
  2. 要涵蓋所有寫入路徑。以 Claude Code 為例,至少要蓋到 Edit、Write、MultiEdit 三種,只擋前兩種會從第三種繞過去。用指令列寫檔的路徑量不到增量,只能提示不能硬擋,而且不應該硬擋,因為還原用的指令本身也會經過那裡,擋了會把自己的退路堵死。
  3. 上限設成整理完的實際字數,不留餘裕。留了餘裕,餘裕就會被填滿。

路由索引的生成邏輯

對每個技能包資料夾:
  讀 SKILL.md 最上方的 frontmatter
  取 description 欄位
  觸發詞 = description 裡「」引號內的詞
         + 「當使用者說 A、B、C」這類頓號串拆出來的詞
         + 別名檔裡手動補的詞
         + 技能包自己的名字
  短描述 = description 截前 120 字
輸出成一份 JSON

兩個設計決定:

  • 不改任何一個 SKILL.md。描述保持原樣,生成器只讀不寫。改了就會變成「為了做索引而動到 108 個檔案」,風險與工作量都不值得。
  • 別名檔是手動的,而且必須手動。從描述自動抽出來的詞覆蓋不了口語講法(「轉錄」抽得到,「錄音轉成文字」抽不到),別名檔就是補這一塊的。它會過期,所以要靠用量紀錄定期回頭補。

路由提示的注入原則

  • 只注入「技能包名稱 + 檔案路徑」,不注入技能包內容。注入內容等於把肥的東西換個地方塞回來。
  • 分數排序用「命中詞的總長度 + 命中數量」,長詞比短詞可信。名稱完全命中給額外加權。
  • 沒命中也要輸出一行。靜默是這套機制最大的風險:關鍵字一定會漏,漏了又不出聲,AI 就完全不知道有這個東西存在。
  • 高風險詞(部署、刪除、金鑰、發文、改規則)獨立一條規則,只要字出現就注入安全提示,不參與分數排序。

測試怎麼寫才有意義

測試句一定要包含這三類,只測命中的等於沒測:

類型例子要驗什麼
同義改寫「幫我把這段錄音轉成文字」索引裡寫的是「轉錄」,這句字面上一個都對不上
無命中「今天天氣如何」要靜默還是要印提示,這是設計決定不是 bug
多包衝突「把逐字稿整理成會議記錄」同時命中五個包,排序對不對

還有一個很容易忽略的:測試腳本本身不要污染用量統計。我第一版沒處理,每跑一次測試就灌進十筆必然命中的假紀錄,兩週後要算漏失率的時候,那份數據是廢的。做法是讓測試帶一個固定的識別碼,記錄那一段看到就跳過。

這篇提到過的
再往前後延伸

我是江江教練

我幫一人公司與中小團隊,把散在腦袋、對話與檔案裡的東西,變成 AI 真的用得動的知識系統。這篇寫的就是我自己每天在跑的那一套。

想從哪裡開始都可以

官網有一百多篇拆解,從第一次跟 AI 講話到整套工作流都寫在裡面。想聊聊你手上那份越長越長的文件,LINE 社群裡直接問我。

加入 LINE 社群 ↗