Skip to content

Open Code Review:把 AI 评审里「必须对」的部分,从模型手里拿走 ​

2026 年 5 月 18 日建仓,到 11 月 15 日,alibaba/open-code-review 是 51,751 个 Star、4,027 个 Fork、345 个 open issue。Go 写的,Apache-2.0,最新提交就在今天。

它做的事情不新鲜:读 git diff,交给大模型,吐行级评审意见。市面上这类工具已经有一打。真正值得看的是它怎么分配工作——哪些环节交给模型,哪些环节坚决不让模型碰。

这个选择的后果很直白,甚至有点反直觉:

在同一个模型、同一份评测集上,它比通用 Agent 报出的问题少得多,找到的真问题也更少——但每一条评论的可信度高出四五倍,花的 token 少一个数量级。

先看它自己怎么解释这件事。

三个病因,官方总结得很直接 ​

README 里对「通用 Agent 做代码评审」的批评,比大多数竞品的自我宣传更诚实。它列了三条:

  • 覆盖不完整:改动集一大,Agent 就开始偷工减料,挑几个文件看看就交差。
  • 位置漂移:报告的问题和实际代码位置对不上,行号、文件名都可能偏。
  • 质量不稳定:自然语言驱动的 Skill 难以调试,prompt 改几个字,输出质量就跳一档。

三条指向同一个根因:纯语言驱动的架构,对评审流程没有任何硬约束。你没法跟模型「约定」它必须看完 37 个文件,也没法「要求」它把行号算准——这些东西一旦交给概率,就会在长尾上失守。

所以 Open Code Review 的核心设计不是「更强的 prompt」,而是一条分界线。

一次 ocr review 的流水线:确定性工程包住中间的 Agent 阶段(本文绘制)

三个阶段里,模型只出现在中间那段和两个兜底模块中。文件怎么选、怎么分组、用哪套规则、评论落在第几行,全由代码判定。

哪一半不该交给模型 ​

拆开 internal/agent/ 这条链路,责任划分是这样的。

