字节笔记本
2026年6月20日
grill-with-docs:有代码库时比 /grill-me 更好的对齐方式
Matt Pocock 在 /grill-me 的基础上推出了 /grill-with-docs,把 relentless interviewing 和领域驱动设计中的 ubiquitous language 结合起来。这个 skill 的目标很简单:在你动手写代码之前,先让 AI 彻底理解你的代码库语言、边界和关键决策,从而大幅减少后续沟通成本。
/grill-me 的局限
/grill-me 通过不断追问帮你梳理设计树的每个分支,直到你和 AI 达成共识。每天有很多人反馈它很好用,但随着使用深入,几个边界开始浮现:
- AI 有时会变得非常冗长,反复解释本可以用一个术语概括的概念。
- 你和 AI 偶尔会碰撞出很好的共享语言,但缺少一个固定的地方记录这些术语。
- 每次新会话都要重新解释代码库中那些"非显而易见"的东西, productive work 开始得很慢。
核心问题不是沟通方式,而是缺少一层最薄的文档。
引入 Ubiquitous Language
Ubiquitous language 来自 Eric Evans 的《Domain-Driven Design》,指的是同时被三方使用的共享语言:
- 代码本身
- 构建它的开发者
- 懂业务但不懂实现的领域专家
当三方说同一种语言时,领域专家说"应用的这部分有问题",开发者立刻知道指的是哪块代码。代码结构和业务语言一一对应,导航、推理、重构都变得更自然。
/grill-with-docs 在每次 grilling 会话中维护一个 CONTEXT.md,把会话中打磨出来的术语实时写进去。
/grill-with-docs 新增了什么
/grill-with-docs 保留了 /grill-me 的核心追问机制,但增加了三个关键行为:
1. 主动寻找 CONTEXT.md
会话开始时,skill 会先查找当前上下文是否已经存在 CONTEXT.md。一个"上下文"在 DDD 里是一个 bounded context;你可以有多个 context,也可以在一个大仓库里只用一个全局 glossary。找到后,AI 会基于已有语言继续追问。
2. 主动打磨语言
会话中,AI 会额外做这几件事:
- 用现有 glossary 挑战你的用词是否一致
- 把模糊表达削尖成精确术语
- 通过具体场景讨论边界情况
- 把术语和代码实现交叉验证
- 实时更新 glossary
3. 引入 ADR
有些模糊不能光靠术语解决,因为它们涉及不可逆、出人意料或存在长期 trade-off 的决策。这时 skill 会建议写一条 Architectural Decision Record(ADR)。
ADR 只在以下情况出现:
- 决策难以逆转
- 决策没有上下文会令人意外
- 决策涉及真实 trade-off,未来会产生后果
例如"用 A 库而不是 B 库"如果两者可互换,就不需要 ADR;但"删除 pitch 时选择 ON DELETE RESTRICT 而非 CASCADE"可能需要,因为它强制用户先 detach,影响删除体验。
实战:给课程管理系统添加 Pitches
Matt 用一个真实案例展示了 /grill-with-docs 的工作流程。
需求
他想在课程管理系统里加入 Pitch 概念:一个视频包装(标题、描述、呈现方式),灵感来自 MrBeast 的"先设计包装再拍视频"。先创建一堆 pitches,挑出最好的再转成正式视频。
问题 1:Cardinality
AI 立即发现 glossary 里已经定义了 Standalone Video:lessonId = NULL 的视频。Pitch 和视频是什么关系?
它推荐了 1:N:一个 pitch 可以包含多个视频(预告片、主视频、不同版本),通过在 video 表上加可空的 pitchId 实现。这样既便宜,又容易回退。
问题 2:术语冲突
如果 video 的 lessonId IS NULL 但 pitchId IS NOT NULL,它还算不算 Standalone Video?
AI 给出两个选项:
- 保持 Standalone Video =
lessonId IS NULL,pitch 是正交元数据,再细分 Unattached Standalone Video 和 Pitched Standalone Video - 重新定义 Standalone Video 为 unpitched,引入 Pitched Video 作为同级概念
推荐选项 (a),因为 "Standalone" 回答结构问题(是否在 lesson 里),"Pitched" 回答包装问题,二者正交。这个区分会直接影响所有变量名和文件名。
问题 3:状态语义
Pitch 的状态 idle | scheduled | shipped 是手动设置还是由时间戳推导?状态转换是线性还是自由?
AI 推荐混合方案:存储 scheduledFor、shippedAt 等时间戳,状态由时间戳计算,允许自由转换。但 Matt 选择更简单的方案:纯手动状态字段,暂时不存时间戳。
问题 4:空 Pitch
Can a pitch exist with zero videos? AI 推荐允许,因为 pitch-first 工作流就是把 pitch 当作规划工件,后续再挂视频。Matt 同意。
问题 5:删除行为
删除 pitch 时,它的视频怎么处理?
ON DELETE SET NULL:视频回到完全独立状态ON DELETE CASCADE:一并删除ON DELETE RESTRICT:有视频时不允许删除
AI 推荐 SET NULL,因为 pitch 只是包装,视频本身有价值。但 Matt 选择 RESTRICT,强制先 detach,符合他"归档而非删除"的偏好。
写入 CONTEXT.md
会话最后,AI 把定义写入 CONTEXT.md:
### Pitches
**Pitch**: A packaging artifact around one or more **Standalone Videos**: a title, an optional description, and a **Pitch Status**. Independent of the course/lesson hierarchy - pitches do not interact with lessons.
**Pitch Status**: One of `idle`, `scheduled`, or `shipped`. Set manually; transitions are free-form. No timestamps are derived from or attached to status changes.
**Pitched Standalone Video**: A **Standalone Video** whose `pitchId` is non-null. Still a Standalone Video - `pitchId` is orthogonal metadata layered on top of the lesson-less structural fact.
**Unattached Standalone Video**: A **Standalone Video** with no pitch (`pitchId IS NULL`). The "totally standalone" case.关系部分也同步更新:
- A **Standalone Video** is either an **Unattached Standalone Video** (`pitchId IS NULL`) or a **Pitched Standalone Video** (`pitchId` references a Pitch)
- A **Pitch** has zero or more **Pitched Standalone Videos**; deleting a pitch is restricted while it has attached videos
- A **Pitch** never references a **Lesson**, directly or transitively真正的好处
1. 回复更简洁
共享语言被文档化后,AI 不再啰嗦。Matt 举例,AI 后续只说:
"Standalone videos are changing, we need to make a change to the pitches and how the pitches display."
一句话就够了。
2. AI 思考更高效,代码更易导航
AI 的 chain-of-thought 也使用语言。共享语言让它内部推理更短、更准。同时,规划文档里的词汇和代码里的命名对齐,搜 "pitches" 就能找到所有相关内容。
这正是 DDD 对人类有效的原因,事实证明对 AI 同样有效。
/grill-me 死了吗
没有。/grill-me 在没有代码库的场景下依然非常出色。Matt 自己把它放到 "Productivity" 分类,/grill-with-docs 则放在有代码库时优先使用的位置。
他甚至听说有人用 /grill-me 给妈妈写悼词,AI 通过提问挖掘出了很多珍贵故事。这种场景 /grill-with-docs 完全不适合。
简单规则:
| 场景 | 使用 skill |
|---|---|
| 有代码库 | /grill-with-docs |
| 没有代码库 | /grill-me |
即使在项目早期,也建议用 /grill-with-docs,因为那是建立共享语言最关键的阶段。
总结
/grill-with-docs 把对齐工作从"每次会话重新解释"变成了"持续维护一份共享语言文档"。它不会替你写代码,但会让你和 AI 在写代码之前说同一种语言,从而少返工、少歧义、少 token。
如果你已经在用 Claude Code 做实际开发,这个 skill 值得优先尝试。