把 Codex Review 做成一项服务
原创 · 约 20 分钟阅读 · 阅读 --

把 Codex Review 做成一项服务

作者: Alex Xiang


AI 写代码越来越常见之后,AI 做代码 Review 几乎是顺理成章的下一步。

但真正跑起来之后会发现,问题并不是“模型能不能看懂 diff”。模型当然能看,尤其是对边界条件、异常处理、测试缺口、接口兼容性、明显的逻辑错误,它的第一轮筛查很有价值。真正麻烦的是另一件事:怎样把 AI Review 变成一条稳定、可控、成本可预期的工程流程。

如果每次都让一个通用 Agent 临场决定怎么拉代码、怎么读 PR、怎么评论、怎么 approve,刚开始会显得很灵活,过一阵子就会变成另一种不确定性来源。

这篇文章记录一次把 Codex Review 从“能跑”改造成“一项服务”的过程。

先看别人怎么做

GitHub 上已经有不少 AI Review 的实践。比较典型的是 Google 的 run-gemini-cli GitHub Action。它可以在 GitHub 工作流中调用 Gemini CLI,对 PR 做 Review、Issue Triage,也可以通过 PR 评论里的指令手动触发。

这种形态很自然:开发者提 PR,Action 读取 diff 和仓库上下文,生成 Review 评论,需要时给出修改建议。对使用者来说,它就像一个住在 GitHub 里的代码审查助手。

这类方案的优点很清楚:

  • 入口在 GitHub,符合开发者习惯。
  • 自动触发和手动触发都比较自然。
  • Review 结果直接留在 PR 里,便于后续讨论。
  • 不需要自己维护太多基础设施。

但它也有一个现实问题:外部服务的策略、额度和成本不是自己能完全控制的。今天可用的免费额度,明天可能变成限量试用;今天适合个人项目的定价,放到团队持续使用时可能就要重新估算。

所以,如果 Code Review 已经成为团队日常流程的一部分,就不能只把它当成一个外部工具调用。它需要变成内部可控的服务。

目标不是“把 Gemini 换成 Codex”

一开始很容易把需求理解成:原来用 Gemini Review,现在换成 Codex Review。

这其实只说对了一半。

模型只是其中一个环节。真正要建设的是一套 Review 工作流:

  • 什么时候触发 Review。
  • 谁可以触发。
  • Review 哪个 PR。
  • 是否默认 approve。
  • 评论写在哪里。
  • 失败时如何反馈。
  • 历史记录在哪里查。
  • 成本如何统计。
  • 同一个 PR 重复 Review 时怎么处理。
  • 不同仓库是否可以用不同规则。

这些问题都不能交给模型每次自由发挥。模型应该负责“读代码和发现问题”,而不是负责“组织整条工程流程”。

因此目标变成了:用 Codex 负责代码理解,用确定性的服务负责流程编排。

第一版:开发机定时扫 PR

最早的版本很直接:找一台开发机,安装 Codex 和 GitHub CLI,写一个定时任务,每分钟扫描一次目标仓库里 open 状态的 PR。

如果发现某个 PR 还没有 approve,就自动触发 Codex Review,把结果评论回 GitHub。

这版最大的优点是快。

不用改 GitHub,不用做 Web 页面,不用做飞书交互。PR 打开以后,后台迟早会扫到。对开发者来说,像是多了一个自动工作的审查员。

但跑了一段时间,问题也很明显。

第一,token 消耗不可控。

定时任务只知道“PR 是 open,且还没有 approve”,却不知道这个 PR 是否真的需要 AI Review。小改动、临时 PR、草稿 PR、重复提交,都会进入扫描范围。模型要读上下文、读 diff、生成结论,这些都是成本。

第二,用户没有表达意图的入口。

开发者不能方便地说:

  • 这个 PR 先不要 Review。
  • 这个 PR 重点看兼容性。
  • 这个 PR 只看测试。
  • 这个 PR 修改后重新 Review 一次。

所有策略都写死在定时任务里。

第三,状态不可见。

任务跑到哪一步了?GitHub 认证是否过期?仓库 clone 是否失败?Codex 是否超时?评论是否已经发出?approve 是否成功?

这些问题只能去开发机或 GitHub 上翻,很难让普通使用者直接理解。

第一版证明了 Codex 可以做 PR Review,但也证明了“全仓库自动轮询”不是一个好的长期形态。

第二版:从聊天入口触发

第二版把入口放到聊天工具里。

思路是:开发者在聊天里发送 PR 地址,请机器人帮忙 Review。机器人理解消息内容,解析 PR 链接,再调用 Codex Review 能力。

这比定时轮询前进了一步。用户终于可以主动触发 Review,而不是等后台扫描。也可以在聊天窗口里看到执行结果,使用门槛比命令行低得多。

但这版很快暴露出另一个问题:链路太长。

一次 Review 请求进来后,先要经过聊天机器人。机器人需要理解自然语言,再决定调用哪个能力,再把参数转换成具体命令。用户可能写:

  • 帮我看一下这个 PR。
  • review 这个链接。
  • approve 一下。
  • 跑一下 Codex。
  • 这个 PR 看看有没有问题。

这些表达都很自然,但对后面的程序来说并不是稳定协议。机器人如果把命令拼错、参数名写错、字段对不上,第一次执行就会失败。失败以后再让 Agent 自动修复,链路就更不可控。

实际使用中会遇到几类问题:

  • Review 命令参数拼错。
  • Skill 或 Tool 的字段名和真实接口不一致。
  • GitHub clone 或认证失败时,错误信息被多层转述,用户看不出问题在哪。
  • 实时回复看起来很慢,像是在一个字一个字吐结果。
  • 很难确认最终动作到底来自指定 Review 能力,还是 Agent 中途改用了别的工具。
  • GitHub 评论结构不稳定,有时建议区域排版很难看。

这说明一件事:代码 Review 是确定性很强的工程任务,不应该把核心流程完全交给通用 Agent 临场组织。

Agent 可以理解用户意图,也可以理解代码;但拉取 PR、执行命令、格式化评论、approve、记录历史、恢复失败,这些步骤应该由普通程序接管。

第三版:做成独立服务

当前更合适的形态,是把 Review 做成一个独立服务。

它不再依赖“某个 Agent 这次是否理解对了”,而是提供清晰的命令协议。聊天入口、Web 页面、命令行入口都只是入口,真正的 Review 流程由服务负责。

服务需要做几件事:

  • 接收命令。
  • 解析 PR URL。
  • 检查 GitHub 认证。
  • 准备本地仓库。
  • 调用 Codex。
  • 整理输出。
  • 评论 GitHub PR。
  • 按策略 approve。
  • 记录历史。
  • 把结果反馈给用户。

这样以后,即使入口换了,核心流程也不变。

命令协议

服务可以支持一组很小的命令:

/review pr_url [approve=true]
/run message
/status
/history [limit]
/help [command]

/review 是核心能力,用于审查 GitHub PR。

/run 用于执行普通 Codex 任务,例如总结某个工作区、分析一段日志、解释一个文件。为了降低使用门槛,普通文本可以默认等同于 /run message

/status 用来查看服务状态和正在执行的任务。

/history 用来查看最近执行历史。

/help 用来告诉使用者当前支持哪些命令。

群聊里还应该有一条基本规则:只有 @ 机器人时才处理消息。否则群里任何一句“帮我看一下”都有可能被误当成命令。

Review 主流程

服务收到 /review 后,流程应该是确定的:

  1. 解析 PR URL,得到 owner、repo 和 PR number。
  2. 检查 GitHub CLI 认证,必要时执行 gh auth setup-git
  3. 克隆或更新目标仓库,切换到 PR 对应分支。
  4. 获取 base 分支和 PR diff。
  5. 调用 Codex 执行代码 Review。
  6. 将 Review 输出整理成统一格式。
  7. 在 GitHub PR 下发布评论。
  8. 按策略执行 approve。
  9. 将命令、状态、输出、错误写入历史记录。
  10. 把结果回复到触发入口。

这里最重要的是职责拆分。

Codex 只负责代码理解和问题发现。GitHub CLI 负责 PR、评论和 approve。聊天工具和 Web 页面负责入口和反馈。服务自己负责命令协议、状态、历史、格式化和策略。

把这些边界拆清楚以后,系统才容易稳定。

Review 评论不应该原样贴模型输出

很多 AI Review 的第一版,都会直接把模型输出贴到 PR 评论里。

这能用,但不好用。

一个真正可用的 Review 评论,应该像一个产品功能,而不是模型的一段长回答。

比较理想的结构是:

  • 顶部先给结论:可以合并、需要关注、存在阻塞问题。
  • 明确 approve 状态:是否已自动 approve,没 approve 的原因是什么。
  • 问题按严重程度分组:阻塞、高、中、低、建议。
  • 每个问题都包含位置、原因、影响和修改建议。
  • 如果建议涉及代码变更,尽量用 diff 展示。
  • 避免大段无结构文字。

比如评论可以长成这样:

## Codex Review

