mcpField
G
grillkit

grillkit

github.com/mimukit生产力2281 次安装4 天前更新
代码仓库

关于 grillkit

grillkit 是用于梳理想法、设计或计划的访谈技能,通过设计树逐轮提出尚未解决的决策,并为每项建议选项。它在决定达成或标记为暂缓后交接结果,不开始实现。

主要功能

  1. 01将主题整理为设计决策树
  2. 02按依赖关系逐轮提问
  3. 03为每项问题推荐选项并说明理由
  4. 04区分需用户判断的决策与默认项
  5. 05记录已定、待定及暂缓事项

适用场景

  1. 01把粗略产品构想整理为明确决策
  2. 02在实现前审视架构或计划中的未决事项
  3. 03为 PR 或设计方案梳理范围与失败路径

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mimukit/skills --skill grillkit

安装后在 Claude Code 中输入/grillkit确认已加载。

详细介绍

grillkit

不断追问用户的想法,直到你们真正达成共识。主题可以是任何内容:一个粗略的概念、用户脑海中的设计、现有的计划文件、架构或 PR。你不需要正式计划也能展开深挖。将其梳理成一棵设计树,让每个决策都分支出与之相关的决策。不要开始构建;重点是先找出所有尚未解决的决策。

如何深挖

  • 先复述想法。 在提出第一个问题之前,用自己的话重述主题:你理解的目标,以及接下来要深挖的内容。这样能及早发现误解,确保你和用户围绕同一个想法展开,而不是在接下来的十个问题中悄然各说各话。
  • 分轮梳理决策树。 当前待决项是指前置条件都已确定的所有决策,也就是你现在无需猜测尚未得到的答案就能提出的问题。每轮一次性列出所有当前待决项,并编号,然后等待用户回答,再进入下一轮。答案取决于本轮另一个尚未确定的问题的问题,属于后续轮次,而不属于本轮。提问轮次是具体格式。
  • 每轮都会重塑决策树。 答案会确定一些决策,推动当前待决项向外扩展,并解锁依赖这些决策的问题。重新计算当前待决项,然后提出下一轮问题。
  • 始终给出建议答案。 对每个问题,都说明你会选哪个选项以及原因。只提出问题会把思考负担推给用户;给出建议则能让用户明确接受、拒绝或调整。
  • 需要用户判断的才提问,其余设为默认。 大多数建议会照单接受,因此每轮只询问需要用户判断的决策,并将其他决策全部列为默认项,供用户按编号修改。提问还是设为默认是具体分类方式。
  • 深入探查薄弱之处。 对未明说的假设、一笔带过的边界情况、错误与故障路径、范围边界,以及任何描述含糊的内容,要重点追问。如果回答不够充分,就在下一轮继续追问,而不是让它就此搁置。每个决策只追问一次;第二次回答仍不充分,就将其记录为暂缓决定,并将其移出当前待决项。
  • 只询问尚未解决的问题。 每轮只包含尚未解决的决策。已确定的决策只有在后续回答与之矛盾时才会重新进入当前待决项,并在该轮中指出是哪项回答重新打开了它。

提问轮次

深挖的效果取决于用户能否迅速作答。选项埋在句子中间的密集段落会让问题难以回答,因为读者必须先解析文字才能找到需要作出的决策。以下每条规则都是为了让用户能一眼看清每轮内容。

询问还是默认

在写出本轮内容前,先对每项待定决策进行分类。分类决定它在本轮中的位置,而不是决定是否给出建议:两类决策都要附带建议。

询问符合以下任一条件的决策:

  • 领域或产品。 产品的功能和目标用户、业务规则、定价、领域术语的名称或含义、范围内或范围外的内容。
  • 品味。 视觉设计、文案、语气、用户可见的命名。
  • 难以撤销。 数据模型、公共 API 或 CLI 界面、迁移、外部契约、成本承诺、安全或隐私方面的权衡。
  • 建议不够有把握。 两个选项相差无几、证据不足,或你的选择与用户所说的内容相矛盾。
  • 对外操作。 任何超出计划自身分支范围的操作权限。何时停止 中的构建停止轮次始终会询问这些事项。

