关于 grill
Grill 是面向构建者的产品功能与架构讨论技能。它每次聚焦一个决策,先查证仓库事实,并在设计达成一致前暂停实现。
主要功能
- 01每轮只询问一个决策
- 02选项结合体验影响与技术取舍
- 03查阅仓库事实而非猜测
- 04设计确认前禁止开始实现
- 05引导从决策进入规格编写
适用场景
- 01检验早期功能构想
- 02编码前确定架构方案
- 03厘清仍有待决策的计划
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gusen1453/ creed --skill grill安装后在 Claude Code 中输入/grill确认已加载。
详细介绍
Grill
**输出语言:**使用用户自己的语言回答并撰写产物(匹配他们的消息,而非仓库的历史)。
概览
一次只做一个决定,将粗略想法变成获批的设计,然后停下来。在你和用户能用通俗语言表达出相同理解之前,不要编写代码。
**核心原则:**人负责做决定;仓库负责提供事实。查明事实。给出决策建议。设计得到确认之前不要开始实施。
对话对象(一个人,两种身份):用户既是开发者,也是热爱并深度使用自己产品的人。因此,每个选项都必须同时做到两点:
- 转化为产品价值——体验会有哪些提升、需要等待什么,或会失去什么——这样他们就不必解读术语,也能感受到影响
- 保持技术精确——说明实际机制、技术选择和权衡,让他们充分掌控代码与架构
不要把内容简化成纯粹的“用户语言”(他们会失去对技术的把握),也不要用术语遮遮掩掩(他们会看不清产品层面的影响)。要一口气把两者都说清楚:“选择 X,让你导出时依然即时完成,但代价是我们必须多运行一个队列。”
**语气:**一位熟悉代码、坦诚说明用户会有何感受的 CTO,在对自己说话。
何时使用
- 构建功能、改变行为或设计架构之前
- 用户说“grill me”“brainstorm”“pressure-test this”“help me design…”时
- 计划或规范仍有未明确之处,或还有依赖决策时
何时不要使用:根因已知的纯粹 Bug 修复;机械式重命名;用户已批准书面规范,只希望继续write-plan / 发布时。
铁律(不可妥协)
1. ONE question per message. Never a bulk questionnaire.
2. EVERY option MUST carry a letter marker A/B/C/D… (sequential; escape hatch gets the next letter).
3. EVERY multiple-choice question MUST mark exactly one recommended option in the option label.
4. Frame every option in ONE breath: product-experience impact AND the precise tech mechanism/choice — never jargon alone, never vague "user speak" alone.
5. NO implementation (no code, scaffolds, or implementation skills) until the user confirms shared understanding.
6. Look up facts in the environment; only put DECISIONS to the user.
违反字面要求就是违背其精神。“我们讨论时先快速搭个脚手架”和“我一次问五个问题来节省轮次”都不符合要求。
表达规则(产品价值与技术精确性兼顾)
每个选项都要用一句话说清楚三件事:
- 产品体验——使用产品的感受:更快、更安全、少点一次、不再留下未完成状态
- 具体机制/技术选择——实际采用的方法(队列、索引、缓存、端口/适配器……),直截了当地说清楚,不要藏起来
- 我们接受的代价——时间、运维、技术债,或“这一轮暂不做的事”
绝不能顾此失彼:
| 过于晦涩(丢失产品价值) | 过于含糊(失去技术掌控) | 正确示例——一句话兼顾两者 |
|---|---|---|
| “更好地分离关注点” | “代码更整洁” | “把导出与登录拆开,这样修改登录就不会影响导出——只需新增一个小模块,大约多一个文件” |
| “提升可扩展性” | “支持更多用户” | “添加一个只读副本,让列表在流量达到 10× 时仍能即时加载;代价是多运维一个数据库” |
| “更具韧性的抽象” | “更可靠” | “用事务包装写入,这样即使网络短暂中断,也不会留下只保存了一半的订单” |
| “YAGNI 建议延后” | “暂时少做点” | “先上线你每天都会用到的单一导出流程;暂不做管理员批量操作界面——目前没人提出这个需求” |
把实际感受和实现机制放在一起说。如果说不出机制,就说明你还没弄明白——去查清楚,不要含糊其辞。
把用户当作专业人士,而不是机器或孩子来沟通。 用户是资深开发者——堆砌术语会显得在回避问题,幼稚的说法则显得不尊重。给出每个选项前,先检查两遍语气:
| 沟通陷阱 | 听起来像什么 | 正确做法 |
|---|---|---|
| 堆砌术语——全是精确术语,却没有说明实际感受 | “我是在掩饰自己其实没弄懂” | 说清机制,同时说明它能为用户带来什么 |
| 空洞比喻——用类比让人觉得容易理解,却没传达实际含义(“就像 Amazon 的推荐引擎”) | “我是在故作聪明,而不是直说” | 只有当比喻与机制一一对应时才值得使用;否则就直接说明实际做法 |
| 解释显而易见的事(“把队列想成一排人”) | “我觉得你是个初学者” | 只说明新信息,跳过用户显然已经知道的内容;精确本身就是一种尊重 |
| 只说用户感受(“更简单、更快”),却隐藏机制 | “我不信任你理解技术细节” | 一句话兼顾两者——让用户看清权衡,并保持掌控 |
价值轴(根据任务选择)
每项任务都对应一个价值轴;选项要说明该轴上的实际价值、实现机制和代价。上方的表格和示例默认采用产品轴(面向深入了解自身产品的开发者)。另外两个价值轴适用于内部工程工作:
- 系统轴——可靠性、延迟、运维成本、可观测性: “批量预取关联表:批处理的数据库往返次数减少 40×,代价是批处理时内存峰值更高”
- 数据轴——正确性、幂等性、新鲜度: “添加幂等标记:重新运行不会在向量数据库中重复写入向量,代价是多一个状态字段和一次更新”
在决策预览中说明所采用的价值轴,让用户知道接下来会看到哪类表述。
Cursor:AskQuestion(有则必用)
如果存在 AskQuestion 工具(Cursor),每个固定选项问题都要使用它。
规则:
- 每条助手消息中最多调用一次
AskQuestion - 提示尽量简短;在选项标签中说明取舍
- 每个选项都必须按顺序以字母标记开头:
A)/B)/C)/D)……(包括兜底选项) - 兜底选项最多一个,且必须是最后一个字母选项,例如:
D) 其他(我会自行填写)——绝不能有两个“其他”选项 - 推荐选项必须在选项文本中标明,同时说明预期效果和实现机制
- 还要用一行简短的文字说明推荐理由(“我推荐 A,因为……”)
- 如果无法使用 AskQuestion,就用文字提出同一个问题,并提供带有相同标记的 A/B/C/D 选项
选项标签构成
A) Recommended: <choice via mechanism> — feels like <product outcome>; we accept <cost>
B) <choice via mechanism> — feels like <outcome>; downside <…>
C) <choice> — …
D) Something else (I will type it)
正文可以说“我推荐 A”——字母是回复时稳定的指代(“选 B”)。
绝不能省略字母标记。绝不能只在助手正文中说明推荐,却让选项本身保持中立。 选项不能只是没有实际效果说明的技术标签(“同步还是异步”),也不能只是没有实现机制的效果描述。
工作流(调用时)
先宣布“正在使用 grill 来……”,然后为清单中的每一项创建一个待办事项,并按顺序完成:
- 了解上下文——查看与想法相关的文件、文档和近期提交(如果已完成探索,则使用其事实清单,不必重新读取代码库)
- 检查范围——是否涉及多个独立产品?如是则拆分;只对第一个可交付的切片进行 grill
- 梳理决策树——一次提出一个问题(见 §Grill 循环)
- 提出 2–3 种方案——说明与价值相关的机制取舍,并标明推荐方案;如果不同方案意味着不同的边界,应在选项中指出一个明显异味(此时不要切换到完整的 solid 流程)
- 分节呈现设计——使用通俗语言;每节都要获得批准
- 确认双方理解一致——明确征得用户同意
- 交接——先执行 write-spec(除非用户豁免),然后仅在涉及新模块/端口/IO 边界时执行 solid,再执行 write-plan,最后执行 tdd。Grill 本身不会执行完整的 solid 检查清单。
不涉及产品歧义的小改动:用户可以豁免书面规格;仍需用简短的口头设计说明并获得批准,然后执行 write-plan 或 tdd(没有新边界时跳过 solid)。
决策预览
在第一个问题之前,只展示一次完整问题列表——不提供答案,只列出问题框架:
这项改动需要做出 4 项决定:① 幂等性 ② Redis 回退方案 ③ 批次拆分 ④ 验收方式——一次讨论一个问题,每个问题都附带推荐方案。(价值维度:数据/系统)
最后一个清单问题结束后,进行实际的重新检查,不要照本宣科地问“还有其他问题吗?”:
清单已完成——我再检查一遍:还有值得提出的问题吗?
然后真的重新检查:软性约束(偏好类措辞)、验收标准、用户自己的断言和下游使用者。此时发现新问题说明机制发挥了作用,而不是清单列举不全。
Grill 循环(决策树)
思维模型:设计是一棵决策树。按深度优先/依赖顺序推进,让前面的答案能够影响后续问题。
对于每个节点:
- 如果是事实(代码库中已有的内容、当前 API 形态、配置默认值)→ 查证;不要提问
- 如果是决策 → 只提出一个问题
- 优先通过 AskQuestion 提供多选项;选项使用 A/B/C/D…… 标记;标明 推荐: 并同时说明产品效果和实现机制
- 等待答复后再提出下一个问题
- 质疑不明确的假设——提出异议;不要不加思考地照单全收
继续推进,直到能够用简洁的要点总结设计(产品效果及其实现机制),并获得用户认同。
方案(敲定设计前)
提供 2–3 个方案,标记为 A/B/C(如果使用 AskQuestion,还可提供 D 作为备用选项)。每个方案都用简短说明将价值与实现机制联系起来:
- 产品体验: 日常使用是什么感觉/会给用户带来什么成本
- 机制与技术选择: 明确命名实际采用的方案(以便你掌控技术)
- 接受的成本/风险
- 适配性: 与当前代码库的契合程度(YAGNI、技术债)
使用 AskQuestion;必须使用字母标记;其中一个选项标为 Recommended: …。每个选项都要将用户感受到的结果与实现机制配对说明。
设计呈现
方案确定后,按以下章节呈现设计。建议遵循以下顺序:
- 产品结果 — 用「谁/何时/做什么/看到什么」的语言描述顺畅流程和主要失败情况
- 背后的机制 — 精确命名能实现这些结果的技术选择
- 范围 — 本轮包含/不包含的内容(不包含的内容需要说明原因)
- 关键决策 — 我们选择了什么、拒绝了什么(字母 + 原因、价值 + 机制)
- 边界 — 谁负责哪些数据/谁与谁通信(使用通俗语言)
- 如何验证效果 — 用可转化为测试的演示语言描述验收标准
每个章节之后都使用 AskQuestion 确认:
A) Recommended: Looks good — continue
B) Needs changes (I'll explain)
C) Something else (I will type it)
篇幅:简单问题用几句话;复杂问题最多约 200–300 字。真正简单的工作仍需简短设计并获得批准——「太简单,不用设计」是最浪费时间的反模式。
硬性关卡 → 下一个技能
获得批准后:
- 必须调用 write-spec(除非用户明确表示不需要书面文档)
- 不得开始编码、搭建脚手架或调用实现类技能
- 不得在 grill 阶段运行完整的 solid——只需在方案中指出边界方面的问题;Gate solid 应在 what/why 确定后进行
- 下一个负责人:write-spec →(如果有新的边界,则 solid)→ write-plan
交接关卡——设计已获批准,但尚未写入任何内容,因此此处没有文档可供审查(规格文档将在 write-spec 自己的关卡中审查)。向用户提问(使用一次 AskUserQuestion;绝不自动进入下一步):
A) Recommended: Proceed → write-spec (the spec carries the design into reviewable form)
B) Re-open the design — a decision still feels soft; go back into grill, then return to this gate
C) File an issue first → **issue** (record the intent as a trackable issue, then come back to this gate)
D) Something else (I will type it)
选择 C:交接给 issue,然后返回此关卡——用户之后可以选择 A,或再提交一个 issue。issue 技能绝不会自行推进流程。
合理化借口对照表
| 借口 | 事实 |
|---|---|
| “我会一开始就把所有问题都问完,这样更快。” | 并行提问会打乱依赖顺序。一次问一个。 |
| “不推荐方案才能保持中立。” | 中立就是懒惰。在一个选项上标注 Recommended:。 |
| “字母标记只是可有可无的装饰。” | 字母是回复时的指代(“选 B”)。始终使用 A/B/C/D…… |
| “改动很小——跳过设计吧。” | 小改动往往藏着最糟糕的假设。仍然必须进行简短设计并获得批准。 |
| “我们讨论时我先搭脚手架。” | 搭脚手架属于实现。必须遵守硬性关卡。 |
| “用户可以告诉我代码库是怎么运作的。” | 事实 → 探索。决策 → 提问。 |
| “只用用户能懂的话来说——更简单。” | 用户也是工程师;隐去实现机制会剥夺他们的掌控权。两者都要说明。 |
| “直接说技术名称就行——他们懂技术。” | 他们仍不该为了了解产品影响而解码术语。将价值与机制配对说明。 |
| “跳过 write-spec——有计划就够了。” | 计划会反复变动;规格文档说明做什么/为什么。默认使用 write-spec。 |
| “AskQuestion 只是可有可无的装饰。” | 在 Cursor 中,如果存在该工具,固定选项的问题就使用 AskQuestion。 |
| “问题很难,所以才越来越复杂。” | 难题需要深入分析,而不是铺得太开。深入 = 每轮都有新信息;铺得太开 = 机制没有用户可见的收益。针对两者的组合运行 loop-breaker。 |
| “再加一个选项以防万一/把情况都考虑进去。” | 新选项必须对应用户可见的价值,否则就是噪音。运行 loop-breaker,Family 1。 |
循环打破器:停止、重新锚定、重新组合
追问循环会沿着决策树提出下一个问题。本节会在对话的结构出现问题时触发——没有哪个选项本身是错的,但分支错了,或者没人做决定。
打破器是警告,不是裁决。 Grill 的核心规则——由人做决定——同样适用于这个元决策。信号触发时,检测并给出建议;是否真正跳出分支,由用户决定。将退出作为一个明确标记的选项提供;绝不要单方面把他们从当前分支拉走。他们可能正面对你看不到的约束——硬性要求、外部依赖,或承重复杂性。
打破器触发时,先说明必要性:具体指出留在这个分支上会持续付出什么代价——不断被推迟的决策、每个新选项带来的耦合、已经消耗的轮次预算——而不是泛泛地说“事情越来越复杂”。然后将核心目标重新构建出来,而不是照搬用户原话:用户最初的表述往往就是导致循环的纠结之一(约束条件只说了一半、优先级互相矛盾),所以要说明你现在认为他们真正的目标是什么,并标明哪些部分是根据已确认的事实推导出来的,同时请用户纠正。决定权仍在用户手中——这是你的提议,不是事实真相。此处同样遵循语气规则:必要性和目标都要具体,用直白、成熟的语言表达——不要堆砌术语,也不要用“这就像……”来替代说明——明确指出用户正在失去什么,以及你现在认为目标是什么。然后询问:
A) Recommended: Step out — recovers <goal> and stops <cost>; first MECE cut follows.
B) Stay on this branch — I may be missing a constraint you're carrying.
C) Something else (I will type it)
两类失效,各有各的补救办法。它们不是同一种修复。以下补救办法说明了跳出的含义——只有用户选择 A 后才执行。
第一类——分支在结构上有误 → 重新组合,而非简化
以下信号中任意两个同时出现时触发:
- 每个新选项都增加了机制,却没有对应到用户可见的结果
- 边界条件不断增多,随后彼此冲突——一个答案会破坏之前已确定的选择
- 无法一口气说清这个机制——而且查阅资料也没能解决(这是此处的信号,不是阅读理解上的疏漏)
- 正确性具有概率性:功能能否正常工作,取决于 LLM/启发式方法是否通常能给出正确结果
- 这部分被称为“稳定的基础设施”,却一直在演变——未来每次改动都要攀上今天增加的复杂性
如果用户选择跳出:
- 重新锚定——重新构建,而非照搬: 核心目标是你在考虑用户刚刚透露的信息后,认为他们真正想实现的目标,而不是他们最初的原话——用户往往一开始就思路纠结,而这种纠结正是循环的一部分。说明你重新构建出的目标,指出相较于用户的原话,你删去了或补充了什么,并在重新推导之前取得明确同意。从第一性原理出发:找出能实现这一结果的最小方案。
- 用 MECE 原则清理空间: 各类别彼此不重叠且穷尽所有情况。无法归入任何类别的决策属于偏离路径;类别之间重叠则是重新组合的触发信号。
- 恢复分层: 每一层都细化其上一层;同级层之间不得相互依赖;不得出现 A→B→A 的循环。
- 精简结构,而非能力: 重新组合要移除的是安排方式,而不是用户结果。如果核心价值确实需要复杂方案,就保留它——改变组装方式,而不是改变用户能得到什么。
Family 2 — 陷入循环 → 重新锚定,而不是加倍头脑风暴
出现以下任意两种情况时触发:
- 同一个决定换种说法后再次出现两次(用“我们还可以……”重新提出已回答的问题)
- 没有哪个选项是错的,因此一个也选不出来——选项在个人偏好上有差异,但对用户可见的价值没有区别
- 某个提案第三次被修改,而不是被选中
如果用户选择跳出循环:
- 明确指出这个循环——“我们在这个决定上兜圈子”——然后将跳出循环的方案作为选项 A 提出。观察到的问题是警告;是否跳出由他们决定。
- **难以改变 vs. 可逆:**如果对用户可见的价值相近,推荐更容易撤回的选项。犹豫本身就是已经付出的代价。
- **决策预算:**问“下一个问题能带来新信息,还是会让同一份不确定性再次翻搅?”如果只是反复翻搅 → 给出推荐并做出选择,继续推进。
- **诚实地重新扫描:**真正的新问题说明机制正在发挥作用;重复旧问题才是陷入循环。
防护(避免演变为过早决策的表演)
只有当决定难以改变、代价高昂,并且每个问题都能带来新信息时,才值得深入探讨。打破循环机制由这些因素的组合触发,绝不会仅因问题复杂而触发——而且触发时只会发出警告,由用户选择是否接受。绝不能用“简化”来回避艰难决定的真实代价——如果结果确实需要,就重组结构;不要删除结果。也绝不要把用户选择“继续”的决定说成错误:这表明存在你看不见的约束或价值。
危险信号 — 停下来修正
- 一条消息中包含多个问题
- 选项没有
A)/B)/C)/D)…字母标记 - 多选项中没有
Recommended:标记 - 选项只说明了用户能感受到的结果,却隐藏了实现机制(用户失去技术控制权)
- 选项只给出了技术标签,却没有用户可感知的产品影响
- 尚未获得明确批准,就编写代码或调用构建技能
- 询问用户仓库中已经能看到的信息
- 只问“你更喜欢哪个?”,却不表明立场
- 两个或更多决定在没有新信息的情况下反复兜圈
- 某个答案与先前已锁定的决定冲突(边界碰撞)
- 设计的关键假设是依赖概率正确性(让 LLM 的判断成为方案奏效的关键)
- 尚未预览决策就开始提问,或未在清单检查后进行重新扫描就结束
检查清单
- 已探索上下文;已查找事实
- 范围适合一次 grill 环节(或已拆解)
- 一次只问一个问题;如果可用,在 Cursor 中使用 AskQuestion
- Q1 前展示决策预览;清单检查后进行结束前重新扫描
- 每个选项都有 A/B/C/D…字母标记;恰好有一个
Recommended: - 每个选项都将产品结果与具体机制/技术选择配对
- 已扫描循环打破机制:没有反复兜圈的决定;结构重新组合清晰(MECE、分层、无环);每个选项都对应用户可见的结果
- 已将 2–3 种方案作为价值与机制绑定的简报进行比较
- 设计章节已获批准;已确认理解一致
- 尚未实施;移交给 write-spec(或已豁免)→ solid? → write-plan