约束 AI 的七层机制
来源:Anthropic Claude Code 团队博客《How the Claude Code team does code review》(2026-10-15),中文版见微信公众号「AI编程实验室」。 文中数字均为该团队内部数据,不能直接外推到其他团队。
要点速览
- 约束 AI = 把「能不能做、怎么验、何时停、怎么退、谁负责」变成模型外部的机制,而不是写更长的提示词。
- 不设一道总闸门,设七层检查,每层只负责一类错误。
- 完成标准必须是可运行、可展示的证据(测试输出、构建结果、截图),不是模型自述「已完成」。
- 审查循环必须设停止条件;「没有新意见」不是收敛的证明。
- 节省的时间要用回滚率和事故率做护栏,否则只是把成本从评审搬到故障。
一、Harness 是什么(前置概念)
模型本身只输出文字。它能改文件、跑命令、连网,靠的是外面包着的一层程序,这层程序叫 Harness(智能体运行框架)。
Harness 决定下面五件事:
- 模型能看到哪些文件、哪些目录。
- 模型能调用哪些工具(读取、写入、执行命令、联网)。
- 模型能改哪些路径,改之前是否需要人批准。
- 模型做完后,用什么标准判定「做完了」。
- 模型什么时候必须停下来。
所以「约束 AI」在工程上等于「配置 Harness」,不是「在对话里拜托模型小心一点」。
二、问题的转移:从「人读过」到「哪层能抓住」
背景数据:
- Claude 写了 Claude Code 自身约 90% 的代码。
- Anthropic 主仓库每天合入的变更,从 2026 年 5 月约 2,500 个涨到 9 月 30,000+ 个。
- Claude Code 仓库 6 月到 9 月:合并的 PR 数量翻倍以上,需要回滚的比例反而下降 40% 以上。
人已经不可能逐行读完全部改动。团队的做法不是取消评审,而是换掉评审要回答的问题:
| 旧问题 | 新问题 |
|---|---|
| 有没有人读过这段代码 | 这个改动可能出什么错,哪一层检查最适合抓住它 |
问题一换,评审的时机也变了:从「写完代码后的关卡」变成「写代码过程中的拼写检查」。大多数改动在人看之前,已经被 Claude 审过至少一遍。
三、七层约束
3.1 让 AI 先自证:给可运行的检查
做法:给 Claude 一个能运行的东西(测试、构建、可对照的设计截图),要求它展示输出,而不是说「我完成了」。
配套动作:提交 PR 前让一个新上下文的 subagent 复审 diff;再跑几个内部 skill(找 bug、简化 diff、端到端验证行为)。
依据:Claude Code 作者 Boris Cherny 认为,给 Claude 一个验证自己工作的办法,可能是拿到好结果最重要的一件事,估计能让最终结果好 2 到 3 倍。
实践要点:「我已完成」是叙述,执行结果才是证据。模型的自述完成度不能作为验收标准。
3.2 规则写成文件,短而具体
| 文件 | 写什么 | 谁维护 |
|---|---|---|
CLAUDE.md | 项目是什么:技术栈、约定、目标与非目标 | 团队 |
REVIEW.md | 这个仓库里「什么算失败」 | 代码负责人(code owner) |
REVIEW.md 的写法:
- 说明该仓库的失败长什么样。文档仓库的失败是「它在说谎」,配置仓库的失败是「它把请求路由错了」。
- 限制挑刺(nit)的数量。
- 列出可以跳过的路径。
- 要求给出文件名和行号作为证据,不接受「从名字猜」。
- 总结以数量开头;没有要修的就直接说没有。
关键机制:同一类问题被反复指出时改源头——改 skill、加 lint 规则、或更新这两个说明文件,而不是每次在 PR 里重复解释。
CLAUDE.md 要短。每次评审都会加载它,在大仓库里它的作用是「指向其他文档」。
3.3 AI 互审,发现要投票去噪
做法:每个 PR 先过一次 AI 评审,再让人看。评审对照整个仓库和 PR 声明的意图,问三个问题:这个改动解决了它要解决的问题吗、符合系统设计吗、会不会弄坏别的功能。
去噪:多个 agent 并行找 bug,另起一组 agent 对每条发现投票,票数够才发出来。只涉及风格、诊断信息、清理的发现直接丢弃。过滤规则先在自家 PR 上做过 A/B 测试才保留。
每条发现标 Important / Nit / Pre-existing,不是本 PR 引入的 bug 不算到作者头上。
强制动作:每条发现都必须被回应——要么修,要么写理由关闭讨论。
效果:获得实质性评审评论的 PR 占比从 16% 升到 54%。
3.4 安全审查有阻断权
安全审查独立于 bug 审查。任何 bug 审查或安全审查的发现还开着,PR 就不能合并。要么修,要么用一句简短理由关闭(这是清除误报的方式)。后续提交修好了,发现自动消失。
要点:约束要「有牙」。只能提意见、不能阻断流程的检查,等于没有检查。
3.5 自动化检查有阻断权
lint、类型检查、各平台测试、构建。一个 CLI 的 PR 在人看之前可能已经跑过几十项检查。
PR 模板强制填三项:怎么测的、风险是什么、怎么撤销。Claude 可以代填,但提出这个改动的人要签字。
3.6 人工审批按风险分级
| 风险 | 例子 | 人工批准人数 |
|---|---|---|
| 低 | 文档、文案、仅内部功能、开关后的新增内容 | 自动审查和安全检查全绿后,可不需要 |
| 中 | 普通产品改动;缓存、自动更新器、系统提示等敏感区域 | 1 人 |
| 高 | 最高风险代码,以及一小批固定需要两人的路径 | 2 人 |
四条容易漏掉的规则:
- 等级由改动决定,不由作者决定。 分类器读改动内容定级;第二个分类器再判断这次改动是否需要额外的人。某些路径永远需要人,例如负责人标记的敏感路径和所有 CI 工作流文件。
- 只有可信名单上的作者能走轻路径。 名单外的人需要第二个人批准。
- agent 的批准永远不算人的批准。 自动评审可以放行低风险改动,但不能填需要人的席位。
- 一次批准只覆盖一个具体 commit。 之后又推了系统无法背书的提交(例如 agent 推的、或有人手工解决的冲突),必须重新批准。
责任规则:谁指挥 agent 做的改动,谁就算必填评审人之一,等同于自己手写的代码。
3.7 合并队列、开关、灰度、快速回滚
- 合并队列:把改动放到接近主线的状态重跑全部检查,避免两个各自通过的 PR 合起来弄坏主线。
- 新行为先放在功能开关后面,先给自己人用,再逐步放开。
- 公开发布先到
latest通道,stable通道随后。 - 出问题时用开关关掉(不用发版),或直接回滚提交。每周有 on-call 轮值,事故复盘追问:本该是哪一层拦住这个问题。
3.8 反馈环:把事故变成考题
- 历史上造成事故的 PR,连同它的修复和回滚,收集成一个评估集(eval)。熟悉那段代码的工程师逐条确认 bug 是否真实、位置在哪。
- 每次改评审者的提示词、工具或模型,都在这个集合上重新打分。
- 用人的行为衡量噪音:统计每条评论最后被怎么处理——修了、说是错的、说是故意这么做的、决定不处理。
- 还会在已知干净的 PR 上跑评审者,统计它多久会给出「照着改会造成伤害」的建议。
优先级写死为:先抓真 bug,再减评审轮数。
四、三条隐性约束
4.1 必须设停止条件
agent 写、agent 审,可以无限互相消耗。一个 CLI 的 PR 在夜里跑了 50 多轮评审和修复,最后是作者手动叫停的。
用 git blame 追查被反复指出的代码,约 59% 在评审第一轮就已经存在。评审者并不是每轮发现新 bug,而是每轮多翻出几个旧问题。
团队因此改了复审规则:
- 轮数上限:3 轮。 超过之后,评审者要求作者退一步重新考虑方案。
- 前几轮之后,只复审新增的 diff。
- 标记 bug 的类别,让作者一次修掉所有同类实例,而不是只修那一行。
- 不重复发已经发过的发现。
要点:「没有新意见」不是可靠的停止条件。必须写明「最多几轮」「每轮看什么范围」。
4.2 误报对 agent 比对人的成本更高
人能一秒挥手忽略一条无意义的建议。agent 会照着改,于是多一个 commit、多一轮评审。噪音在 agent 写作时会被放大。
4.3 度量要成对看
团队追踪的指标:
- 每个 PR 的人工批准数(中位数和 95 分位)、人工评论数、PR 等人的时长。
- 护栏:回滚率和事故率。 这两个上升,说明省下的时间只是被搬到了后面。
只砍审批、不看护栏,等于把成本从评审环节搬到线上故障环节。
五、人保留的五个决定
自动化把「读 diff」接走之后,人负责这些:
- 要不要做这件事:方向、品味、范围。
- 风险代码:计费、自动更新器、CI 工作流。
- 架构:会成为别人模仿模板的设计。
- 读证据:测试输出、跑了什么命令、返回什么、截图、评审发现。说不清「这些检查漏了什么」,就应该要求一次真正的评审,而不是快速点通过。
- 承担结果:每个上线的改动都有一个人负责,不管是谁敲的代码。
六、落地顺序
按顺序做,前一步没做好不要做后一步。
- 写一个短规则文件(
AGENTS.md或CLAUDE.md)。只写技术栈、约定、禁区,控制在能一次读完的长度;长内容放到别的文件,从这里指过去。 - 每次任务先说清验收方式。写清「跑哪条命令、看到什么输出算成功」,要求 AI 把输出贴出来。
- 限权限。默认只读;需要写时只开工作目录;需要装依赖或改系统时才临时放宽,每次放宽都由人确认。
- 小步提交。一次只做一件事,一次一个 commit,保证能单独回滚。
- 设预算和轮数上限。例如最多 3 轮返工、最多 N 次工具调用,超过就停下来问人。
- 留回滚点。动手前先提交一次干净状态;确认用
git revert或关掉开关就能退回。 - 记录失败案例。每次被 AI 坑到,把「输入 → 错误输出 → 正确做法」记一条,下次放进规则文件或检查脚本。
七、常见反模式
- 把规则写成几百行提示词。没人维护,模型也抓不住重点。
- 接受「我已完成」作为完成标准。
- 让两个 agent 无限互审,不设轮数。
- 把「没有新意见」当作收敛。
- 只统计审批数量,不看回滚率和事故率。
- 按作者身份决定审查强度,而不是按改动风险。
八、在 DSH 中的对应配置
下表是本文作者按 DSH 现有概念做的映射,不是原文内容:
| 文章里的机制 | DSH 里对应的东西 |
|---|---|
| 沙箱、限制改动范围 | 文件策略:read-only / workspace-write / danger-full-access |
| 需要人确认才放宽 | 审批策略 ask,放宽时由人批准 |
| 项目规则文件 | 工作区的 AGENTS.md、CLAUDE.md 自动加载 |
| 新上下文复审 | subagent(独立上下文,只回传结论) |
| 先想清楚再动手 | 计划模式:先出计划,人批准后再执行 |
| 小步提交、可回滚 | 允许本地 git commit;禁止自动 git push |
| 可验证的完成标准 | 要求跑测试、构建、命令并回贴输出 |
相关笔记
- Harness-Engineering知识沉淀实践:讲 harness 里该沉淀什么知识(规则、决策、坑);本文讲这些知识怎么变成检查机制。