安装此技能
npx skills@latest add mattpocock/skills --skill=code-review 然后在你的编码 agent 里输入 /code-review 。
本页目录
它做什么
code-review 沿着两个维度(axis)审查 HEAD 与你指定的固定点(fixed point)之间的 diff(一个提交、一个分支、一个 tag、main、HEAD~5)。**标准(Standards)**维度问的是代码是否遵循本仓库写代码的方式。**规范文档(Spec)**维度问的是代码是否做到了最初那个 issue 或规范文档(spec)所要求的事。每个维度都在自己的子代理(subagent)里运行,所以谁都不会看到另一方的推理。
这个技能从不合并或重新排序这两个维度。报告以每个维度最严重的问题收尾,并拒绝在两者之间说出一个单一的赢家。一次改动可能通过一个维度而失败于另一个维度。遵循了每一条约定却实现了错误东西的代码,会通过标准维度而失败于规范文档维度。完全按工单(ticket)要求去做却破坏了仓库约定的代码,则正好相反。混合的裁决会让通过的那个维度藏起失败的那个维度。
什么时候用它
输入 /code-review;或者当你要求审查一个分支、一个 PR、正在进行的工作,或者任何「自 X 以来」的东西时,agent 会自动去拿它。
| 你的处境 | 该用哪个 |
|---|---|
| 已经有一个 diff,你想知道它是否构建得对,并且是不是对的东西 | code-review |
| 你想在 diff 里猎捕 bug:空路径、竞态、差一错误 | Claude Code 自带的审查,不是这一个(见下文的重名冲突) |
| 还什么都没写,你想让它按测试先行写出来 | tdd |
| 整份规范文档需要构建,包括审查 | implement,它自己会调用这个技能 |
| 整个代码库都漂移了,而不是一个 diff | improve-codebase-architecture |
| 有东西坏了,你不知道为什么 | diagnosing-bugs |
你必须提供固定点。如果你不提供,技能会向你要一个,而不是去猜。在它启动任何东西之前,它会检查那个 ref 能解析、并且 diff 不为空,所以一个拼错的分支名会失败在你面前,而不是失败在两个子代理里面。
前提条件
标准维度什么都不需要。它读仓库记录下来的任何东西(CODING_STANDARDS.md、CONTRIBUTING.md 之类),当仓库什么都没记录时,回退到一套内置基线。
规范文档维度需要存在一份规范文档,而且它得能被找到。它按这个顺序查找:
- 提交信息里的 issue 引用(
#123、Closes #45、GitLab 的!67),通过追踪器文档抓取。 - 你作为参数传入的一个路径。
docs/、specs/或.scratch/下与分支名或功能名匹配的一份规范文档文件。- 问你。
第 1 步依赖追踪器文档,那是由 setup-matt-pocock-skills 写下的。没有它,只要你交给它一个路径,这个维度仍然能工作。如果完全没有规范文档,技能会跳过规范文档子代理,报告会说「没有可用的规范文档」,而不是编造需求。
两个维度
| 标准 | 规范文档 | |
|---|---|---|
| 问题 | 它构建得对吗? | 它是对的东西吗? |
| 读什么 | 仓库记录在案的标准,加上坏味道基线(smell baseline) | 最初的 issue 或规范文档 |
| 报告什么 | 有明文记录的违规(可以是硬性判断),以及坏味道(永远是主观判断) | 缺失或部分满足的需求、范围蔓延、实现方式错误的需求 |
| 每条发现引用 | 标准文件与规则,或者点名的坏味道加上差异块 | 规范文档里的一行 |
这个设计是为了避开一种不知道你标准的通用审查技能。那样的技能会把你代码库里刻意为之的东西标出来,却漏掉你代码库所依赖的不变量。所以仓库自己的文档是标准维度上的一手来源(primary source),而且仓库永远优先。
坏味道基线位于仓库标准之下。它是 Fowler《重构》(Refactoring)第 3 章里的十二种代码坏味道:神秘命名(Mysterious Name)、重复代码(Duplicated Code)、依恋情结(Feature Envy)、数据泥团(Data Clumps)、基本类型偏执(Primitive Obsession)、重复的 switch(Repeated Switches)、霰弹式修改(Shotgun Surgery)、发散式变化(Divergent Change)、夸夸其谈通用性(Speculative Generality)、过长的消息链(Message Chains)、中间人(Middle Man)、被拒绝的遗赠(Refused Bequest)。每一种都是一个带标签的启发式判断(「可能的依恋情结」),从来不是硬性违规。每一种都说明这种坏味道是什么、怎么修,所以一条发现会附带修法,而不只是抱怨。两个维度都会跳过你的 linter 已经强制检查的东西。
常见问题
它和 Claude Code 自带的 /code-review 撞名了。我该怎么办?
这是关于这个技能报告得最多的问题,而且没有修。Claude Code 自带一个 /code-review,它做的是不同的事:它在 diff 里猎捕 bug,而这一个检查规范文档符合度与仓库标准。当你安装这个技能库时,其中一个会赢,而赢的是哪个取决于你的安装方式:
- 插件市场。 每个技能都会带上
mattpocock-skills:前缀,内置的那个在不带前缀的名字下就变得很难够到。 - 普通的技能安装。 本地文件胜出,这个技能遮蔽了内置的那个。
一个答案是彻底移除 Claude Code 的内置技能。那能省下大量上下文(context),撞名也就不再有影响。遮蔽本身可以说是 Claude Code 运行环境(harness)的一个 bug(技能作者本该有自由给技能起任何名字),所以另一个答案是重命名本地副本。npx skills update 会撤销对 frontmatter 的编辑或对重命名目录的改动。用户报告的最持久变通做法是:把技能 fork 成一个新名字,并把 code-review 从受管集合里去掉。记下你 fork 自哪个提交,好手工重新同步。
它的子代理不断再次调用 /code-review,并生出更多代理。
这是一个已知的未修复 bug。好几个人复现过它,涉及不止一个运行环境。标准与规范文档的提示词没有禁止委派,所以一个子代理可以再次找到这个技能并再次扇出。有一份报告达到了 50 多个代理。人们在 fork 上应用的修法是:在两个子代理的任务简报后面各追加一行:「不要调用 /code-review,也不要生成额外的代理:直接执行这次审查。」有些人更愿意在运行环境层面处理它,让每个技能都继承这道防护。两者都还没有进入已发布的技能。如果你无人值守地跑它,盯着代理数量。
我该在写代码的同一场会话(session)里运行它吗?
优先用一场全新的会话。正如一位读者所说:「同一份上下文审查自己,不是审查,是带着斜杠命令的确认偏误。」在编写它的那场会话里审查的 agent,上下文里装着塑造这段代码的每一个假设。独立的审查者不会有那份上下文。这也是为什么有人要求 implement 去掉它内置的审查步骤,因为那一步会在刚写完 diff 的那场会话内部运行审查。独立版本的做法,是你自己从一场干净的会话里调用 /code-review。
每个工单之后审一次,还是最后审一次?
两种都行,技能不会替你决定。逐工单审查能让每个 diff 都小到规范文档维度有一份清楚的规范文档可供对照——这正是 implement 使用的模式。攒到分支末尾再审查,能抓住逐工单审查各自漏掉的工单间交互。如果你不确定,就逐工单审查,并在分支点再做一次最终审查。
我能相信这些发现吗?
不核查就不能信。子代理的输出是假设,不是证据。有一个团队报告了十几处基于散文的审查漏掉的破坏性变更。技能把两份报告按原样合并,或者稍微清理一下。它不会对照文件重新核实每一条主张,所以一条发现可能引用错误的位置,或者夸大影响。在据一条发现行动之前,先读它的引用。技能要求每条发现都带上引用(一条标准规则、一种坏味道加上它的差异块,或者规范文档里的一行),正是这一点让发现可以被核查。
为什么我每跑一次,它都能发现新问题?
每一次修复都会加入新的代码供审查,而标准维度中属于主观判断的那一半,每次运行给出的结果都不同。一位读者这样描述这个循环:「/code-review 和 /improve-code-architecture 每次总是能找到新东西。我实现修复,重跑这些技能,然后一次又一次。」没有收敛保证。把一次审查当作一串线索。只处理那些背后有引用规则支撑的线索,然后停下。不要把它放进循环里跑到干净为止,因为它永远不会干净。
它会审查我未提交的工作吗?
不会。它 diff 的是 <fixed-point>...HEAD。三点形式从 merge-base 起算,排除已暂存和工作区里的改动。如果 implement 还没有做出一个中间提交,审查就看不到即将进入下一个提交的工作。先提交,再审查,然后 amend 或补一个 fixup。
它生效的标志
- 在任何子代理被启动之前,它就拒绝在坏 ref 或空 diff 上开始。
- 报告以两个独立的块送达,分别位于
## Standards和## Spec下,而不是一份合并的列表。 - 每一条标准维度的发现,要么点名你仓库某个文件里的一条规则,要么点名十二种坏味道之一,并引用差异块;每一条规范文档维度的发现都引用规范文档里的一行。
- 收尾总结给出每个维度最严重的问题,并拒绝挑出一个总体赢家。
- 没有可用的规范文档时,规范文档块会如实说明,而不是列出它从代码里推断出来的需求。
它在体系中的位置
code-review 是构建链尾部附近的审查步骤:grill-with-docs → to-spec → to-tickets → implement → code-review → retro。它也能独立地站在你指向的任何分支或 PR 上。
- implement 是最近的邻居。它驱动构建,并在提交前调用这个技能作为自己的收尾审查。implement-spec 则在整条集成分支上做一次同样的事。
- retro 在它之后到来,并调校它。当一场会话显示审查漏掉了某一类错误时,
retro会提议加上那项检查,或者那条标准维度随后会读取的CODING_STANDARDS.md规则。 - pr 在被审查的工作推上去之后写 PR 正文。
- to-spec 和 to-tickets 产出规范文档维度据以对照的那份文档,所以一份含糊的规范文档会让那个维度也含糊。
- improve-codebase-architecture 是对应的全代码库版本,因为这个技能只看一个 diff。
当你不确定这个处境需要哪个技能时,ask-matt 会在整套技能之间为你路由。