怎麼用 grill-with-docs:讓 AI 別急著點頭,先把你盤一遍
很多時候,你剛跟 AI 下完需求,它就迫不及待開始寫程式碼,把你還沒想清楚的地方一起帶進專案。grill-with-docs 反過來:它不急著寫程式碼,而是拿你專案自己的術語表和程式碼來採訪你,詞沒磨利不准往下走,邊盤邊把術語表和決策記錄寫好。下面看一場真實記錄——它當場逮到一個我沒看見的術語衝突。
github.com/mattpocock/skills @6eeb81b 30 秒速覽 · 沒空讀全文,先抓這些
- 痛點:AI 太順,爛方案丟過去 → 它直接寫程式碼 → 你的糊塗一起帶進專案。
- grill-with-docs 反著幹:盤你。拿你專案的
CONTEXT.md術語表 + 程式碼,逐條挑你方案的刺。- 怎麼盤:一次一問、先給推薦答案;能查程式碼就查;詞敲定 → 寫進
CONTEXT.md;難回頭的決策 → 落一條 ADR。- 裝:
npx skills@latest add mattpocock/skills· 用:「用 grill-with-docs 盤一下我這方案:<方案>」- 最適合:往成熟專案加複雜功能、而且有些詞大家講的不是同一回事。別硬上:空儲存庫 / 無所謂的小改 / 指望它替你寫程式碼。
1. AI 太好說話,這是個隱患
跟 AI 結對幹活,最危險的一點是它幾乎從不反駁你。
你丟一個沒想清楚的方案過去——「加個功能,讓使用者取消訂單裡的幾件商品,再退錢」——它眼睛都不眨:「好的!」程式碼嘩啦啦就出來了。可那句話裡一堆沒敲定的東西它一個都沒問:「取消」是出貨前還是出貨後?「退錢」算誰的?跟專案裡已有的「撤單」是不是同一回事?它不問,直接替你假設,把假設寫死在程式碼裡。
三週後你才發現:同一個「取消」,產品、程式碼、資料庫各指一個意思,程式碼成了一鍋粥。
不是 AI 不聰明,是它太想幫你,不肯停下來逼你想清楚。
grill-with-docs 反著來:讓 AI 別急著點頭,先拿你的方案盤問一遍(grill 本義就是「拷問、炙烤」)。詞沒磨利,不准往下走。
2. 它怎麼運作:一場帶著你專案記憶的盤問
機制一句話:拿你專案自己的語言和決策,盤你的新方案。
具體幾條(原作把這套行為拆進了 grilling 和 domain-modeling 兩個 skill,下面說):
一次只問一個,先給推薦答案。 順著方案的決策樹一個岔路一個岔路地問,每問先亮出「我建議選這個,因為……」,而不是甩你一張二十問的清單。
能自己查程式碼的就不問你。 翻程式碼能知道的答案,它自己去翻,不拿來煩你。
拿術語表卡你。 專案根目錄那份 CONTEXT.md 就是它的尺。你蹦出一個詞跟表裡對不上,它當場攔:「術語表裡『撤單』是 X,你講的明明是 Y——哪個?」
模糊的詞,逼你磨利。 你說「帳戶」,它問:「指的是 Customer 還是 User?這兩個是兩回事。」
拿程式碼跟你對質。 你說功能怎麼運作,它翻程式碼核對,對不上就點出來:「程式碼裡撤的是整單,你卻說能撤一部分——哪個算數?」
詞敲定了,當場寫進 CONTEXT.md。 不攢著、不等一下。
難回頭的決策,才落一條 ADR。 ADR(架構決策記錄)它給得很省:只有「難反悔、沒上下文會讓後人困惑、是真權衡的結果」三條同時成立,才提議記一筆。
這其實是把領域驅動設計裡的兩件正經事:通用語言(ubiquitous language) 和 決策留痕,包進一場你逃不掉的對話。
一個變化值得知道:它其實是兩個 skill 拼的。 Matt 把 grill-with-docs 拆成了 grilling(那場盤問)和 domain-modeling(術語表 + ADR 那套紀律),自己變成一個薄殼,正文就一句「跑 /grilling,用上 /domain-modeling」。行為一個都沒變,但你能拆開單用:只想被盤就 /grilling,只想維護術語表和 ADR 就 /domain-modeling,兩個都要才是 grill-with-docs。
3. 上手:裝好,然後丟個方案給它盤
裝。 在 mattpocock/skills,官方一行命令,跟提示勾上 grill-with-docs:
npx skills@latest add mattpocock/skills
因為前面的拆分,grill-with-docs 得靠 grilling 和 domain-modeling 才完整,三個一起勾(或直接用後兩個)。已經 clone 到本機的,把這幾個目錄複製進專案的 .claude/skills/ 也行。
餵。 別再說「幫我實作 X」,換一句:
用 grill-with-docs 盤一下我這個方案:<把你那個還沒完全想清楚的方案丟進去>
注意:它標了 disable-model-invocation,不會自己冒出來,得你點名喊(或敲 /grill-with-docs)才啟動。然後準備好:它不會順著你,它會開始問。
第一個真結果往往就是它的第一個問題:你以為想明白的事,被一問,發現根本沒想明白。下面這場是我真跑出來的。
4. 跟著看一場真實的盤問
我搭了個小專案讓它盤,故意埋了個坑。專案裡已經有一份 CONTEXT.md,寫著:
**Cancellation(撤單)**:
訂單在出貨前被整單撤銷,庫存原樣退回。不涉及任何退款流程。
_Avoid_: Refund, Return, 退貨
程式碼 src/orders.ts 裡的 cancelOrder() 也老老實實:只能整單撤、只在出貨前、不碰錢。
然後我丟給它一個方案(就是開頭那個):「讓使用者取消訂單裡的某幾件商品(不是整單),然後把這幾件的錢退給他。」
它讀完程式碼和術語表,第一句話不是「好的」,是:
在開始盤問之前,有兩個術語衝突需要當場指出。
你說的「取消某幾件商品並退款」,在現有術語表裡撞到兩條定義:
CONTEXT.md定義 Cancellation(撤單)= 整單撤銷 + 不涉及任何退款流程。你說的是部分撤銷,還帶退款——兩點都衝突。- 術語表
_Avoid_欄裡明確排除了「退貨」這個詞。所以你描述的動作在現有詞彙裡沒有對應詞。我們需要先命名這個新概念,再繼續討論設計。
我自己都沒意識到:我說的「取消」,跟專案裡定死的「撤單」根本不是同一回事。它不只逮到了,還順手翻了程式碼:
現有的
cancelOrder在src/orders.ts:3只允許status === "PLACED"的訂單操作。你說的「取消某幾件商品」,是只限出貨前,還是也包含出貨後?我的建議:只限出貨前。 出貨後的退件在商業上是退貨流程,複雜度差了一個數量級……先做出貨前這條路,邊界最清晰。
我答「採納,只限出貨前」。接著它幹了件更關鍵的事——給這個沒名字的新概念起名,當場寫進術語表:
Partial Cancellation(部分撤單):訂單在出貨前,移除其中若干(非全部)line item,被移除商品的庫存退回。不涉及任何退款流程。
_Avoid_: 部分退款, 部分退貨, 商品取消
這條是它真的寫進了 CONTEXT.md 檔案,不是嘴上說說。退款那一半它明確劃走:「歸 Billing 管,不寫在這裡。」
往下盤到邊界,它停下來判斷要不要留痕,然後真生成了一條 ADR:
ADR 已落在
docs/adr/0001-partial-cancellation-no-refund.md: 「部分撤單不觸發退款,退款完全交由 Billing 上下文。……備選方案是在 Ordering 內部直接觸發退款,把『撤單+退款』做成一個原子操作——我們拒絕了,因為它會讓 Ordering 依賴 Billing 的內部介面,破壞已有的上下文邊界。」
最絕的是它的下一個問題,直接引用了它自己剛寫下的這條 ADR:
問題 3 / Billing 怎麼知道要退款?現有程式碼裡
cancelOrder什麼事件都沒發(src/orders.ts:7)。
- A. 發領域事件,Billing 訂閱並退款。
- B. Ordering 直接呼叫 Billing 的退款介面。
- C. 什麼都不發,讓上層呼叫方自己串起來。
我的建議:A。 方案 B 讓 Ordering 直接依賴 Billing,剛好是 ADR 0001 明確拒絕的。
你品品這個閉環:它逼我磨利一個詞 → 寫進術語表 → 把邊界決策記成 ADR → 再用這條 ADR 擋住後面一個會破壞邊界的選項。它在用你剛和它一起建立的語言,守住後面每一步。 這就是「帶著專案記憶盤問」的意思。
5. 它的脾氣:什麼時候該用,什麼時候別硬上
它很提神,但不是萬能,也不是隨時都該開:
- 得有東西可盤才好使。 有
CONTEXT.md、有程式碼,它才能拿來卡你、對質。空儲存庫裡它也能從零幫你建術語表,但遠不如「拿你既有的語言挑刺」。所以最適合往一個長起來的專案裡加東西。 - 它磨的是清晰度,不是程式碼。 盤完你手裡多的是磨利的術語、幾條 ADR、一個想透的方案——不是一坨實作。寫程式碼是盤清楚之後的另一步,別指望它順手幹了。
- 別拿它盤無所謂的小事。 改個按鈕顏色、加個無關欄位,它也陪你一本正經走流程,純屬浪費。它的價值在「詞不磨利、後患無窮」處:領域概念、上下文邊界、幾個概念容易攪在一起的時候。拿大砲打蚊子,蚊子沒事,你累。
- ADR 它給得很省,這是優點別嫌煩。 只在「難反悔 + 會讓後人困惑 + 真權衡」三條都中時才記一條。嫌它「怎麼不多記點」時先想想:你是真要留痕,還是只想要個儀式感?ADR 不是越多越好,是越該記的才記。
一句話:往成熟專案加複雜功能、又隱約覺得「有些詞大家講的不是同一回事」時,開它。 這是它的主場。
6. 速查卡
裝:npx skills@latest add mattpocock/skills # 跟提示勾 grill-with-docs
盤:對 AI 說 "用 grill-with-docs 盤一下我這個方案:<方案>"
它會做:
一次問一個問題,每問先給推薦答案
能查程式碼就查,不空問
拿 CONTEXT.md 術語表卡你,詞對不上當場攔
模糊的詞逼你磨利("帳戶"=Customer 還是 User?)
拿程式碼跟你對質,對不上就指出
詞敲定 -> 當場寫進 CONTEXT.md(術語表,不放實作細節)
難回頭的決策 -> 落一條 ADR(docs/adr/,三條標準全中才記)
CONTEXT.md:只放術語表,每個詞一兩句、給出該用的詞 + _Avoid_ 該避開的
ADR 三標準:難反悔 + 沒上下文會讓人困惑 + 是真權衡的結果(缺一不記)
最適合:往成熟專案加複雜功能,且"有些詞大家講的不是同一回事"
別硬上:空儲存庫 / 無所謂的小改動 / 指望它替你寫程式碼
7. 延伸
- 原始碼:grill-with-docs(MIT),以及拆出來的 grilling 和 domain-modeling。術語表和 ADR 的格式說明現在在 domain-modeling 裡:CONTEXT.md 格式、ADR 格式,都值得一讀。
- 想深挖,查「領域驅動設計(DDD)」裡的通用語言(ubiquitous language) 和 ADR(Architecture Decision Record)——grill-with-docs 就是把這兩件事變得隨手可做的輕量殼。
- 喜歡這種「換個姿勢跟 AI 協作」的玩法?上一篇拆了 caveman(讓 AI 閉嘴只講重點),正好一對:一個讓它少說廢話,一個讓它多問狠話。系列會接著拆 Matt 儲存庫裡的其他 skill。
本文是 usesuperpowers.com 的原創教學,講解的 grill-with-docs skill 來自 mattpocock/skills(
source_commit: 6eeb81b),遵循其 MIT 授權。文中盤問過程為真實運行記錄(已隱去無關細節);引用的原作規則版權歸原作者,我們的拆解、演示與文字為原創。
關於版本:本文基於
6eeb81b。此版本裡 Matt 把原來單一的 grill-with-docs 拆成了grilling+domain-modeling兩個 skill,grill-with-docs 改為組合兩者的入口;教學裡講的行為和那場真實盤問均不受影響,只是用法上多了「可拆開單用」這一層。