同样一段改动,让写它的 Agent 自己复查,往往会轻轻放过;换另一个厂商的 CLI 来审,结论就未必一样了。cc-pair 把 Claude Code 和 Codex 配成一对互审搭档:一个写代码、另一个评审,通过编号消息文件来回几轮,直到评审方给出 approve,或达到轮次上限把问题交还给人。角色是对称的,整条评审线程都落在本地磁盘上,随时能翻出来看。本教程六步走完:安装与前置、初始化与沙箱授权、手动模式跑通一轮、自动模式与参数、唤醒 Codex、轮次上限与排障,全部命令来自官方 README 与 DESIGN.md。
一、先看懂它的三个概念
cc-pair 不引入新模型、不搭服务,只约定了一套「用文件当消息队列」的协议:
| 概念 | 落盘位置 / 含义 |
|---|---|
| Channel(通道) | ~/.pair/<repo>-<hash>/,每个 git worktree 独立一条,可用 PAIR_HOME 改根 |
| Lane(方向) | claude-to-codex/ 或 codex-to-claude/,由作者方命名 |
| Thread(线程) | 一次评审,编号消息:request → review → response → review,评审方 approve 即关闭 |
一次手动模式的线程长这样(自动模式由 pair 自己每轮拉起评审方):
终端 A: claude 终端 B: codex("be my reviewer")
完成任务
pair send request --> ~/.pair/<repo>-<hash>/claude-to-codex/<thread>/001-request.md
pair wait ⏳ pair wait <-- 取走
002-review.md <-- pair send review --verdict changes
核实意见、修复
pair send response --> 003-response.md
pair wait ⏳ pair wait <-- 复查修复
004-review.md <-- pair send review --verdict approve
done ✓
作者自己注明前提未经实测:「Agent 审自己的活会放水」是经验性判断(anecdotal),不是基准结论。另外项目以 Unlicense 发布、自动模式仅支持 macOS 与 Linux;Windows 请直接用手动模式,官方明确写了这条路线。别把互审当成测试或安全审计的替代品,它只是多一双眼睛。
Step 1:安装与前置检查
# 检查 Node 版本,需要 22 或更高
node --version
# 全局安装(包名与命令名不同,命令叫 pair)
npm install -g claude-codex-pair
# 确认命令可用
pair --help
# 两个 CLI 都要装好并已登录
claude --version
codex --version
想改源码就从仓库装:git clone 后 npm install && npm link。官方要求两个 Agent 的沙箱都必须能写通道根目录,这是下一步要解决的事。
--claude PATH / --codex PATH 可以指定可执行文件绝对路径;不给就取 PATH 里找到的开头那个。机器上装了多版本 CLI 时,显式指定能省掉很多「明明登录了却说没登录」的排查。Step 2:pair init 与沙箱写授权
cd /path/to/your-repo
pair init
pair init 会打印带真实路径的配置片段。默认通道根是 ~/.pair,对应两处授权:
# ~/.codex/config.toml
[sandbox_workspace_write]
writable_roots = ["/Users/you/.pair"]
# ~/.claude/settings.json
"sandbox": { "filesystem": { "allowWrite": ["~/.pair"] } }
它还会在工作区写入双方要读的说明:.claude/skills/pair/SKILL.md 给 Claude Code,一段带标记的章节写进 AGENTS.md 给 Codex(这段标记会告诉「非 Codex 的 Agent」忽略它)。pair start 在会话运行处发现缺失会自动补写;手动模式则要自己在每个工作区跑一次 pair init。
初始化前已开着的 Agent 会话要重启,否则读不到新写入的说明文件。另外 Codex 桌面版给每个会话单独沙箱,可能不应用 writable_roots:这时要么批准它在沙箱外执行 pair 命令,要么在客户端允许该会话写通道根。密钥安全方面,本教程不接触任何 API Key;两个 CLI 用的是你已有的登录凭据,不要把令牌写进 AGENTS.md 或提交到仓库。
Step 3:手动模式跑通一轮互审(Windows 可用)
分别在同一个工作区启动两个 CLI。评审方先说「be my reviewer」,作者方完成任务后说「ask codex for a review」(作者是 Codex 就反过来)。底层落的命令是:
# 作者方:发出评审请求并等待
pair send request
pair wait --as claude
# 评审方:取走请求,给出「需要修改」的裁定
pair wait --as codex
pair send review --verdict changes
# 作者方:核实每条意见,修复或带着理由驳回,再回一条响应
pair send response
pair wait --as claude
# 评审方:复查修复,通过
pair wait --as codex
pair send review --verdict approve
预期效果:通道目录下出现 001-request.md → 002-review.md → 003-response.md → 004-review.md 四个编号文件,评审通过时线程关闭。这些是纯文本,可以直接用编辑器打开核对「到底提了哪几条、作者如何回应」。
自动模式在 Windows 不可用,官方写明 macOS / Linux 才支持 pair start。Windows 就按本步的手动模式跑,协议与落盘格式完全一致,只是两个终端由你自己开。
Step 4:自动模式与常用参数(macOS / Linux)
# 交互作者是 Claude,每轮自动拉起 Codex 当评审
pair start --as claude
# 反过来:Codex 写、Claude 审
pair start --as codex
# 带参数的完整例子:独立 worktree、高推理档、作者侧传模型
pair start --as claude --worktree feature/login --reviewer-effort high -- --model opus
pair start --as codex --reviewer-model opus --reviewer-args="--max-budget-usd 2"
# 无人值守跳过确认
pair start --as claude -y
# 从另一终端查看与控制
pair status
pair ps -v
pair stop
pair start 必须在你自己的终端里跑,不能套在某个 Agent 会话内部。启动前它会打印会话运行位置、作者对话、评审方设置、是否要跑 init,然后等你按 Enter;输入其它内容、Ctrl-C 或输入结束都会取消且什么都不会启动,-y 才跳过这步确认。
| 参数 | 默认 / 作用 |
|---|---|
| --worktree NAME | 默认当前工作区;在 ../<repo>-NAME 建 git worktree,斜杠转横线 |
| --reviewer-effort | Codex: none / minimal / low / medium / high / xhigh / max / ultra;Claude: low / medium / high / xhigh / max / ultracode |
| --reviewer-model | CLI 默认;Codex 的模型 ID 区分大小写 |
| --timeout SECONDS | 900,最大 86400;只约束单轮评审,作者侧不限时 |
| --grace SECONDS | 2,最大 30;终止到强杀之间的等待 |
| --resume | 复用该 worktree 记录的上一次作者对话,仅对话、其余参数重新给 |
工作区隔离是硬约束:作者与评审方必须在同一个 worktree,评审方要读作者刚改的文件;不同 worktree 各有独立通道,彼此看不到消息。另外作者拿到的是终端流但没有控制终端,需要 /dev/tty 的程序以及 Ctrl+Z 在自动模式下不可用。若所有监督进程被强杀,可能留下 stale socket,pair status 会点名,需人工检查后删除。
Step 5:唤醒 Codex(手动模式的通知链路)
手动模式下 Codex 结束一轮后不会被后台命令自动唤醒,而让模型反复轮询 pair wait 又每一次都要花一次模型调用。cc-pair 的做法是注册一个 MCP 服务器,消息到达时由它把 Codex 叫起来:
# pair init 会打印带真实路径的这条命令
codex mcp add --env 'PAIR_CODEX=/opt/homebrew/bin/codex' pair -- '/path/to/node_modules/claude-codex-pair/dist/pair.js' mcp
# 之后 Codex 会注册并调用 pair_listen;消息到达时服务器用固定提示执行 codex queue
# 查看注册与最近事件
pair status
几个官方明确的条件:PAIR_CODEX 用来钉死 codex 可执行文件(服务器跑在沙箱外、不搜 PATH);命令应指向已安装的包而非你会随时修改的源码检出;pair_listen 需要 MCP 工具审批,never 策略不支持,用 on-request 时批准头一次调用即可。Codex 只给 MCP 服务器传很少的环境变量,PAIR_HOME 与 XDG_STATE_HOME 若设置过,改动后要 codex mcp remove pair 再重新添加。服务器只写一个日志:~/.local/state/pair/<repo>-<hash>/codex.listen.log,256 KB 轮转。
通知会在注销后停止:说「stop as reviewer」触发 pair unregister,或 Codex 后台服务在最后一个窗口关闭约 1–2 分钟后卸载会话,通知就停了;这个空档里到达的消息仍会起一轮但没有窗口附着。没有这个服务器时,Codex 只检查一次、说明自己无法被唤醒,之后要你说「check pair」才再查。这是通知链路的边界,不是评审协议失败。
Step 6:轮次上限、环境变量与收口
线程在评审方 approve 时关闭;若 PAIR_MAX_ROUNDS 轮之后还有未关闭的意见,线程会被升级(escalate),双方停下并把问题交给用户。默认 3 轮。
# 会话级覆盖(macOS / Linux)
PAIR_MAX_ROUNDS=5 pair start --as claude
# 常用环境变量一览
# PAIR_HOME ~/.pair 通道根,相对路径按 worktree 根解析
# PAIR_AGENT 无 作为 --as 的默认值
# PAIR_KEEP 100 保留已完成线程数;all 全留,0 不留
# PAIR_NO_UPDATE_CHECK 未设置 任意值即关闭 npm 版本检查
# PAIR_AUTO_SOCKET_DIR /tmp/pair-auto-<uid> 自动模式 socket 目录,保持短路径
# 停掉作者、评审方及其工具
pair stop
# 手动模式里已注册的 Codex 会话会阻塞 pair start,先注销
pair unregister
预期效果:正常路径以 004-review.md 的 approve 收尾;分歧路径在第 3 轮后双方停下、向你提问。可以用 pair status 看通道、自动会话状态、作者对话、最近一次失败与日志位置,用 pair ps -v 看按工作区列出的完整进程命令。
它是协作协议,不是质量证明。官方 DESIGN.md 专门列了监督与已知限制:评审方起不来、没给裁定或超时,请求会保留,错误里附上评审方自己的消息,作者可用 pair wait --as <author> 以相同设置重试该轮;要改评审模型或推理档,得 pair stop 后重新 pair start(--resume 可保留作者对话)。把产出照常过 CI 与人工评审,别因为「另一个 Agent 批了」就跳过。
--worktree NAME 为每个特性开独立工作区,多个 pair 会话可以并行且互不串消息;pair status 会给出一条「cd 到该 worktree 并 resume 对话」的可复制命令,中断后接着审很方便。常见问题速查
| 现象 | 大概率原因与处理 |
|---|---|
| pair 命令找不到 | 包名是 claude-codex-pair、命令是 pair;确认 Node 22+ 且全局 bin 目录在 PATH 里 |
| 写通道被拒 | 两个 Agent 的沙箱都要允许写 ~/.pair;按 pair init 打印的片段配置并重启会话 |
| Windows 上 pair start 不可用 | 官方仅支持 macOS / Linux;改用 Step 3 的手动模式 |
| 评审方一直不醒 | 检查 MCP 服务器是否注册、pair_listen 是否获批、PAIR_CODEX 路径是否有效 |
| 某轮卡住不动 | 评审方超时或没给裁定;用 pair status 看失败原因,再 pair wait --as <author> 重试 |
| 反复三轮仍不通过 | 设计如此,线程升级给人;把意见带到人工评审,不要无限调大 PAIR_MAX_ROUNDS |