安安~我是ChiYu~
AI 寫得很快,但寫錯方向只會更快抵達錯誤終點
假設你只丟給 Coding Agent 一句:「幫我做一個預約取消功能。」
它很可能立刻新增 API、補按鈕、改資料庫欄位,連測試都順手寫好了。速度快得很舒服,直到你準備驗收才發現:什麼狀態可以取消?誰有權限取消?取消後要不要通知?重複取消要回成功還是錯誤?
這些問題都沒談,但 code 已經長出來了。
AI 寫 code 的速度越快,這種落差越危險。因為我們省下的可能只是打字時間,卻把需求誤解、錯誤切分和無效測試一起加速了。
Matt Pocock 的 skills 專案
吸引我的地方,就在它沒有把答案押在「再寫一段更厲害的 Prompt」。它把軟體工程裡原本就重要的控制點,拆成一組可以組合的 Skills:先把話講清楚,再留下規格、切小任務、縮短測試回饋,最後把「code 寫得對不對」與「需求做得對不對」分開檢查。
這篇不會把它當成萬能框架,也不會假裝我已經在真實專案導入過。我要做的是依照 2026 年 8 月 10 日查閱的官方 main 分支(commit 84fdeff),拆開它最值得學的一條工程 Workflow,看看每一段到底交付了什麼,以及哪些地方仍然需要人類做判斷。
Matt Pocock Skills 是什麼
專案 README 對自己的定位很直接:這是一組用在真實工程工作的 Agent Skills,而且刻意不做成接管整套流程的大型框架。作者對 GSD、BMAD 與 Spec-Kit 的批評是,這類方法在「擁有流程」的同時,也可能拿走開發者的控制權,讓流程本身的 bug 更難處理。相較之下,這個專案選擇的是「小、可調整、可組合」。這是作者的設計立場,不是已被證明適用所有團隊的定律,但方向很清楚。
如果你還不熟悉 Agent Skill,可以先看我之前整理的 「什麼是 AI Agent SKILL?」 。簡單說,Skill 不是單次對話裡的一句 Prompt,而是一份能重複使用的工作規範;它告訴 Agent 何時應該使用某種能力、應該遵循哪些步驟,以及怎麼判斷完成。
截至這次查閱, 官方 README 提供兩條主要安裝路徑:
- Claude Code 可以安裝
mattpocock-skillsplugin,由套件管理更新。 - Codex 與其他支援 Skills 的 Agent,可以執行
npx skills@latest add mattpocock/skills,挑選需要的 Skills,並包含setup-matt-pocock-skills。
安裝完成後,還要在每個 repository 執行一次 /setup-matt-pocock-skills,選擇 issue tracker、triage labels 與文件存放位置。README 也明確寫著:原生 Codex plugin 仍在 roadmap。換句話說,現在可以把 Skills 裝進 Codex,不代表原生 Codex plugin 已經推出,這兩件事不能混在一起寫。
這不是會自動跑到底的全包式 Pipeline
先把最容易誤會的地方講清楚:下面這條 Workflow,是我依官方 Skills 的責任與交接關係整理出的工程主線,不是專案提供的一顆「從需求自動跑到 commit」按鈕。
官方把 Skills 分成兩類:
- User-invoked Skills:要由使用者主動啟動,負責協調一段流程。
- Model-invoked Skills:當任務符合時,可以由 Agent 自己選用,承載可重複使用的工程紀律。
grill-with-docs、to-spec、to-tickets 與 implement 都屬於 user-invoked。官方規則甚至刻意限制:user-invoked Skill 可以使用 model-invoked Skill,但不能自己再呼叫另一個 user-invoked Skill。
所以真正的節奏比較像這樣:人類在適當時機推動下一階段;implement 進場後,再把 tdd 和 code-review 這兩項 model-invoked discipline 帶進實作流程。
這個差別很重要。它保留了控制點,也代表你不能只安裝完就期待 Agent 自己把所有關卡跑完。
Workflow 全貌:每一棒都要留下下一棒接得住的東西
這條主線真正串起來的不是六個指令,而是六次交接:
%%{init: { 'theme': 'base', 'themeVariables': { 'primaryColor': '#10b981', 'secondaryColor': '#3b82f6', 'lineColor': '#6b7280', 'textColor': '#374151' }}}%%
flowchart TD
A["需求想法"] --> B["grill-with-docs<br/>共同語言、CONTEXT.md、ADR"]
B --> C["to-spec<br/>Spec 與測試 seam"]
C --> D["to-tickets<br/>垂直切片與 blocking edges"]
D --> E["implement<br/>逐項實作與持續檢查"]
E --> F["tdd<br/>一個 Red → Green 切片"]
F -->|"下一個行為"| E
E -->|"功能完成"| G["code-review<br/>Standards 與 Spec 雙軸審查"]
G --> H["通過後 Commit"]我特別把 tdd 畫成 implement 裡的迴圈,而不是「全部實作完才補測試」。這比單純排成六個直線步驟更接近目前 Skill 的規則:一次選一個行為,先 Red,再用最小實作進入 Green,接著才處理下一個行為。
| 階段 | 它先問什麼 | 主要產物 | 誰推動 |
|---|---|---|---|
grill-with-docs | 我們講的是同一件事嗎? | 共同語言、CONTEXT.md、ADR | 使用者啟動 |
to-spec | 到底要交付哪些外部行為? | Spec、測試 seam 決策 | 使用者啟動並確認 |
to-tickets | 工作怎麼切才小而完整? | 垂直 Tickets、blocking edges | 使用者啟動並核准 |
implement | 目前要完成哪個切片? | 可執行 code、檢查結果 | 使用者啟動 |
tdd | 公開介面真的呈現正確行為嗎? | Red → Green 的測試證據 | implement 期間使用 |
code-review | 做法合規,而且需求也做對了嗎? | 兩條互不混淆的 findings | 實作完成後使用 |
六個階段如何把需求一路送到 Code Review
grill-with-docs:先消滅「我以為你懂」
grill-with-docs 要處理的不是 code,而是對齊失敗。
它自己的 SKILL.md
其實非常短:執行一場 grilling,同時使用 domain-modeling。真正有意思的是這兩件事被綁在一起。
grilling 負責持續追問,不讓「差不多」「應該」「照以前」這些模糊字眼直接溜進實作;domain-modeling 則把問答裡形成的領域詞彙、規則與決策寫回 CONTEXT.md 和 ADR。最後留下的不是一份冗長逐字稿,而是一套後續對話都能重複使用的共同語言。
例如「預約已處理」到底表示櫃台看過、已核准,還是服務已完成?如果這個詞沒有被固定下來,Spec、變數名稱、API 狀態與測試案例很可能各自發明一套答案。
這一棒的交付物,是可被後續規格與 code 重複引用的名詞和決策。
to-spec:不再訪談一次,而是把已知內容收斂成邊界
to-spec
的第一條規則很值得注意:不要再訪談使用者,而是綜合目前對話和 codebase 理解。
這讓 grill-with-docs 與 to-spec 的責任不會打架。前者把問題問清楚;後者把已經談清楚的內容整理成 Problem Statement、Solution、User Stories、Implementation Decisions、Testing Decisions、Out of Scope 與 Further Notes。
在寫 Spec 前,它還要求先找出測試 seam,也就是我們要從哪個公開邊界觀察行為。既有 seam 優先,數量越少越好;如果需要新增,也要盡量放在高層介面,而且必須先跟使用者確認。
這一段很工程。因為規格如果只寫「新增取消功能」,到了測試階段仍然會重新爭論該測 API、Service、Database,還是 UI 上的按鈕。to-spec 直接要求提早決定驗證座標。
它也刻意避免把容易過期的檔案路徑和大段 code 塞進 Spec。交付物的重點是穩定的行為、邊界與決策,不是把實作草稿偽裝成需求文件。
to-tickets:不是把工作切碎,而是切成能獨立驗證的直切片
很多任務拆分看起來很細,實際上只是把同一個大功能橫著剖開:先做資料庫、再做 API、最後做 UI。結果任何一張 Ticket 完成時,都沒有一條真的能展示或驗證的使用路徑。
to-tickets
要求的是 tracer-bullet vertical slice:每一張 Ticket 都要以很窄的範圍,穿過完成該行為所需的各層;做完後能單獨 demo 或驗證,而且大小要能放進一個新的 context window。
每張 Ticket 還要聲明 blocking edges。沒有 blocker 的工作可以立刻開始;有依賴的工作,就把真正擋住它的 Ticket 寫清楚。Agent 在發佈 Tickets 前,必須先把拆分結果拿給使用者確認粒度、依賴關係,以及是否需要合併或再拆。
有一說一,這裡最有價值的不是「幫我開很多 issue」,而是它拒絕把錯誤的切分直接固化到 issue tracker。
如果遇到無法垂直切分的 wide refactor,官方也沒有硬套同一招,而是改用 expand–contract:先讓新舊形式並存,再分批遷移,最後才移除舊形式。這個例外很重要,因為成熟流程不是每個問題都拿同一把刀切。
implement:實作不是自由發揮,而是沿著已核准的邊界前進
implement
只有十幾行,但它把執行邊界壓得很緊:依 Spec 或 Tickets 實作;在事先同意的 seams 使用 TDD;定期執行 type checking 和單一測試檔;最後跑完整測試,再使用 code-review,通過後才 commit。
這代表 implement 並不是收到規格後一次把所有 code 生完。它比較像現場領班:目前做哪一張 Ticket、在哪個 seam 驗證、多久收一次回饋,都已經有前一階段留下的座標。
前面的文件如果做得好,這裡的 Agent 就不必一邊寫 code,一邊重新猜需求、重新發明名詞、重新決定測試層級。
tdd:Red → Green 一次只推進一個外部行為
tdd
把好測試定義得很明確:透過公開介面驗證外部行為,不測 private method,也不把內部協作者的互動當成產品行為。即使內部全面重構,只要外部能力沒變,測試就不該跟著碎掉。
它特別防三種常見陷阱:
- Implementation-coupled:測到內部細節,重構一下就整片壞。
- Tautological:測試用和實作相同的算法算 expected,結果當然永遠同意自己。
- Horizontal slicing:先想像整套測試,再一次寫完全部實作,失去逐步回饋。
目前 Skill 的 loop 規則是:先看到 Red,再寫剛好足以進入 Green 的最小實作;一次只處理一個 seam、一個測試、一個切片。測試 seam 也不能由 Agent 臨時決定,必須是前面已經和使用者確認的邊界。
這裡有一個官方內容本身的細節需要清楚交代。README 用 Red–Green–Refactor 描述 TDD;但目前 tdd Skill 明確寫著,Refactoring 不屬於這個實作 loop,而是放到 review 階段。我的解讀是:專案仍認同 Red–Green–Refactor 的整體精神,只是執行規則把 Red → Green 留在每個垂直切片,把較大的重構判斷延後到 review。文章如果只寫成漂亮的三段口號,反而會漏掉真正的操作差異。
code-review:寫法合規,和需求做對,是兩張不同考卷
code-review
是整條 Workflow 最有辨識度的一段。
它先固定比較點,例如 commit、branch、tag 或 merge-base,再以 git diff <fixed-point>...HEAD 取得同一份變更。接著找出兩種不同的審查依據:
- Standards 軸線:專案自己的 coding standards,加上一組 Fowler code smells baseline。
- Spec 軸線:原始 issue 或 Spec 要求的行為、範圍與決策。
兩條軸線由平行 subagents 分開檢查,避免「code 看起來很漂亮」掩蓋做錯需求,也避免「功能確實能跑」掩蓋它破壞專案慣例。最後 findings 並列呈現,不重新混排成一個總分。
這個拆法很實際:完全符合規範的 code,仍然可能做錯功能;完全符合 Spec 的功能,也可能留下 Shotgun Surgery、Mysterious Name 或 Speculative Generality。它們都重要,但不是同一種錯。
用一個虛構功能走過完整 Workflow
下面用一個明確標示為虛構的教學案例,把六個階段串起來。原始需求只有一句:
使用者可以取消尚未處理的預約。
先問清楚「尚未處理」和「取消」到底代表什麼
grill-with-docs 不會立刻要求新增 CancelAppointmentAsync(),而是先追問:
- 哪些角色能取消?建立預約的人、管理者,還是兩者都可以?
- 「尚未處理」對應哪些狀態?只有
Pending,還是Confirmed也算? - 取消後是刪除資料,還是保留紀錄並改成
Cancelled? - 重複取消要回成功、衝突,還是找不到?
- 通知、退款和稽核紀錄是否屬於這次範圍?
假設這次共同語言最後定義為:「尚未處理」只代表 Pending;「取消」是保留預約資料並轉成 Cancelled;只有建立者可以操作;通知與退款不在本次範圍。
Spec 留下外部行為,不先綁死實作細節
to-spec 可以把討論收斂成這幾個可驗證行為:
- 預約建立者可以取消自己的
Pending預約。 - 已是
Confirmed或Completed的預約不可取消。 - 非建立者不可取消該預約。
- 成功取消後保留原資料,狀態改為
Cancelled。 - 通知、退款與資料刪除不在本次範圍。
測試 seam 則先約定在公開介面 POST /appointments/{id}/cancel。這讓 UI、Application Service 與資料存取怎麼調整仍保有實作空間,但驗收位置不再飄來飄去。
Tickets 依行為直切,不依技術層橫切
這個例子可以拆成三張小而完整的 Tickets:
- 建立者取消
Pending預約:無 blocker,完成 API 到狀態更新的最窄成功路徑。 - 拒絕不可取消狀態:blocked by #1,從相同公開介面回傳明確衝突結果。
- 拒絕非建立者操作:blocked by #1,從相同公開介面驗證授權行為。
這不是「先建欄位」「再寫 Service」「最後補 Controller」。每一張 Ticket 完成時,都有一條可從公開介面驗證的行為。
TDD 一次推進一個行為,Review 再分開看兩種錯
第一張 Ticket 的 Red 可以是:「建立者取消自己的 Pending 預約時,API 回傳成功,重新讀取後狀態為 Cancelled。」測試先失敗,再加入剛好足以通過的實作。
第二張 Ticket 再新增 Confirmed 預約必須被拒絕的 Red,接著只補足這個規則。不是先把所有可能狀態和權限一次寫完,再祈禱整批測試能替我們找到問題。
到了 code-review,兩條軸線可能各自回報:
- Standards finding:實作使用
status == 3判斷取消資格,形成 Mysterious Name/Primitive Obsession,應改用清楚的領域狀態。 - Spec finding:實作讓
Confirmed也能取消,違反 Spec 中「只有Pending可以取消」的規則。
前者是寫法與模型問題;後者是需求符合度問題。把它們分開,修正時才不會拿「code 很乾淨」回應錯誤需求,也不會拿「功能有做」跳過技術債。
為什麼這套流程比一句大 Prompt 可靠
我真正看重的,不是這些 Skills 能不能讓 Agent 多寫幾行 code,而是每一段都留下可以被檢查、修改與交接的中間產物。
- 需求理解錯了,可以在共同語言和 ADR 階段修。
- 範圍切錯了,可以在 Spec 階段修。
- 任務太大或依賴關係錯了,可以在 Tickets 發佈前修。
- 行為做錯了,可以在每一個 Red → Green 切片修。
- 寫法與需求各有問題,可以在兩條 Review 軸線分開修。
一句大型 Prompt 常把這些判斷全部塞在同一個 context 裡。Agent 一旦在前面誤解,後面每個「看起來合理」的決定都可能沿著錯誤方向繼續長。
這套 Workflow 做的事比較樸素:不要期待一次答對,把回饋距離縮短,並在錯誤還小的時候讓人類看得見。
它也和我在 Workflow Skill Router V2 處理的問題互相呼應。Router 關心的是「這個任務現在應該載入哪些能力」;Matt Pocock 這套工程 Skills 更關心「選好能力後,需求如何經過可驗證的階段交付」。前者管 Skill selection,後者管 engineering feedback loop,兩者不是同一層。
Skills 能守住工程流程,但不能替你做完所有驗收
這個專案值得學,不代表裝完就會自動得到高品質軟體。至少有幾個邊界不能跳過:
- 人類仍要做決策。
grill-with-docs能把問題問出來,不能替產品負責人決定業務規則;to-tickets能提出拆分,也要求使用者核准粒度和 blocker。 - Spec 錯了,後面可能只是更一致地做錯。 文件化不等於正確,前段對齊仍是整條流程最重要的風險控制。
- 它不能取代專案自己的 release gates。 CI、資安掃描、資料移轉、部署驗證、觀測性與正式驗收,仍要由 repository 和環境提供。
code-review預期有平行 subagents。 如果使用的 Agent host 不支援這種能力,就需要調整執行方式,不能只看到「支援任何模型」便假設所有 host 都能原樣執行。- Issue tracker 與文件位置要先設定。 沒跑
/setup-matt-pocock-skills,to-spec和to-tickets就缺少明確的發佈目的地與 triage 規則。
另外,小修正不一定值得建立完整 Spec、三張 Tickets 和一場正式 Review。可組合的真正好處,就是不用每次把所有 Skill 全開。若你已經有自己的 Skill Tree 或路由規則,更應該先控制選擇範圍,而不是把「完整」誤認成「專業」。
小修正、中型功能與跨模組工作,流程不用開到同一檔
下面是我的工程建議,不是 mattpocock/skills 官方規則:
| 工作規模 | 建議起點 | 為什麼 |
|---|---|---|
| 小型修正 | 先寫清楚驗收條件,再用 tdd 與雙軸 review | 需求邊界已知時,不必為流程而製造文件 |
| 中型功能 | grill-with-docs → to-spec → implement | 先固定名詞、範圍與測試 seam,再決定是否需要 Tickets |
| 跨模組或多人工作 | 跑完整主線 | Spec、垂直 Tickets 與 blocking edges 能成為共同協作邊界 |
判斷標準不該只是「預計改幾個檔案」。更值得看的是:領域詞彙是否模糊、規則是否有多個分支、工作是否能被一個 context 吃下,以及錯誤會不會跨越多個模組擴散。
任務越難回頭,前面的對齊和切分就越值得做;任務越小、回饋越快,流程也應該跟著縮短。
AI 開發真正缺的,是更短的回饋迴路
mattpocock/skills 沒有保證 Agent 從此不犯錯。它做了一件更可信的事:把錯誤可能發生的位置拆開,讓我們知道現在該檢查語言、規格、任務、行為,還是 code quality。
從 grill-with-docs 到 code-review,真正被傳遞的不是一串指令,而是一組逐步變得更具體、也更容易驗證的工程證據。
AI 寫得快,當然很好。但速度真正有價值的前提,是我們仍然知道它正在往哪裡走,而且每走一小段,都有機會把方向拉回來。