前置阶段用代码做完所有「可判定」的事。 git diff 取变更(工作区、分支区间、单 commit 三种模式);selection.go 过滤文件——默认排除各语言的测试、快照、生成代码,清单里有 *_test.go、*.pb.go、__snapshots__/** 这类几十条规则;grouping.go 做语义分组,把中英 properties 打进同一个评审单元,而不是按目录机械切分。

分组这一步是整个设计里最被低估的地方。每个组启动一个独立子 Agent,有自己的消息缓冲,--concurrency 默认 8 并发。上下文隔离带来两个直接好处:超大改动集不会把某一轮对话撑爆;组与组可以真正并行。这是「分而治之」在工程上的落点,不是一句口号。

中段的 Agent 只负责语义判断。 每组先跑一次 plan 出清单,再进主循环。主循环不是跑一遍就完——--effort 三档对应 1 / 2 / 3 轮:low 一轮求快,medium(默认)两轮,high 三轮。第二轮开始的输入里,前几轮已确认的问题会作为「已发现」注入,而 plan 会被拿掉。文档里的理由写得很到位:plan 在找到明显问题之后会变成覆盖上限,反而限制了 Agent 继续深挖。这个细节说明写文档的人真的跑过几百次。

工具集也是收窄的。不是给 Agent 一个 bash 就完事,而是从生产环境的调用轨迹里蒸馏出来的几个:file_read、code_search 之类,调用频率、单工具重复率、新增工具对调用链的影响都算过。工具少,行为就稳。

后段又回到代码。 每一条评论先进 CommentWorkerPool,用滑动窗口把 existing_code 对齐到 diff 的精确行号;匹配失败才启用一次模型兜底(RE_LOCATION_TASK);主循环结束后还有一轮 REVIEW_FILTER_TASK,专门删掉站不住的结论。

有个细节很能说明这套设计的诚实程度:落不到行的评论,起始行直接记 0,没有任何标记位,下游统一靠 start_line == 0 判断「需人工定位」。不掩饰,不打补丁,用一个约定解决。

长会话必然会撞上下文墙,这里用的是三区切分:最近若干轮留在 active 区,更早的进 compress 区,被压成一段摘要塞回原始用户消息里,frozen 区不动。阈值是两个点——到 20 万输入上限的 60% 就异步开始压缩、主循环不停;到 80% 就同步压缩,确保下一次请求一定塞得下。输出上限是单独的 16384,跟输入上限解耦,免得为大窗口模型调参数时把输出预算一起放大。

同模型、同数据集,差在哪里 ​

说得再好,还是要看数字。AACR-Bench 的规模是:50 个热门开源仓库、200 个真实 PR、10 种语言、1,505 条由 80 多位资深工程师交叉验证的真值问题。数据集公开在 Hugging Face,这一点值得记一分。

挑一行最干净的对照——同一个 Claude-4.6-Opus:

同一模型下两种架构的四项指标对比(本文绘制,数据取自官方榜单)

三行质量指标里,OCR 赢两行输一行。下面两行成本,量级差得比质量差距更刺眼。

把数字摊平看:

Open Code ReviewClaude Code倍数
F125.10%11.57%2.2×
精确率33.90%(301/889)7.23%(435/5,980)4.7×
召回率20.00%(301/1,505)28.90%(435/1,505)0.69×
平均 token385K5,664K1/14.7
平均耗时1m23s13m6s1/9.4

最刺眼的是精确率那行的分母。Claude Code 报了 5,980 条评论,其中 435 条是真的;Open Code Review 报了 889 条,其中 301 条是真的。换算一下:通用 Agent 多报了 5,091 条噪声,只换来 134 个额外真问题——大约每 38 条误报换 1 条有效发现。

这个比例决定了工具能不能活下来。把 5,980 条评论摆在一个工程师面前,他不会挑出那 435 条,他会关掉这个工具。

榜单里还有一行更极端:Qwen3.7-Max 跑 Claude Code,召回率 23.37%(全表第二高),代价是报了 4,260 条、精确率 8.23%。通用 Agent 的高召回,本质是靠海量输出硬凑出来的,不是靠看得更准。

官方对这件事的说法是「召回率更低是有意的取舍」。信不信另说,但至少它在榜上如实列出了自己输的那一栏。

一个反例:模型更新,评审不一定更好 ​

同一个榜里有个容易被忽略的角落。换成 Claude-4.8-Opus,Open Code Review 的精确率升到 37.80%——全表最高——召回率却掉到 11.70%,全表最低,F1 反而低于 4.6 那一档。

这提醒一件事:评审质量不是「模型越新越好」的单调函数。更保守的模型会把不确定的结论咽回去,精确率上去了,覆盖就下来了。榜单上版本号也不统一(并排挂着 v1.3.1 和 v1.8.7),说明这是一份长期累积的多版本成绩单,不是某一次统一横评。

所以这套数字的正确读法是:看趋势和量级,别抠小数点。同架构对比下的方向性差异是可信的;「25.10% 比 21.00% 好」这种同量级比较,换一次运行就可能翻转。

也别忘了 F1 25% 的绝对含义:报三条大约一条对,1,505 个真问题只找到 301 个。这是整个 AI 代码评审行业当下的天花板,不是这一家的失败。 它现在的合理定位是「把你从第一遍扫描里捞出来」,不是「替你看完」。

规则是一张查找表 ​

内置规则集覆盖 40 多种语言与文件类型,可以按文件精确到 java.md、go.md、swift.md、objc.md,甚至细到 MyBatis 的 mapper XML、GitHub Actions 的 workflow YAML、Solidity 合约、Verilog 时序。有个小设计挺讨巧:.m 文件先按扩展名不确定是 MATLAB 还是 Objective-C,于是看文件内容嗅探再决定用哪套规则。

比规则本身更关键的是它怎么被选中:

规则的四层优先级链(本文绘制)

四层,从上往下找,第一层有匹配项就停。前三层的文件不存在时静默跳过,不报错——所以一个从不写规则的项目也能直接跑。

这套机制的工程味在于:它不是把规则拼进 prompt 里让模型自己领会,而是查表命中一段文字,填进模板占位符。 同样的文件、同样的配置,每次拿到的规则文本完全一致。可复现、可审计、可 diff——这是模板引擎相对自然语言引导的根本优势,也是前面「质量不稳定」那条病因的解药。

项目配置长这样,放在 .opencodereview/rule.json 里随仓库提交:

json
{
  "rules": [
    {
      "path": "src/api/**/*.go",
      "rule": "启动事务后必须立即 defer tx.Rollback()。"
    }
  ]
}

