---
title: "让 Agent 主动审视自己的代码"
description: "如何通过 skills、hooks 和 lint 规则让 AI agent 主动发现代码异味，而不是等待人类审查者指出。"
lang: zh
pair: en.md
lastUpdated: 2026-05-07
status: published
---

# 让 Agent 主动审视自己的代码

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

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

## 问题：上下文优先级

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

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

## 机制 1：变更后 Skills

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

一个面向构建层的 review skill 通常会检查：
- 可以用 `Promise.all` 的独立 `await` 调用
- 出现多次的字符串字面量
- 参数越来越长的 render 或模板调用
- 重复的过滤/映射逻辑
- 接近项目自定义尺寸或复杂度阈值的构建文件

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 时点：
- 在编辑类工具调用之后（如写入或修改文件）
- 在 git commit 之后
- 在触及敏感操作之前

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

> **本项目的例子：** 一个作用于 `build/**` 的 post-edit hook 会触发 build code review skill。Agent Skills 兼容的 runtime（例如 Claude Code）提供 `PostToolUse` 和 `PostCommit` 等 hook 点；其他 agent 的命名可能不同，但模式一致。

### 局限性

- Hooks 为每个匹配操作增加延迟
- 过于宽泛的 hooks 产生噪音并拖慢工作流
- Hook 配置需要显式权限（agent 不能自行修改自己的 hooks）

### 建议

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

## 机制 3：Lint 规则

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

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

- `max-params`（ESLint）：标记超过 N 个参数的函数。强制使用对象解构，减少合并冲突并提高可读性。
- `no-await-in-loop`（ESLint）：捕获循环内可以并行化的串行 await。
- 项目特定的自定义规则（如"模板文件中不允许硬编码 URL"）。

### 与冲突预防的关联

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

## 三种机制的分层

三种机制形成递进关系：

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

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

## Agent 仍然做不到的事

即使有了这三种机制，agent 仍然难以：

- 识别重构在当前规模下是否有可衡量的影响
- 判断一个模式是"正在向问题演进"还是"已经是问题"
- 知道何时记录信号留待以后，何时立即行动

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