AI Workflow · part 15
[Dev Workflow] 幫 AI agent 的 skill 減肥:193 個塞爆 2% 預算,砍到剩 7 個
❯ cat --toc
- 白話版:工具給太多,AI 反而找不到該用的那個
- 前言
- 一個 skill 不是免費的:193 條描述塞爆 2% 預算,常用的被靜默剪掉
- 兩個 lever:allowlist(不是刪)加薄殼配深引擎
- 三層治理:一個閘門、一個稽核、一個退場區,守住 7 不讓它肥回 193
- 這樣搭起來,換回什麼
- 實際怎麼砍——還有我在最常用的 skill 裡挖到的幽靈
- 砍預算之前,我先把整套 skill 庫健檢一遍——最恐怖的不是肥,是最常用的 skill 在爛
- 研究 mattpocock 的 skills repo:偷了三個 pattern、擋掉兩個
- 副產物:別把一行改動派單出去
- 收穫
- 如果你也要幫 agent 的工具箱減肥,這是我試出來的順序
TL;DR
某天早上讀 codex 紀錄,滑到一行:描述被剪短,才塞得進 2% 的 skills 預算。我共用的 root 有 193 個 skill,全載進一塊上限 2% 的 context,於是每條描述都被截斷——我天天在用的,被剪掉是為了替我從不碰的騰位子。解法是兩個 lever:allowlist(不是刪,disable 掉、檔案留、還能具名叫)把這個 agent 看到的從 193 降到 7;薄殼配深引擎,壓低每個 skill 的載入成本。再用三層治理守住:一個閘門管共用 root、一個稽核抓漂移、一個退場區可逆拆除——跟這系列同一套形狀。載更多工具,不等於更能幹。

白話版:工具給太多,AI 反而找不到該用的那個
想像你請了一個助理,上工第一天先發他一本「你會做的事」清單——他每天照著這本清單,知道自己能幫你做哪些事。問題是,這本清單有頁數上限。你東西塞太多、超過上限,系統不會提醒你,而是自作主張把每一條的說明都剪短,硬塞進那幾頁。結果呢?你每天真正會叫他做的那幾件事,說明被剪到他都認不太出來,慢慢就不主動做了;而那些被留著完整說明、其實你半年也用不到一次的,反而佔著位子。
我那個幫我跑很多雜事的 AI 助理,就是這樣。我把幾個月累積的「技能」(它能做的事,一件叫一個 skill)全丟進同一個共用資料夾,不知不覺變成 193 個。每次它開工,這 193 條說明要全部讀進它有限的「工作記憶」,而這塊記憶我只留了 2% 給這份清單。塞不下,它就把每條說明剪短——我天天在用的那幾個,被剪掉是為了替我從沒碰過的一百多個騰位子。
這篇要講的,就是我怎麼發現這件事、又怎麼把它從 193 條砍到 7 條:不是把用不到的刪掉(它們對我另一個助理有用),而是「這個助理不該看到」的就不要發給它。清單短了、常用的說明完整了,它反而更會做事。順便講一個更嚇人的:我趁機幫整套技能做健檢,結果發現我最常用的那個,居然一直在叫一個根本不存在的工具。
前言
某天早上,我終於認真讀了 codex 紀錄裡那行我滑過去很多次的字:Skill descriptions were shortened to fit the 2% skills context budget——描述被剪短了,才塞得進那 2% 的 skills 預算。
我共用的那個 skill root 有 193 個 skill。codex 開工會把它們全部載進一塊上限 2% 的 context,好讓它知道自己有哪些能力、什麼時候該伸手去拿。193 條塞不下 2%,於是它把每一條描述都截短,才擠得進去。翻成白話就是:我每天在用的那幾個 skill,描述被剪掉,是為了替另外那一百多個我從來不碰的騰位子。
這個系列前面幾篇,一路在把 agent 腦子裡「隱性的東西」外化成看得見、可驗證的檔案:它知道什麼(知識)、它做到哪(狀態)、任務派給誰(工單)、記得住什麼(記憶)、怎麼交接(協作)。這篇輪到外化最後一塊:「能力的可見度」——這個 agent 到底看得到哪些 skill。而我那行紀錄告訴我,這塊我一直放給它自己長,長到爆了。
一個 skill 不是免費的:193 條描述塞爆 2% 預算,常用的被靜默剪掉
先破一個我自己也曾經有的錯覺:多裝一個 skill,好像不花你什麼。錯。一個 skill 不是免費的——它的名字加描述,每個 session 都要載進 context,agent 就是靠這一小段字知道「這個 skill 存在、什麼時候該叫它」。一個兩個沒感覺,193 個那份「工具清單」就不再免費了。
我的 agent 明文只給 skill 這件事 2% 的 context。超過會怎樣?它不會報錯、不會停下來問你,而是「靜默截斷描述」:不是把 skill 丟掉、也不是大聲警告,是把每條描述剪短、剛好塞下。於是常用 skill 的觸發詞被剪掉,那個 skill 就悄悄不再被叫——因為 agent 靠描述裡的詞判斷「現在該用哪個」,詞沒了,它就看不到了。結論很反直覺:skill 越多,discoverability(agent 找不找得到某個 skill)反而越差。
而且根因不是「數量」,是「沒門禁」。這個共用 root 是開放的:任何 skill 丟進去就自動全載,沒有 allowlist、沒有 per-agent 的 view。193 這個數字根本不是我某天決定的,是幾個月一個一個累積出來的,而且每一個都預設「載進每一個 agent」。沒有人守門,它只會往上長。

