Agent 写的代码能跑。但"能跑"不等于"好"。两者之间的差距是代码异味积累的地方——可以并行的串行 await、硬编码常量、不断膨胀的函数签名、过早的抽象。人类审查者能发现这些。Agent 不会,除非环境告诉它去看。

本指南介绍三种缩小这一差距的机制。

#问题:上下文优先级

当 agent 在执行"添加 sitemap 生成"时,它的注意力集中在让 sitemap 正常工作上。它不会同时思考新代码是否引入了硬编码字符串、刚扩展的函数调用是否变得容易冲突、或者构建文件是否接近复杂度阈值。

这不是能力限制。Agent 被要求时可以分析代码质量。问题是默认工作流中没有任何东西要求它这样做。

#机制 1:变更后 Skills

Skill 是 agent 在完成任务后运行的结构化检查清单。它将 agent 的视角从"实现功能"切换到"审视我刚写的东西"。

一个面向构建层的 review skill 通常会检查:

Skill 不修复任何东西。它呈现发现,使重构决策变得显式。

本项目的例子: skills/build-code-review/SKILL.md 针对 build/build.mjs 把这一模式固化成带具体阈值(如约 300 行)的 skill。其他项目应该依据自己的构建层选取合适的阈值。

#何时使用

在修改特定领域的文件后(构建系统、API 层、测试基础设施)。Skill 应该是领域特定的,而不是通用的——"审查所有东西"的 skill 太宽泛,没有实用价值。

#如何触发

当前:把该 skill 和它对应的触发文件列在项目的 agent 指令文件中(例如 AGENTS.md、CLAUDE.md、.cursorrules)。Agent 读取这些指令后在相关文件变更时运行 skill。

未来:hooks 在相关文件变更后自动调用 skill。

#机制 2:Hooks

Hooks 是无需人类提示即可运行的自动化触发器。它们是最强的机制,因为不依赖 agent 记住要做某事。

#常见的 hook 时点

大多数 agent runtime 会暴露几类 hook 时点:

一个作用于特定目录(比如构建层)的 post-edit hook,可以在该目录下的任意文件发生变化时自动运行对应的 review skill。

本项目的例子: 一个作用于 build/** 的 post-edit hook 会触发 build code review skill。Agent Skills 兼容的 runtime(例如 Claude Code)提供 PostToolUsePostCommit 等 hook 点;其他 agent 的命名可能不同,但模式一致。

#局限性

#建议

从 skills(手动触发)开始。只有在 skill 经过多个会话验证其价值后,才提升为 hooks。这避免了过早自动化的陷阱。

#机制 3:Lint 规则

Lint 规则是最可靠的机制,因为它们在构建时运行、是确定性的、不依赖 agent 行为。

与 agent 编写的代码相关的规则:

#与冲突预防的关联

许多提高代码质量的 lint 规则同时也减少了合并冲突频率。这不是巧合——使代码难以审查的模式同样使代码难以合并。

#三种机制的分层

三种机制形成递进关系:

  1. Lint 规则 在构建时捕获确定性的、可模式匹配的问题
  2. Skills 捕获需要上下文的判断性问题(这个复杂度合理吗?这是正确的抽象吗?)
  3. Hooks 将已证明价值的 skills 自动化

不要从 hooks 开始。从 skill 开始,验证它能捕获真实问题,然后再考虑自动化。

#Agent 仍然做不到的事

即使有了这三种机制,agent 仍然难以:

这些需要人类判断。目标不是消除人类审查,而是通过更早捕获机械性问题来减少到达人类审查的问题数量。