用途 cross-model-review 的目标是让评审结果“有人愿意一直读下去”,也就是发现数量少但正确,而不是给出许多看似合理的猜测。不同模型会犯不同的错误;让它们在互相看不见、彼此独立的条件下运行,模型之间的一致就可以当作证据。只由一个模型提出的发现,必须经受住“试图反驳它”的检验,才有资格被保留。同样的思路也适用于计划:在花一天执行一个计划之前,先让另一个模型来挑毛病。
两种模式
- panel:在本地运行,使用 2–3 个模型。适用于 PR、diff、计划和技能,凡是有人要求评审时都可以用。
- precision:作为单个自动化评审器在每个就绪 PR 上运行。最多允许 2 条发现,只发评论,默认保持沉默。
何时使用 / 不使用 使用场景:
- 在把 PR 交给其负责人(L2)之前,或在有门控的自行合并(L4)之前;达成一致的发现和线程处置是这些级别所需的证据;
- 在执行一个需要一天以上、或会分发给许多执行者的计划之前;
- 当工作约 2 小时没有进展时:写一个更简单的计划,并让它通过 panel 模式;
- 在嘈杂机器人会被静音的仓库上自动运行评审。 不使用场景:
- 代码风格与格式问题,那是 linter 的职责;
- 单独作为合并门控。评审是自主性拨盘的证据(docs/autonomy.md),不能替代 CI;
- 草稿,除非有人明确要求。
panel 模式:PR 与 diff 为每个评审者收集同一份材料包:diff、关联 issue 或简报、被改动文件的周边代码,以及仓库的评审规则。排除作者对该改动的看法、其他评审者的输出,以及任何关于预期答案的暗示——这就是“盲评”的含义。 并行分发给来自不同提供商的 2–3 个模型,使用一条中立提示词:“找出会导致错误行为、数据丢失、安全暴露或契约破坏的缺陷。对每个缺陷给出文件与行号、机制、具体的失败输入或序列,以及你的置信度。不要评论风格。”大型 diff 按区域拆分,每个区域都交给每个模型。 将输出规范化为 findings.json,每条发现一个条目:{model, file, lines, mechanism, failing_case, severity P1–P3, confidence}。 对发现分桶。两条发现指向同一位置和同一机制即视为匹配。匹配由单独的一轮完成,评审者彼此看不到对方。分为:
- 一致(agreed):至少 2 个模型提出;
- 单一(single):只有 1 个模型提出;
- 被反驳(contradicted):另一个模型明确表达了相反观点。 用下文证明表尝试反驳每一条 single 和 contradicted 发现,只有以高置信度存活的才保留。 对剩余发现排序:一致的优先,然后按严重程度,并受最大发现数拨盘限制。模型对严重程度有分歧时,取较低者。 报告:在本地,向操作者给出排序后的列表加计数(例如“3 条一致,1 条通过证明,9 条丢弃”)。在 PR 上,只针对存活的发现发布一条带内联评论的评审,并跳过与已有线程重复的内容。丢弃计数放在一条折叠备注中,或干脆不写。 后续跟进中对已有评论做分诊。高度重视人类评审者的评论;机器人评论要先核实再处理。每个线程都要以修复或拒绝理由关闭。
panel 模式:计划与技能(“橡皮鸭”) 把计划和它的 Loop Card 交给 1–2 个不同模型,不加引导性框架。提问:“哪个假设是错的?我们会无法度量什么?哪些约束是不必要的?达到同样结果的最简单计划是什么?” 按与 PR 相同的方式分桶。达成一致的反对意见必须处理;单一反对意见若通过证明检验则处理。 修订计划并记录改了什么、为什么。由作者决定,评审者只提供建议。 卡住时,用一个更简单的计划做橡皮鸭,而不是已经停滞的那个。
precision 模式:单个自动化评审器 触发条件:pull_request_ready_for_review,加上带 -is:draft 查询的 pull_request_synchronize。绝不要在每次推送时评审草稿。 读取 diff 及其上下文,私下列出候选缺陷。 为每个候选构建证明表,任何一行不通过就丢弃:
- Premise:你声称哪里错了;
- Counter-evidence searched:你在哪里找过“它其实没问题”的证据;
- Before → after behavior:具体输入下旧结果与新结果;
- Reachability:真实调用方或能触达的路径;
- Consequence:什么会坏、对谁坏;
- Remedy:最小修复;
- Confidence:高 / 中。 最多发布 2 条发现(P1–P3)作为内联评论。绝不批准、绝不请求更改、绝不挑剔、绝不推测。 如果没有任何发现存活,就不发布任何内容。大多数运行中,沉默是预期结果。 每次运行以记录结束:ACTED(n 条发现)、NOOP(无存活)、BLOCKED(原因)。用 automate-it 创建自动化:以暂停状态启动,给它最小工具集(读 PR、读文件、发评审评论),并配一个改进器,由它提出提示词修订供人工应用。
拨盘(默认值与选项)
- 模式:panel(本地)、precision(自动化);二者皆可,任意位置;
- 模型:来自不同提供商的 2–3 个;任意名册,记录每个选择的原因及其成本层级;
- 盲评:开启;仅在调试评审者时关闭;
- 一致阈值:2 个模型;可选全部 N 个;
- 单一模型发现:经证明检验,存活才发布;可选仅汇总或丢弃;
- 最大发布发现数:panel 5,precision 2;可任意;
- 最低置信度:高;可选中;
- 严重程度下限:P3;嘈杂仓库可仅 P1;
- 输出:本地 findings.json;PR 评审;两者皆可;
- 草稿:跳过;可应要求评审;
- 触发范围(precision):ready_for_review + synchronize -is:draft;可仅 ready_for_review(最省);
- 评论来源信任:人类高,机器人先核实;可按机器人历史设定权重;
- 自主性:他人仓库为 L0(仅评论);L1 及以上时作者智能体可自行修复一致发现;
- 模型层级:标准;高风险路径可用高级模型,每次调用成本约为 15 倍,需明确说明。
输出
- findings.json,列出每条发现及其模型、分桶和证明结果;
- 一条只包含存活发现的 PR 评审,或什么都不发;
- 对计划:一份批评、一份修订计划,以及简短的“改了什么”说明;
- 运行记录:ACTED / NOOP / BLOCKED,外加计数。
该技能自身的反馈循环
- 行动率:已发布发现中被作者修复或被回复“valid”的比例,这是首要指标。若低于约 50%,收紧置信度或严重程度拨盘。
- 每次运行的发布率与内联率。发布率上升而行动率持平,说明评审器正在变吵。
- 每模型贡献:各模型参与的一致发现数,对比只有它提出且后来被丢弃的发现数。剔除只增加噪音的模型。
- 逃逸:已评审代码在合并后发现的 bug,用于重新校准严重程度下限。
- 计划:批评是否改变了计划,修订后的计划是否交付。
它防止的失败模式
- 机器人在每次推送时发布吹毛求疵和“也许”,导致被静音;
- 某个模型的幻觉被当作事实发布;
- 锚定:评审者因读到彼此输出而趋同;
- 在本应只评论的仓库上批准或请求更改;
- 每次推送触发且无草稿过滤,导致评审成本倍增;
- 停滞的计划被原样重试,而不是简化。
为什么存在 几个月里约有 25 次把同一个 PR 发给三家不同厂商的模型,要求“把发现发到 PR 上”。真正留下来的指令是“只给我模型们一致的问题”。这个习惯后来变成了内置评审命令。 在一组针对队友仓库的评审自动化中,每天约 2,200 次运行读取 PR,37% 发布了评审,9.5% 留下了内联发现。默认沉默正是队友不静音机器人的原因。 机器人评审评论被判断约 50% 是噪音,而人类评论通常是对的,因此采用按来源加权的分诊。 用第二个模型对计划和技能做橡皮鸭成为固定习惯,并在技能发布前发现了过度约束的问题。 无草稿过滤的每次推送触发使每个 PR 的评审运行增加约 2–3 倍,而 PR 数量几乎没变——触发条件决定成本。