implement-spec Skill 详解:把整份 spec 并行做完
/implement-spec 是 Matt Pocock 开源 skills 合集里负责"构建"的那一步。你给它一份 spec,以及 /to-tickets 从中切出的工单。它把工单当作任务图来读,为每张就绪的工单启动一个实现子代理,各自在独立的 git worktree 里工作,把完成的工作合并进同一条集成分支,最后只做一次代码评审。本文讲清楚一次运行怎么走、它对 spec 和工单有什么要求、它和 Superpowers 的 subagent-driven development 有什么不同、它自己的文档列出了哪些问题,以及我们在运行前后补上的检查。
本文是独立的解读文章,Spec Coding 与 Matt Pocock 及 AI Hero 没有任何关联。内容已对照 GitHub 上该 skill 的源码和文档核对;我们没有实际计时或做基准测试。本文接续 to-spec skill 详解,安装方式和 spec 本身见那篇。
/implement-spec 做了什么
这个 skill 的描述只有一行:"Implement the result of /to-spec and /to-tickets in code."(把 /to-spec 和 /to-tickets 的结果用代码实现。)按 SKILL.md 的说法,目标是"整份 spec 在同一条集成分支上实现,每张工单都按任务跟踪系统的方式关闭"。一次运行大致如下:
- 读 spec 和工单,根据工单之间的阻塞关系整理出任务图。
- 探索(可选)。一个探索子代理阅读相关代码和文档,把 markdown 笔记存到仓库之外的目录,之后所有子代理都能读到,实现子代理就可以专心写代码。
- 创建集成分支。如果你的任务跟踪系统通过 PR 关闭工作,或者你要求开 PR,它会在第一次合并后开一个 draft PR。
- 为每张就绪的工单启动一个全新的实现子代理,各自在独立的 worktree 和分支上工作,条件允许时在后台运行。每个实现子代理先确认自己的 worktree 基于集成分支,用
tddskill 完成工单,报告完成前先把集成分支的最新提交合并进自己的分支。 - 合并。每完成一张工单,由一个合并子代理把它合进集成分支,然后为刚解除阻塞的工单启动新的实现子代理。
- 只评审一次。所有工单都落地后,对集成分支运行
code-reviewskill,把全部问题交给一个全新的实现子代理修复。 - 收尾:把 draft PR 标为可评审,或者按跟踪系统的方式逐张关闭工单,然后删除所有 worktree。
有两条规则贯穿始终。每个子代理都从全新的上下文窗口开始;子代理之间的沟通尽量少,主要传递上下文指针(spec、工单、探索笔记、之前的提交),而不是粘贴摘要。这样每个实现子代理的提示都很小,编排者的上下文窗口也能留给任务图本身。
和 /to-spec 一样,这个 skill 设置了 disable-model-invocation: true,只有你输入命令时才会运行;它的 Codex 配置同样禁止了隐式调用。版本说明:最新发布的 v1.3.2 已经让每个子代理从全新上下文开始。发布之后 main 上又多了一个提交(a496f55,10 月 29 日),明确规定每张工单配一个全新的实现子代理,修复 code-review 问题的也是一个全新的子代理。
工单是一张任务图:前沿
它和"一张一张做工单"的区别在于任务图。/to-tickets 产出的每张工单都写明了哪些工单阻塞它。任何时刻,阻塞项已经全部落地的那些工单构成前沿(frontier),前沿上的工单同时开工。文档的原话是:"the graph's shape sets the pace, not the tickets' order on the tracker"(节奏由图的形状决定,而不是工单在跟踪系统里的排序)。
下面用 to-spec 那篇里的优惠券 spec,切成四张工单。这是我们手写的示例,不是从 skill 实际输出中截取的:
Spec: Coupon codes at checkout (AC-1 to AC-4) 01 Apply a valid code at checkout blocked by: none closes AC-1 02 Reject expired codes with a message blocked by: 01 closes AC-2 03 Allow one coupon per order blocked by: 01 closes AC-3 04 Record the coupon on paid orders blocked by: 01 closes AC-4 Frontier during the run wave 1 01 wave 2 02 03 04 three implementers in parallel worktrees then code-review over the integration branch, one fix subagent
工单 01 是"曳光弹":一条贯穿定价模块、结账表单和测试的细路径。其余三张都依赖它、彼此之间不依赖,所以可以一起跑。如果每张工单都阻塞下一张,运行就成了一条直线,不比手动一张张做快;如果完全没有阻塞关系,四张会同时开工,后面几张就会建立在还不存在的代码上。
运行前需要准备什么
| 前提 | 为什么需要 | 缺少时会怎样 |
|---|---|---|
用 /setup-matt-pocock-skills 配置好的任务跟踪系统 | 工单从这里读取,也在这里关闭 | skill 会停下来,让你先运行配置 |
带阻塞关系的工单,即 /to-tickets 写出的那种 | 阻塞关系就是任务图 | 图是平的,所有工单同时开工 |
| 能在后台运行子代理、并给每个子代理分配 git worktree 的 harness | 同时跑多张工单正是它的意义所在 | 文档原话:"it is only a slower implement"(它只是一个更慢的 implement) |
| 通过 PR 关闭工作的跟踪系统(可选) | 决定是否会有 draft PR | 运行停在集成分支上,配合本地 markdown 跟踪方式也能离线完成 |
安装方式和合集里其他 skill 相同。在 Claude Code 里,claude plugin install mattpocock-skills@claude-plugins-official 会装上一个能自动更新的插件;其他 agent 用 skills.sh 安装器。to-spec 那篇介绍了这两种方式和一次性配置。
implement-spec、implement 与 Superpowers 的 subagent-driven development
把书面计划交给子代理写成代码,有三种看起来相似的方式。区别在于谁来派活、一次跑几个任务、什么时候评审:
/implement | /implement-spec | Superpowers subagent-driven development | |
|---|---|---|---|
| 输入 | 一份 spec 或一张工单 | 一份 spec 及其带阻塞关系的工单 | 一份实现计划,通常来自 writing-plans |
| 谁来派活 | 你自己:每张工单一个会话,中间清空上下文 | 一个编排 agent | 你会话里的一个控制 agent |
| 同时进行的任务 | 一个 | 前沿上的所有工单 | 一个;当前任务通过评审后才开始下一个 |
| 隔离方式 | 当前分支 | 每张工单一个 worktree,最后合进集成分支 | 整个计划共用一个 worktree |
| 测试 | 在你交互确认的接缝上运行 tdd | 每张工单运行 tdd,没有交互确认接缝的步骤 | 实现子代理自己测试、提交、自查 |
| 评审 | 每个会话结束时运行 code-review | 对集成分支运行一次 code-review,交给一个修复子代理 | 每个任务之后做规格符合度和代码质量评审,最后再评审整个分支 |
| 进度记录 | 工单状态,由你更新 | 跟踪系统和集成分支 | 一个能在上下文压缩后保留下来的台账文件 |
本质上是评审频率和吞吐量之间的取舍。Superpowers 的规则是控制者"never move to the next task while the review has open Critical/Important issues"(只要评审还有未修复也未裁定的严重或重要问题,就不进入下一个任务),并为每个角色选能胜任的最便宜的模型。/implement-spec 让所有就绪工单同时开工,文档也承认代价是"you no longer read each ticket's work as it lands; you review the integration branch at the end"(你不再逐张查看工单的产出,而是在最后评审集成分支)。两者都没有错,只是适合不同的 spec:独立的工单多,就适合任务图;任务之间耦合紧,就适合每步评审。名字也容易混淆:Superpowers 里的 "SDD" 指的是 subagent-driven development,而不是 spec-driven development,我们的 OpenSpec vs Superpowers vs Spec Kit 对比文章专门讲过。
官方文档列出的六个问题
这个 skill 的文档对出问题的地方相当坦率。下面六条会改变你的用法:
- 评审加修复的循环可能跑好几个小时。
code-review拿代码对照整份 spec,所以只有在所有工单落地后运行才有意义;中途运行的话,每张还没做的工单都会被判为失败。即便时机正确,skill 目前也没说修复之后什么时候停。有用户反馈,一个五张工单的功能"the review and fix loop took roughly four hours"(评审和修复循环花了大约四个小时)。如果发现又开始了第二轮全面评审,让 agent 只针对已修复的问题做定点检查,然后停下。 - 并行的实现子代理会撞车。"Worktrees don't remove collisions; they postpone them to merge time."(worktree 不会消除冲突,只是把冲突推迟到合并时。)两张看似不相关的工单仍可能共用一个文案目录、一个配置注册表或一个类型,而每个实现子代理只看得到自己的工单。有一次反馈的运行里,网页端和移动端两张工单给同一个字符串分别起名
blockedSince和blockedOn。办法是在这类工单之间加一条阻塞关系,或者在探索笔记里先把具体命名定下来。 - 在 GitHub 上,被阻塞的工单一直不开工。阻塞计数只有在阻塞项关闭时才会减少,而工单通常要等 PR 在运行结束时合并才关闭。让编排者自己记录哪些工单已经合进集成分支,并据此计算前沿。
- 测试在 worktree 里被悄悄跳过。worktree 里只有 git 跟踪的文件。依赖被 gitignore 的测试数据、本地数据库或凭据的测试,在那里可能直接跳过,工单却报告全绿。这类工单应该在主工作区里运行。
- 接缝不会和你确认。每个实现子代理都会运行
tdd,但不像/implement会话那样有一步让你确认测试接缝。想固定接缝,就在 spec 或工单里写明。 - 产出只是草稿。文档说得很直接:"The run's output is a draft that the review completes, not something to ship on its own."(运行的产出是一份要靠评审来完成的草稿,不能直接上线。)第一次评审发现真问题是正常的。
运行前我们检查什么
上面大多数问题都可以追溯到 spec 和工单本身,而在并行开跑之前修正它们的成本很低。下面的检查建立在我们给每份 /to-spec spec 补上的编号验收标准之上:
- 每条验收标准有且只有一个归属。每张工单写明自己关闭哪些
AC-n,每条标准只出现在一张工单里。没人认领的标准就是没有子代理会去做的工作;被两张工单共享的标准迟早会撞车。 - 每条验收标准在开始时都是失败的。
/to-tickets的文档给出了检验方法:"For each criterion, name the observation that would show it false, and confirm it fails at the commit the implementer starts from."(对每条标准,说出能证明它不成立的观察,并确认它在实现者起步的那个提交上确实失败。)一开始就通过的标准什么也衡量不了。 - 共享文件提前定好。逐个检查每一波前沿,看有没有工单会改同一个文件。在优惠券的例子里,02 和 03 都要往同一个错误码列表里加一项,所以我们在运行前就把
COUPON_EXPIRED和COUPON_LIMIT写进探索笔记。 - 接缝写明。spec 的测试决定里写清接缝,最好只有一个,让所有实现子代理在同一个边界上测试。
- 标出依赖未跟踪文件的工单。测试需要被 gitignore 的材料的工单,标注为在主工作区运行。
使用本地 markdown 跟踪方式时,通过这些检查的工单长这样(手写,按 skill 的本地工单模板):
.scratch/coupon-codes/issues/02-reject-expired-codes.md
# 02: Reject expired codes with a clear message
**What to build:** a customer who enters an expired code sees
"This code has expired", and the order total does not change.
**Blocked by:** 01
**Status:** ready-for-agent
- [ ] AC-2: an expired code returns COUPON_EXPIRED; the total is unchanged
- [ ] Fails at start: on 01's merge commit, price(cart, "EXPIRED10")
returns no COUPON_EXPIRED error
- [ ] Error code name fixed in the exploration notes: COUPON_EXPIRED
运行后我们在集成分支上评审什么
因为不逐张查看工单的产出,运行结束时的评审比平时更重要。我们对照 spec 逐条验收标准评审,每一行都要有证据才允许合并:
AC Ticket Test at seam price(cart, code) Start End AC-1 01 applies a valid code fail pass AC-2 02 rejects an expired code fail pass AC-3 03 rejects a second code on one order fail pass AC-4 04 stores coupon_code and discount_cents fail pass Also check - each ticket landed as a fast-forward merge, not a conflict resolution - nothing from Out of Scope was built (stacking, usage limits, admin UI) - code-review findings are fixed, or recorded with a reason
"Start" 这一列让全绿的测试变成证据:一个从未失败过的测试,证明不了引入它的那张工单做对了什么。我们的测试证据门禁一文讲了如何把这项检查放进 CI,而不是靠人工。
什么时候用它
| 你的情况 | 用什么 |
|---|---|
| spec 已切成带阻塞关系的工单,想一次跑完 | /implement-spec |
| 想在自己的上下文窗口里一次做一张工单 | /implement |
| spec 还没切成工单 | 先用 /to-tickets |
| 改动很小,没有真正的依赖图 | 直接用 /implement |
| 无人值守的工作,比如通宵跑 | 确定性的循环:文档推荐 Sandcastle、shell 脚本或 CI 任务,更快、更便宜、更可靠 |
在这张表之外,我们的经验法则是:看最宽的那一波前沿。如果没有一波超过两张工单,并行带来的收益很小,却要放弃逐张评审,不如用 /implement 一张张做。
常见问题
implement-spec skill 是什么?
Matt Pocock 开源 skills 合集里一个需要手动调用的 skill。给它一份 spec 和 /to-tickets 从中切出的工单,它把工单当作任务图来读,为每张就绪的工单在独立的 git worktree 里启动一个实现子代理,把完成的分支合并进同一条集成分支,最后对整体结果运行一次 code-review。
/implement-spec 和 /implement 有什么区别?
用 /implement 时你自己负责派活:每张工单开一个会话,中间清空上下文,还要自己记哪些工单已经解除阻塞。/implement-spec 把这件事交给一个编排 agent,让所有已解除阻塞的工单同时开工。代价是你不再逐张查看工单的产出,而是在最后评审整条集成分支。
/implement-spec 一定要用 GitHub 吗?
不需要。运行在集成分支上结束;只有当你的跟踪系统通过 PR 关闭工作,或者你明确要求时,它才会开 draft PR,所以配合本地 markdown 跟踪方式也能离线运行。
它和 Superpowers 的 subagent-driven development 一样吗?
不一样,尽管两者都给每个任务一个全新的子代理。Superpowers 按计划一次做一个任务,每个任务都先评审再继续。/implement-spec 让所有就绪工单并行,最后对整条分支只评审一次。
参考资料
- implement-spec SKILL.md
- implement-spec 文档(适用场景、常见问题)
- to-tickets SKILL.md 及文档
- GitHub 上的 mattpocock/skills(README:安装、skill 列表)
- Superpowers subagent-driven-development SKILL.md
- Claude Code 文档:Subagents
2026-11-10 核对,依据 mattpocock/skills main 分支提交 a496f55(2026-10-29,发布版 v1.3.2 之后的一个提交)和 obra/superpowers v7.0.2。引文均出自上面链接的文件。