AI Engineering

Ship with skills, not vibes 把 25 支 skill 串成一條開發流程

這不是工具箱清單,是一條主幹流程加幾條匝道。從一個模糊的想法走到 commit,中間每一步該打什麼、該在哪裡停下來、以及哪些地方會安靜地壞掉。

01

先建立三個底層觀念

本頁描述的是 mattpocock/skills(MIT 授權)第 1.2.3 版,25 支已發布的 skill。這套 skill 不是 TauX 的作品;這篇教學是。下面所有的判準、坑與劇本都是我們讀完官方文件與 issue 之後重新編寫的中文教材,不是翻譯,也不是轉載。

不先懂這三件事,後面每一支 skill 都會用錯。

一、誰能叫它

這是整個 pack 唯一的分類軸線

User-invoked Model-invoked
誰能觸發 只有人類打出名字。其他 skill 也不能叫它 你可以打,agent 也會自己判斷後抓來用
設定 disable-model-invocation: true 兩者都不設
description 寫給誰 人類(slash command 清單) 模型(含大量觸發語句)
定位 編排者:決定流程怎麼走 紀律庫:可重複使用的方法論

三個實務後果

  • 文件寫「接著跑 /implement」,那是叫去打。agent 不會自己接下去。
  • harness 不把 user-invoked skill 注入模型的清單,所以 agent 常常「以為」這些 skill 沒安裝。它們在,照打就是。
  • 想確認到底裝了什麼,看 .claude-plugin/plugin.json,那才是權威。

規則本身:user-invoked 可以呼叫 model-invoked,但永遠不能呼叫另一個 user-invoked

二、四種角色

主幹

從想法到 ship 的固定路徑:grill-with-docsto-specto-ticketsimplementcode-review

匝道

產生工作、然後併入主幹:triage(別人丟進來的)、wayfinder(一個 session 裝不下)、improve-codebase-architecture(定期體檢產生題目)。

獨立

隨時抓來、用完就走:prototyperesearchdiagnosing-bugsresolving-merge-conflictswizardhandoffteachto-questionnairewait-whatgrill-me

詞彙層

沒有流程,只提供精確用詞,被別人借用:codebase-design(模組形狀)、domain-modeling(領域語言)、writing-for-agents(給 agent 讀的文件)、grilling(訪談原語)。

詞彙層最容易誤用

它們沒有流程。你對著 codebase-design 說「開始吧」,agent 會自己發明一套流程,然後燒掉 100k token 重構你沒問的東西(已登記的 issue 449)。詞彙層要用「driver skill 在上、詞彙層在下」的方式跑。

三、Phase boundary

一個 session 裡的一塊工作叫 phase(訪談、實作、QA…)。「我的 context 該怎麼辦」這個問題只在兩個 phase 之間才成立。phase 中間沒得選,只有繼續,或把剩下的丟給 subagent。

順位 選項 什麼時候選
1 繼續 下一個 phase 需要這個 phase 的原話,或你的 smart zone 還有餘裕。這是唯一保住一手資料的選項,所以先排除它再考慮別的
2 clear 後面的東西全部可丟。最便宜,但判斷錯了就是單向
3 handoff 有東西要搬家:換 harness、換目錄、給同事、把中途發現的支線分出去
4 subagent 任務範圍夠緊,可以你人不在也跑得完
5 compact 以上都不是。它是保底而不是首選,但實務上落點最多

最常被搞錯的兩個:handoff 不是「跨窗口的通用橋樑」,它買的只有可攜性compact 是樹的底部而不是第一反應。三者保住的東西不同——compact 保住你的意圖,clear 什麼都不保,handoff 保住工作的移動能力。而這三個都會把對話(一手資料)變成摘要(二手資料)。

02

安裝:兩條路,選一條

兩種安裝方式代表兩種哲學。裝兩次會讓你每個 skill 都有兩份。

路線 A — 訂閱

claude plugins install mattpocock-skills

或在 session 內打 /plugin install mattpocock-skills。已在官方 marketplace,不用先加來源,更新自動到。代價:唯讀,你不能改。

路線 B — 可改版

npx skills@latest add mattpocock/skills

會問你要裝哪些 skill、裝到哪些 agent 上。一定要勾 setup-matt-pocock-skills檔案以「你擁有的普通檔案」寫進 repo,可隨便改;要更新時自己跑 npx skills update

路線 B 的陷阱

你手改的 SKILL.md 會被 npx skills update 覆蓋。任何想長期生效的行為,寫在你自己的 CLAUDE.md / AGENTS.md(見 第 09 節),或每次呼叫時講出來——不要改 skill 檔。

想玩 beta

npx skills@latest add mattpocock/skills --skill=<name>

plugin 不會給你這些。撰稿時的 in-progress bucket 有 loop-mewriting-beatswriting-fragmentswriting-shapeclaude-handoffsetup-ts-deep-modules——沒有文件頁、隨時可能改掉或消失。另有一個不在 plugin 內的 misc bucket:git-guardrails-claude-code(用 hook 擋危險 git 指令)、setup-pre-commitmigrate-to-shoehornscaffold-exercises

03

前置設定,每個 repo 跑一次

/setup-matt-pocock-skills 是所有 engineering skill 的前置條件,不是流程的一步

決策 它會先提議 什麼時候才真的問你
Issue tracker 依你的 git remote 猜 每次都問——這是唯一真正的選擇
Triage 標籤 沿用五個標準名 只有裝了 triage 才問
Domain 文件配置 單一 context:root 一份 CONTEXT.mddocs/adr/ 只有偵測到 monorepo 訊號才問

Tracker 四個選項:GitHub(需 gh)、GitLab(需 glab)、Local markdown.scratch/<feature>/,連 remote 都不用)、Other(你寫一段描述工作流程的話)。

Local markdown 是一等公民不是備案:單人專案、沒有 remote,完全支援。但不要在用 GitHub 的專案同時用 local markdown,它們是替代品不是疊加。

「Other」也不是佔位符——Jira、Linear、Azure DevOps 能跑就是靠它:你描述工作流程,它把你的話寫進 docs/agents/issue-tracker.md,下游 skill 照那段話做。這也是為什麼這整套沒有綁 GitHub,而且你永遠不用改 skill 檔來換 tracker。

三個一定要知道的坑

一、它不會幫你建 label

triage-labels.md 只是「對照表」。全新的 GitHub repo 上那些 label 根本不存在,貼標籤就會失敗。自己先建一次:

gh label create needs-triage
gh label create needs-info
gh label create ready-for-agent
gh label create ready-for-human
gh label create wontfix
gh label create bug
gh label create enhancement

要用 wayfinder 的話,另外五個也要先建(gh 遇到不存在的 label 是直接失敗):wayfinder:mapwayfinder:grillingwayfinder:prototypewayfinder:researchwayfinder:task

二、它看檔案存不存在,不是看你用哪個 harness

你在 Codex 但 repo 有殘留的 CLAUDE.md,那段 ## Agent skills 就會寫到 Codex 永遠讀不到的地方。解法:手動搬到 AGENTS.md,或讓 AGENTS.md 當本尊、CLAUDE.md 只放一行指向它。

三、更新 skills 之後可以再跑一次

種子模板會改版,舊的 issue-tracker.md 可能對不上新的 skill。下游行為變怪時,重跑是最便宜的修法。