兩個 lever:allowlist(不是刪)加薄殼配深引擎
怎麼從 193 降下來?我用了兩個 lever,一個管「這個 agent 看得到幾個」,一個管「每個 skill 載進來多貴」。
Lever 一:allowlist,不是刪。 codex 有原生的 [[skills.config]],可以把 skill 標成 enabled = false——檔案還在磁碟上、你要時仍能具名呼叫它,只是它不再吃「每個 session 都載」的那份常載預算。我一口氣 disable 掉大約 186 個,只留一份 7 個的 keep-list(handoff、record-learning、verify-citations、dev-loop-routing 這些 codex 真的會伸手去拿的)。那行 2% 的警告當場消失,這個 agent 的 skill 面從 193 掉到 7。
這裡的關鍵是 view——每個 agent 看得到的,是它自己那份 skill 清單。重點不是那 186 個 skill 沒用(它們多半是我另一個 agent 天天在用的),是「這個 agent 不該看到它們」。可見度應該是 per-consumer 的:同一個共用 root,不該把整堆東西原封不動發給每一個來拿的人。
Lever 二:薄殼配深引擎。 光是砍數量還不夠,還得壓低「留下來的每一個 skill」的載入成本。做法是把常載的那份壓成一行殼——只寫「這個 skill 是什麼、什麼時候用」;真正的邏輯放進另一個 module,agent 用到了才拉進來。一行殼幾乎不吃預算;反過來,一個 300 行的 skill,只要它常載,你每開一個 session、那 300 行都會吃掉 context,不管你這次用不用得到。(這是 John Ousterhout 講的 deep module:簡單的介面,底下藏著大功能。)同一個道理也套在共用的 CONTEXT.md 詞表上:handoff、工單這些名詞定義一次就好,別讓每個 skill 的前言各自重講一遍。這幾個 pattern,是我讀 mattpocock 的 skills repo 偷來的。
三層治理:一個閘門、一個稽核、一個退場區,守住 7 不讓它肥回 193
砍是一個下午的事。真正的工作是「守住」——因為那個把我養到 193 的原因(沒門禁)還在原地,你不擋,它明天就開始長回來。我用三層。
一、一個閘門。 那個共用 root 現在只有唯一一個 writer:一個同步用的 process。skill 不能再自己冒出來——想加,得走那道門。
二、一個稽核,盯著它實際看得到的清單。 我把 agent 實際看得到的那份 skill 清單納入週期健檢:把 config compile 出來對照 keep-list,只要多出我不認得的 skill,就丟進待辦清單。漂移從「隱形」變成「每次健檢都會被點名」。
三、一個退場區。 我幫另一個 agent 的 skill 目錄從 47 砍到 16 的時候,拿掉的那 31 個不是刪掉,是移進一個叫 _retired_ 的觀察期目錄。這一步是可逆的:先擺著,一段時間確定沒人用到,再真的刪。
如果你讀過這系列的 Part 14,這個形狀會很眼熟——一個閘門守寫入、一個稽核抓漂移、一個可逆的拆除。跟我管知識、管狀態、管記憶用的是同一套三件式,只是這次管的是 agent 自己的工具箱。

