grill-me 精读:一个只有 7 行的技能,为什么反而是设计
grill-me 的正文只有一行:调用 grilling。本文走一遍它的真实触发路径,解释薄指针与厚原语的分工,用 git 历史还原它从三段指令收缩成七行的过程,并说清楚它刻意剥离了触发词、状态、问题数量上限之后,为什么行为反而更准。
(本文读的是 mattpocock/skills 快照 5beb35b,2026-10-19,引用原文都能按文中路径回仓库核对。这是「逐个技能精读」系列的第二篇,聚焦 grill-me 一个技能。)
先看实物:七行
skills/productivity/grill-me/SKILL.md 全文如下,一字不差:
---
name: grill-me
description: A relentless interview to sharpen a plan or design.
disable-model-invocation: true
---
Call the Skill tool with "grilling".
frontmatter 四行、空行一行、正文一行,一共七行。旁边的 agents/openai.yaml 也只做一件事:声明 allow_implicit_invocation: false。作者在 wait-what 的文档里说过「三行长的技能是设计,不是未完成的草稿」,grill-me 是同一套思路的另一个样本。
走一遍真实触发路径。你手动敲 /grill-me——disable-model-invocation: true 保证模型永远不会自己抓它,只有人能打;agent 读到正文,唯一动作是调用 Skill 工具、技能名 grilling;访谈从这一刻起由 grilling 接管。它按 design tree 走,每一轮把整个 frontier(前置已定的那批问题)一次问完,每题附上自己的推荐答案,事实派子代理去查,决定权留给你,直到 frontier 空才算聊清楚。
产出是什么?一段对话。它不写文件、不留工作区。docs/productivity/grill-me.md 的原话是它 stateless,“the only result is a clearer version of the idea, in your own head”。
七行给模型,七十六行给人
这里有个容易被忽略的分工。同一个技能,仓库里有两份材料:
skills/productivity/grill-me/SKILL.md—— 7 行,给模型读。docs/productivity/grill-me.md—— 76 行,给人读(发布在aihero.dev/skills-grill-me)。
后者装的是「什么时候该用它」「三类 grilling 技能怎么选」「什么是设计访谈的失败模式」这类只有人需要的信息。仓库 AGENTS.md 规定了这类文档页的固定骨架:What it does、When to reach for it、Common questions、It’s working if 四节。技能本体里一句都不重复。
也就是说,长不是被删掉了,是被分给了正确的读者。给模型的七行里没有一句解释「为什么要这么做」;给读者的七十六行里没有一句执行指令。这个切分比「把文档写短」更有参考价值。
它和「一般技能」的差别:薄指针 vs 厚文档
绝大多数技能是厚文档:把指令、规则、格式、分支统统内联在自己的 SKILL.md 里,读者(其实是模型)打开一个文件就拿到全部。grill-me 是反面样本——薄指针(thin pointer)。它不装指令,只装一个地址。
地址指向 skills/productivity/grilling/SKILL.md,30 行,装着访谈的全部机制。而 grilling 并不是给 grill-me 一家用的。ask-matt 里写得很清楚:/triage、/wayfinder、/improve-codebase-architecture 内部都跑它,grill-with-docs 也调它。也就是说,这套访谈规则全仓库只有一份。
这个形态不是一开始就有的,是改出来的。看 git 历史最直观:221ffca(2026-05-31)那次提交新建了 grilling,同时把 grill-with-docs 的正文从 88 行砍到两句,把 grill-me 的正文换成一句 Run the /grilling skill.。之后还有三次措辞收敛:cbf6db4 改成 Run a /grilling session.,d28dfdc 改成 Call the Skill tool for "grilling",fcf0071 定稿为现在的 Call the Skill tool with "grilling"。
七行是收敛后的稳态,不是省事的结果。四次提交都在同一个方向上抠字。
它有意识摒弃了什么
一、摒弃了触发词。 早期的 description 塞满了触发条件,62f43a1 那一版是 “Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill me"”。现在只剩一句人话:A relentless interview to sharpen a plan or design. 这不是偷懒,是配套改写。.agents/invocation.md 把规则写死了:user-invoked 技能的 description 是给人看的,“a one-line summary read by a person browsing slash-commands. Strip trigger lists.” 触发词的全部作用是抢自动调用;既然已经 disable-model-invocation: true,这句抢词就变成了纯开销,删掉。
二、摒弃了规则正文的复制。 谁都不许把 grilling 的机制抄成第二份。仓库要求跨技能调用显式写成「call the Skill tool with X」,而不是跨目录链到 ../grilling/SKILL.md、也不是在散文里丢一个 /name 让模型自己领会。为什么这么较真?.agents/invocation.md 给了理由:多数 harness 把技能调用暴露成一个工具,“naming the tool is what gets it fired”。单一来源(single source of truth)换来的收益是:改一处,grill-me、grill-with-docs、triage、wayfinder 一起生效。
三、摒弃了状态。 它是这批技能里少见的无状态技能:不写文件、不建工作区。文档解释了这个取舍——正因为它无状态,它才可携带:不需要 repo、不需要任何配置、也不假设话题和软件有关,“people use it for business decisions, for writing, and for what to do next”。
四、摒弃了「问题数量上限」这类护栏。 一般技能怕跑飞,会写「最多问 5 个问题」。这里没有上限,只有一个终止条件:frontier 空了。文档甚至给了预期量级,“forty-six questions across four rounds is an ordinary session”。把护栏换成完成判据,规则更短,行为反而更准。
五、摒弃了「一次只问一个」。 有意思的是它一度就是一次一问——历史提交 a6bdfd9 正是 “Add instruction to ask questions one at a time”。后来这个约束被「一轮问完整个 frontier」取代,因为一轮一问在几十个问题上慢得没有意义。如果你确实偏好旧行为,文档给的答案不是让技能二选一,而是教你自己往全局 CLAUDE.md 里加一行。
六、摒弃了把查证推给用户。 grilling 正文的分工非常干净:事实是 agent 的活——需要环境里的某个事实时 “dispatch a sub-agent to find it”;决定才是你的——“the decisions are the user’s: put each to them and wait.” 一般技能常常反过来,把「你去看看配置文件里写的是什么」这种活派给用户,等于把本该自动化的部分退回去。
原文证据
skills/productivity/grilling/SKILL.md(快照 5beb35b)开头:
Interview the user relentlessly until you reach a shared understanding. Map this as a design tree: every decision branches into the decisions that hang off it.
同一文件的结尾:
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.
而 skills/productivity/grill-me/SKILL.md 的全文,就是上文那七行。两处并排看,就是「薄指针 + 厚原语」的分工图:七行负责把控制权交出去,30 行负责真正干活。
可迁移结论
- 把公共原语抽出来,让指针留薄。 一段访谈逻辑被五个技能共用时,它就该是独立技能;调用方只留一行地址。改一处生效多处,这是七行真正的价值,而不是「写得少」。
- 指针要写「调哪个工具、叫什么名字」,别写散文。
Call the Skill tool with "grilling"比「跑一次 grilling」更容易命中,因为技能调用在多数 harness 里是一个工具名。 - 调用方式和描述配套改。 禁掉自动调用,就顺手剥掉 description 里的触发词;留着它只是在每次加载时白付一份 token。
- 用完成判据替代数量上限。 「frontier 空」比「最多 5 问」短,且能覆盖真正长的会话。
- 薄不等于空。 七行能成立的前提有三个:它指向的材料真的存在、那确实是单一来源、调用语法写对了。三者缺一,薄就退化成坏。
读 grill-me 最容易得出的结论是「这也算技能?」。但把它和 grilling 并排看,会发现这七行承载的是一次归档决策:把可复用的部分抬出去,把入口留下来。技能可以薄,责任不能少。
讨论
用 GitHub 账号留言;评论保存在公开仓库chengshu-blog-discussions的 Discussions 里。也可通过 RSS 订阅后续文章。