约束 AI 的七层机制

来源:Anthropic Claude Code 团队博客《How the Claude Code team does code review》(2026-10-15),中文版见微信公众号「AI编程实验室」。 文中数字均为该团队内部数据,不能直接外推到其他团队。

要点速览

  1. 约束 AI = 把「能不能做、怎么验、何时停、怎么退、谁负责」变成模型外部的机制,而不是写更长的提示词。
  2. 不设一道总闸门,设七层检查,每层只负责一类错误。
  3. 完成标准必须是可运行、可展示的证据(测试输出、构建结果、截图),不是模型自述「已完成」。
  4. 审查循环必须设停止条件;「没有新意见」不是收敛的证明。
  5. 节省的时间要用回滚率和事故率做护栏,否则只是把成本从评审搬到故障。

一、Harness 是什么(前置概念)

模型本身只输出文字。它能改文件、跑命令、连网,靠的是外面包着的一层程序,这层程序叫 Harness(智能体运行框架)。

Harness 决定下面五件事:

  1. 模型能看到哪些文件、哪些目录。
  2. 模型能调用哪些工具(读取、写入、执行命令、联网)。
  3. 模型能改哪些路径,改之前是否需要人批准。
  4. 模型做完后,用什么标准判定「做完了」。
  5. 模型什么时候必须停下来。

所以「约束 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 人

四条容易漏掉的规则:

  1. 等级由改动决定,不由作者决定。 分类器读改动内容定级;第二个分类器再判断这次改动是否需要额外的人。某些路径永远需要人,例如负责人标记的敏感路径和所有 CI 工作流文件。
  2. 只有可信名单上的作者能走轻路径。 名单外的人需要第二个人批准。
  3. agent 的批准永远不算人的批准。 自动评审可以放行低风险改动,但不能填需要人的席位。
  4. 一次批准只覆盖一个具体 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,而是每轮多翻出几个旧问题。

团队因此改了复审规则:

  1. 轮数上限:3 轮。 超过之后,评审者要求作者退一步重新考虑方案。
  2. 前几轮之后,只复审新增的 diff。
  3. 标记 bug 的类别,让作者一次修掉所有同类实例,而不是只修那一行。
  4. 不重复发已经发过的发现。

要点:「没有新意见」不是可靠的停止条件。必须写明「最多几轮」「每轮看什么范围」。

4.2 误报对 agent 比对人的成本更高

人能一秒挥手忽略一条无意义的建议。agent 会照着改,于是多一个 commit、多一轮评审。噪音在 agent 写作时会被放大。

4.3 度量要成对看

团队追踪的指标:

  • 每个 PR 的人工批准数(中位数和 95 分位)、人工评论数、PR 等人的时长。
  • 护栏:回滚率和事故率。 这两个上升,说明省下的时间只是被搬到了后面。

只砍审批、不看护栏,等于把成本从评审环节搬到线上故障环节。

五、人保留的五个决定

自动化把「读 diff」接走之后,人负责这些:

  1. 要不要做这件事:方向、品味、范围。
  2. 风险代码:计费、自动更新器、CI 工作流。
  3. 架构:会成为别人模仿模板的设计。
  4. 读证据:测试输出、跑了什么命令、返回什么、截图、评审发现。说不清「这些检查漏了什么」,就应该要求一次真正的评审,而不是快速点通过。
  5. 承担结果:每个上线的改动都有一个人负责,不管是谁敲的代码。

六、落地顺序

按顺序做,前一步没做好不要做后一步。

  1. 写一个短规则文件(AGENTS.md 或 CLAUDE.md)。只写技术栈、约定、禁区,控制在能一次读完的长度;长内容放到别的文件,从这里指过去。
  2. 每次任务先说清验收方式。写清「跑哪条命令、看到什么输出算成功」,要求 AI 把输出贴出来。
  3. 限权限。默认只读;需要写时只开工作目录;需要装依赖或改系统时才临时放宽,每次放宽都由人确认。
  4. 小步提交。一次只做一件事,一次一个 commit,保证能单独回滚。
  5. 设预算和轮数上限。例如最多 3 轮返工、最多 N 次工具调用,超过就停下来问人。
  6. 留回滚点。动手前先提交一次干净状态;确认用 git revert 或关掉开关就能退回。
  7. 记录失败案例。每次被 AI 坑到,把「输入 → 错误输出 → 正确做法」记一条,下次放进规则文件或检查脚本。

七、常见反模式

  1. 把规则写成几百行提示词。没人维护,模型也抓不住重点。
  2. 接受「我已完成」作为完成标准。
  3. 让两个 agent 无限互审,不设轮数。
  4. 把「没有新意见」当作收敛。
  5. 只统计审批数量,不看回滚率和事故率。
  6. 按作者身份决定审查强度,而不是按改动风险。

八、在 DSH 中的对应配置

下表是本文作者按 DSH 现有概念做的映射,不是原文内容:

文章里的机制DSH 里对应的东西
沙箱、限制改动范围文件策略:read-only / workspace-write / danger-full-access
需要人确认才放宽审批策略 ask,放宽时由人批准
项目规则文件工作区的 AGENTS.md、CLAUDE.md 自动加载
新上下文复审subagent(独立上下文,只回传结论)
先想清楚再动手计划模式:先出计划,人批准后再执行
小步提交、可回滚允许本地 git commit;禁止自动 git push
可验证的完成标准要求跑测试、构建、命令并回贴输出

相关笔记

参考资料