Skills For Real Engineers 系列之二:grill,把需求想清楚,也别把自己问进死胡同

0 阅读15分钟

书接上回。

上一篇,我们用 RxStudy 介绍了 setup-matt-pocock-skills 和 ask-matt:先配置项目的协作约定,再找到适合当前问题的技能入口。回看第一篇。

选好了入口,接下来总可以开始写代码了吧?

先等一下。我想改进日志输出,听起来是个明确需求;但如果继续问:旧实现保不保留?新旧日志怎么切换?导出失败怎么反馈?做到什么程度算完成?

咳咳,代码还没开始写,问题先来了一串。

这就是今天要聊的 grill-me 与 grill-with-docs。我理解 grill 的本质,是把自己的点子、模糊的思路和 AI 讨论清楚,让需求逐渐明朗。

不过,想清楚有时真的很痛苦。这篇除了介绍用法,也聊聊被问到卡住时,该怎么继续。

1. grill 到底在做什么?

“帮我优化一下日志。”

我们平时很容易这样提需求。助手可以马上列方案,甚至直接改代码。但“优化”可能意味着打印更容易读、能在文件里查问题,也可能是支持导出,或者降低 Release 的输出量。

它们涉及不同目标,也可能互相牵制。如果目标没对齐,代码写得越快,返工也可能来得越快。

grill 会沿着这些模糊的地方继续追问,把隐藏的假设拿出来讨论。比如我说“保留旧实现”,究竟是保留几个类,还是原来的初始化顺序、日志目录与导出行为都要保留?

问到这里,我们才开始对同一个需求有相近的理解。

还可以做一个小检查:把“更好”“方便”“优雅”这些形容词暂时拿掉,需求还能不能说清楚?“导出更方便”很模糊,“导出结束后返回文件地址,失败时返回调用方可识别的错误”就更容易讨论和验证。我们仍然可以调整方案,但至少知道双方在讨论什么行为。

我喜欢把它理解成一次认真做事前的设计讨论。AI 负责检查已有事实、提出问题和建议,我负责表达目标、判断取舍。讨论形成的共识,最终要能落到行为与验收条件上。

2. Talk is cheap, grill me!

第一次看这两个技能的文件,可能会愣一下:就这么几行?

下面是对应版本两个 SKILL.md 的完整内容。

2.1 grill-me:一个很薄的入口

---
name: grill-me
description: A relentless interview to sharpen a plan or design.
disable-model-invocation: true
---

Call the Skill tool with "grilling".

前面的 YAML 是技能元数据:名字、用途,以及禁止模型自动调用的标记。这与它作为显式讨论入口的用途相符;具体调用方式取决于编程助手。

正文只有一句:调用 grilling。查看源文件

2.2 grill-with-docs:再组合一个能力

---
name: grill-with-docs
description: A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.
disable-model-invocation: true
---

Call the Skill tool twice, for "grilling" and "domain-modeling".

它组合了 grilling 与 domain-modeling:前者推动讨论,后者负责领域语言和重要决策的记录。查看源文件

用程序员熟悉的写法表示,大概就是:

grill-me        → grilling
grill-with-docs → grilling + domain-modeling

01-skill-composition.png

图 1:短入口复用底层能力,记录职责由领域建模承担。

这里的“少即多、大道至简”,我理解是职责集中、能力可以组合。短的是入口,真正的方法在依赖技能里。

就像一个函数调用另一个已经实现好的函数,调用处只有一行,不代表它完成的工作只有一行。我们也不能据此认为,把提示词删得越短,效果就越好。

2.3 顺藤摸瓜,看看 grilling 的方法

底层 grilling 把讨论组织为一棵设计树:一个决定会影响后续问题,先决定前面的事情,再讨论依赖它的选择。

当前前置条件已经明确、可以回答的那批问题,它叫作 frontier。每轮问这一批,给推荐答案,等用户回应后再调整下一轮。

比如“是否保留旧日志体系”还没决定,就不应该急着问“旧模式的导出接口如何兼容”。后一个问题需要前一个答案,提前问只会让人猜。

另外两条也很关键:事实由助手查,决定交给用户;讨论达到共同理解后,要经用户确认再行动。源码中的几个关键词值得记住:

design tree
frontier
Finding facts is your job
The decisions are the user's

原文还要求,涉及环境事实时用子代理探索,只有依赖该事实的问题等待,其余可回答的问题继续讨论。实际执行要服从所用工具的能力和项目约束;核心分工是,不能把助手本可查清的信息变成用户的问卷。

这套方法有约束,但它仍由模型执行。有没有查证,推荐是否合理,以及问题是否越界,我们仍要检查。

02-question-rounds.png

图 2:先确定前提,再讨论依赖它的问题;这里是方法示意。

2.4 with-docs 会写下什么?

domain-modeling 会挑战模糊或混用的术语,结合具体场景与代码确认含义,并在术语明确时更新 GLOSSARY.md。