判斷它成功了

  • docs/agents/issue-tracker.mddomain.md 存在(裝了 triage 還有 triage-labels.md
  • 你的 harness 真的會讀的那個指令檔裡出現 ## Agent skills
  • 之後 /to-tickets 不再問你 issue 放哪;/triage 是「貼」標籤而不是「發明」標籤
  • skill 檔本身一個字都沒動。如果 setup 改了某個 SKILL.md,那就是出事了

04

全套 25 支地圖

「硬依賴」那一欄是實戰重點——依賴沒裝,skill 會安靜地退化成一場即興表演。

Skill 呼叫權 角色 一句話
setup-matt-pocock-skillsUser前置每 repo 跑一次,設定 tracker、label 與文件配置
ask-mattUser路由器描述你的處境,它告訴你該打哪一串
grillingModel原語一輪一輪的訪談引擎,其他 grilling 全建在它上面
grill-meUser獨立無狀態訪談,不需 repo、主題不必是程式
grill-with-docsUser主幹頭同樣的訪談,加上讀 codebase、寫 CONTEXT.md 與 ADR
wayfinderUser匝道一個 session 裝不下的大工程,畫成 decision ticket 地圖
to-specUser主幹把對話收斂成一份 spec 並發到 tracker,不再訪談
to-ticketsUser主幹把 spec 或對話切成 tracer-bullet ticket 並宣告阻塞邊
implementUser主幹照 ticket 做,內部驅動 tdd,收尾跑 code-review,commit
tddModel引擎red-green,只在事先同意的 seam 上寫測試
code-reviewModel主幹尾對某個固定點的 diff 做 Standards 與 Spec 雙軸審查
triageUser匝道別人丟進來的 issue 走狀態機
improve-codebase-architectureUser匝道掃 codebase 找「加深模組」的機會,出 HTML 報告
prototypeModel獨立用丟棄式程式碼回答一個設計問題
diagnosing-bugsModel獨立難 bug 與效能回歸的六階段診斷,先有 red loop 才能猜
researchModel獨立背景 agent 讀一手來源,留下一份帶引用的 markdown
resolving-merge-conflictsModel獨立逐 hunk 依「意圖」解衝突,跑檢查,完成 merge,絕不放棄
wizardModel獨立產生一支互動 bash script,帶人類走只有人能做的步驟
codebase-designModel詞彙層模組、介面、depth、seam 的精確用詞與四條原則
domain-modelingModel詞彙層主動建立與磨利領域語言,即時寫進 CONTEXT.md 與 ADR
handoffUser獨立把當前對話壓成一份可攜的交接文件
teachUser獨立把當前目錄變成跨 session 的教學工作區
to-questionnaireUser獨立把「只有別人知道」的決策變成一份問卷
wait-whatUser獨立剛剛那段話沒聽懂時打它,agent 重講一次
writing-for-agentsModel詞彙層寫給 agent 看的文件(skill、指令檔、spec、prompt)的準則

兩個分岔要記住

  • prototype 岔路:訪談中遇到「講不出來、要看到東西才知道」的問題,停下來做 prototype,看完回來一行回答。
  • spec 與 tickets 只在跨 session 才划算。單一 context window 做得完的改動,直接 grill-with-docsimplement,跳過中間兩步。

05

主幹七步,逐步實作

貫穿案例

內部工具 repo(Next.js 加 Postgres),要加「合約到期提醒」——列出 30 天內到期的合約、寄信給負責人、後台顯示紅點。跨 schema、API、UI 與寄信,夠廣,值得走完整流程。

Step 1 — 把模糊的想法烤成決策

/grill-with-docs 我想加一個合約到期提醒功能

開一個乾淨的對話,關掉 plan mode。plan mode 會催 agent 趕快產出計畫,那正好和「保持在提問狀態」相反。

會發生什麼

它會讀你的 codebase,然後一輪一輪問你問題。每一輪是當前 frontier——所有前置條件都已解決的問題一次問完,所以你不會被問到還懸在半空的問題。格式固定:編號標題、內文、一行建議答案。13 題通常落在 3 輪;46 題分 4 輪是很正常的一場。

你該怎麼回

1 是
2 選第二個
3 不要,理由是我們的合約沒有部分終止
4 我不知道

最大的失敗模式是被動。連答四十個「同意」,出來一份 agent 寫的、你點頭過的計畫——感覺很有生產力,因為它很長。但什麼都沒被真正決定,而結果帶著它沒賺到的確定性。主動的意思是:問得比你需要的精度還淺時推回去;範圍在漂時講出來;真的不知道就答「我不知道」,這是真的答案。

grillable vs ungrillable

「一張長表單還是三頁?」「這個互動應該是什麼感覺?」——這種問題談不出來,需要有東西可以反應。碰到就停下來去做 prototype,看完回來一行回答。在 ungrillable 的問題上硬談,是 session 爆炸的主因:agent 一直換句話問,你一直猜,範圍膨脹來填補不確定性。

解決了什麼 落在哪
一個術語——這專案自己的用詞CONTEXT.md當場寫入,不是最後批次產出
一個難以逆轉、沒有 context 會覺得意外、真的有取捨的決定docs/adr/ 下的一份 ADR
其他所有你決定的事只在對話裡,別的地方沒有

第三列的意思

你談出來的絕大部分東西只存在於這個 context window。所以不要 clear、不要 compact,直接在同一個對話裡接 /to-spec

CONTEXT.md詞彙表,而且只是詞彙表——不放實作細節、不放 spec、不放草稿。ADR 三個條件要同時成立,所以大部分 session 產出 0 份 ADR,這是設計如此

這一步用你最好的模型。grilling 吃的是模型自己對「系統會怎麼壞」的直覺;實作階段反而比較吃 context,可以用便宜一點的。

Step 2 — 把已決定的事變成一份可存活的文件

/to-spec在同一個對話裡,不要開新的

不訪談你。你走到這一步該決定的都決定完了,所以它是「綜合」——從對話、codebase、CONTEXT.md 與 ADR 裡整理。

spec 是決策紀錄,不是決策現場

它存在的理由是 context window 會結束:你剛烤出來的一切,都在一個即將被清掉的對話裡。spec 就是那場對話的倖存者。所以它不驗證任何事、不決定任何事。spec 裡任何一句你沒說過的話,都是缺陷。

它會先跟你確認 seam

寫任何一個字之前,它會先草擬這個功能要在哪些 seam(測試觀察行為的公開邊界)上被測,然後拿來問你。它偏好已存在的 seam 而不是新開一個,並取它能取到的最高的 seam——理想的數字是整個改動只有一個。這個「事先同意的 seam」會一路往下傳:tdd 只在事先同意的 seam 上寫測試,code-review 會檢查有沒有用了沒同意過的 seam。所以這段對話要認真回,不要拖到實作階段。

你在哪 跑什麼
什麼都還沒決定grill-with-docs
決定了,而且一個 context window 做得完直接 implement跳過 spec
決定了,工作要跨好幾個 session/to-spec,然後 /to-tickets
剛清空一張 wayfinder 地圖/to-spec #<map_issue>

常見坑

  • ready-for-agent 標籤的誤會:spec 會被貼上它,意思是「不需要再 triage 了」,是輸入資格而不是工單。但如果你有無人看管的 agent 在輪詢這個標籤,它分不出差別,會一口氣想把整份 spec 做完。解法:在那個 agent 的 prompt 裡明確排除 parent spec,或 /to-tickets 跑完就把標籤拔掉。
  • 重構型工作不合模板:模板重壓 user story,架構工作套上去會變成「沒人要求過的故事」。改靠 implementation-decisions 與 testing-decisions 兩節,耐久的架構決定讓它以 ADR 形式從 grill-with-docs 落地。
  • 它不會查重:不會搜 tracker 看有沒有人開過同樣的 issue,也不會把它遵守的 ADR 連進來。熱區自己先搜一下。
  • spec 太大會被截斷:巨大的 spec 超過 tracker issue 能乾淨回傳的量,而且沒有本地副本可退。/to-spec/to-tickets 之間不要 clear 也不要 compact。

Step 3 — 切成 tracer bullet

/to-tickets,同一個窗口,或 /to-tickets #<spec_issue>。計畫只在對話裡、沒寫成 spec 也行,它直接讀對話。

水平切片(錯) 垂直切片(對)
一張票交付改動的一層(全部 schema 一張、全部 API 一張)穿過所有層的一條細路
落地後每層都到位前什麼都不能動自己就能 demo
驗收條件必須伸手到別張票擁有的工作只評自己擁有的東西

這是最常被違反的規則,代價有實測:某團隊用 26 張按層切的票(corpus、producer、aggregator、selector),平均每張票關閉要跑 20 次 agent,其中約四分之三是重工。他們自己的檢討把每一類失敗都追回到水平切片,而不是實作品質。

你要做的檢查

對每一張票問一句——「這張做完我能 demo 什麼?」答不出行為的,就是水平切片。有人會在每張票加一行 demo path,據報能把模型推向垂直分解。

發布前

Prefactoring:它會先找「先讓改動變容易,再做那個容易的改動」的工作,排在最前面。然後給你編號清單並質詢你:粒度對不對、阻塞邊是不是真的、有沒有該合併或拆開的。在你核准之前不會有任何東西進 tracker——這個質詢步驟就是你推回去的地方。

寬重構是唯一的例外

有一種形狀打破 tracer-bullet 規則:單一機械式改動,但爆炸半徑遍及全 codebase(改一個欄位名、換一個共用型別)。一次編輯打爛上千個呼叫點,沒有任何垂直切片能綠燈落地。走 expand–migrate–contract:Expand——新形式加在舊形式旁邊,什麼都不壞;Migrate——依爆炸半徑分批搬呼叫點,一批一張票,都被 expand 阻塞,CI 保持綠燈因為舊形式還在;Contract——沒有呼叫者了才刪掉舊形式,被所有 migrate 批次阻塞。

常見坑

  • 三行的改動切出 12 張票:過度分解是最常見的摩擦。在質詢步驟叫它合併。更根本的答案是:整個改動塞得進一個 context window,你根本不需要這支 skill
  • GitHub 上沒建成 sub-issue:已知未修(issue 554),Codex 更嚴重。gh 自 v2.94 原生支援 gh issue create --parentgh issue edit --add-sub-issue
  • 「Blocked by」只寫在內文:同類問題(issue 513)。GitHub 有原生的 gh issue create --blocked-by。因為阻塞者先發布,號碼在建立時一定拿得到。
  • 驗收條件什麼都沒評到:對每一條,指出「什麼觀察會證明它為假」,並確認它在起始 commit 上是紅的。
  • 票發完了,然後呢?沒有自動派工。看板面、數沒有未完成阻塞者的票有幾張,就開幾個 agent session。一票一個全新 context,中間 clear。

Step 4 — 一票一個 session

/implement https://github.com/you/repo/issues/12

為什麼要寫完整 reference

/implement #2#2 是對「agent 看得到的任何編號清單」解析的——在新 session 裡那可能是一個 todo 檔或 checklist,而不是你設定的 tracker。而且它解析得很自信、不會 fail-closed,所以錯了你不會馬上發現。傳完整 URL 或 owner/repo#2,並要它把標題唸回來確認再開始。

一次 run 的五拍

  1. 讀 ticket 或 spec,推出 seam
  2. 在事先同意的 seam 上驅動 tdd,一次一個 red-green 切片
  3. 頻繁 typecheck,過程中跑單一測試檔
  4. 最後跑一次完整測試套件
  5. code-review,然後 commit 到當前 branch

它絕不做的事

它從不重開計畫。沒有訪談、沒有澄清回合、不會提議另一種做法。上游決定的東西就是輸入,它的工作就是把它變成一個 commit。這正是它和「對一個新 agent 打『做這個』」的差別——後者會邊做邊重新設計。

症狀 說明
跑完了,但票還開著、驗收條件還沒打勾正確且預期。implement 沒有收尾步驟,它停在 commit。票要你自己關——這在依賴鏈上咬最兇:frontier 的定義是「阻塞者全關」,沒人關就永遠沒有票變成可做
能不能一次做完所有票、平行跑?不行。同一 checkout 並行跑多個 implement 比「不支援」更糟:有實地回報一個下午內出現 amend 打到另一個 session 的 commit、stash 消失、commit 落到錯的 branch。社群 workaround 是 worktree,但 stash 仍共用
能不能開 PR?沒有內建。它 commit 到當前 branch,也不會幫你開 branch。有人在呼叫時覆寫
code-review 說看不到我的改動它審 diff <fixed-point>...HEAD排除 staged 與 working tree。implement 在 commit 前跑 review,所以除非已有中途 commit,那個 diff 裡沒東西。先 commit 再 review
一張票燒掉 150k token通常是票太大而不是用錯。一個 run 含探索 codebase、每個 seam 的 red-green、完整套件、review,超過 100k token 是正常的。槓桿在上游:把票調到一個新窗口裝得下。單張票一直爆就拆它,不要調高 effort

有些人刻意不要內建的那道 review——寫程式的 agent 審自己寫的程式會偏袒自己的解法。在乾淨的 session 裡對固定點另跑 code-review 是合理的替代做法。

Step 5 — red-green 引擎

tdd參考資料,不是驅動器:它握著迴圈的規則,跑 session 的是別人(你,或 implement)。

Red-green

寫失敗的測試,然後只寫剛好讓它通過的程式。不預先寫下一個測試。沒有 refactor 階段——2026 年 6 月移除,因為 agent 幾乎從不執行它,而且 review 與 implementation 分開 session 效果更好。重構歸 code-review。

Vertical slice

一個 seam、一個測試、一個最小實作,然後重複;第一個 cycle 是 tracer bullet,證明一條路端到端走得通。反面是先寫所有測試再寫所有程式——那是在驗證想像的行為,檢查東西的形狀而不是使用者做的事,並且在你理解實作之前就把你綁進一個測試結構。

Pre-agreed seam

規則是絕對的:沒有確認過的 seam,不寫測試。完整鏈路裡 seam 在 to-spec 就談好;單獨呼叫時它直接問你。

反模式 徵兆
Implementation-coupled你改一個內部函式名字、行為沒變,測試卻壞了。mock 自己的內部協作者、斷言呼叫次數、用資料庫查詢驗證而不是用介面
Tautological期望值是「照程式的算法」算出來的,所以測試必然通過。期望值必須來自別的地方:已知良好的字面值、手算的範例、spec
Horizontal slicing一批測試在任何實作之前就落地了

Mock 只用在系統邊界:外部 API、時間、隨機。有時是檔案系統或資料庫。不要 mock 你自己的模組。

常見坑

  • 「它問我選哪個 test seam,我根本不知道選哪個」:最常見的摩擦(issue 607)。提示只列出候選 seam 的名字,沒說各自抓到什麼、漏掉什麼。回問 agent 取捨:component 層的 seam 漏掉什麼是 integration seam 抓得到的、慢多少。這也正是完整鏈路要在 to-spec 就談 seam 的理由。
  • 它先寫實作才寫測試:會發生。skill 是「帶著這件事一起活」的寫法,沒有任何指令能讓 agent 100% 遵守。某個切片真的需要嚴格遵守,就盯著它跑。
  • 它先寫瀏覽器測試然後鬼打牆:有人回報 agent 先寫 Playwright、然後在一個還不存在的功能上反覆跑、最後結論是「測試壞了」。在 repo 的指令檔宣告:browser 測試在行為可運作之後才寫。
  • 它不知道你其他張票:對著一張票跑,它會很開心地提議屬於兄弟票的工作(issue 129)。把 spec 和 ticket 一起給它有幫助;一開始就把票切對更有幫助。

Step 6 — 雙軸審查

/code-review main

固定點你必須提供;不給它會問你,不會亂猜,而且會先驗證 ref 解得出來、diff 非空,才生 sub-agent。

Standards Spec
問題做得對不對?做的是對的東西嗎?
讀什麼repo 自己記載的規範,加內建 smell 基準源頭的 issue 或 spec
報什麼明文違規(可以是硬性的)加 smell(永遠是判斷題)缺漏或部分實作的需求、範圍蔓延、實作錯的需求
每個發現必須引用規範檔加條目,或 smell 名稱加 hunkspec 的那一行

兩個軸各跑在自己的 sub-agent 裡,互相看不到對方的推理。報告結尾給「每個軸各自最糟的問題」,並拒絕跨軸選一個總冠軍——因為一個改動可以一軸過一軸掛:遵守所有慣例但做錯東西的程式 Standards 過、Spec 掛;完全照票做但破壞 repo 慣例的反之。混合的裁決會讓過關的那軸掩護掛掉的那軸。

Smell 基準是 Standards 底下的地板:Fowler《Refactoring》第 3 章的 12 個 code smell。每個都是「可能是…」的啟發式標籤、永不是硬性違規,而且都以「它是什麼,怎麼修」陳述,所以發現送到你面前時自帶一個動作。你的 linter 已經在管的東西,兩個軸都跳過。

常見坑

  • 和內建的同名指令撞名:最常被回報,未修。內建那個是「在 diff 裡找 bug」,這個是規範與 spec 合規。裝了就有一個會贏,誰贏取決於安裝方式。
  • sub-agent 又去呼叫自己,生出更多 agent:多人多 harness 重現過,有一次到 50 個以上。fork 上的修法是在兩個 sub-agent brief 各加一行「不要呼叫 code-review 或生成額外 agent,直接執行這次審查」。無人看管跑這支時,盯著 agent 數量。
  • 該在寫程式的同一個 session 跑嗎?偏好用新的。有人講得很好:同一個 context 審自己,等於帶著 slash command 的確認偏誤。
  • 發現可以信嗎?不查證不能信。sub-agent 的輸出是假設不是證據。它彙總兩份報告但不逐條回檔案驗證,所以引用可能指錯位置或誇大影響。看每個發現的引用再行動。
  • 為什麼每次跑都找到新問題?修改會創造新表面,而判斷題那半不是決定性的。沒有收斂保證。把一次 pass 當成線索清單,處理有明文規則背書的,然後停手——不要跑到它「乾淨」為止,它不會。

Step 7 — 收尾與循環

一票的循環:

  1. clear context
  2. /implement <ticket>tdd 在裡面跑)
  3. commit
  4. /code-review <fixed-point>,乾淨 session
  5. 手動關票、對驗收條件——implement 不會做這件事
  6. 回到 frontier 抓下一票,回到第 1 步

