双模型交叉审查:用明确裁决把住合并关
作者让 Claude Code 与 Codex 分别承担编码和审查,基于独立 worktree 与已提交代码开展交叉检查。审查必须输出明确裁决,崩溃、缺少裁决或编码模型自行批准均无法通过合并检查,新提交还需重新审查。
AI 深度解读
让 Claude Code 写代码,再让 Codex 审查,真正需要设计的不是调用顺序,而是审查失败后怎么办。作者给出的答案很明确:审查必须针对已提交的代码,必须输出固定结论,进程崩溃、结论缺失都算失败,写代码的引擎也不能给自己的提交签发通过凭证。
这套流程值得程序员参考的地方,在于它把 AI 审查接进了可检查的合并条件。不过,双引擎是否比单引擎更可靠,原文没有对照数据;能直接借鉴的是流程约束,效果仍要自己验证。
先固定提交,再谈谁写谁审
作者默认让 Claude Code 写、Codex 审。理由是写代码需要持续积累计划、文件修改和测试上下文,审查则主要依赖 diff 与项目规则。两款来自不同公司的引擎可能有不同盲区,这是他的选择依据,并非经过量化验证的结论。
写入端用 claude -w feature-auth 启动独立 git worktree,位置在 <repo>/.claude/worktrees/<name>。worktree 可以理解为同一仓库的另一个工作目录,让写代码的修改避开审查使用的检出目录。
作者要求每完成一项修改就提交并停止,审查只针对 commit,不针对尚未提交的编辑。这样,发现、结论和测试结果才能对应同一个确定版本。
Codex 的审查调用如下,解决的是无人值守执行、限制写入和保存结论的问题:
codex exec -s read-only -c model_reasoning_effort=high \
--color never --output-last-message .ai/last-review.md \
- < review-prompt.md
要看清 --output-last-message 这一行:后续脚本从 .ai/last-review.md 读取最终消息,不从运行日志里寻找结论。末尾的 - 表示从标准输入接收提示词;-c 覆盖本次运行的配置,这里把 model_reasoning_effort 设为 high,而作者的 Two Engines Kit 默认用更高一级的 xhigh。
按原文描述,codex exec 默认就是只读沙箱,显式写出 -s read-only 是为了让约束可见。但沙箱之外还有通道:如果 ~/.codex/config.toml 中的 MCP server 能修改外部系统,审查时应在对应配置表设置 enabled = false。
固定结论行,是为了让失败不能混成通过
作者要求审查的最后一行只能是 Verdict: ACCEPT 或 Verdict: CHANGES REQUIRED。这不是排版偏好,而是给脚本一个明确的判定入口。
没有明确完成的审查,不能被当成通过。
脚本还检查 Codex 是否以退出码 0 结束,以及审查后检出目录是否保持不变。崩溃或缺少结论行都判失败,结果按被审 commit 的哈希保存,新提交不能沿用旧提交的 ACCEPT。
审查内容也有格式约束:每条发现必须包含严重程度、文件与行号,以及具体失败场景。严重程度分为 blocker、should-fix、nit;前两类必须有具体、可复现的失败,风格偏好只能算 nit。整份审查控制在 600 个英文单词以内,并要求第一轮一次列全问题。
固定格式能检查,第一轮是否真的找全却无法靠提示词保证。这里应把它理解为减少审查反复的目标。
作者的免费门禁 two-engines-gate 还检查两件事:通过结论不能来自写代码的同一引擎,测试通过记录必须属于获得 ACCEPT 的那个提交。AI 审查没有替代测试,也不能替另一个版本的代码背书。
每条意见都要回应,但不必照单全改
作者要求写入端逐条处理发现:要么在新提交中修复,要么提供证据反驳。证据可以是通过的测试、证明已有处理逻辑的文件与行号,或与审查结论矛盾的命令输出。
这条规则很实用。审查模型也会误判,为不存在的问题加补丁,同样可能引入风险。
轮次规则则限制了讨论范围:第 1 轮列全问题,第 2 轮确认修复落地,第 3 轮起只有 blocker 和安全问题阻止合并,nit 放进后续事项文件。新提交仍需重新审查。
角色也可以交换。设置 BUILDER=codex 后,由 Codex 写、Claude Code 审;Codex 写入端使用 codex exec --sandbox workspace-write - < task.md。Claude Code 审查端的限制如下:
claude -p "Do the review described on standard input." --restricted --strict-mcp-config \
--permission-mode dontAsk --tools "Read,Grep,Glob" --allowedTools "Read,Grep,Glob" \
--disallowedTools "Bash,Edit,MultiEdit,Write,NotebookEdit,WebFetch,WebSearch,Task,Agent"
要注意 --tools "Read,Grep,Glob":这里只开放读取与搜索,连 git 命令也不能执行,所以门禁必须把提交信息和完整 diff 放进提示词。按原文说明,--strict-mcp-config 在未提供 MCP 配置时不加载 MCP server,dontAsk 则拒绝原本需要请求批准的操作。
两端还要共享规则。Claude Code 读取 CLAUDE.md,Codex 读取 AGENTS.md,其中都写上:每次修改后提交并停止、审查保持只读、不碰审查记录目录。由于 Codex 的 project_doc_max_bytes 限制加载字节数,关键规则应保持简短,长参考资料另放。
我的判断
我更认可这里的提交绑定、失败判定和证据回应机制。相比让同一个模型写完后自查,它增加了一个独立审查入口;相比人工复制 diff、阅读自然语言结论,它更容易接入脚本并追溯记录。
但「不同公司模型的盲区不同」仍是经验判断。原文没有提供缺陷检出率、误报率、耗时或成本对比,也没有证明 xhigh 比 high 更划算。作者说明这是自己项目在用的方案,不能据此推断一般团队也会获得同样收益。
第 3 轮起缩小阻塞范围,也有取舍:它能抑制无限打磨,却可能让仍未解决的 should-fix 不再阻止合并。团队采用前,需要明确这种风险是否可接受。
此外,只读权限解决的是修改边界,不是理解能力。作者自己也承认,审查只能覆盖交给它的 diff;缺失的业务上下文不会因为结论格式严格就自动补齐。
能拿来做什么
- 给日常 AI 编程建立最小闭环:完成修改后提交,针对该 commit 审查,并把退出码、固定结论行和提交哈希一起记录。
- 在前端或 Node 项目中,把现有测试绑定到同一个提交;出现新提交后,重新获取测试与审查结果,避免复用旧的通过记录。
- 要求审查意见写出文件、行号和可复现失败场景,同时允许写入端用测试或代码证据反驳,减少被误报带偏的修改。
- 先借鉴权限限制与记录机制,再评估是否需要双引擎和更高推理强度。原文没有给出收益对照,具体投入应由自己项目中的有效发现决定。