默认行为有个坑要记:匹配到的用户规则会整段替换内置规则,不是叠加。如果你写一条 **/* 的全局安全规则,等于把 java.md、python.md 全丢了。想两者都要,得显式加 "merge_system_rule": true——而且它在合并时是按文件重新解析内置层的,一条 catch-all 就能让每个语言各自叠上自己的默认规则。

改完别猜,用 ocr rules check <path> 直接看这个文件最终拿到的是什么。

跑起来 ​

bash
npm i -g @alibaba-group/open-code-review
ocr config provider      # 选服务商、填 key、选模型,自带连通性测试
ocr review --preview     # 先看它打算审哪些文件
ocr review               # 工作区模式

--preview 这个命令值得单独提。多数 AI 评审工具的黑箱感来自「我不知道它到底看了什么」,先把文件清单打出来,能省掉大量「为什么这个问题没被发现」的扯皮。

常用的几种形态:

bash
ocr review --from main --to feature-branch   # 分支区间,merge-base 模式
ocr review --commit abc123                   # 单个 commit
ocr scan --path internal/agent               # 不做 diff,整文件审(审计陌生仓库)
ocr review --format json --audience agent    # 给上游 Agent / CI 吃的纯 JSON

还有一条跟其他工具走法不同的路:委派模式。ocr delegate preview / ocr delegate rule 只让它负责挑文件和解析规则,真正的评审交给你正在用的编码 Agent,用它自己的模型和额度——OCR 侧不需要任何 API key。这个设计很务实:很多人手里已经有一份 Claude Code 订阅,不愿意再为评审单独买 token。

接入面上铺得很宽:GitHub Action(会更新 bot 自己的 summary 评论)、GitLab CI、Gerrit、GitFlic;编码 Agent 侧有 Claude Code、Codex、Cursor、Kimi Code、OpenCode 的插件;另有 MCP Server、ACP 适配器、OpenTelemetry,以及一个能在浏览器里回放评审过程的 Session Viewer。

该冷静的地方 ​

第一,星数不等于成熟度。 六个月、345 个 open issue、4.0k fork,这是一个正在高速运动的项目,不是一个稳定件。榜单上 v1.3.1 与 v1.8.7 并排、CLI 在 11 月还有 refactor(cli)! 的破坏性变更,都说明接口仍在动。要接进 CI 当门禁,先锁版本。

第二,低召回是个产品定位问题,不是指标问题。 如果你的用法是「把人从噪声里捞出来」,少报多准正是你要的。如果你的用法是「不合规就卡住合并」,20% 的召回意味着门禁形同虚设——这时候你不该用它当唯一的守门人,它只配当第一道粗筛。

第三,自带榜单永远要打折看。 数据集公开是加分项,但上榜版本不一、自家工具自家调参,第三方独立复现之前,「精确率高 4.7 倍」这个结论只能说方向可信、幅度待验。文中所有数字都标注了来源与口径,就是为了方便你自己去核。

第四,规则是模板匹配,天花板明确。 它能覆盖「这个 handler 没校验入参」「这个 SQL 有注入风险」,覆盖不了「这个模块的边界划错了」。语言与缺陷类型的广度换来了语义深度上的妥协,这是查表式规则的固有代价。

第五,成本仍在。 385K token 一次评审不算离谱,但对一天几十个 PR 的团队,账还是要自己算。好在 --effort low 和 --max-tokens-budget 都留了口子。

一个判断 ​

它真正的贡献不是「又一个 AI 评审工具」,而是把一个被普遍忽略的问题摆上了台面:在 Agent 应用里,哪些环节必须由确定性代码兜住?

过去两年的主流做法是把能力尽可能塞给模型——给工具、给上下文、给自由度,指望它自己规划。这条路在开放式任务上确实有效,但在有明确对错标准的流程上(行号对不对、文件看没看完、规则用没用对),概率系统会在长尾上持续失守。Open Code Review 的答案是:把这些环节做成查表、分组、滑动窗口、优先级链,让模型只负责它真正擅长的那部分——读懂代码在干什么,判断这里有没有风险。

代价写在同一张表上:召回率更低,覆盖面更窄。它主动放弃了「发现一切」的野心,换回「说的每条都值得看」。

这个取舍适合谁,取决于你把 AI 评审当什么用。当第二双眼睛,它现在是开源里最接近可用的一个;当自动门禁,它还不够,整个行业都还不够。装一个、跑在本地、用 ocr review --preview 看看它到底读了你哪些文件——半小时就能判断它对你的代码库有没有用,比读十篇评测都准。

配图与参考 ​

文中 3 张示意图均为本文绘制;benchmark 数值取自项目官网首页公开榜单(2026-11-15 抓取),版本与口径以官方页面为准。

最后更新于: