学习精选 · AI 工具
Codex

让 Claude Code 写、Codex 审:一套可照做的 review gate 搭建经验

DEV Community2026-11-04约 6 分钟读完AI 整理查看原文

作者把写代码交给 Claude Code、把审查交给只读模式下的 Codex,再用三个 bash 脚本把「测试通过」和「审查 ACCEPT」绑定到具体 commit 上,没有这两样就不许合并。文中记录了只读沙箱被 MCP 和 hook 破坏、测试命令被悄悄收窄仍能通过等真实踩坑,并给出可复现的验证方法。

今天就能做

  • 在自己的仓库里先跑一遍最小闭环:写代码 → 只读审查出 verdict → 测试出 pass 记录 → merge-check 拒绝无证据的 commit。
  • 审查前把 ~/.codex/config.toml 里能改外部状态的 MCP server 设 enabled = false,并检查有没有 Stop hook 会吞掉最终 verdict。
  • 给 gate 设 GATE_COUNT_RE 和 GATE_MIN_TESTS,并养成看 pass 记录里 Command: 行的习惯,防止测试命令被悄悄收窄。

先分工:谁写、谁审

  • Claude Code 在自己的 git worktree 里写代码,Codex 只读审查,最后一条消息必须以单行 Verdict: ACCEPT 或 Verdict: CHANGES REQUIRED 开头,后面跟问题清单。
  • 把写作交给 Claude Code 是因为写作会堆积上下文(计划、brief、worktree、gate 日志);审查只需要 diff、规则和这次改动的目的。
  • 审查方永远不改代码,prompt 里明确写 You review; you never fix,每个问题描述到作者能在新 commit 里修,修完再走一次审查。
  • 角色可互换:脚本里设 BUILDER=codex 就变成 Codex 写、Claude Code 审。

让只读真的只读

  • Codex 的审查调用是 codex exec -s read-only --color never --output-last-message <file> -,沙箱允许读文件和跑 git diff 这类只读命令,不能写。
  • ~/.codex/config.toml 里配置的 MCP server 在审查时照样启动,能改动沙箱外东西的 server 要在审查期间设 enabled = false。
  • hook 也会在 codex exec 下运行:一个让 Codex 继续工作的 Stop hook 可能把最终消息替换成空,gate 找不到 verdict 直接 exit 1,只留诊断日志。
  • Claude Code 当审查方时只给 Read、Grep、Glob 三个工具,它跑不了 git,所以脚本要把 commit 和完整 diff 塞进 prompt。

共享规则要短

  • 两个引擎需要同一套规则,作者在 CLAUDE.md 和 AGENTS.md 各放一小段:写的一方一次只提交一个改动就停、不碰 .ai/ 目录、绝不合并;审的一方保持只读。
  • Codex 的指令文件累计到 project_doc_max_bytes(默认 32 KiB)就不再加载,规则写在超长 AGENTS.md 末尾可能根本到不了它手里。
  • 指令文件也是入口:两个引擎都会加载它们读到的文件,包括不是你写的文件,要检查本机到底加载了哪些。

证据必须绑定 commit

  • gate.sh 在干净 checkout 上跑测试命令,写一条以 commit 命名的 pass 记录;review.sh 把 commit 和 diff 发给另一个引擎,把 verdict 存到被审的 commit 名下。
  • merge-check.sh 只在当前 commit 同时有 pass 和 ACCEPT、且 ACCEPT 来自非 builder 的审查方时才放行。
  • 新 commit 从零开始,旧 commit 的 ACCEPT 覆盖不了没人审过的新代码。作者演示的例子里,sum.sh 漏掉第一个参数,测试只测 sum 0 4 恰好通过,审查要求修改,修复 commit 必须自己再拿一次 pass 和 ACCEPT。
  • 三个脚本都拒绝有未提交或未跟踪文件的 checkout,因为测试可能在一个没进 commit 的文件上通过;测试跑完还会再查一次,测试留下快照或构建产物也算失败。
  • 有个自指的坑:按说明把 .ai/ 加进 .gitignore,这个改动本身就是未提交变更,gate 第一个拒绝的就是你刚加的那行。

最大的坑:收窄的测试命令照样通过

  • gate 只认测试命令在干净 checkout 上 exit 0 且计数检查接受输出,它不知道项目本来有哪些测试。
  • Node 20.19 的例子里,add() 返回错误结果,GATE_CMD="node --test test/" 得到 FAIL;换成 GATE_CMD="node --test test/format.test.js" 就得到 PASS 并写下 pass 记录,add() 依然是错的。
  • 默认计数检查只拦空输出或汇总为零的情况,这里跑了一个测试所以放行;pass 记录里存了 Command: 行,但 merge-check.sh 不拿它做比对。
  • 缓解办法是设 GATE_COUNT_RE 和 GATE_MIN_TESTS(例如 '^# pass ([0-9]+)$' 配 2),加测试时要手动调大这个数,而且它只比总数、看不出跑了哪些测试。
  • 第二层是审查:prompt 要求审查方检查任何削弱既有检查的改动,但命令行里敲的命令不会出现在 diff 里,计数检查是唯一能看见它的东西。信任一条 pass 记录前,先读它的 Command: 行。

原文:How to use Claude Code and Codex together: setup lessons from my review gate

来源:DEV Community · 2026-11-04

查看原文

本文由 AI 阅读原文后整理,未经人工逐字核对,内容以原文为准。

登录后可以点赞、查看和发表评论