節奏

  • 每天:主幹。一票一 session,中間 clear。
  • 每幾天/improve-codebase-architecture,把結構債變成新的題目餵回主幹。
  • 有 inbound 工作時/triage。沒有外部回報的專案,你會很少開它。
  • 需要補技能時/teach,開一個專屬目錄。

別忘了

整條鏈唯一沒有人幫你做的事,是關票與對驗收條件。implement 停在 commit。依賴鏈要往前走,就得靠你把票關掉——不然 frontier 永遠不會出現新的可做項目。

06

情境索引,什麼時候抓哪一支

主幹以外的 skill 都是「特定情況才岔出去」。這裡按你的處境排列。

獨立 — prototype

這個問題我談不出來

它寫的是回答一個問題的丟棄式程式碼。問題先來,而且決定後面所有東西的形狀;回答錯問題的 prototype 是純浪費,不管它多好看。「丟棄式」是對怎麼寫的約束,不是「一定要銷毀」的承諾:沒有測試、除了跑得起來以外沒有錯誤處理、沒有抽象、沒有持久化。

兩條分支的產出物差很多。「這個邏輯或狀態模型感覺對嗎?」得到一個可分享的單一 HTML 檔——自帶 state panel、free-play 按鈕、分頁式導覽,全部用領域語言標示,可以直接丟給設計師或領域專家自己感覺;背後邏輯是一個乾淨的純模組,不碰 DOM,驗證過就能抬進正式程式碼。「這個看起來該長怎樣?」得到同一 route 上幾個差異劇烈的 UI 變體,用浮動底列切換;變體必須在結構上不同意,不是顏色——三個微調過的 card grid 是壁紙不是 prototype。

發現自己在「加固」它的那一刻,你就不是在做 prototype 了——加測試、接真資料庫、為了「以後可能要」而泛化。

產出物怎麼處置:答案(裁決加它解決的問題)落在耐久的地方——commit message、ADR、實作 issue;prototype 本身不刪,但也不進 main,commit 到 prototype/<name> branch、永不 merge,在實作 issue 上留一個指標。

:agent 會在你其實該實作的時候叫你 prototype——命名問題,它對不熟流程的 agent 讀起來像「有票之後的顯然下一步」。另外不要 prototype 整個 app:沒有自然停止點,會靠慣性變成正式產品,而「沒測試沒錯誤處理」的程式就這樣上線見用戶。

獨立 — research

有個外部事實卡住決策

它只從一手來源工作(官方文件、原始碼、規格、第一方 API),每個主張都追回擁有答案的那個來源。它不在對話裡回答你——輸出是一份檔案,每個主張帶連結。決定性的動作是:讀的部分跑在背景 agent

