What · 是什么
核心设计理念:能工程化保证的环节交给确定性流水线,动态决策交给 LLM Agent,各司其职
Open Code Review 的核心设计理念:将代码审查任务拆解为『确定性工程』与『Agent』两个互补部分,而非让 LLM 全权接管所有环节
确定性工程负责强约束环节:文件筛选、打包、规则匹配、定位(code_comment 异步定位)与反思(REVIEW_FILTER)组件,这些环节用传统代码实现,行为可预期、可测试、无随机性
Agent 只负责动态决策环节:场景化提示词(针对不同审查场景定制 prompt)与场景化工具集(按场景注册不同工具组合),把需要语义理解的自由度交给模型,把需要精确保证的逻辑留给代码
该架构源自阿里内部两年的大规模生产验证,说明不是实验室构想而是经过了真实工程流量的打磨
在相同模型下,该混合架构的 SEM-F1(审查有效性指标)比 Claude Code 高出 1.3-2.2 倍,同时 token 消耗节省 5-15 倍,验证了『约束越多、模型越省心、产出越稳』的设计假设
Why · 为什么
原理 · Principle
纯 Agent 驱动的审查工具会把文件筛选、diff 解析、规则匹配等强逻辑环节交给 LLM,而这些环节恰恰是 LLM 容易出错且不可复现的地方,用确定性工程替代可消除这一不确定性源
LLM 每次调用都有 token 成本与延迟,把可代码化的环节用代码实现(如文件过滤、规则匹配),把 LLM 调用集中在真正需要语义理解的地方,是 token 省 5-15x 的根本来源
确定性组件提供『硬边界』(哪些文件审、哪些规则适用、评论是否成立),Agent 在边界内自由发挥,避免了模型自由发挥导致的范围漂移和幻觉路径
阿里内部两年规模化验证提供了实证基础:混合架构在同等模型下 SEM-F1 比 Claude Code 高 1.3-2.2x、token 省 5-15x,说明该分工方式在真实代码库规模下依然成立
How · 怎么做
文件层面:确定性代码负责选择(eng-filter 的 whyExcluded 过滤链)、过滤、分束(arch-dispatch 四层规则链),Agent 不接触文件筛选逻辑
打包层面:diff 获取由确定性 Provider(range/commit/workspace 三模式)完成,ParseDiffText/ParseHunks 状态机解析 diff 文本,Agent 只读取已打包好的 diff
规则层面:custom>project>global>system 四层规则链由模板引擎匹配,比纯语言驱动(直接让 LLM 理解规则文本)更稳定,规则适用性判定不依赖模型
定位与反思层面:code_comment 由确定性组件异步注入(强制带 path),REVIEW_FILTER_TASK 以证伪优先的确定性五步法把关评论有效性,而非让模型自审
决策层面:场景化提示词(Plan 单轮 LLM、MainTask ReAct 循环)与场景化工具集(6 工具受限注册)由 Agent 承担,保留语义灵活性
比例分配上遵循『能确定的绝不交给模型』:文件过滤、diff 解析、规则匹配、评论定位、反思否决全部确定性化,模型只做『看 diff 出评论』和『按反馈改评论』两类任务
案例 · Cases
| 代表性案例 |
|---|
| 同一代码库、同一模型下,混合架构与 Claude Code 对照评测:SEM-F1 高 1.3-2.2x、token 省 5-15x,典型案例是工具调用型审查任务中模型不再需要自行拼装 diff 与文件路径,token 消耗大幅下降 |
| 阿里内部两年规模化运行期间,确定性组件承担了全部文件级决策(过滤、分派、超时),使大量并发审查在资源受限下依然可控,验证了架构可扩展性 |
反模式 · Anti-patterns
- 让 LLM 直接读取 git diff 原始输出并自行筛选相关文件——把确定性环节交给模型,既费 token 又不可复现,违背混合架构分工原则
- 把规则匹配做成『把规则文本塞进 prompt 让模型理解』的语言驱动方式——模板引擎匹配更稳定,语言驱动在规则增多时表现劣化
- 把 REVIEW_FILTER 反思也交给模型自审(让同一模型检查自己的评论)——反思必须是独立确定性组件,否则证伪优先原则失效
- 模型越权访问被过滤文件的 diff——应通过 injectDiffMap 供 file_read_diff 按需读取,而非放开文件访问权限
正反实例论证 · Evidence
正例 · Pro
文件筛选与规则匹配交给确定性代码,Agent 只做语义决策
// 确定性:whyExcluded 过滤链按固定顺序执行entries := filterFiles(diffEntries) // binary -> exclude -> include -> ext 白名单 -> 路径黑名单// Agent 只收到已过滤的 diff 与场景化 promptprompt := buildScenarioPrompt(entry, rulesMatchedByTemplateEngine)确定性组件(过滤、规则匹配、定位、反思)用代码实现,行为可预期可单测;Agent 仅在确定性边界内做『看 diff 出评论』的动态决策,这正是 SEM-F1 比 Claude Code 高 1.3-2.2x、token 省 5-15x 的来源
反例 · Con
让 LLM 自行读取 git diff 原始输出并筛选文件
prompt := "以下是本次变更的原始 git diff,请自行判断哪些文件需要审查..."// 模型需自己理解 diff 结构、自己过滤文件、自己找规则 → 不可复现、token 暴涨把强约束环节交给模型:同一输入两次审查结果可能不同(不可复现),模型在无关文件与规则文本上消耗大量 token,直接抵消混合架构的 token 优势,且无法单测
正例 · Pro
反思组件确定性化,打破模型自审偏差
REVIEW_FILTER_TASK: 证伪优先五步法1) 保护主题否决 2) 低价值否决 3) Ground A (目标不在 diff) 4) Ground B (字面反驳) 5) 批准独立反思组件只能看到 diff 与评论 JSON,用确定性五步法先尝试推翻评论,推翻不了才批准,评论质量闸门可审计
反例 · Con
把 REVIEW_FILTER 反思交给同一模型自审
// 反例:评论产出后原样丢回同一模型要求复核reviewer.CheckMyComments(comments) // 模型天然偏向认可自己的产出同一模型自审自己的评论存在确认偏差,『我的评论是对的』倾向使证伪优先失效,无效评论漏网率上升