這樣搭起來,換回什麼
四個好處,照重要性排:
- 預算守在 2% 以下、描述完整。 這才是重點:discoverability 救回來了——agent 又看得到每個 skill 的完整觸發詞。省 token 只是附帶的 bonus,不是主菜。
- 每個 session 變便宜。 我拿一個固定的 canary 量,skill 那塊的 overhead 從「被截斷的 193 態」掉到大約 10k token。
- 它不會再靜默肥回去。 有閘門加稽核,要回到 193,得先過一道「會當場點名陌生 skill」的檢查——工具庫要再變肥,不會再默默發生了。
- 什麼都沒丟。 allowlist 不是刪、退場區也不是 rm。整套工具都還躺在磁碟上,只是這個 agent 眼前只看得到對它重要的那 7 個。
架構到這裡就講完了。只想直接套用的,拉到文末那份五行 checklist 就是全部。想看我實際怎麼砍、還有我在最常用的 skill 裡挖到的那隻幽靈——再往下讀。
實際怎麼砍——還有我在最常用的 skill 裡挖到的幽靈
底下是砍的過程,跟我順手挖出來的幾個坑。不讀不影響你套用上面那套設計,想拿結論的直接跳到收穫。
砍預算之前,我先把整套 skill 庫健檢一遍——最恐怖的不是肥,是最常用的 skill 在爛
動手砍預算之前,我先把整套 skill 庫健檢了一遍。結果最嚇人的不是「太肥」,是「我最常用的那個 skill 在爛掉」。
我的 blog skill(我跑最勤的檔之一)裡,引用了一個叫 webwright 的 skill 去生封面圖。問題是,那個 skill 整棵目錄根本不存在——這是一個幽靈引用。正確的做法其實早就寫在另一個 skill 裡,只是從來沒同步過來。這個洞擺了好幾個月沒人發現,因為大家都走熟路,而幽靈就住在那條很少有人走的岔路上。
同一場健檢還抓到別的:一個 clink(gemini) 呼叫早就死了(Google 把個人免費層下架了),但呼叫還留在那;還有一組叫「gate」的 skill,frontmatter 自稱串進 blog pipeline,我 grep 下去卻發現根本沒人叫它們——真正在跑的是內建的簡化版,那幾個外部 skill 是孤兒。
稽核跑出來的那張「零觸發清單」,乍看是一張「要不要刪」的清單,其實它是「壞了也沒人會發現」的清單——33 個 skill 裡有 21 個在 30 天內零觸發,而其中至少一個不是沒用,是接線斷了。這就是為什麼治理比砍更重要:skill 不只會越堆越多,實際行為還會慢慢偏離它宣稱的功能;那些你很少檢查的,接線可能早就斷了。
研究 mattpocock 的 skills repo:偷了三個 pattern、擋掉兩個
我認真讀了 mattpocock 那個 skills repo,而這段的紀律其實在「我沒拿什麼」。
偷進來三個結構 pattern:薄殼配深引擎(前面講過)、共用的 CONTEXT.md 詞表(名詞定義一次)、還有顯式的 disable-model-invocation——把「使用者手動叫」跟「模型自動觸發」分開,別為了讓模型自動觸發,就把一堆觸發詞硬塞進描述(那正好是把 2% 預算撐爆的元兇之一)。
擋掉兩個。第一個是它那套工單生態:我自己已經有一套工單,再接一套只會變成「兩份真相」,比一份還糟。第二個是 npx skills add 這個安裝通道——它會讓外部程式碼直接走進我的 harness,正好違反我前一段才立起來的那道門禁。整包裝進來,會把我一個下午的工全抵消掉。所以我的做法是:偷 pattern,別裝整包。
副產物:別把一行改動派單出去
最後一個坑很小,但很值得說。這整件事一開始,我把整個改動——兩個 config 值加一行規則——當成一張工單丟給背景 agent 跑,結果它跑了 20 分鐘。
我自己的鐵律是「工程執行外包、指揮官不下場」(這條在 Part 10 講過)。但「指揮官不下場」不等於「連 vi 改一行都要外包」。一個一行的 config 改動、diff 一眼就驗得完、有備份秒回滾,派單的成本(額度、排隊、還要盯它)比改動本身還高。門檻不是「這是不是 code」,是「有沒有調查量、有沒有跨檔的邏輯」;一行改動,兩個都沒有。
收穫
最花時間的地方
不是砍。砍是一個下午。最花時間的是那場健檢——因為我得先搞懂一件反直覺的事:「沒用」跟「接線斷了」,從外面看長得一模一樣,都是「零觸發」。我最常跑的那個 skill,一直在叫一個不存在的工具,而它零觸發的原因不是我不需要它,是它根本叫不動。分辨這兩者,比砍掉任何一個都花時間。
可搬走的診斷方法
三個,別的地方也用得上。第一,把「描述塞不下」那種警告當成「預算爆了」來讀,不是當成可以滑過去的嘮叨——你在用的東西被剪掉,是為了塞你不用的。第二,把「零觸發清單」當成「疑似壞掉」的清單,不是「該刪」的清單:凡是 frontmatter 宣稱有串接的,實際 grep 一遍,看到底有沒有人叫它。第三,整包裝任何外部工具之前,先確認它的安裝路徑有沒有違反你已經在依賴的某條邊界。
通用原則
agent 的能力是一種「有預算的共用資源」,而可見度需要門禁:allowlist 要 per-consumer、薄殼壓低每個 skill 的載入成本、稽核讓實際清單不再偏離 keep-list。這跟我管這整個系列其他東西用的是同一套三件式——一個閘門、一個抓漂移的稽核、一個可逆的拆除。載入更多工具,不會讓 agent 更能幹;讓更多工具「看得見、又讀得到」,才會。
如果你也要幫 agent 的工具箱減肥,這是我試出來的順序
- 把 skill 當預算看。 每一個常載的 skill,它的描述都在搶一塊有上限的 context;爆了,描述被截、discoverability 就壞了。所以要限制「載進來的量」,不是無腦往裡塞。
- allowlist 要 per-consumer,別用刪的。 給每個 agent 一份它真的會用的 keep-list,其餘 disable 掉——檔案留著、還能具名叫。可見度是 per-agent 的,不是一桌吃到飽。
- 薄殼、深引擎。 常載的那份保持一行殼,邏輯放進「用到才載」的 module;共用的詞表定義一次就好。
- 閘門守 root、稽核守面。 共用 root 只留一個 writer;週期檢查會點名那些「不該被看到」的 skill。
- 退場不是刪。 拿掉的 skill 先進一個觀察期目錄;在確定用不到之前,都留一條回頭路。
說到底,這篇把系列一開頭開的那個環扣了起來:知識、狀態、工單、記憶、協作,現在再加上 agent 自己的工具箱——全都用同一套在治:一個閘門、一個稽核、一個可逆的拆除。這麼做不是因為模型不可信,是為了讓你永遠不必去信它。
常見問題
- 為什麼 skill 越多,AI agent 反而越找不到該用的那個?
- 因為每個 skill 的名字加描述,每個 session 都要載進 context,agent 才知道它存在、什麼時候該叫。我的 agent 明文只給 skill 這件事 2% 的 context 預算;共用 root 累到 193 個,那份『工具清單』就撐爆上限。超過不是把 skill 丟掉、也不是大聲警告,是把每條描述剪短塞下——於是常用 skill 的觸發詞被剪掉,agent 悄悄不再叫它。skill 越多,discoverability 反而越差。
- allowlist 跟直接刪掉 skill 差在哪?
- 刪是把檔案從磁碟拿掉,別的 agent 也沒得用了。allowlist 是給每個 agent 一份它真的會用的 keep-list,其餘 disable 掉(codex 原生的 `[[skills.config]]` 標 enabled=false)——檔案留在磁碟、還能具名呼叫,只是不吃『每個 session 常載』的預算。可見度是 per-agent 的,不是共享自助餐;多數被 disable 的 skill 其實是我另一個 agent 天天在用,只是這個 agent 不該看到。
- 砍完之後,怎麼防止它又慢慢肥回去?
- 三層治理。一個閘門:共用 root 現在唯一的 writer 是一個同步 process,skill 不能自己冒出來。一個稽核:週期健檢把 agent 看到的 skill 面 compile 出來,確認正好等於 keep-list,任何陌生 skill 進待辦。一個退場區:移除的 skill 不是刪,是移進 `_retired_` 觀察期目錄,可逆,確定沒人用到才真的刪。
- 『薄殼配深引擎』是什麼意思?
- 壓低每個 skill 的載入成本。常載的那份保持一行殼(這是什麼、什麼時候用),真正的邏輯放進另一個 module、用到才拉進來(John Ousterhout 講的 deep module:簡單的介面藏著大功能)。一行殼幾乎不吃預算;一個 300 行的 skill 只要常載,你每開一個 session、那 300 行都會吃掉 context,不管你用不用得到。同一套詞表(handoff、工單這些名詞)也定義一次就好,別每個 skill 的前言各自重講。
接著讀
- 2026-07-16[Dev Workflow] 一群 AI 交接工作卻不用重講:原來是同一套系統的兩條軸
這是 AI Workflow 系列裡『兩軸合流』這一段的收尾。回頭看整段路,前面六篇其實在蓋同一套系統的兩條軸:持久知識(我知道什麼,長效、要用再查)和即時狀態(我現在做到哪,易逝、隨時寫)。這篇講清楚兩條軸為什麼互不代替、怎麼匯流到『多 AI 交接』、又受同一套哲學管——以及那條讓一群不完全信任的模型還能安全協作的中心律:沒有收據就不信。
- 2026-07-15[Dev Workflow] 搜尋找得到,卻要每個 session 重推一遍:幫 AI 記憶加一層蒸餾層
我拿一批 markdown 檔當 AI 的長期記憶,在檢索(搜尋加知識圖譜)之上再疊一層蒸餾層。檢索撈回的是原始材料,每個 session、每個 agent 都得重讀重推一遍;蒸餾層把定案結論冶煉一次、存成一檔一個 claim,之後直接取用。這篇講清楚這層是什麼、為什麼它的目的是『少解釋一次』而不是『逼大家講一樣』、以及我怎麼學會真的去信它。
- 2026-07-14[Dev Workflow] 搜尋找得到筆記、卻連不起來:幫 AI 記憶加一張知識圖譜
我拿大約 600 篇 markdown 檔當 AI 的長期記憶,分成三層:檔案本身是唯一的真相源、一個搜尋引擎讓它們找得到、一張知識圖譜用概念把它們連起來。這篇先講清楚這個設計、每一層為什麼存在、換來什麼好處,最後才講我建它時走錯的那幾條路。
- 2026-07-12[Dev Workflow] 交辦 AI 工程任務:交出去的單位是一張工單檔,不是一段對話
交辦 AI 工程任務,交出去的不是一段對話,是一張工單檔。這篇講我怎麼把任務寫成自足工單(目標/步驟/機器可驗收/紅線)、detached 背景派工給 Codex、用三個 flag 和一個看門狗擋掉永久卡死,以及為什麼收到完工報告不等於做完——報告是 claim,驗收重跑才是 evidence。
不想錯過新文章?
訂閱我確保不漏接!
隨時一鍵退訂。