research 是你委派的跑腿,不是你外包的思考。

:它會生出第二個自己(issue 530)——skill 叫呼叫者開背景 agent 但沒限制 agent 類型,於是生出的是通用 agent、握著同樣的工具和指令、再開一次。有人量到單一 research 任務跨三次重疊執行燒掉約 450k token,重複那個在半小時後、完全在視線外完成。呼叫後看一下背景任務列表,把重複的停掉。

另外三件:反向失敗是你的全域指令禁止再委派時,背景 agent 會禮貌拒絕、skill 靜靜什麼都沒做;「高信任來源」由模型自己判斷、沒有 allowlist,你實際的緩解手段是隨機追兩三個引用,落在「那個東西的摘要」而不是那個東西本身就是失敗;沒有停止準則,範圍是你的責任——一個 API、一個行為、一個版本主張,比「research X」回來得好太多。

research 檔案不是 ADR:ADR 留、research 檔用完歸檔或刪掉。過期的 research 檔比沒有更糟,它會污染未來的 repo 讀取。

獨立 — diagnosing-bugs

有東西壞了、我不知道為什麼

六階段:建 repro、最小化、排序假設、埋探針、帶回歸測試修好、清乾淨。

它不讓 agent 在有「緊」的回饋迴圈之前形成理論。一個具名指令、已經跑過一次、在這個 bug 上是紅的、修好之後會變綠。coding agent 拿到 bug 報告的預設行為是讀程式碼然後猜——這支 skill 擋掉它。沒有能變紅的指令,就沒有 Phase 2。那道 gate 就是這支 skill 的全部價值。

「有一個」迴圈不是目標,「緊」才是:快(秒級)、決定性(每次同樣裁決)、銳利(斷言你確切的症狀,不是「沒 crash」)、agent 能無人看管地跑。30 秒又會 flaky 的迴圈,比沒有好不了多少。對偶發性 bug,目標不是乾淨的 repro 而是提高重現率——迴圈觸發、平行化、加壓、注入 sleep。

建迴圈的階梯,按偏好排序

  1. 在能碰到 bug 的 seam 上的失敗測試
  2. 對著 dev server 的 curl 或 HTTP script
  3. 帶 fixture 輸入的 CLI 呼叫,加對已知良好快照 diff
  4. headless browser script,斷言 DOM、console 或 network
  5. 重播捕獲(存下來的 request、payload、event log)
  6. 丟棄式 harness(系統的最小子集、一次函式呼叫)
  7. property 或 fuzz 迴圈,處理「有時候輸出錯」
  8. 能交給 git bisect run 的 bisect harness
  9. differential loop(同輸入,舊版對新版)
  10. human-in-the-loop 的 bash script,最後手段
Gate 必須為真
進 Phase 2一個具名指令,已經跑過,輸出也貼出來(已遮蔽敏感值),能在這個 bug 上變紅
進 Phase 3repro 已重現已最小化——剩下的每個元素都是承重的
進 Phase 43 到 5 個排序過、可否證的假設,各自陳述預測,在測試任何一個之前先給你看
進 Phase 5探針對應到特定預測,一次一個變數,每條 debug log 帶可 grep 的標籤
完成原始 repro 不再重現、儀器全部移除、猜對的那個假設寫進 commit message

:它會在你只想要一個直接答案的輕量問題上觸發——最常被回報的問題(issue 578,四人回報同一形狀)。講清楚「直接回答,不要診斷」,或關掉它的 model invocation。不能拿它掃「效能問題在哪」,它診斷一個你已經能講出名字的失敗。它不會在寫修正之前停下來問你,只有 Phase 3 有人類檢查點。

獨立 — resolving-merge-conflicts

我卡在 merge 或 rebase 衝突裡

拒絕把衝突當成文字問題。動一個 hunk 之前,先把兩邊追回一手來源——commit message、PR、原始 issue——所以它是在兩個意圖之間選,不是在兩塊文字之間選,並且在相容的地方兩邊都保留。真的不相容時,選符合這次 merge 已陳述目標的那邊,並講出取捨。它不會為了粉飾衝突而發明新行為,而且它不放棄:merge 一定被帶到一個完成的 commit。

它還會找出 repo 自己的自動化檢查並在 commit 前跑——因為 merge 是 git 裡最容易產生「同時滿足兩個 branch、但兩邊測試都不過」的地方。

額外的實務知識:不要為了避免衝突而在平行任務之間「劃分檔案」,那成本比收益高。唯一值得保留的紀律是大重構先做。worktree 平行開發時,merge 回去最好由寫那個改動的 session 做,因為只有它知道意圖。把大家的衝突 batch 給最後一個 agent,正好丟掉這支 skill 要辛苦重建的東西。

匝道 — improve-codebase-architecture

codebase 在腐爛

它掃 codebase 找加深機會——淺模組(介面幾乎和它藏的東西一樣複雜)可以變成深模組的地方——寫成一份 HTML 報告,然後對你選的候選做 grilling。

它從不改程式碼。整個 run 產出「一個 HTML 檔加一場對話」。重構本身之後在另一個 session、走正常建置流程。這就是它是巡檢而不是重構工具的意思,也是為什麼值得對「你還沒準備要動」的 codebase 跑它。

兩道過濾器deletion test——想像刪掉這個模組,複雜度會集中到一個更小的介面後面,還是散開到各個呼叫者身上?只有「集中」的案例拿到卡片。另外除非你指定區域,它先讀最近的 commit 歷史,把掃描偏向正在變動的路徑——沒人碰的程式碼裡的加深,是你永遠不會兌現的重構。

強度標章三階:Strong(deletion test 清楚通過、摩擦真實,認真看)、Worth exploring(說得通,但報酬取決於程式碼接下來要去哪)、Speculative(為完整性列出,大部分可以安心忽略)。

情境 怎麼用
例行保養每幾天、或有空檔就跑,防止功能之間結構腐爛
大工程之前把它指向 spec:「我們怎麼讓這個改動變容易?」這是最有效的 prompt
Brownfield 稽核對大型、無結構、vibe-coded 的 repo 跑,看清它實際是什麼形狀
Legacy 測試工作先用它找出缺少的 seam,再去對難測的程式寫測試

:「它為了一個想法烤我一小時」是最大聲的抱怨——呼叫時就講「不要烤我,直接給報告」。報告開起來沒樣式沒圖,是因為它從 CDN 載外部資源、被擋時靜默失敗而 agent 看不到(它從不渲染那個頁面),要它用 inline CSS 與手寫 SVG。一個 session 一個候選。它幾乎不會說「你的 codebase 沒問題」——整份都是 Speculative 的報告,就是它用唯一會的方式告訴你它什麼都沒找到。

匝道 — triage

別人丟了一堆 issue 進來

只用於你沒有建立的 issue。原始 bug 報告、外來 feature request、突然出現的外部 PR。to-tickets 產出的票依構造就已經 agent-ready,對它們跑 triage 最好的情況是白做工。它建議然後等待:告訴你分類與狀態的判斷加理由,在你指示之前不套用任何東西。

每個被 triage 的項目最後帶恰好一個分類角色加一個狀態角色。分類兩個:bug、enhancement。狀態五個:needs-triage(你需要評估它)、needs-info(等回報者,回覆後回到 needs-triage)、ready-for-agent(完整規格化、附 agent brief)、ready-for-human(同樣的 brief 加上「為什麼不能委派」)、wontfix(關閉,理由已記錄)。

wontfix 分三種,差別重要,因為只有一種會寫進知識庫:已實作的留個指向它已存在位置的留言、不寫進 out-of-scope(那是已建功能不是被拒功能,寫進去會污染去重檢查);拒絕的 bug 禮貌解釋後關閉;拒絕的 enhancement 在 out-of-scope 目錄寫一份檔案、從關閉留言連過去。那個目錄是一個被拒概念一份 markdown(不是一個 issue 一份),而 triage 在評估任何東西之前先讀整個目錄,按概念比對而非關鍵字

先驗證再寫 brief:對 bug 照回報者的步驟重現,對 PR checkout 並跑相關測試,然後報告三種結果之一——已確認(附程式碼路徑)、無法重現、細節不足以嘗試(這本身就是最強的 needs-info 訊號)。這一切都是為了讓 agent brief 變好,而它被寫成耐久而非精確:寫型別、簽章、行為契約,永不寫檔案路徑與行號,因為 issue 可能躺好幾週而底下程式碼在動。

:label 不會自動建立;五個狀態不夠用是最常被提的缺口(blocked、deferred、implemented 都有人要,都沒 ship);不要一次對整個 backlog 放它跑——「顯示需要注意的東西」那一 pass 是給挑選用的便宜列表,一次跑二十個 issue 時 agent 會悄悄把它當成證據基礎,而它只回 issue 內文、不回留言

匝道 — wayfinder

這個工程一個 session 裝不下

它接手一個大到一個 agent session 裝不下的工程——你能講出目的地、但還看不見路線——把它畫成 tracker 上一張共享的地圖,由 decision ticket 組成,然後一次解一張直到路清楚。

它規劃、不執行。每張票握著一個「解決後產出決定」的問題,而不是一塊要執行的建置切片。地圖完成的定義是:在有人去建這個東西之前,沒有東西還需要被決定。這條規則是 agent 最常打破的。

grill-with-docs 的分界是 session 數,不是專案大小:一個對話裝得下就用 grilling(更便宜也更好);裝不下才用 wayfinder。對一個範圍良好的功能抓 wayfinder 是常見錯誤。

