AI 审查
一次审查的形态
标题为“一次审查的形态”的部分一次 AI 审查,就是针对一个处于打开状态的 pull request 运行一次预置的 pr_review
流水线。流水线会打开该 PR 的审查空间,派出多个审查智能体,在该空间的隔离检出中阅读
diff;每个审查者把自己的发现项以结构化 审查节点 的形式提交,随后由主导智能体汇总
成一份走查,最后由终结器计算出一个判定:Ship、Hold 或 Block。流水线绝不会
做的一件事是发布 —— 向 GitHub 发帖是一个单独的、需要人主动执行的步骤。
本页其余部分会解释各个组成部分,以及它们为什么被设计成这样。
每个 PR 一个审查空间
标题为“每个 PR 一个审查空间”的部分PR 的审查上下文是一个消息空间 —— 模式为 review,类型为 pr —— 通过
审查空间关联 与这个 pull request 绑定。它的创建是幂等的:PR 页面、审查流水线和各个聊天界面
都通过同一条代码路径解析该 PR 唯一 的底层空间,因此,一个审查 PR 的模板和一个打开
该 PR 的人,永远不会落到两个不同的房间里、看着两份不同的检出。
该空间的隔离工作树中,PR 已检出至其 head ref。一个房间也意味着同一份检出:所有审查者 都在同一个空间里工作,而不是各自克隆一份工作区。
每个审查者都在这个空间里自己的具名流中发言,发现项是 review_node 消息,而不是普通的
散文式文字。最后在空间范围内汇总是有意为之 —— 若只根据某一条线程的发现项计算判定,
那就等于悄悄只对一个审查者下了判定。
该关联带有一条状态阶梯 —— requested → in progress → awaiting approval →
completed —— 正是它决定 PR 评审标签页上的 发布到 GitHub 按钮能否使用。
审查级别
标题为“审查级别”的部分审查的深入程度是一项工作区策略,共三个级别,在 设置 → 工作区 → 通用 中、 工作区策略 卡片上设置:
| 级别 | 派出的审查者 | 报告方式 |
|---|---|---|
light |
仅工程师 | 只报告真正重要的内容 |
balanced |
工程师、QA、架构师(默认) | 常规的一遍检查 |
thorough |
全部五个,包括安全和性能 | 不作任何降级 |
级别同时拨动两个旋钮:一是派出哪些审查者,这由流水线模板的 runWhen 状态门禁强制执行,
而不是靠提示词措辞 —— 提示词措辞可以被忽略,门禁不行;二是低于阈值的发现项呈现在哪里。
这两个旋钮都不会删除任何发现项:报告更少的级别,提交的发现项数量完全相同,只是把其余
部分归到一组。
安全和性能这两遍检查复用预置的架构师和工程师智能体,而不是引入新的智能体。其专长体现在 派发审查者时随附的任务说明里,而不是每个轴各用一个独立智能体 —— 每个轴一个智能体, 只会让每个工作区多出五行记录,却带不来任何额外能力。审查者的选择从不检查 diff 的语言 或领域。
审查节点:发现项是数据,而非散文
标题为“审查节点:发现项是数据,而非散文”的部分用 add_review_node 提交的发现项会成为该 PR 上的一个 审查节点 —— 评审标签页渲染
的正是它,判定正是根据它计算出来的,而“发布到 GitHub”正是把它变成行内评论。只返回
散文式文字的审查者,会让流水线运行看起来成功了,而审查界面却空空如也;真正承重的是
提交这个动作。
每个节点包含:
| 字段 | 取值 |
|---|---|
| 类型 | bug、suggestion、recommendation、question、ticket |
| 优先级 | P0(严重)→ P3(细枝末节) |
| 分诊三元组 | 类别(security、stability、…)、严重程度、工作量 |
| 锚点 | 文件路径、起始行与结束行 |
| 修复承载 | 建议的替换行、可选的 diff、可选的修复提示词 |
| 置信度 | 一个 [0, 1] 分值 |
| 推理过程 | 在发现项之前写下的分析 |
有两个细节是有意为之。只有当审查者给出了确切的替换行时,才会提供一键 GitHub 建议 ——
从 unified diff 里推断替换行,出错时悄无声息,而把一次错误的推断一键提交,比根本不给
按钮更糟。另外,add_review_node 的 schema 把 reasoning 放在发现项之前,这样按 schema
顺序填充对象的模型会先写出分析。该字段是可选的:省略它并不会让节点被拒收。载荷格式不
正确的节点会直接消失,而不会污染审查结果。
同行共识
标题为“同行共识”的部分节点会经历 open → consensus-ready → resolved 或 dismissed 的状态流转。中间
这一步是这套模型的核心:发现项只有在另一位审查者确认后才会升级,而智能体永远不能
确认自己提出的发现项。 MCP 工具 publish_review_to_github 和 RPC 的默认行为仍然只
发布经同行确认的发现项。而评审标签页的 发布到 GitHub 按钮则会发送所有仍然未解决的
发现项。
这条规则在三个相互独立的地方强制执行 —— 确认工具、终结器和发布器 —— 因此即使其中 任何一个的调用方有 bug,规则依然成立。所有状态变更都经由同一个服务处理,这正是状态 能够有意义的原因:在此之前,两条各自走一半的路径可能会对同一个发现项是否已解决给出 不一致的结论。
当审查者意见不一致时 —— 同一个文件和行、优先级相差两级或更多,或者一个称其为 bug
而另一个称其为 suggestion —— 这种分歧会显示在发现项列表上方。这正是审查者意见出现
分歧、而人的判断最有价值的地方。
驳回一个发现项还会向记忆域写入一条低置信度的软性抑制事实 —— 一次驳回只是一种偏好, 而不是一条规则。
队列:审查围绕什么分组
标题为“队列:审查围绕什么分组”的部分审查计算这一遍会把 PR 中变更的文件按代码图划分为若干 队列:变更的文件映射到它们 触及的符号,符号再映射到相互连接的组件,队列则按影响半径排序。一个队列带有引导式阅读 顺序、图表和洞见,而不是一份平铺的文件列表。
有两条诚实性规则塑造了这一点。队列键由内容派生,并且在多次 push 之间保持稳定,因此 发现项和审查进度能挺过 rebase 或 force-push,而不会成为孤儿。另外,当仓库没有代码 索引时,分组会退回到按普通路径进行,并且会明确说明这一点 —— 这种退路绝不会伪装出 语义上的可信度。
审查轴与门禁
标题为“审查轴与门禁”的部分除了审查者的发现项之外,一次审查还会累积 轴结果:六个轴,分为两类。
| 轴 | 类别 | 来源 |
|---|---|---|
correctness、security |
由 token 驱动 | 审查者自己的发现项 |
testGap |
由 token 驱动 | 审查者的发现项 |
visual、apiContract |
确定性 | 无需消耗 token 即可算出 |
performance |
确定性 | 仅有枚举 —— 产品中没有任何东西会计算出结果 |
一个轴的判定结果为 pass、warn、fail、partial 或 unavailable —— 只有 pass
或 warn 能通过门禁。fail、partial 与 unavailable 之间的区分是承重的:受门禁
约束的轴如果无法完成或根本无法运行,会拖住总体判定不放行,而不是让它通过。证据缺失
绝不会转化为门禁通过。
有些轴有意只作提示。由队列推导出的测试缺口轴看不到依赖注入或工厂的覆盖情况 —— 从它 的角度看,一个没有索引但测试套件很完备的仓库,和一个完全没有测试的仓库一模一样,因此 无论声称哪一种都是撒谎;它只出现在仪表板中,不参与门禁。由 token 驱动的那些轴只作提示, 因为发现项的优先级已经决定了判定,再凭它们施加门禁就是重复计数。
终结器在状态为 open 或 consensus-ready 的发现项上计算判定:
- 任何置信度 ≥ 0.7 的 P0 发现项 → Block
- 否则,任何 P0(低置信度)或任何 P1 → Hold
- 否则 → Ship
该判定带有一个总体置信度,它由各个参与贡献的置信度的离散程度推导而来 —— 一致会提高它, 分歧会降低它。
主导(CEO)智能体的汇总是一遍编辑式整理,而不是重新罗列:手写一份发现项的第二副本, 恰恰是那种会逐渐偏离真实版本的东西。重复的发现项会被降级,而不是重复呈现 —— 多个 审查者被指派去看同一个 diff,他们的职责范围刻意重叠,因此同一个缺陷三次到达终结器, 恰恰说明系统在正常工作;而把它发布三次,则是系统把自己的架构泄漏进了读者的收件箱。 在重新审查时,发现项会被取指纹并与上一轮做 diff,因此浮现出来的是真正的增量。
最后,各个轴加入进来,而它们只会让判定变得 更 严重:受门禁约束且失败的轴会强制 给出 Block —— 它不会被发现项投票推翻 —— 而受门禁约束、无法完成的轴则至少会强制给出 Hold。
发布始终在你手中
标题为“发布始终在你手中”的部分流水线有意不向 GitHub 发帖;发布由用户把关,因此一次审查绝不会重复发布。当你按下 发布到 GitHub 时:
- 会提交一条 GitHub 审查。已经解决或已驳回的发现项会被跳过。该按钮会发布所有仍然
未解决的发现项(
selection: all_open)。MCP 工具publish_review_to_github的默认 行为仍然是只发布经同行确认的发现项(consensus)。 - 锚定到文件和行号的发现项会变成行内评论;其余的一切都归入摘要正文,每一项都带有 “— Control Center AI review”页脚,以便来源清楚明确。
- 发布时会根据 PR 的 当前 diff 重新校验锚点。对已经被改写的代码留下评论,是审查者 可能留下的最破坏信任的做法;如果 GitHub 仍然拒绝某个行内锚点,整条审查会重新发送, 并把每一个发现项都归入正文,这样就不会有任何东西被悄悄丢弃。
- Block 判定会以
REQUEST_CHANGES提交;Hold 以COMMENT提交;Ship 则由 按钮以APPROVE提交(approve_on_ship: true)。除非你传入approve_on_ship, 否则 MCP 工具会把 Ship 保留为COMMENT。 - 审查以服务器应用的标识发布。是谁按下的发布按钮会被记录下来,用于角色门禁和审计 日志;发布者并不是 GitHub 上的作者。
发布会声明 prPublish 动作类别,因此护栏卡点会像对待任何变更类操作一样对它施加
门禁 —— 它默认会弹出确认提示,并且在未连接任何审批人时以失败关闭的方式处理。
参见护栏。
审查者可以做什么
标题为“审查者可以做什么”的部分审查智能体运行在 review 模式下:只读沙盒,以及一份精心筛选的工具允许列表,涵盖
发现项、评论、工单和同行评审 —— 但不允许任何变更操作。审查者无法修改它所批评的代码;
它可以附上一个建议的修复,由人来应用。当某个智能体仍试图动手时,该模式的拒绝消息会
告诉它先把审查定稿,再让用户基于已发布的摘要采取行动。