怎么用 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 改为组合两者的入口;教程里讲的行为和那场真实盘问均不受影响,只是用法上多了”可拆开单用”这一层。