默认处理其他所有事项:有能力的实现者通常会毫无争议地选定的实现细节、以后能通过提交轻松撤销的选择,以及仓库惯例已有明确规定的选择。分类不明确时,就询问。

用户回复本轮且未推翻某项默认选择后,该选择即告确定。用户的回答覆盖原决定后,该决定也随之确定,并遵循与已询问决定相同的后续跟进和延期规则。除非之后的回答与之矛盾,否则默认决定不会在后续轮次中再次出现。

分类由 Agent 决定,因此用户必须能够看到分类结果。每项默认决定都要出现在本轮表格中,并附上一句理由;交接 中的回顾会标明每项已确定的决策是通过询问还是默认确定的。

当每项待定决策都列入默认决定表,或已写成待询问的问题时,本次分类即告完成。

一轮的结构
### Round 2: 5 open decisions, 2 asked, 2 defaulted
Blocked behind this round: storage format, migration path.

**Defaults.** Taken unless you change one by number.

| # | Decision | Default | Why |
|---|---|---|---|
| Q4 | Page file names | (a) kebab-case from the page title | matches the repo's existing docs |
| Q5 | Link style between pages | (a) relative Markdown links | renders in GitHub and in every engine |

---

❓ **Q6. Where does the doc map live?**
Stakes: `update` needs a code-path → page lookup without reading every page, and `audit`'s recency prefilter needs to know which paths a page describes.

- **(a) Per-page colocated metadata.** Can't drift from the page, one grep pass, invisible in every renderer
- **(b) YAML frontmatter.** GitHub renders it as a visible table, and it may collide with an engine's own schema
- **(c) Central manifest.** One more file to keep in sync
- **(d) Re-derive each run.** No drift, but throws away the cheapness `audit` depends on

➡️ **(a)** as an HTML comment under the visible stamp: ``

---

❓ **Q7. Contributor docs: in or out?**
Stakes: dev-env setup and release steps are *derivable from the repo*; a CONTRIBUTING.md is a social contract that isn't in the repo at all.

- **(a) Split on that seam.** Mechanical half becomes how-tos, the social half stays out
- **(b) All in.** Pulls PR etiquette and CoC into scope, which can only be invented
- **(c) All out.** Loses two how-tos that verify cleanly

➡️ **(a)** with `how-to/set-up-a-dev-environment.md` and `how-to/cut-a-release.md` joining the doc set; root `CONTRIBUTING.md` is never written, only linked.

---

⏳ **Q8. Which renderer serves these pages?** Waiting on a sub-agent checking the repo for a docs generator. It gates the frontmatter decision, so it lands next round.

Reply `6a 7b`, change a default with its number (`5b`), or say "go with your picks" to take everything.
形成这些规则的原因
  • 选项必须是列表,不能写成散文。 每行一个选项,始终如此,即使只有两个选项也一样。在一句话里写成 Options: (a) …, (b) …, (c) …,是问题清单中最影响可读性的做法。强行把二选一也写成列表,还能揭示原本会被埋进第四句话里的接缝。
  • 每个选项都要说明自己的取舍。 把拒绝 (b) 的理由写在 (b) 那一行。推荐意见如果要反驳三个选项,而读者上次看到它们时已经是 200 个字符之前,就会让他们在问题清单里来回找。
  • 先讲利害,最多两句话。 标注为 Stakes:,说明为什么这个决定至关重要,也就是后续哪些事情会因此出问题或仍悬而未决。其他所有内容都放在选项行里。
  • 推荐意见单独一行。 ➡️ **(a)** <the concrete form it takes>。指出选项字母,然后只补充列表中无法涵盖的内容:你会写下的确切语法、路径或形式。绝不要重述选项本身的描述。
  • 问题之间用分隔线隔开。 --- 在每个终端里都会显示为水平线,并阻止问题彼此混在一起。
  • 跨轮次连续编号。 第一轮 Q1–Q3,第二轮从 Q4 开始。每轮都从 Q1 重新编号,会让任何人一旦回指就无法确定“Q2”指什么,包括你在 Hand off 中的回顾。
  • 代码跨度仅用于字面内容。 路径、文件名、标志、命令、标识符。概念性强调使用 斜体。把普通散文词语放进代码跨度,会让整轮内容变得五颜六色,掩盖真正的引用。
  • 明确显示待处理事项,不要藏起来。 如果子 Agent 仍在获取某个问题所依赖的信息,就用 ⏳ 列出该问题,并注明正在等待什么。一个没有提问的可见分支会让人觉得被遗忘;加一行说明它是受阻,而不是被搁置。
  • 默认项放在最前面,汇总成一张表。 每个默认项占一行:编号、决定、带字母的选项,以及简短到能放进一个单元格的理由。默认项不需要利害说明或选项列表;想覆盖默认项的用户可以询问选项。没有默认项的轮次就省略该表。
  • 给每轮加标题并在结尾收束。 标题说明进度,即当前有多少个未决决定、已提问多少个、已设为默认多少个,以及这些决定会解锁什么;否则这些信息无从得知,会让冗长的问题清单显得没完没了。结尾一行说明回复格式,避免用户每轮都要自行设计。
