Matt Pocock 人类主动编排的工程开发流程Skills

Matt 用来约束一次软件开发的主链路,大致是:

Setup → Clarify → Shape → PRD → Issues → Triage → Build → Debug → Repair → Handoff

这条链路不是强制工作流。它更像一组可插拔的刹车:每个节点都拦住 Agent 的一种典型跳步。

只知道这条链路还不够。真正值得学的是每个 skill 怎么长出来:它来自哪类真实失败,把人类工程师的哪个隐性动作显式化,又把哪些状态写进仓库或 issue tracker。读这篇时,应该把每个节点都还原成四个问题:它拦什么失败,要求 Agent 先看什么,产生什么 artifact,在哪里停下来等人或验证结果。

AFKaway from keyboard,指人可以暂时离开,Agent 能按明确上下文独立推进。HITLhuman in the loop,指执行中必须有人参与判断、授权或验收。

Setup:先建立仓库约定

setup-matt-pocock-skills 不是自动 hook,而是新仓库第一次使用这套工程 skill 前的人类授权初始化。它要写清 issue tracker、triage label、domain docs 三件事。SKILL.md#L9-L16

这个节点解决的是状态归属问题。没有它,后续 skill 不知道 PRD 发到哪里、ready-for-agent 对应哪个真实 label、CONTEXT.md 和 ADR 应该读哪里。

它不是一次性生成高质量项目知识。CONTEXT.md 和 ADR 的高质量内容来自后续真实澄清、设计、调试和架构讨论。Setup 只把坑位建出来,让后续 skill 有地方写。

这个 skill 的来源很具体:Matt 发现工程类 skill 如果默认 GitHub、默认 label 名、默认 CONTEXT.md 路径,很快会在不同仓库里误写状态。于是 setup 不做业务判断,只建立翻译层:标准角色如何映射到本仓库的真实工具和文档位置。

还原这个 skill 时,正文不能写成"创建几个文件"。它应该写成探索协议:先读 remote、AGENTS.mdCLAUDE.mdCONTEXT.md、ADR、docs/agents/.scratch/;再把 issue tracker、label vocabulary、domain docs 三个决策逐个向用户确认;最后只更新已有入口文件,不能随便创建并行入口。这个写法的重点是防止 Agent 在不了解仓库约定时自作主张。

Clarify:先压实问题

Matt 把澄清拆成两层。

grill-me 适合没有仓库上下文的计划压测。它让 Agent 一次只问一个问题,沿着设计树追问,直到人和 Agent 对目标达成共享理解。

grill-with-docs 是工程版澄清。最新版里它已经极短:运行 /grilling,同时使用 /domain-modelingSKILL.md#L1-L7 这说明 Matt 把访谈循环和长期 domain model 维护拆开了:grilling 负责问,domain-modeling 负责把术语、边界和长期决策写进 CONTEXT.md 或 ADR。

domain-modeling 的关键不是"读文档",而是在设计时主动挑战术语、制造边界场景、检查代码是否支持用户说法,并在术语确定时立即更新 CONTEXT.mdSKILL.md#L42-L64

这个节点拦的是最常见失败:用户以为自己说清楚了,Agent 也以为自己懂了,最后做出来才发现双方理解不同。

这组 skill 的设计来源,是人类工程师在需求澄清中会做两件隐性动作:一边追问,一边把稳定术语和长期决策记下来。旧版把这两件事都放在 grill-with-docs 里;新版把访谈循环抽成 grilling,把长期语言维护抽成 domain-modeling。这个拆分很关键:问问题是对话动作,沉淀术语是状态写入动作。

如果要还原这类 skill,不要只写"多问用户几个问题"。正文要明确三条规则:问题一次只问一个,能从代码回答就先查代码,术语一旦被解析就立即写入 CONTEXT.md。还要写清 ADR 门槛:难逆转、没有上下文会意外、确实有取舍,三者都满足才写。这样 skill 才不会把澄清会话变成无限追问,也不会把所有聊天内容都塞进长期文档。

Shape:用原型回答方案形状

Clarify 解决"要不要做、要解决什么问题"。Prototype 解决另一种不确定:这个方案形状是否成立。

prototype 的定义很准确:原型是用来回答一个问题的 throwaway code,问题决定形状。SKILL.md#L7-L18

如果问题是"订单取消状态模型是否合理",原型应该是一个小 terminal app,让用户连续触发下单、支付、取消、发货、退款等操作,并在每步后打印完整状态。如果问题是"取消入口应该长什么样",原型应该是几个 UI variant,让用户切换比较。

这个 skill 的完成线不是"留下一个能跑的小项目"。它要求原型从第一天就被标记为可丢弃,只保留答案。答案应该进入 commit message、ADR、issue 或 prototype 旁边的 NOTES.md,代码本身最后要删除或吸收进正式实现。SKILL.md#L20-L31

