← 返回上一页

tech

Open Code Review:确定性工程 × 自研 Agent,以及委托模式

拆开 OCR 审查流水线:Go 管什么、自研 agent 怎么跑、delegate 与默认模式差在哪——以及官方基准实际比的是什么。

Open Code Review(ocr)是阿里开源的 AI 代码审查 CLI,用 Go 写。读完源码后,最值得记下的不是「又一个调大模型的工具」,而是它把审查拆成两层:确定性工程负责不能错的事,自研 tool-use agent 负责需要判断的事。下面按「是什么 / 为什么」把主干理清,并说明默认模式和委托模式为什么不是一回事。


核心设计:确定性 × Agent

是什么: 审查流水线里,选文件、过滤、分组预算、规则匹配、评论钉行号、误报过滤,由 Go 写死;「这段改动有没有 bug、要不要再读上下文」,交给 LLM + 专用工具。

为什么: 通用 Agent(Claude Code 等)做 review 常见三件事——大 diff 漏文件、行号对不上、效果随 prompt 飘。根因是纯语言驱动缺少硬约束。OCR 的取舍很明确:换 更高 Precision / F1、更少 token(官方称相对通用 Agent 约 1/9),代价是召回略低、更少噪声。


一次 ocr review 怎么跑

是什么: 默认路径大致是:

git diff → 过滤 → 语义分组 → 每组并发子任务
  (可选 Plan → Main tool-use → Filter)→ 行号解析 → text/json/sarif

输入可以是工作区(staged + unstaged + untracked)、分支区间(merge-base)、或单个 commit。没有向量 RAG:上下文来自入参里的 diff/规则,以及 agent 按需调用的 file_read / code_search 等。

评论定位也不信模型直接报行号:模型给 existing_code 片段,Go 按 本文件匹配 → 跨文件重挂 → 必要时再调 RE_LOCATION 钉位置。

为什么这样拆: 覆盖和定位必须可复现;判断可以动态。分组 + 并发是为了大变更时分治,避免一个超长上下文里模型偷懒。


Go 侧到底干什么

是什么: Agent.Run(internal/agent)是总控:取 diff、过滤、分派;真正对话循环在 internal/llmloop——发请求、解析 tool call、Go 执行工具、结果回灌,直到 task_done 或预算耗尽。工具实现在 internal/tool,定位在 internal/diff。

为什么要强调这点: 读代码时容易把整个仓库当成「一个大 prompt」。实际上下判断的只有 LLM;能不能审到、钉在哪一行、哪条评论被删,是工程逻辑。

go.mod 里没有 LangChain / Agent SDK。所谓 agent 就是自研的 tool-use 循环;「每个文件组一个 sub-agent」= 隔离的 goroutine + 消息历史,不是多 agent 框架。


怎么用自带 Agent

是什么: 默认模式 = 给 OCR 配 LLM,然后跑它自己的审查 agent。

ocr config provider
ocr config model
ocr review                          # 工作区
ocr review --from main --to feature
ocr review --commit abc123

为什么要先配 key: 这条路径会真正调用 loadLLMRuntime → agent.New → ag.Run。官方 AACR-Bench 上的数字,测的也是这条路径,不是委托。


委托模式:另一条命令,不是同款效果

是什么: ocr delegate 在 OCR 端 不调任何 LLM。只做两件事:

  1. ocr delegate preview — 复用同一套选文件/过滤(agent.Preview),输出可审文件 + mode/merge_base
  2. ocr delegate rule <paths...> — 解析规则并按内容分组

宿主(Cursor / Claude / Codex)按 Skill 剧本:拿列表 → 拿规则 → 自己 git diff → 自己审 → 自己报覆盖率。

为什么要有它: 订阅制编码 Agent 已经付过模型钱,想复用额度、不想再给 OCR 配一份 API Key。OCR 只当「审前工程官」。

确定性还在吗? 在,但 只剩审前半截(过滤 + 规则)。分组并发、plan/main/filter、评论定位链、Agent.Run 整段 不跑。Skill 是给宿主看的说明书,不是 OCR 内部又起了一个 agent。


两边代码怎么写(对照)

根命令并列:reviewCmd 与 delegateCmd。前半共用 loadCommonContext、exclude、ref 校验;后面彻底分叉。

默认 ocr review 委托 ocr delegate
入口 review_cmd.go delegate_cmd.go
LLM loadLLMRuntime 必装 无
核心调用 agent.New → ag.Run Preview + GroupRules
产出 结构化评论 规格 JSON/Markdown,宿主接着审

Preview 的注释写得很直白:只加载 diff、跑过滤,不派 LLM,不建 session/runner。internal/delegate 包注释同样写明:只生成 review spec。

所以从实现上看,二者从来就不是「同一条流水线换个开关」。


效果一样吗?官方比过吗?

结论:不一样;官方也没有把二者对打。

官方有的是 OCR(ocr review)vs 通用 Agent(Claude Code / Codex) 在 AACR-Bench 上的对比:同模型下 OCR 更高 Precision/F1、更少 token,召回更低。站点数据里 source 字段只有这几类,没有 Delegation。

从代码也能推出不该默认等价:delegate 缺少定位、过滤、强制分组那些质量管线;审得好不好取决于宿主模型是否老实按 Skill 覆盖每个文件。

场景 选
要质量、CI、可复现 ocr review
本地顺手、不想配 OCR Key ocr delegate

别把「都能审代码」理解成「效果一个样」——仓库里已经用两条命令、两套实现写清楚了。