如果有选项选择器,就提供给用户

如果有 AskUserQuestion 可用,就以混合方式进行这一轮:先打印完整的文字版问题,列出利弊、证据和建议,然后仅针对选项调用工具。用户只需点击,不必重新输入字母,同时仍能读到推理过程。

  • 选择器只包含要问的问题。 默认值保留在表格中,用户只需在回复中输入一个数字即可覆盖默认值。
  • 选择器必须与文字版问题完全一致。 问题顺序相同,每个问题中的选项顺序也相同。这个控件是用户刚读过的这一轮问题的第二种呈现方式,而不是重新展示一遍。改动任何一处的顺序,字母就失去意义:用户读完支持 (c) 的理由,点击第三个选项,结果却变成了别的选项。
  • 如果选项本身没有顺序,就把推荐选项写成 (a)。 用户大多数时候都会采纳建议,因此把它放在首位,就能让用户无需按方向键,只需点击一次;而且由于选择器与文字版问题一致,只需在顶部排好一次,两种呈现方式中就都正确了。如果选项本身有顺序(例如一条光谱、逐步扩大的范围或时间顺序),则保留原有的优劣顺序,因为为了省一个按键而打乱顺序,给读者带来的损失比节省的更多。
  • 撰写选项时就确定顺序,绝不要在两种呈现方式之间调整顺序。 在选择器中重新排序会破坏字母对应关系,而且没有必要:无论推荐选项位于何处,(Recommended) 都会标明它。
  • 每个标签都加上字母前缀,例如 (a) Per-page metadata、(b) YAML frontmatter。这样对应关系就明确了,而不是仅靠位置判断;即使控件在侧边自行标上序号,(b) 也仍然表示 (b)。
  • 无论推荐选项排在什么位置,都在其标签末尾标注 (Recommended),让选择器与 ➡️ 行保持一致。
  • 标签要简短;理由应放在文字版问题中,而不是选项说明里。
  • 工具每次调用最多支持 4 个问题、每个问题最多 4 个选项,并且总会追加一个供用户自行作答的“Other”选项。如果需要呈现更多选项,就按这一轮问题的顺序分批调用,或仅使用文字版问题;绝不要为了适应控件而删减选项。包含第五个选项的问题无法完整呈现:要么在两种呈现方式中都合并两个选项,要么只在文字版问题中提出该问题,不要向选择器展示截断后的选项列表。

事实由你查明,决策由用户做出

查明事实绝不是用户的工作。如果某件事能通过查看代码库、文档或配置得知,就由你自行查明,而不是询问用户;问题应留给真正的决策,也就是需要由用户做出的判断。

如果某个问题需要先从环境(文件系统、工具、配置)中查明事实,而且你有子 Agent 工具,就派遣子 Agent 去查,不要因此停下其他工作。 正在进行的探索只是尚未确定的前置事项,因此只有依赖它的下游问题需要等待子 Agent 的报告;现在就询问本轮中的其他问题,并用 ⏳ 标记受阻的问题,让用户知道它还在等待结果,而不是被遗漏。如果没有子 Agent 工具,就在向用户提出依赖该事实的问题之前,先自行查明。