prototype 的来源不是"开发前先做 demo"这条泛建议,而是 Agent 常把尚未验证的方案直接写进正式代码。人类工程师会先用草图、状态表、纸面流程或临时脚本试一下手感;Agent 没有这种默认习惯,所以 skill 必须把"实验"和"正式实现"硬切开。

这个 skill 的设计要点有三个。第一,先写问题,因为问题决定原型形状;第二,产物必须可运行和可观察,logic prototype 要把状态打印出来,UI prototype 要能切换多个差异明显的方案;第三,完成线是删除或吸收,而不是留下一个半成品。照这个思路写自己的 prototype skill,就不能只写"先建立原型",而要写清问题分支、运行方式、观察信号和退出规则。

PRD:把对话压成可执行需求

to-prd 不再采访用户。它只把当前对话和代码理解综合成 PRD,并发布到项目 issue tracker。SKILL.md#L7-L19

这里的 PRD 不是传统纯产品文档。它是面向 Agent 执行的需求 artifact:前半段讲问题、方案和用户故事,后半段记录实现决策和测试决策。

它可以写模块、接口、schema、API contract 和测试 seam,但不要写具体文件路径或代码片段。原因很直接:路径和代码会很快过期,PRD 应该保存稳定决策。SKILL.md#L43-L57

这个节点拦的是"边聊边写代码"。没有 PRD,Agent 会把对话里最近出现的细节当成最高优先级,忘掉前面已经定下的约束。

to-prd 的来源,是一次对话里信息权重会不断漂移。用户后面补的一句细节很容易压过前面已经确定的目标,Agent 也容易把"当前上下文还记得"误当成"已经有稳定执行物"。PRD 的价值不是正式感,而是把散落对话压成一个能被后续 Agent、issue 和测试共同引用的事实源。

这个 skill 的关键设计不是模板,而是边界。它明确"不再采访用户",因为采访应该发生在 clarify;它要求先 sketch 测试 seam,因为执行前必须知道行为从哪里验证;它禁止具体文件路径和代码片段,因为 PRD 要保存稳定决策,不保存易腐烂执行细节。要还原这类 skill,正文应该把"合成已知上下文"和"继续澄清"分开,并把 PRD 写成连接用户故事、实现决策和测试决策的中间 artifact。

Issues:把大需求切成可领取切片

to-issues 把 PRD、spec 或 plan 拆成可独立领取的 issue。它强调 tracer-bullet vertical slices:每个 issue 都是一条窄但完整的端到端路径,而不是只改 schema、只改 API、只改 UI 的横向任务。SKILL.md#L25-L35

订单取消的例子里,差的拆法是"加数据库状态字段""加取消接口""加前端按钮""补测试"。这种拆法每张 issue 都不独立,任何一个 Agent 做完都无法证明业务闭环成立。

更好的拆法是"未支付订单可取消并释放库存""已支付订单取消进入退款中""已发货订单不能取消"。每个 issue 都穿过必要层次,并有自己的验收标准。

to-issues 发布 issue 前要让用户确认粒度和依赖关系。它不是替用户做项目管理,而是防止 Agent 拿到过大的任务,或者拿到无法独立验证的横向任务。SKILL.md#L37-L57

to-issues 的来源,是大需求进入执行时会被错误拆层。人类工程师知道"先打穿一条路径"比"先把每层都铺开"更容易验证,但 Agent 很容易按文件层或技术层拆任务,最后每张 issue 都做完一点,却没有任何一张能独立证明用户路径成立。

所以这个 skill 的正文必须反复强调 vertical slice,而不是只要求"拆小"。它还要让用户确认粒度和依赖,因为"可独立领取"不是 Agent 自己能完全判断的。可还原写法是:先读上游 PRD 或 issue,再探索代码里的现有层次和可能的 prefactor,随后给出编号切片,每个切片都写清覆盖哪些 user story、依赖谁、完成后如何单独验收。最后还有一条很重要的边界:子 issue 不能关闭或改写 parent,避免执行切片污染上游事实源。

Triage:判断现实 issue 是否能执行

有了 PRD 和 issue,不代表一定要 triage。刚从 PRD 拆出来、用户已确认、验收标准完整、没有新评论改变前提的 issue,可以直接进入 TDD。

triage 处理的是另一种情况:issue 进入 tracker 后变成协作对象,可能被评论补充、被误标、被外部 PR 关联、被 reporter 更新复现步骤。它要判断这张 issue 此刻处于什么状态,是否能交给 AFK Agent。SKILL.md#L24-L45