ADR 则更克制:决策难以逆转、未来读者缺少背景会觉得意外,而且存在真实取舍时,才提出记录。文件按需创建。领域建模说明

所以,with-docs 不是把每轮聊天存档,也不是每个选项都生成一份 ADR。术语表解释词义,规格描述交付要求,ADR 保存重要取舍的原因,各有用途。

3. 两个入口怎么选?

当前处境入口
没有项目工作目录,讨论一个想法、计划或设计grill-me
在仓库中持续讨论,希望沉淀术语与决策grill-with-docs

这是该版本 ask-matt 给出的使用方向。两者共享追问方法,区别在于是否组合领域建模。流程导航

回到 RxStudy。项目已有新旧日志体系说明:默认 .legacy,编译前可以选择 .modern,每次启动只启用一套,新体系提供独立导出接口。

如果回到设计阶段,可以这样发起讨论:

/grill-with-docs

我想把 RxStudy 的日志改一改,平时看起来方便一点,也能导出。
不过旧的那套我还想留着,新方案有问题时能切回去。
你先看看代码,咱们聊聊怎么做,先别急着改。
聊清楚的东西,按项目里的约定记下来。

上面是日志改造的调用示例。要看真实讨论是什么样,还可以翻翻我在 RxStudy 中的一次 grill-me 对话。

2026 年 10 月 14 日,我对项目的分支管理和工程结构不太满意,于是讨论 CocoaPods、Tuist 和两个 App Target 应该怎么继续维护。

下面是原始对话节选,省略其他问题与分析。保留当时的问题编号,按发生顺序展示;这不是当前项目最终方案。

第一轮,AI 给了一个我不接受的建议:

❓ Q2 — 旧历史的归宿:你是否接受把 CocoaPods 版本作为历史参考保留,让现有 Tuist/SwiftUI 成果逐步成为后续开发主线,避免再尝试把两条无共同祖先的历史整体合并?

➡️ 我的建议:是。 已完成的迁移值得保留,不必为了纠正起点重做。后续用明确的版本标记保存旧实现,新工作集中在一个持续维护的主线上;具体如何调整分支,等定位确定后再决定。

我回答了这一轮的问题,其中 Q2 的原话是:

Q2:其实没有所谓的历史归属,我希望CocoaPods+RxSwift继续作为一个开发分支保留下去,同时Tuist+RxSwift/SwiftUI继续作为另外一个分支演进下去,只是通过不同分支,切换不同的第三方库依赖方式

下一轮,AI 收回了这个建议:

明白,Q2 的定位已明确:两条长期开发线,分别使用 CocoaPods 和 Tuist;Tuist 分支同时保留 UIKit/RxSwift 与 SwiftUI 两个 Target。 我收回“将旧版仅作为历史参考”的建议。

随后,它继续追问功能是否需要同步:

❓ Q4 — 两条开发线是否保持功能一致:对于 UIKit/RxSwift 部分,你是否希望两条分支的功能和业务修复基本同步,只允许依赖集成方式存在差别?

➡️ 我的建议:是。 这样两条分支的用途清晰:同一套 UIKit 实现,提供两种构建方式;SwiftUI 则在 Tuist 分支独立发展。否则时间久了,“切换依赖方式”会变成“切换不同版本的 App”。

03-correct-the-recommendation.png

图 3:原始对话的过程概括,不代表当时原话或当前最终方案。

这次讨论里,我没有照着推荐选“是”,而是直接把自己的想法说出来:我希望两条开发线都继续维护,只是切换依赖管理方式。这个前提一改,后面该问的问题也跟着变了。

这才是我觉得 grill 有用的地方。它可以给建议,我也可以不同意;我们把分歧聊出来,再继续往下走。原始对话展示的是追问方法,前面的日志示例则展示了如何用 grill-with-docs 发起带文档记录的讨论。

4. 坦白说,grill 有时真的很痛苦

按照我的使用体验,grill 的问题会非常多。有些看一眼就能答,有些会让人停下来:我之前根本没想过这个问题。

早先遇到不给推荐答案的提问方式时,这种感受更明显。原本想借助 AI 推进,结果先收到一堆需要自己做功课的选择题。

这里说的是个人体验,不据此给技能划一条版本时间线。本文核对的 grilling 已明确要求每个问题给出推荐。

有推荐后,确实多了一个讨论起点。但它的建议有时又不符合预期。看着解释好像都有道理,自己仍觉得哪里不对,来回讨论几轮,就可能陷进思考泥潭。

我觉得至少要区分三种情况。

4.1 这确实是一个需要我决定的问题

比如要不要保留旧实现,可能影响改造范围和验证成本,也影响回退方式。这种取舍原本就存在,只是以前没显式拿出来。

需要想一想很正常。可以让助手列出两三个具体使用场景和代价,帮助判断,不必急着接受第一个推荐。

4.2 它把自己的功课交给了我

虽然这种情况现在很少出现,因为它在看代码的时候,一般顺手都可以帮你把的Bug给修复。