何时停止

在前沿被视为空之前,如果主题是需要构建的内容,就先进行构建停止轮次。以下问题是构建过程原本会因此停下来的问题;如果此时没人回答,代价最高:

  • 对外操作。 计划要求执行的每项超出自身分支的操作所需的许可,例如提交后续问题、推送或部署。
  • 测试基础设施。 对于每个需要运行仓库尚不支持的某类测试的阶段,确定运行器和方法。
  • 需要人工参与的阶段。 每个需要有人参与的阶段,例如选择设计方案或批准模型图。在可以讨论时现在就定下来。否则,确认该阶段仍需人工参与,并且会先于可无人值守运行的阶段。

跳过计划中已有答案的问题。

当前沿为空时,讨论就结束:设计树中的每项决策都已敲定,或已推迟并明确标记为推迟。用户也可以在任意一轮停止讨论;仍未解决的决策将被推迟。然后交接,在用户明确表示继续之前,不要开始实施。

如何处理结果

grillkit 的职责是达成共识,而不是生成特定文件;但这些共识最终写入何处,取决于会话的开始方式:

  • 从计划文件开始。 如果输入是现有计划文档(例如 NNNN-plan-<slug>-YYYY-MM-DD.md,或不带序号的旧版文件),默认将已确定的决策合并回同一个文件,无需询问。用户交给你一份计划让你完善;按预期结果,应将完善后的计划交还给用户。直接重写原文件,不要另建副本,也不要更改其名称、序号或创建日期后缀;并告知用户你已更新文件。只有用户明确要求其他处理方式(单独的说明、不写文件、写入其他位置)时,才跳过或改为其他写入操作。为完善后的计划添加标记:在标题正下方添加一行 Grilled: YYYY-MM-DD(使用今天的日期;重新 grill 时更新日期)。这个标记是持久的机器可读信号,表示该计划已通过 grill;下游工具会将其作为来源依据:例如,issuekit 只有在来源带有此标记时,才会将计划中的问题标为 ready(可安全地无人值守处理);否则会将未经 grill 的计划标为 needs-planning。这是来源信息,而不是跟踪工具产物,因此即使项目完全不创建问题,也应以同样方式写入标记。此标记仅适用于经过 grill 的计划,不适用于之后的编辑。 实质性编辑会使标记失效:包括新增、删除或更改已确定的设计决策;新增、删除阶段或调整阶段范围;更改某个阶段的 Done when: 可观察结果;或更改非目标或迁移部分。进行此类编辑的人应删除该行,重新 grill 后再添加。措辞修正、阶段标题注释(例如 (#41) 或 (built YYYY-MM-DD))以及新增未决问题,都不影响标记。也要在计划中记录构建停止时的答案:将每项获批的对外操作和每个测试运行器分别作为一行写入已确定的设计决策;对于每个仍需有人值守的阶段,在其标题下方添加一行 Attended:,说明该阶段在等待什么。无人值守的运行器会读取这些信息,因此仅在本次对话中给出的批准不会传递给它。如果无法访问文件系统,请在总结中打印标记行,供用户自行添加。
  • 从其他内容开始。 如果输入是粗略想法、某人脑中的设计、架构或 PR,就没有可供更新并交还的文件,因此应询问这些决策应写到哪里:就地更新某个现有文件、在当前目录中撰写单独的说明,或完全不写文件。不要未经提示就写入文件,也不要擅自假设保存位置;grillkit 不负责制定规范的计划文档格式,也不负责推行 docs/plans 约定。

如果 grill 确定了值得记录的领域术语,或难以逆转的权衡决策,且已安装 domainkit,则由它负责记录;否则,告知用户将已确定的决策记录为词汇表条目或 ADR。grillkit 负责询问和厘清,不负责规定记录格式。

发布结果

用户几乎每次完成 grill 后,都会要求做同样几件事:提交计划、推送、更新 issue 正文、更改标签。将它们作为一个操作,一次确认即可。如果 grill 没有写入任何文件,也没有处理任何 issue,或者没有 Git 仓库,则跳过本节。

生成一份预览。 列出适用的每项操作,省略无关条目:

  • 提交。 路径:你重写的计划文件,以及 grill 期间写入的任何词汇表或决策记录。Conventional Commits 格式的提交说明,例如 docs(plan): grill the <slug> plan。
  • 推送。 当前分支及其 origin 目标,作为普通快进推送。
  • Issue 正文。 grill 完善的 issue,可以是启动 grill 时使用的 issue,也可以是计划中提到的 issue。说明变更内容:已确定的决策、计划链接,以及 grill 已解决的待解决问题。
  • 标签。 仅当计划带有 Grilled: 标记且没有延后任何决策时,才将 needs-planning → ready。如果有延后的决策,则保留标签,并在预览中说明原因。issuekit 负责晋升规则;如果 issue 指明了尚未解决的依赖项,标签可变为 blocked。没有 issuekit 时,只有在 issue 未提及任何尚未解决的依赖项时,才将标签改为 ready。

只询问一次。 提供三个选项:全部发布、仅提交或跳过。使用 AskUserQuestion。

按以下顺序执行获准的操作: 提交、推送、issue 正文、标签。

  • 使用 commitkit 提交并推送,并传入准确的路径。没有 commitkit 时,运行 git add -- <paths> && git commit -m "<subject>" && git push。
  • 使用 issuekit 编辑 issue 正文。没有 issuekit 时,运行 gh issue edit <n> --body-file <file>。
  • 使用 issuekit 的 triage,通过定向请求晋升标签(#<n> is grilled, mark it ready)。没有 issuekit 时,运行 gh issue edit <n> --remove-label needs-planning --add-label ready。

标签操作放在最后,因为 ready 会触发无人值守的工作,而这类工作需要远程仓库中已有计划。

首次失败时立即停止。 推送被拒绝(分支受保护、非快进或权限不足)时,停止执行:报告错误,保持 issue 正文和标签不变,并说明直接的解决方法。绝不强制推送,也绝不创建用户未要求的拉取请求。

所有获准的操作均已执行,或已报告首次失败且之后的操作均未执行时,本步骤即告完成。

移交

本节使用流程化的语气:每句话只给出一条指令,使用主动语态和现在时,不用隐喻。

每次 Grill 都用同样的方式收尾;只有在安装了同级技能时才点名,否则就直接说明要做的事:

变更内容。 简要回顾共同敲定的决定,每项单独一行。列出你提出但尚未解决的问题;用户推迟做出的决定不算决定,后续会再次出现,并阻塞构建。将每项决定标为已询问或默认采用。指出仍需关注的每个阶段,以及用户批准的每项外部操作。

结果位置。 说明你原地重写的计划文件及其 Grilled: 标记,或说明用户要求改写的其他文件;如果用户拒绝创建文件,则说明没有文件。完成发布结果后,给出提交 SHA、已推送的分支、问题 URL 和标签,或说明用户跳过了其中哪些步骤,或哪些步骤失败。

下一步。 标记是完成一次 Grill 的关键,因此要说明它能解锁什么。如果发布步骤将现有问题移至 ready,该问题就可以开始构建:对它运行 afkkit(run issue #<n> unattended);否则使用 issuekit start <n> 启动;再否则创建分支并手动构建。如果项目通过 GitHub Issues 跟踪工作,且尚无问题,那么经过完善的计划就可以转化为问题,issuekit 会读取标记,将这些问题设为 ready(可安全地无人值守处理),而不是 needs-planning。如果项目在其他地方或根本不跟踪工作,同一个标记就表示计划已获准构建,因此要指出 implementkit 及其第一个阶段。不要默认适用第一种情况:项目即使使用 GitHub,也可能在 Linear、Jira 或文件中管理待办事项;提示词或仓库的 Agent 指南文件会说明实际情况。如果没有计划文件,就说明这些决定将用于什么:直接用于构建(implementkit),或用于决策记录(domainkit)。不要启动其中任何一个;Grill 到达成共识为止。

评论

支持 Markdown