地圖上的四樣東西Destination——走到盡頭是什麼樣子,在任何票存在之前先命名Decisions so far——每張關閉的票一行,各自連到細節真正住的地方;Not yet specified,也就是戰爭迷霧——你看得出要來、但還無法精確表述的決定,判準是你現在能不能精確說出那個問題,不是你能不能回答它;Out of scope——判定在目的地之外的工作,關掉、永不畢業。地圖是索引不是儲存,決定只活在它自己的票裡。

Frontier 是「開著、沒被阻塞、沒被認領」的票。session 在做任何工作之前先把票 assign 給自己來認領,所以 assignee 就是認領。票全程用名字稱呼,不用裸的編號——一牆的 issue 編號在敘述裡沒法讀。

類型 模式 什麼時候用
grillingHITL預設。問題可以靠談清楚
prototypeHITL「這該長怎樣」——談不出來的問題,產物從票上連出去當 asset
researchAFK工作目錄之外的事實卡住決策。畫地圖時就發射、並行燒完
task兩者皆可沒有東西要決定,但手動工作卡住一個決定——開權限、註冊服務、搬資料讓形狀看得見

task 是唯一「做」而不是「決定」的類型,它的存在理由是解除一個決定的阻塞永不是交付目的地的一塊。這是實務上最常出錯的類型:agent 把它當實作步驟,開始在地圖裡寫產品程式碼。research 是「一 session 一票」的唯一例外。

三個致命坑。一、agent 在 wayfinder session 中間開始寫正式程式碼——最常回報的失敗。「規劃不執行」預設可以在地圖的 Notes 裡被覆寫,但 Notes 是 agent 寫的,所以約束和它的豁免住在同一個由「被約束方」擁有的檔案裡。有使用者看著 agent 把「這張地圖帶執行」寫進自己的 Notes,然後在後續 session 讀回來當自己的許可,在正式伺服器上動工。二、地圖清空之後還是要 /to-spec/to-tickets——decision ticket 在地圖關閉時全都關了,剩下的是「一張塞滿連結決定的地圖」,那不是建置計畫。三、不要平行跑 grilling 票,兩個 session 不共享 context,你會在一邊被問到剛在另一邊答過的問題。

還有一個實測:「我畫了 27 張票,做到第 13 張時後面全部不合理了」。兩個反制:把地圖範圍縮到一個有界的目的地(一個定義好的 epic 比籠統的「實作 V1」表現好太多),以及積極 prototype。作者的說法是 wayfinder 是「prototypemaxxing」而不是「planmaxxing」。

獨立 — handoff

有東西要搬家

它把當前對話壓成一份交接文件——一個 markdown 檔,寫到 OS 暫存目錄(不是工作區),讓一個全新 agent 讀了就能接手。

它買的是可攜性,不是壓縮。這讓它比聽起來窄得多:只有工作要移動時你才需要檔案。四個觸發情境:換 harness、搬到不同目錄或 repo、把工作送給同事、把 phase 中途發現的支線分叉出去。

最常被跳過的用法是分叉。你留在自己的 session,把累積的 context 複製一份交給第二個 agent 平行工作。prototype 岔路就是這樣用的:你正在一場很深的設計對話裡、撞到一個只有跑起來才能解的問題、又不想把辛苦建起來的 thread 花在查這件事上——handoff 到一個 prototype session、拿到答案、把答案交回來、在原 thread 引用它。兩次跨越、一場活著的對話、什麼都不用重講。

什麼會旅行:文件帶著活的 thread(在飛什麼、為什麼、下一步),加上一段建議的 skill。秘密會在寫入前被遮蔽。它刻意帶任何已經寫下來的東西——spec、計畫、ADR、issue、commit、diff 一律用路徑或 URL 引用、絕不複製。

:檔案在暫存目錄,路徑長、每個 OS 不同,問它路徑並記下來再往下走;有些環境會在 session 之間清掉 temp,下一個 session 不會很快開始就自己複製到耐久的地方;交給下一個 agent 的方式是指向路徑,不要把摘要貼進 shell 指令——含特殊字元的摘要會被搞爛,而典型失敗是靜默截斷;「它抓到 what、沒抓到 why」是公允的批評,把「下一個 session 要做什麼」當參數傳進去,並留意它把沒驗證過的信念寫成事實。

獨立 — to-questionnaire

答案在別人腦子裡

它把一個你無法自己拍板的決策,變成一份問卷,交給那個握有你缺的東西的人。

它烤的是「這次寄送」,不是主題。針對主題訪談你在這裡毫無意義——不懂主題正是你要寫給別人的原因。所以它只問你永遠答得出的兩件事:要給誰(他們的角色、專業、跟你的關係,這固定了語氣與文件要自帶多少 context)與你需要拿回什麼(你無法自己解決的具體決定或事實,這變成成品被衡量的檢查表)。之後全是起草。

文件的形狀:一行 purpose 加一小段給「從沒在你腦子裡待過的人」的 context;問題最重要的先來、依主題分組;一題一個想法、絕不複合明確允許回答「我不知道」——被標記的不確定有用,讀起來像事實的自信猜測沒用;結尾一個 catch-all。

它刻意分支、多收件人。三個人握著三塊答案,就跑三次。最常見的用法是一場 grilling 卡住了:在同一個對話裡跑它——它沒有 ingest 階段,能在 grilling 之後 work 純粹因為那場 session 已經在 context 裡。

獨立 — wait-what

這段話我沒聽懂

agent 會把剛講的東西重新推銷一次:補上你缺的 context、用白話寫、並使用你專案 CONTEXT.md 裡的詞彙。

這支 skill 只有三行,那是設計不是未完成稿。打冗長的 skill 會靠變長而失敗:一份四百行的「簡潔 skill」還是會讓模型冗長,因為模型讀到的是體積而不是懇求。

名字就是機制。帶頭的詞是 wait。「講精簡一點」是關於 agent 輸出的指令,模型會用「剪字」來服從,於是你更迷路。wait 是關於你的狀態:它說「理解在這裡失敗了」。聽到「講短一點」的 agent 寫電報;聽到「等等,你把我弄丟了」的 agent 會退回去重講。每個流行的解法都在命名輸出,模型於是過度修正成一種更短但沒更清楚的語體;命名聽者同時要到兩半:更少的字,而且你缺的那個前提。

它也刻意說「重講那個」而不是「上一則訊息」——把你弄丟的通常比一段大,多遠要退回去由 agent 決定。真正的解藥是事先建立共享語言;wait-what 修的是已經發生的那一則。

獨立 — teach

我想學一個東西,跨很多天

它把你執行它的那個目錄變成常設教學工作區,用一系列自帶樣式的短 HTML 課程跨多個 session 教你一個主題。

它不從模型已知的東西教。parametric knowledge 被當成不可信:教之前它先去找高信任資源、記進資源檔、並在每一課裡引用。它是有狀態的——mission、資源、課程、學習紀錄全部以檔案形式住在目錄裡:

路徑 放什麼
MISSION.md你為什麼學這個。其他一切掛在它上面;缺它,它第一件事就是訪談你到它存在
RESOURCES.md經過挑選的來源,分 Knowledge 與 Wisdom(社群)
lessons/編號課程——教學的主要單位
reference/壓縮的小抄、演算法、詞彙表:你真的會回來翻的文件
learning-records/ADR 風格的「你已明確學會什麼」,用來決定接下來教什麼
assets/可重用元件——第一個是共用 stylesheet——讓課程看起來像同一門課
NOTES.md你陳述的教學偏好

核心觀念是 storage strength(長期保留)而不是 fluency(當下的回想感,讀的時候像精通、一週後就沒了)。它用期望難度建前者。知識先來(此時難度是敵人,會吃掉你理解所需的工作記憶),技能再靠緊的回饋迴圈操練(此時難度是工具)。課程很少被重讀,參考文件會——所以一課的壓縮精華屬於參考目錄,不是埋在引入它的那一課裡。

:檔案可能被寫到錯的地方(issue 377,有人的課程被寫進全域 skill 目錄),開始時明確講出目錄名小考正確答案永遠是第一個選項(多模型確認、未修,有貢獻者測到 9 課 33 次全部落在 A);沒有能力評估步驟,第一則訊息就把你的既有知識與缺口講出來;沒有間隔重複排程,要複習就自己要。

不只給程式用——紀錄裡非程式的用途佔更大部分。在程式裡,最強的用途不是從零學一門語言,而是在陌生的 codebase 或新團隊的技術棧裡找方向。作者提過一個漂亮的組合:被烤到一個你不懂的東西時,不要停下 grilling 去學——handoff 到一個教學工作區、在那裡學會、再回來接續。

獨立 — wizard

有段人類才能做的手動流程

它產生一支互動 bash script,一步一步帶人類走過手動程序——串第三方服務、跑一次性遷移、把專案從狀態 A 搬到狀態 B。

agent 寫 script,但從不執行它。你在自己機器上跑。所以 wizard 不是一份你照著做的說明——它是一個驅動流程並持有狀態的程式,你的部分是點、貼、按 Enter。Stage 是「一個畫面上的一件聚焦任務」,script 在 stage 之間清空終端。

寫 script 之前先 scoping:它讀你的 repo 而不是冷問——環境檔、compose 檔、framework config、以及 CI 設定裡每一個 secret 與變數引用;每一個都是 wizard 必須產出的值。然後把排序過的 stage 清單給你確認,之後才把每個 stage 對應到人類走的確切路徑。不知道現在的 UI 長怎樣時,它問你或查文件,而不是發明點擊