但是,但是,但是!如果模型很“蠢”的时候还是会出现的。

“现在日志用哪个库?”“代码里有没有导出接口?”

如果仓库就在面前,这些应先查代码。尚未决定是否运行时切换,就追问设置页面放哪里,也属于过早展开。

可以直接纠正:

这些代码里不是能看出来吗?你先帮我看看。
前面那个问题我还没决定,后面这些先别展开,
我们先把眼前这件事聊清楚。

4.3 推荐成立的前提,与我想的不一样

如果它提出的问题,它自己推荐的回答达不到预期,你要做的事情,就是把自己的想法说出来,而不是顺着它的推荐走。

程序员怼天怼地怼空气,眼前的一个AI,那必须马上开怼啊。

及早的纠正需求错误,比开始Coding再悬崖勒马要容易的多,更何况对面是AI,不是产品。

甚至如果你觉得本轮讨论不好,新开一轮对话,重来!

5. 想不清楚时,不一定要继续硬想

有些问题需要判断,有些需要补信息,还有些看一眼能操作的东西,比讨论半天更清楚。

卡住的原因下一步
不知道现有实现或工具能力查代码、文档,做针对性研究
缺少产品、用户或团队信息收集反馈,明确谁有权决定
状态变化、交互效果难以想象用 prototype 验证一个问题
讨论范围太大缩小本轮目标,记录待定事项与验证条件

04-get-unstuck.png

图 4:补齐当前缺口,再带着结论回到讨论。

所以我赞同用 prototype 解开部分死结,但先得把问题缩小。

“帮我做个日志系统原型”仍然太大。我们可以只问:导出中再次点击、没有日志、导出失败时,状态与反馈如何变化?

5.1 用一个能操作的小东西回答问题

prototype 将原型定义为回答问题的一次性代码。当前版本有两条分支:逻辑/状态问题采用可分享的单 HTML 演示,视觉问题生成可切换的 UI 变体。先选对要回答的问题,再选形式。技能说明

日志导出这个例子更接近状态问题,可以这样委托:

/prototype

光这么聊,我还是有点想象不出来。
你做个能直接打开的 HTML,让我点点看吧,不用接真的日志。
比如导出成功了、失败了,或者根本没日志,各是什么样?
导出还没结束时,我再点一次,是没反应好,还是提示一下好?
这两种都让我试试,旁边也显示一下现在到了哪一步。
用假数据就行,不连后端,也别读真实日志或保存数据。
试完咱们再看看哪些想清楚了,哪些还得去真机上验证。

上面的界面行为是拟验证的设计,不代表 RxStudy 已经提供导出页面。现有文档明确,新体系提供导出接口,不新增导出页面。

原型应轻量、容易启动,默认不持久化,相关状态要看得见,不为它增加与问题无关的封装和打磨。这里展示的是提示词,本篇没有实际创建或运行原型。

5.2 原型也有回答不了的事情

点击模拟按钮,可以帮助比较状态与提示;它不能证明真实文件已刷盘,也不能证明系统日志在所有设备上都可见。

这些问题需要真实库、文件与设备上的针对性实验。缺少实验条件时就记录待验证,不要让模型用更长的解释代替证据。

讨论回到主线时,我会要求整理三类内容:哪些结论已被证据支持,哪些假设暂时采用,还有哪些问题仍未验证。原型顺畅,只能支持它实际覆盖的判断。

按该版本规则,原型和结论还应作为可追溯来源保留:原型保存在主分支之外的临时分支,在实现任务中留下指针;主分支承接验证后的决定。一次性强调实现成本,不意味着验证后立刻删掉所有依据。

如果需要切换目录或工具,可以用 handoff 携带问题、约束与结论,回到原讨论后再确认;无需交接时就继续当前会话。术语明确后写术语表,满足条件的决策再记录 ADR。

6. 什么时候可以停止追问?

技能将 frontier 为空、各分支讨论完毕作为完成条件。实际使用时,应先界定本轮设计范围,否则“所有问题”很容易越问越大。

我会检查:目标和边界是否明确,关键行为能否举例,验收条件能否验证,重要取舍能否解释;未决问题有没有负责人、验证方式或后续阶段。

未决问题如果影响核心可行性,仍应阻塞相关实现。可以暂缓的问题则记录下来,双方明确接受当前范围与假设,不能默默当作已经解决。

最后让助手复述共识,我确认后再进入行动。with-docs 过程中按约定写术语和决策,与修改业务代码是不同的授权范围。

复述时也要保留“不做什么”和“尚未验证什么”。这些边界最容易在后续会话里丢失,却往往决定实现会不会偏离原来的目标。

好了,grill 会让人思考,也可能让人头大。我更愿意把它用来推动一次有依据的讨论:能查的先查,需要取舍的认真讨论,需要看效果的做最小验证。

想清楚是目标,问题多本身并不是成绩。我们下期见。

参考资料