更直观的例子是 bug:"取消订单后库存没有恢复。"PRD 已经说了正确行为是取消后释放库存,但真实 issue 还不够执行。它可能发生在未支付订单、已支付订单、重复点击取消、前端缓存、库存表或搜索索引。triage 要先读 issue body、comments、labels、author、dates 和历史 triage notes,再尝试复现或提出具体问题。SKILL.md#L68-L86

缺复现就 needs-info。复现成功并且不需要人类权限或设计判断,才是 ready-for-agent。如果需要人工判断,就是 ready-for-human。如果历史上已经拒绝类似需求,就是 wontfix

Triage 不重复 PRD 的验收测试,也不代替 TDD。它判断的是现实 issue 是否已经清楚到可以开始 TDD。

triage 的来源,是 issue tracker 不是静态需求库,而是协作现场。评论会补充信息,label 会错,外部 PR 可能带着代码进入,reporter 可能只描述症状没有复现。人类 maintainer 会先判断"这张票现在该交给谁",Agent 如果跳过这步,就会把所有 issue 都当成可执行任务。

这个 skill 的设计核心是状态机。category 只判断 bug 还是 enhancement,state 判断它在流程里的位置:needs-triageneeds-infoready-for-agentready-for-humanwontfix。还原这个 skill 时,正文要先定义状态角色,再要求读取 label mapping,最后根据状态输出不同 artifact:ready-for-agent 写 agent brief,needs-info 写具体问题,ready-for-human 写不能委托的原因,wontfix 写拒绝理由。这样 Agent 才不会用同一种评论模板处理所有 issue。

Build:用 TDD 推进行为

tdd 是 model-invoked,因为它是执行阶段可复用纪律。它的核心不是"写很多测试",而是一条行为一轮红绿。

Matt 明确反对 horizontal TDD:先写一堆想象中的测试,再写一堆实现。正确做法是 vertical slices:一个测试、一个最小实现、再进入下一个测试。SKILL.md#L18-L41

在订单取消里,第一轮可以只写:

text 复制代码
given a pending order
when the user cancels it before shipment
then the order becomes cancelled and inventory is released

这个测试先失败。Agent 只写足够代码让它通过。下一轮再处理"已支付订单进入退款中"或"已发货订单不能取消"。

tdd 的沉淀不是额外归档文档。它沉淀为可运行的行为测试、public interface 和最终实现。只有出现额外知识时才转交其他 artifact:需求边界变化回 issue 或 PRD,架构 seam 不存在转成架构问题,长期设计决策进入 ADR,会话边界交给 handoff

tdd 的来源,是 Agent 太容易把"我理解需求"直接变成"我开始写实现"。人类工程师会用一个失败测试约束自己,Agent 也需要同样的外部刹车。Matt 的写法没有把 TDD 讲成信仰,而是把它压成一个执行纪律:红绿必须纵向交替,不能先铺一堆测试再铺一堆实现。

这个 skill 的设计要点是限制工作宽度。先找 public interface 和最高测试 seam,只测外部行为;再让用户确认行为优先级,因为不可能测试一切;每轮只拿一个行为写失败测试,然后写最少代码通过;红的时候禁止重构。要还原它,正文要有明确的错误示例和正确示例,像 Matt 的 horizontal / vertical 对照一样,让 Agent 看见自己最容易犯的错。

Debug:先建立会变红的反馈环

diagnosing-bugs 取代了旧文里的 diagnose 名称。它处理的是已有行为坏了,而不是新增行为。

这个 skill 的第一阶段最重要:先建立 feedback loop。Matt 直接写道"这就是这个 skill"。没有一个会在这个 bug 上变红的 tight loop,就不要开始猜原因。SKILL.md#L12-L31

它要求 Agent 先构造能复现 bug 的测试、curl、CLI、headless browser、trace replay、throwaway harness、fuzz loop 或 bisection harness。无法建立 loop 时,要明确停止,列出尝试过什么,并向用户要环境、日志、录屏或临时 instrumentation 权限。SKILL.md#L47-L60

有了 loop 以后,流程才进入复现、最小化、提出 3 到 5 个可证伪假设、逐一插桩、修复、补回归测试、清理 debug log 和写 post-mortem。SKILL.md#L62-L134

这个节点拦的是 Agent 最危险的习惯:看几行代码就给一个"看起来合理"的补丁。

diagnosing-bugs 的来源,是 bug 修复里的最大幻觉:补丁可以靠读代码猜出来。人类调试时会先找复现路径和观察点,但 Agent 经常把静态解释当证据。这个 skill 把"先建立会变红的反馈环"写成第一阶段,而且明确说这就是这个 skill。