template 已經解決了 UX:進度、確認門、跨平台開 URL、secret 隱藏輸入、環境檔冪等寫入、CI secret 寫入、以及「它必須跳過什麼」的收尾摘要。固定函式庫那半每支 wizard 都一樣、永不手改,一致性就是重點。寫 wizard 的 agent 不會端到端跑它,改用靜態驗證,第一次跑是你,而那次就是測試

不能中途回上一步,第 3 站打錯就中斷重跑(重跑很便宜,已寫進環境檔的值會當預設回饋);提示裡方向鍵有 bug(issue 741),backspace 有效;它不會去查第三方服務的狀態;API key 不會進模型 context——但你在 scoping 時把 key 貼進聊天,那就跟任何貼上的文字一樣在 context 裡了。

詞彙層 — codebase-design

模組該長什麼形狀

它固定你設計模組時用的字,精確定義每一個、禁掉鬆散替代品,並陳述由它們推出的幾條原則。

意思
Module任何有介面與實作的東西。刻意與規模無關——一個函式、一個 class、一個 package、跨層的一個切片
Interface呼叫者為了正確使用它必須知道的一切:型別簽章,加上不變式、順序約束、錯誤模式、必需設定、效能特性
Depth介面上的槓桿。:小介面後面大量行為。:介面幾乎和實作一樣複雜
Seam一個你可以改變行為卻不需在那裡編輯的地方。它是介面的位置
Adapter在某個 seam 上滿足某介面的具體東西。命名的是角色不是材質
Leverage呼叫者從 depth 拿到的:每學一單位介面得到更多能力
Locality維護者從 depth 拿到的:改動、bug、驗證集中在一處

Depth 刻意不定義成「實作行數除以介面行數」——那個指標會獎勵把實作寫得更臃腫。這裡用的是 depth-as-leverage。

四條原則:depth 是介面的性質、不是實作的性質;deletion test——刪掉這個模組,複雜度消失代表它是 pass-through,複雜度在 N 個呼叫者身上重新出現代表它有在賺錢;介面就是測試面,你想測到介面之外,就是模組形狀錯了;一個 adapter 代表假設性的 seam,兩個 adapter 才代表真的 seam

不要拿它當驅動器(issue 449)。被叫去「繼續並推進未決事項」時,agent 會抓它找得到最像動作的東西,重新探索前一個 session 已經畫過的程式碼,跑很久才問你任何事。點名一個 driver skill,讓這支坐在下面。

詞彙層 — domain-modeling

詞在打架

它在你設計的同時建立與磨利專案的 ubiquitous language——挑戰和詞彙表衝突的用詞、在你用了模糊字時逼出精確的字、用具體情境壓力測試一段關係直到邊界精確。

它是主動紀律、不是被動的。CONTEXT.md 借用詞彙是任何 skill 都能做的一行習慣;這支是給你在改變模型的時候用的。這就是它會打斷你的原因:它在術語被解決的那一刻、對話中間就寫進 CONTEXT.md——因為批次版是一場 session 的摘要,即時版是那場 session 的實際產出

兩個產物、兩套標準。CONTEXT.md術語(一個東西是什麼,一兩句話),寫入門檻是「一個模糊的詞變成正式術語」,時機是即時,永不裝實作細節、spec、草稿紙、一般程式概念。ADR 裝一個決定(一到三句:context、選擇、理由),寫入門檻是三個全中——難以逆轉、沒有 context 會覺得意外、真實取捨的結果——而且是提議,不預設。

要真正記住的是 CONTEXT.md 那條規則,因為它是實戰中會壞的那條:它是詞彙表,而且只是詞彙表。不管的話,模型會把「寫進 CONTEXT.md」當成「把你給的每個答案都持久化」的許可,檔案就變成一份跑動的 spec——這是本 skill 最常被回報的問題,跨多個模型。

讓這支有感的動作:你陳述某件事怎麼運作時,它去查程式碼並把矛盾攤出來——「你的程式碼取消整張 Order,但你剛說可以部分取消,哪個對?」語言和程式碼被迫出聲對齊,在任何一邊被改之前。限制:它只交叉參照程式碼與已 commit 的文件,不搜你的 issue tracker,所以幾個月前在一張已關閉 issue 裡吵完並刻意定案的命名衝突,會被當成新的攤出來。

CONTEXT.md 長到 500 行以上——大小是症狀不是病,直接下令它精簡並移除實作細節;只有在檔案真的精瘦、卻仍涵蓋兩個讀者不會想同時裝進腦裡的領域時,才考慮切分——切一個臃腫的檔案只會得到好幾個臃腫的檔案自動觸發是它最弱的地方:一場 grilling 跑完 CONTEXT.md 一動也沒動,就是這件事發生了,點名叫它。沒有經人審閱、由 agent 撰寫的詞彙表比沒有更糟:它會變成聽起來很自信的傳說,被後續 session 當成真理。

詞彙層 — writing-for-agents

我要寫給 agent 看的文件

skill、指令檔、spec、runtime prompt、README——任何 agent 會讀的文件。包裝不同,寫法一樣。

它的預設動作是刪除,不是解釋。叫 agent 寫給另一個 agent 的指令,它大部分字會花在解釋模型已經知道的東西,每一行都是 no-op:付了 context 卻沒改變任何行為。這份參考就是找出它們的鏡片,所以它在你已經有的文件上賺到的價值,至少和在空白檔案上一樣多。

兩種負擔。Context load 是永遠載入的材料在 agent 窗口上的成本:指令檔的一行、skill description、任何每個 turn 都在 context 裡的東西,不管它有沒有被觸發。Cognitive load 是在身上的成本:有哪些文件存在、什麼時候該抓哪一個,你就是那個索引。這不是要最小化的成本,它是人類主導權的價格。想通這兩種之後,大部分寫作決定都變成同一個取捨在不同地方做。

五個槓桿Context pointer(在 context 裡、指名 context 外材料、並編碼「何時去拿它」的引用;決定 agent 多可靠地伸手穿過它的是 pointer 的用字,不是它的目標)、Information hierarchy(從「檔內步驟」到「檔內參考」到「pointer 後的外掛參考」的梯子)、Completion criteria(對抗過早完成的防線)、Leading words(模型預訓練裡已有的壓縮概念,錨定兩次:body 裡錨定執行、pointer 裡錨定觸發)、Pruning(單一真實來源、相關性、逐句套用 no-op test)。

no-op test 是行為性的、不是美學性的:刪掉那一行,問 agent 的行為有沒有改變。一個句子不通過,刪整句而不是修字。對它有歧見時,跑那份文件來解決,不要爭論。判準:文件變好的同時變短,而且你會驚訝剩下這麼少;沒有任何東西被說兩次(重複是「這份文件從未被測過」最可靠的徵兆)。

獨立 — grill-me

我有個想法,還沒成形

它拿一個鬆散的想法訪談你,直到你能對它做出承諾。你不需要一份想好的計畫才能開始——產出那份計畫正是這場 session 的用途。它是無狀態的:不寫檔案、不留工作區,留下的只有你腦子裡那個更銳利的版本。主題不必是程式,也不需要 repo。

關掉 plan mode。它會催 agent 趕快產出計畫,那正好和「保持在提問狀態」相反。

它在正常工作的樣子:你不同意某件事——一場你完全沒推回去的 session,是一場你不需要的 session;問題以「少數幾輪」而不是一長串點滴到達,而且後面的輪次明顯建立在你前面說的話上;你走到一個沒預期的地方,因為某個問題翻出了你一直在隱性做的決定;結束時,每個選擇你都能對一個當時不在場的人辯護。

數輪不要數題。46 題分 4 輪是普通的一場。200 題代表範圍太大,而且超長 session 會漂進 dumb zone——context window 滿到問題品質下降。烤完之後如果確定要做,不要開新 session,那場對話的 context 就是價值所在。

路由器 — ask-matt

我不知道該用哪支

建議然後停下。不會 grill、不會寫 spec、不會開檔案、不會幫你發射它剛點名的 skill——你拿到的是「下一步該打什麼」,然後你去打。它給你的思考單位是 flow:一條穿過 skill 的路徑,而不是單一個 skill。

必須知道的誠實限制。它是手寫的地圖、會落後 repo,而且只認得這個 pack 的 skill。它會告訴你「一半的 skill 沒安裝」——已知未修:大部分被它路由的 skill 是 user-invoked,harness 就不把它們放進注入 agent 的清單,agent 把那份清單當成完整的,於是報告它們不存在。它們有裝。

它也可能描述錯別的 skill 的行為:它從自己那份一行摘要回答,而不是從 skill 本身。有一份詳細回報在單一 session 裡追到三次,包括憑「把 thread 變成 spec」這個粗略印象建議跳過 to-spec——那份 SKILL.md 從未被打開,代價是少了一次真正的 seam 檢查,切出來的票低估了工作量。當它對別的 skill 做出承重的斷言時,要它先去打開那份 SKILL.md

定位:ask-matt 是這整套之上的 secondary source。router 和 SKILL.md 打架時,SKILL.md 是對的。

07

四個完整劇本

主幹案例在 第 05 節。這裡是另外四個最常見的處境。

案例 A — 生產環境偶發 500

處境:客戶回報「有時候按送出會噴 500」,你自己重現不出來。

  1. 這是別人回報的,先走匝道:/triage。能不能照回報者步驟重現?重現不出來就 needs-info,或決定現在就追。
  2. 決定現在追,開新 session/diagnosing-bugs,並明講「先幫我建一個會變紅的迴圈」。

