怎麼用 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. 它怎麼運作:一場帶著你專案記憶的盤問

機制一句話:拿你專案自己的語言和決策,盤你的新方案

具體幾條(原作把這套行為拆進了 grillingdomain-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 得靠 grillingdomain-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() 也老老實實:只能整單撤、只在出貨前、不碰錢。

然後我丟給它一個方案(就是開頭那個):「讓使用者取消訂單裡的某幾件商品(不是整單),然後把這幾件的錢退給他。」

它讀完程式碼和術語表,第一句話不是「好的」,是:

在開始盤問之前,有兩個術語衝突需要當場指出。

你說的「取消某幾件商品並退款」,在現有術語表裡撞到兩條定義:

  1. CONTEXT.md 定義 Cancellation(撤單)= 整單撤銷 + 不涉及任何退款流程。你說的是部分撤銷,還帶退款——兩點都衝突。
  2. 術語表 _Avoid_ 欄裡明確排除了「退貨」這個詞。

所以你描述的動作在現有詞彙裡沒有對應詞。我們需要先命名這個新概念,再繼續討論設計。

我自己都沒意識到:我說的「取消」,跟專案裡定死的「撤單」根本不是同一回事。它不只逮到了,還順手翻了程式碼:

現有的 cancelOrdersrc/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),以及拆出來的 grillingdomain-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 改為組合兩者的入口;教學裡講的行為和那場真實盤問均不受影響,只是用法上多了「可拆開單用」這一層。