grilling 精读:把『问问题』抽成一个所有技能都调用的原语
grilling 只有 30 行,却是 Matt Pocock 整套技能里被复用最多的一个:grill-me、grill-with-docs、triage、wayfinder、improve-codebase-architecture 都调它。本文讲透它的三件机制——design tree、frontier、round——以及它为什么把事实交给子代理去查、把决定留给人,还把『frontier 空』和『人确认』设成两道闸门。
(本文读的是 mattpocock/skills 快照 5beb35b,2026-10-19。引用的原文都能按文中的文件路径回仓库核对。)
它不是入口,是垫在下面的原语
系列前两篇读的 ask-matt 和 setup-matt-pocock-skills 都是「你敲才活」的 user-invoked 技能。grilling 恰恰相反:它是 model-invoked,也就是模型或人都能到达它,而且通常是由别的技能在内部调用的。
skills/productivity/grilling/SKILL.md 只有 30 行——模板、格式、机制全在里面。它的定位是「原语」:
grillingis a primitive, not a step you schedule: the single source of truth for the interview technique, kept in one place so every skill that needs an interview reaches for it instead of inventing one.
grill-me 和 grill-with-docs 是它面向人的两个前门(都是 user-invoked),另外 triage、wayfinder、improve-codebase-architecture 也都在内部跑它。也就是说,这套技能里凡是需要「把一件事问清楚」的地方,都去调用同一个 grilling,而不是各自再写一遍访谈流程。
它的 frontmatter 保留了触发词——因为它要能被模型自动捞起来:
name: grilling
description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
把这一行和 ask-matt 的 description 放一起看,就能读出仓库的那条分界线:能自动调用的写触发词,只能人打的写人话。 同一个字段,两种写法,取决于这个技能「谁来打」。
直接敲它,和经由封装敲它
直接输入 /grilling 得到的是一次「不加任何外层的访谈」。如果你要的不止于此,docs 给了一张分流表:不在工作目录里,用 grill-me(同一场访谈,但换成一个模型绝不会自己触发的名字);在工作目录里,用 grill-with-docs(同一场访谈,同时写 GLOSSARY.md 和 ADR);一件大到一个会话装不下的事,用 wayfinder(它画一张地图,在决定工单里跑 grilling);一个靠嘴说不清的问题(长什么样、手感如何),用 prototype(先写出一次性的版本再回来);而如果你自己在写一个需要访谈的技能,就直接在里面调 /grilling,不要再发明一个访谈。
机制:design tree、frontier、round
grilling 的全部内容就是三个概念。
design tree 是对主题的建模:每个决定会长出挂在它下面的决定。frontier 是「前置条件都已定下来的那些决定」,也就是现在就能问、不用猜任何还没听到的答案的问题集合。round 是一整条 frontier,一次问完。
SKILL.md 把一轮的格式钉死成这样:
❓ **Q1** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
➡️ <your recommended answer>
---
❓ **Q2** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
➡️ <your recommended answer>
两条规则让这个格式真的好用。一是“Word each question so “yes” accepts your recommended answer.“——把问题写成「回答 yes 就等于采纳推荐答案」。二是你答完一轮,被定下来的决定把 frontier 往外推,它重新算一遍 frontier 再问下一轮;「依赖本轮另一个未定问题」的问题属于后续轮,不属于这一轮。docs 给的数量感是:13 个问题通常落在约 3 轮里,而不是 13 轮。
facts 归 agent,decisions 归人
这是它最锋利的一条设计。SKILL.md 原文:
Finding facts is your job, never the user’s. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a sub-agent to find it; don’t ask the user for anything you could look up yourself. Don’t block on it: a running exploration is an unsettled prerequisite, so only the questions downstream of it wait for the sub-agent to report; ask the rest of the frontier now. The decisions are the user’s: put each to them and wait.
三类东西被严格分开:事实是技能自己的活,能查就别问人(派一个子代理去查,而且不阻塞,只有下游问题等它);决定是人的,必须问了之后等。所以一次「agent 自己把决定也答了」的运行,在这个技能的定义里就是坏了,不是高效。
完成条件也是双重的:
The session is done when the frontier is empty: every branch of the design tree visited, nothing left silently assumed. Do not act on it until the user confirms you have reached a shared understanding.
frontier 空只是第一道闸门;在你说「我们达成共识了」之前,它不许动手,这是第二道闸门。docs 里专门有一条常见问题就叫「It ran out of questions and started building.」——弱一些的模型会跳过这道确认门。
它和一般技能哪里不一样
- 它是一个被复用的原语,不是一个你要记住去跑的步骤。 大部分时候你甚至不会直接敲它,是别的技能在跑它。
- 单点真相带来一次升级、处处受益。 docs 讲改「一次问一个 vs 一轮问完」时提到:改动做在
grilling本体上,于是所有封装它的技能(grill-me、grill-with-docs、triage、wayfinder)一次全拿到了,“There is nobatch-grill-meto install”。这是原语化最直接的回报。 - 它把事实和决定切开,并把「谁等谁」写清楚。 事实不阻塞整轮,决定必须等。
- 它是家族里唯一 model-invoked 的成员。 正因如此它才能被别的技能在内部调用,而不需要人先敲一个名字。
它有意识摒弃了什么
- 摒弃了「一次问一个」。 默认改成整条 frontier 一轮问完。理由是:一轮内的问题互不依赖,所以一个答案不会作废同轮另一个问题——这正好回答了「一次问完会不会丢掉我前面答案引出的问题」这个最常见的质疑。
- 摒弃了问题数量上限。 明确 out of scope:“Some plans need three questions and some need fifty; a fixed ceiling either truncates the hard case or feels arbitrary on the easy one.” 控制手段是自然语言——叫它收尾,或就地接受计划。
- 摒弃了异步模式。 没有人回答的 grilling 产出的是 agent 的观点,不是你的;所以那种「读一个 issue、发一份合并决定备忘」的变体被明确划成另一个技能。
- 摒弃了在每个封装技能里重写访谈流程。 共享原语取代了复制粘贴。
- 摒弃了人设和长模板。 整篇 30 行,格式只有
❓和➡️两行。
可迁移结论
- 把重复出现的交互抽成原语。 当好几个技能都在做同一件事(访谈、评审、路由),把它抽成一个被调用的技能,升级一次全体受益。
- 写清「何时算做完」和「谁来决定」。 完成条件 + 人的确认闸门,两道缺一不可;否则模型会把「问完了」当成「可以动手了」。
- facts 和 decisions 分离。 事实自己查(子代理、不阻塞),决定留给人、必须等。这一条直接决定了这个技能是不是真的在帮你想,还是在替你拿主意。
- 给交互发明一个低成本作答的格式。 编号 + 每题一行推荐答案,让你能「1 是、2 第二个、3 否」地整轮回复。
- 用推荐答案压低来回次数,但要承认它的边界。 docs 提醒:推荐答案有时会和问题措辞相反,那就是「同意推荐但要回答 no」的情况。
- 不要设问题上限。 固定的天花板要么截断最难的情况,要么在简单情况上显得武断。
grilling 短到只有 30 行,但它把「怎么问」这件事从每个技能里拿出来、放在一个地方,并且只规定了三件必须规定的事:按 frontier 分轮、事实自己查、决定等人答。 剩下的交给具体处境。这大概就是一个原语该有的样子:小、唯一、被很多地方调用。
讨论
用 GitHub 账号留言;评论保存在公开仓库chengshu-blog-discussions的 Discussions 里。也可通过 RSS 订阅后续文章。