Phase 1 是唯一難的一關,也是你唯一要盯的

它必須先給你一個已經跑過、輸出貼出來、在這個 bug 上是紅的指令。偶發性的 bug,目標不是乾淨重現,是提高重現率沒有紅的指令,就不要讓它進 Phase 2。它想開始猜就把它拉回來。

後面是機械性的:最小化(剩下的每個元素都要能說出為什麼是承重的)、3 到 5 個排序過可否證的假設(唯一的人類檢查點)、埋帶標籤的探針、先寫回歸測試再修、清乾淨、猜對的假設寫進 commit message。

一個分岔要知道:沒有正確的 seam 可以放那個回歸測試時,它應該直說,而不是寫一個給你假安全感的淺測試——「沒有 seam」本身就是發現,交給 improve-codebase-architecture

案例 B — 接手一個沒人整理過的 legacy repo

處境:你剛加入一個八年的專案,或接手一個 vibe-coded 的 repo。沒有 ADR、沒有領域語言、沒有設計原則。

  1. 第一天/setup-matt-pocock-skills 設定 tracker 與文件配置。
  2. 第一天/grill-with-docs,請它幫你把這個既有 repo 用 CONTEXT.md 建立起來。預期一場很長的訪問(有人回報 50 題以上才把檔案弄成形),而且要主動導引——它會讀程式碼、問你它找到什麼,而「程式碼裡現有的哪些詞才是對的詞」是你決定的
  3. 第二天/improve-codebase-architecture,開口就說「不要烤我,先給我報告」。全部都是 Speculative 等於它其實什麼都沒找到;挑一個 Strong 的候選。
  4. 第二天:一次一個候選,讓它對那個候選 grilling,產出是「決定」不是 diff。然後接 to-specto-ticketsimplement
  5. 之後:每幾天再跑一次架構巡檢當保養。

為什麼順序是這樣

先建立共用詞彙,架構巡檢的輸出會好非常多——候選會用「Order intake 模組」這種你們的名詞,而不是「FooBarHandler」。

誠實的期望值:真正失控的專案,有人回報它「幫了一點但還是不夠」;一個八年的 legacy codebase 上有人看到模型在原地繞圈,而同一支 skill 在整齊的 repo 上會產出乾淨的圖。目前沒有專門處理這種案例的 skill。

案例 C — 綠地大專案

處境:要從零做一個新產品模組,路線完全不清楚,明顯不是一場對話能談完的。

  1. 先確定五個 wayfinder: label 存在(不存在的 label 會讓 gh 直接失敗)。
  2. /wayfinder。第一件事是命名 destination。它問的是「整張地圖的目的地」,不是這場 session 的目的地;把範圍縮到一個有界的 epic,不要「實作 V1」。
  3. 它做一次廣度優先的 grilling,畫出 Destination、Decisions so far、迷霧與 Out of scope。迷霧與票的判準是你「現在」能不能精確說出那個問題。開場的 grill 找不到任何迷霧,它應該停下來說「這件事小到不用地圖」。
  4. research 票在畫地圖時就被發射並行燒;其他票一次做一張,用 assign 給自己來認領。
  5. 每解一張:貼 resolution 留言、關票、在地圖留一行,然後停下。清掉前方的迷霧,把現在可表述的畢業成新票。
  6. 地圖清空後:/to-spec #<map_issue>(傳主地圖,不是個別 decision ticket),然後 /to-tickets/implement

三個致命坑已在 第 06 節 的 wayfinder 條目列出:agent 會開始寫正式程式碼、不要跳過 to-spec、不要平行跑 grilling 票。

案例 D — 完全不是程式的決策

處境:你在想一個商業決定——要不要做一條新產品線、一份提案怎麼定價、一篇文章的論證骨架。

  1. 開一個乾淨對話(不需要在任何 repo 裡),關掉 plan mode,跑 /grill-me
  2. 一輪一輪回答,用編號整批回。推回問得太淺的問題;範圍在漂就講;「我不知道」是真的答案
  3. 遇到「看到東西才能答」的問題,它是 ungrillable。非程式情境下通常是:先做一頁草稿、先算一張表、先問一個客戶。
  4. 遇到「答案在別人腦子裡」的問題,在同一個對話裡/to-questionnaire,寄給那個人,答案回來再開下一輪。
  5. 它是無狀態的:不寫檔案、不留工作區。留下的只有你腦子裡那個更銳利的版本。

08

已知坑總表

依「你會先看到的症狀」排列。嚴重代表會浪費你錢或時間。

症狀 嚴重 解法
agent 說某些 skill 沒安裝user-invoked skill 不進模型的清單。它們有裝,照打。權威是 .claude-plugin/plugin.json
gh 說 label 不存在setup 不會建 label,自己 gh label create 一次
訪談一次丟出全部問題、沒有建議答案grilling 或 domain-modeling 沒載入。問 agent「你載了哪些 skill」
訪談很好但 CONTEXT.md 沒變domain-modeling 沒載。點名叫它
CONTEXT.md 膨脹成 500 行以上它吸收了實作細節。直接下令精簡並移除實作細節
讀 spec 一直被截斷嚴重兩步之間不要 clear 或 compact,同一個窗口跑完
三行的改動切出 12 張票質詢步驟叫它合併。真的很小就直接 implement,別用這支
切出來一層一張票逐票問「做完能 demo 什麼」,答不出行為的就是水平切片
沒建成 sub-issue、blocked-by 只寫在內文已知未修。事後自己用 gh issue create --parent--add-sub-issue--blocked-by
驗收條件在動工前就通過對每條問「什麼觀察會證明它為假」,並確認它在起始 commit 是紅的
/implement #2 做了完全無關的事嚴重#2 是對「任何看得到的編號清單」解析。傳完整 URL,並要它唸回標題
跑完票還開著、驗收條件沒打勾預期行為,它沒有收尾步驟。手動關票,依賴鏈才會往前走
code-review 說看不到我的改動它 diff 到 HEAD,排除未 commit 的。先 commit 再 review
平行跑好幾個 implement 出現詭異 git 狀況嚴重同一 checkout 不支援。用 worktree,但 stash 仍共用
和內建的 code-review 撞名移除內建的那個,或 fork 成新名字
review 的 sub-agent 又生出更多 agent嚴重已知未修,有一次到 50 個以上。無人看管跑時盯 agent 數;fork 上加一行禁止再生成
review 每次跑都找到新問題沒有收斂保證。當成線索清單,處理有明文規則背書的,然後停手
research 燒掉 450k token嚴重nesting bug(issue 530),它會生出第二個自己。呼叫後檢查背景任務列表
只想要一句答案,它跑去建重現情境講「直接回答,不要診斷」,或關掉它的 model invocation
它先寫實作才寫測試會發生,skill 帶著這件事一起活。某個切片要嚴格就盯著跑
它先寫瀏覽器測試然後鬼打牆在 repo 的指令檔宣告:browser 測試在行為可運作之後才寫
架構報告開起來沒樣式沒圖外部 CDN 被擋。要它用 inline CSS 加手寫 SVG
它烤我一小時而不給我選項呼叫時講「不要烤我,直接給報告」
對詞彙層說「開始」燒掉 100k token嚴重它沒有流程。點名一個 driver skill,讓它坐在下面
wayfinder 的 agent 開始寫正式程式碼嚴重Notes 可覆寫「規劃不執行」,而 Notes 是 agent 寫的。先讀 Notes
27 張票做到第 13 張全部不合理範圍縮到一個有界 epic,並積極 prototype
grilling 每個問題三段落、很累降 reasoning effort 加全域指令檔一句白話指示。未解決
handoff 檔案不見了暫存目錄會被清。問它路徑,需要就自己複製到耐久位置
課程被寫到全域 skill 目錄嚴重issue 377。明確講出目錄名,第一課落在哪先確認
小考正確答案永遠是 A已知未修(33 次全中)。把位置當無意義,或要一個 render 時洗牌的元件
wizard 打錯字想回上一步沒有回上一步。中斷重跑(已存的值會當預設);方向鍵有 bug,用 backspace
我改了 SKILL.md,更新後不見了嚴重npx skills update 會覆蓋、plugin 唯讀。長期行為寫進你自己的指令檔

09

建議放進你自己的指令檔

這是「用官方管道客製」的方式——改 skill 檔會被覆蓋,這裡不會。整段可以直接複製進你的 CLAUDE.mdAGENTS.md

## Agent behaviour

- When grilling, ask one question at a time.
- Do not start implementing without my explicit permission.
- Browser and end-to-end tests are written after the behaviour works,
  never as the first red test.
- Keep questions and recommendations short. One paragraph maximum
  per question.
- When a skill asserts something about another skill's behaviour,
  open that skill's SKILL.md before acting on it.
- code-review sub-agents must not invoke /code-review or spawn
  additional agents; perform the review directly.

每一行擋的是什麼

  • 一次一題:換回單題節奏。讀得慢、用第二語言、或需要專注鷹架的人都推薦。
  • 不要未經允許就開始實作:防 grilling 在 frontier 清空後自己開始做,弱模型或低 effort 時會發生。
  • 瀏覽器測試最後寫:防 tdd 先寫 Playwright 然後鬼打牆。
  • 問題與建議要短:緩解 wayfinder 與 grilling 的冗長。
  • 先打開被斷言的那份 SKILL.md:防 ask-matt 用自己的摘要誤述別的 skill。
  • review 的 sub-agent 不得再生成 agent:防失控 fan-out,這是 fork 使用者實測有效的那一行。

