Agent 改完的代码, 你敢直接合吗
Claude 改完代码说了一声"Done", 你看了一眼觉得差不多, 就合并了。然后周一线上挂了。
没有可运行的检查, agent 觉得"做完了"和你觉得"做完了"是两码事。最贵的 bug 不是崩溃, 是安安静静返回了错误结果。
最简单的: prompt 里加一句
最轻量的做法, 就是在 prompt 末尾加一句话:
改完之后跑一下测试, 不通过就继续修.
Claude 改完代码会自己去跑 npm test, 挂了就回头看代码, 修好了再跑。全过程不需要你介入。
但这有个问题——它只按照自己理解的标准来验证。如果你的测试覆盖率不够, 或者"完成"的定义比跑通测试更复杂, 就需要更多层。
分层往上加
第一层: prompt 内检查
就是上面说的, 告诉它跑测试。日常小改动用这个就够了。
第二层: 定义完成标准
在 prompt 里说清楚什么算"做完":
每次修改完运行 npm run build && npm test, 把输出发给我.
这样你至少能看到它跑了什么、输出了什么, 不是它说 done 你就信。
第三层: 不让它糊弄
加一句关键的:
修复根因, 不要掩盖错误.
这能防止 agent 用空的 try-catch 或者假的 fallback 数据来敷衍你。
第四层: /goal 条件
把验证条件设成会话级的 goal, 每次修改后自动检查:
/goal 测试全部通过, 构建产物不超过 200KB
Claude 会在每轮修改后重新检查, 不满足就继续改, 不需要你每次都说"再跑一下测试"。
第五层: Stop Hook
这是最硬的——写一个 hook 脚本, Claude 改完代码之后自动触发检查, 检查不过不让这一轮结束。
{
"hooks": {
"Stop": [
{
"hooks": [
{ "type": "command", "command": "npm test && npm run build" }
]
}
]
}
}
Hook 是确定性的, 不像 CLAUDE.md 里的指令"建议性"的。如果规则必须每次执行, 用 hook 而不是写在 prompt 里。
第六层: 验证 Subagent
让一个新模型在独立上下文里审查 diff, 然后报告缺口。做作业的人不判卷, 它能发现原推理里埋下的盲点。
Claude Code 自带 /code-review 命令, 就是在独立 subagent 里审当前 diff 的。你也可以自己写 prompt: “用 subagent 审查这个 diff, 对照 PLAN.md 检查每个需求是否实现, 边缘情况是否有测试。”
常见的翻车方式
光有验证还不够, 你得知道 agent 通常在哪些地方出问题。
大杂烩会话
同一个会话里干好几件不相关的活。前面的推理会污染后面的决策。任务之间习惯性地 /clear。
越修越乱
每一次失败的尝试都留在上下文里, 新的修正堆在上面, 最后 Claude 自己都搞不清楚当前是什么状态。
正确的做法: 把进度保存到文件里, /clear 清空上下文, 用更精确的 prompt 重新来。
信任但不验证
看起来对的代码在边界情况上可能会挂。每次 review 的时候多问自己一句:“如果这里的数据是空的/负数的/非法的, 它还能正常工作吗?”
无限探索
没有范围的调研会读几百个文件, 把上下文塞满却什么都没产出来。给调研任务设好边界, 或者直接扔给 subagent。