还原这个 skill 时,正文必须比普通 debug checklist 更硬。第一步不是列假设,而是构造 loop:测试、curl、CLI、headless browser、trace replay、throwaway harness、fuzz loop、bisect,哪种能让 bug 稳定出现就用哪种。没有 loop 就停,列出尝试过什么,向用户要环境或日志。只有 loop 存在后,才允许最小化复现、提出 3 到 5 个可证伪假设、逐个插桩验证、修复并补回归测试。这个顺序不能换,因为它防的正是"先猜后证"。

Repair:把局部失败上升为结构问题

当 TDD 或 debug 暴露出没有好 seam、测试只能写得很浅、概念散落、模块太浅时,就进入架构修复。

最新版把架构词汇拆成两层。codebase-design 是共享设计语言:module、interface、depth、seam、adapter、leverage、locality。它强调深模块:小接口后面藏大量行为,并且这个接口同时是测试表面。SKILL.md#L6-L29

improve-codebase-architecture 是人主动调用的扫描和选择流程。它先读 CONTEXT.md 和 ADR,再探索代码摩擦,找 shallow module、坏 seam、难测试路径和缺 locality 的区域。SKILL.md#L16-L31

它的第一份产物不是长期文档,而是写到 OS temp 的 HTML report。这个 report 是临时工作台,用来帮助用户选择要深入哪一个架构候选。SKILL.md#L32-L56

长期沉淀只在必要时发生。命名了新的深模块概念,就更新 CONTEXT.md;用户用长期有效的理由拒绝某个方向,才提议写 ADR,避免未来重复建议。SKILL.md#L57-L66

Repair 这组 skill 的来源,是 TDD 和 debug 经常暴露出更深问题:不是某个函数写错,而是代码没有合适 seam,概念散落,模块接口太浅。Agent 如果把这种问题当普通重构,会输出泛泛建议;如果直接动代码,又会扩大风险。

Matt 的设计把"语言"和"行动"拆开。codebase-design 先提供评判词汇:module、interface、implementation、depth、seam、adapter、leverage、locality。improve-codebase-architecture 再用这些词找 deepening opportunity,先写 HTML report 给用户选择,而不是直接改代码。还原这类 skill 时,正文要先定义架构判断语言,再规定扫描对象和临时产物,最后写清长期沉淀门槛:新的业务概念进 CONTEXT.md,长期有效的拒绝理由才进 ADR。

Handoff:跨会话保留现场

handoff 处理的是会话边界,不是项目文档。它把当前对话压缩成临时目录里的 handoff document,让另一个 Agent 能继续工作。SKILL.md#L1-L16

这个 skill 的关键是不要复制已经存在的事实源。PRD、issue、ADR、commit、diff 里已有的内容,只引用路径或 URL。handoff 要保存的是"下一轮该从哪里继续":当前任务、已完成产出、关键决策、未完成问题、建议使用哪些 skill。

它和 CONTEXT.md、ADR 的关系不同。CONTEXT.md 保存长期语言,ADR 保存长期决策,handoff 保存短期现场。

handoff 的来源,是 Agent 会话天然会断。人类交接时会说"我做到哪了、看了哪些东西、下一步该从哪里继续",但 Agent 很容易写成背景总结,把已有 PRD、issue、ADR 再复制一遍,制造第二份事实源。

这个 skill 的设计要点是索引而不是复述。它要保存到临时目录,不落当前 workspace;已有事实源只引用路径或 URL;敏感信息要删;内容聚焦下一轮如何继续。还原它时,正文应该包含固定槽位:当前任务、已完成产出、关键决策、未完成问题、相关引用、建议下一步使用哪些 skill。它的完成线不是"总结得完整",而是下一位 Agent 能直接恢复现场。

这条流程的真正作用

这条链路不是为了让用户背顺序。真正的使用规则更简单:

  • 不知道用哪个 skill,先用 ask-matt
  • 需求没说清,用 grill-megrill-with-docs
  • 方案形状不确定,用 prototype
  • 对话已经清楚但还没成执行物,用 to-prd
  • PRD 太大,用 to-issues
  • issue 已经在 tracker 里流转过,用 triage
  • 要新增行为或修 bug 且 seam 清楚,用 tdd
  • bug 原因不明,用 diagnosing-bugs
  • 执行中发现 seam 或模块形状有问题,用 codebase-designimprove-codebase-architecture
  • 会话要结束,用 handoff

Matt 的核心贡献不是发明这些工程动作。人类工程师本来就会澄清需求、做原型、写测试、复现 bug、重构架构。他做的是把这些隐性动作显式化成 Agent 可触发、可检查、可接力的协议。

如果要自己写同类 skill,不要先问"我要不要写一个 PRD skill、TDD skill、debug skill"。更好的起点是问:我在真实项目里反复看到 Agent 跳过了哪个人类隐性动作?这个动作需要读哪些状态?会产生什么中间物?什么时候必须停下来等人?什么证据能证明它完成了?能回答这五个问题,skill 的骨架才会自然长出来。