10

核心詞彙

這些詞是整套 skill 的共用語言。看不懂它們,skill 的輸出你就讀不懂。

定義
Seam你可以改變行為卻不需要在那裡編輯的地方。測試住在 seam 上。它是介面的位置
Pre-agreed seam在寫任何程式之前就談好的 seam。這是測試耐久的原因——底下的實作可以重寫而測試不動
Tracer bullet穿過所有層的一條細但完整的路,落地當下就能單獨 demo
Vertical / horizontal slice垂直是一條路穿所有層(對);水平是一次一層(錯,最常見的失敗)
Deep / shallow module深是小介面後面大量行為;淺是介面幾乎和實作一樣複雜
Deletion test想像刪掉這個模組:複雜度集中到更小的介面後(值得留)還是散開到呼叫者(那是 pass-through)
Locality / LeverageLocality 是維護者得到的(改動集中在一處);Leverage 是呼叫者得到的(每學一單位介面得到更多能力)
Design tree / Frontier / Round設計樹是決定掛著決定;frontier 是前置條件都已解決的決定集合;一 round 是把整個 frontier 一次問完
Grillable / ungrillable談得出來的問題,相對於需要有東西可反應的問題(後者去 prototype)
Fog of warwayfinder 地圖上「看得出要來、但還無法精確表述」的決定
Decision ticketwayfinder 的單位:握著一個問題(解決後產出決定),不是一塊要執行的建置切片
Destination一整張 wayfinder 地圖的終點樣貌。畫地圖的第一個動作就是命名它
Spec / Ticketspec 是目的地與固定它的決策(保留);ticket 是抵達的執行步驟(用完即丟)
Primary / secondary source一手是對話本身、commit、官方文件、原始碼;二手是任何摘要。衝突時一手為準
Context pointer在 context 裡、指名 context 外材料、並編碼「何時去拿」的引用
Progressive disclosure把只有某條分支需要的參考移到 pointer 後面,讓主檔保持可讀
Context load / Cognitive load前者是永遠載入的材料在模型窗口上的成本;後者是「有哪些文件、何時該用」在身上的成本
No-op刪掉之後 agent 行為不變的那一行文字。付了 context 卻沒改變任何行為
Leading word模型預訓練裡已有的壓縮概念(tight、red、tracer bullet),agent 拿它來思考
Storage strength / fluency長期保留,相對於當下的回想感(後者讀的時候像精通、一週後就沒了)
Smart zone / dumb zonecontext window 還有餘裕,相對於已經滿到品質下降
HITL / AFK人類在迴圈裡(必須靠活的交換解決),相對於你人不在也跑得完
Phase boundary兩塊工作之間;唯一該問「我的 context 怎麼辦」的地方
Expand–migrate–contract寬重構的三段式:新形式加在舊的旁邊、分批搬呼叫點、沒有呼叫者才刪舊的

11

七種反模式

這套東西最常被用壞的方式。

  1. 被動 grilling。連答四十個「同意」,出來一份 agent 寫的、你點頭過的計畫。一場你完全沒推回去的 session,是一場你不需要的 session。
  2. 在 to-spec 和 to-tickets 之間 clear 或 compact。你烤出來的東西絕大部分只在那個 context window 裡。這一刀下去,spec 會安靜地漏掉你真正決定的東西。
  3. 對自己產生的票跑 triage。to-tickets 的票依構造已經 agent-ready。triage 是別人丟進來的工作的匝道。
  4. 範圍良好的功能抓 wayfinder。判準是 session 數:一場對話裝得下就用 grill-with-docs,它更便宜也更好。
  5. 把詞彙層當驅動器。codebase-designdomain-modeling 說「開始吧」,agent 會自己發明流程並燒掉大量 token。點名一個 driver。
  6. 把 review 跑在寫程式的同一個 session。同一個 context 審自己不是 review,是帶著 slash command 的確認偏誤。
  7. SKILL.md 來客製。會被更新覆蓋,plugin 安裝根本唯讀。長期行為寫進你自己的指令檔。

還有一個元反模式

把它當成「有了流程就不用想」。作者在 README 裡的立場是相反的——那類接管流程的做法幫你的代價是拿走你的控制權、並讓流程本身的 bug 難以解決。這套 skill 刻意做得小、好改、可組合。產出的品質追蹤的是你答案的品質,而不是問題的數量。

12

14 天學習計畫

每天約 30 到 60 分鐘,用你自己真實的專案

做什麼 怎麼算過關
01三個底層觀念;裝 plugin 或 skills.sh(選一);在一個 repo 跑 setup;建好 labeldocs/agents/ 三個檔案存在,指令檔有 ## Agent skills
02/grill-me 烤一個非程式的決定。刻意練習「推回去」至少推回三次;能對一個不在場的人辯護每個選擇
03/grill-with-docs 對你現有 repo 做一次小功能的訪談CONTEXT.md 在過程中逐條長出來;ADR 0 到 1 份
04同一對話接 /to-spec。認真看 seam 與 out-of-scope 兩節spec 裡每個決定你都記得自己做過
05同一窗口接 /to-tickets。在質詢步驟逐票問「能 demo 什麼」每票能 demo 行為;最上面那張沒有阻塞者
06/implement 做第一張票(完整 URL),全程看 tracetrace 裡看得到 tdd 呼叫;走到 commit
07新 session 跑 /code-review main。逐條追引用兩塊分開的報告;你至少駁掉一個發現
08codebase-design 的詞彙表,把它當字典而不是流程你的設計對話裡不再出現 component、service、boundary
09遇到一個「談不出來」的問題,跑 /prototype一個可分享的 HTML 檔或幾個結構上不同意的變體;答案一行
10對一個真的 bug 跑 /diagnosing-bugs。盯緊 Phase 1 的 gate先看到紅的指令輸出,才看到第一個理論
11/improve-codebase-architecture(記得說「先給報告」),挑一個 Strong 候選HTML 報告;一個候選被烤成一個決定
12/handoff 練一次「分叉」:主對話留著,開一個平行 session原 session 還在原地;新 agent 直接開工不用你重講
13/wait-what/to-questionnaire;把 第 09 節 寫進指令檔重講是「更短且更清楚」;問卷可以直接寄出去
14挑一件真的太大的工作跑 /wayfinder,範圍縮到一個有界 epicdestination 在任何票之前就寫下來;每張開著的票讀起來都是一個問題

之後的節奏:主幹每天跑,架構巡檢每幾天跑一次,/teach 在需要補技能時開一個專屬目錄。

13

一頁速查

每個 repo 一次

  • /setup-matt-pocock-skills — tracker、label 與文件配置

主幹(想法到 ship)

  • /grill-with-docs — 有 repo、單一 session 談得完
  • /to-spec — 只在跨 session 才需要。同窗口,別 clear
  • /to-tickets — 切 tracer bullet,宣告阻塞邊。同窗口
  • /implement <完整 ticket URL> — 一票一 session,中間 clear
  • /code-review <fixed-point> — 乾淨 session 跑,先 commit

匝道

  • /triage — 別人丟進來的 issue
  • /wayfinder — 一個 session 裝不下。清空後回 /to-spec
  • /improve-codebase-architecture — 每幾天一次的結構體檢

隨時

  • /grill-me — 無 repo、無檔案,主題不必是程式
  • /prototype — 談不出來的設計問題,一次一個問題
  • /research — 外部事實。背景跑,檢查有沒有生兩個
  • /diagnosing-bugs — 難 bug。先有紅的迴圈才准猜
  • /resolving-merge-conflicts — 已經卡在衝突裡
  • /wizard — 只有人類能做的手動流程
  • /handoff — 有東西要搬家,或分叉支線
  • /to-questionnaire — 答案在別人腦子裡
  • /wait-what — 剛剛那段沒聽懂
  • /teach — 跨很多天要學一個主題
  • /ask-matt — 不知道用哪支。它建議然後停

詞彙層,不要當驅動器用

codebase-designdomain-modelinggrillingwriting-for-agents

Phase boundary 五選一,依序判斷

繼續 → clear → handoff → subagent → compact

出處

這篇教學依據什麼寫成

依據 mattpocock/skills plugin 1.2.3 版(25 個已發布的 skill),讀該 repo 的 README.mdCONTEXT.md、25 篇官方 skill 文件、.claude-plugin/plugin.jsonCHANGELOG.md 之後整理與重寫。該 repo 以 MIT 授權釋出。

本頁為 TauX 獨立編寫的中文教學,不是官方文件的翻譯或轉載。skill 本身、它的名稱與它的行為屬於原作者;本頁的編排、判準、譯名與所有評論由 TauX 撰寫,不代表原作者立場

文中所有 issue 編號皆為該 repo 的 issue,撰稿時多數仍開啟。這代表兩件事:這些坑是真的,而且它們可能已經被修好。跑起來遇到怪事,先去該 repo 搜一下症狀——一份寫死的坑表最好的下場,就是有一天全部過期。

版本標記在這裡不是裝飾。這套 skill 改得很快(to-prd 在 v1.1 改名成 to-spectdd 的 refactor 階段在 2026 年 6 月被移除),沒有版本號的教學讀者無從判斷哪一段還有效

想把這條流程接進你自己的團隊?

工具是公開的,難的是接到你既有的 tracker、規範與交付節奏上。那部分我們做過。