结论:需要关注,但未发现阻塞性问题。

Approve:已自动 approve。

### 中风险

1. `src/api/user.ts:87`
   - 问题:异常分支没有释放连接。
   - 影响:高并发下可能导致连接池耗尽。
   - 建议:把释放逻辑移动到 `finally`

### 建议

1. `tests/user.test.ts`
   - 建议补充 token 过期场景。

模型可以生成原始判断,但最终评论最好由服务统一组装。这样团队可以逐步优化评论模板,而不是每次都看模型随机发挥。

默认 approve 也要成为策略

当前可以先采用简单策略:Review 完成后默认 approve。

这听起来有点激进,但在很多内部流程里是合理的。因为第一阶段的目标不是让 AI 代替人做最终责任判断,而是让它帮助 PR 快速进入可合并状态,同时把风险点留在评论里。

但这件事必须是一个明确策略,而不是模型自己决定。

后续可以逐步改成:

  • 没有阻塞性问题才 approve。
  • draft PR 不 approve。
  • CI 未通过不 approve。
  • 某些仓库默认不 approve。
  • 涉及安全或计费模块时只评论不 approve。

这些都应该放在配置里,而不是写进 prompt 里让模型每次理解。

为什么服务化比 Agent 转发更稳

把 Review 做成服务以后,收益很明显。

第一,成本更可控。

只有明确触发的 PR 才会 Review,不再全仓库轮询。后续还可以按仓库、PR 大小、文件类型、标签做过滤。

第二,状态更清楚。

每个任务都有状态:queued、running、success、failed。失败原因可以直接保留原始错误,不需要通过多层 Agent 转述。

第三,历史可追溯。

什么时候谁触发了哪个 PR,模型输出了什么,是否评论成功,是否 approve,耗时多久,都可以查。

第四,入口可以变化。

今天是聊天工具,明天可以是 Web UI,后天可以是 GitHub comment command。入口变了,核心流程不用变。

第五,Review 质量更容易迭代。

评论模板、严重程度分类、默认 approve 策略、幂等更新逻辑,都可以在普通代码里迭代,不必每次重写 prompt。

一个实用的能力清单

一个能长期使用的 Codex Review 服务,至少应该具备这些能力:

能力作用
聊天入口让开发者不用离开日常沟通工具
Web UI查看历史、状态、详情和错误
GitHub PR 评论保留团队原有 Review 工作流
自动 approve支持轻量化合并流程
历史记录方便追踪任务和排查问题
队列控制避免多个大 PR 同时压垮开发机
失败反馈让用户知道是认证、网络、clone 还是 Codex 超时
配置化策略不同仓库使用不同 Review 和 approve 规则
评论幂等重复 Review 时更新旧评论,减少 PR 噪音
token 统计按仓库、PR、日期估算成本

这些能力看起来不像“AI”,但它们决定了 AI Review 能不能长期跑。

后续可以继续做什么

第一,统计 token 消耗。

按 PR、仓库、日期统计 Codex 消耗,才能知道哪些 Review 最贵,哪些仓库需要过滤,哪些 prompt 需要压缩。

第二,做评论幂等更新。

同一个 PR 的 Codex 评论,最好优先更新旧评论,而不是每次新增一条。否则一个 PR 多次 push 后,评论区会很快变乱。

第三,按仓库配置规则。

例如:

  • 文档仓库只做轻量检查。
  • 后端仓库重点看事务、异常和兼容性。
  • 前端仓库重点看状态管理、交互边界和可访问性。
  • 安全相关仓库只评论不 approve。

第四,支持 Review 模板。

不同团队关注点不一样。有的团队更关心测试,有的更关心性能,有的更关心接口兼容。模板应该配置化,而不是都塞在同一个 prompt 里。

第五,把结果做成更友好的消息卡片。

聊天工具里的回复不需要贴完整 Review。可以只展示状态、PR 链接、approve 结果、问题数量和失败原因,完整内容留在 GitHub PR 和 Web UI 里。

结论

AI Code Review 的关键不是“让哪个 Agent 更聪明”,而是把工程流程拆清楚。

Codex 适合读代码、找问题、解释风险。GitHub CLI 适合处理 PR、评论和 approve。聊天工具和 Web UI 适合做入口和反馈。服务本身负责协议、状态、历史、格式化、配置和策略。

当这些职责拆开以后,AI Review 才会从一次性的演示,变成可以长期使用的团队基础设施。

这也是我现在更推荐的方向:不要让通用 Agent 承载整个 Review 流程,而是把 Codex Review 做成一项服务。

参考资料