LZWcc's Blog

Back

我的开发方式是:Claude Code 跑在服务器上,项目代码、依赖、构建和测试都在 Mac 上,Claude Code 通过 ssh 操作 Mac。Codex CLI 也装在这台 Mac 上,额度一直用不完。

于是想换个分工:Claude Code 负责写计划和验收,Codex 负责写代码。 以前试过 Claude Code 的 Plan 模式,但每次都要手动把计划复制给 Codex,再把 Codex 的结果复制回来,太麻烦。

目标是:我只说一句「写好计划,让 Codex 执行」,Claude Code 就自动完成「派活 → 等待 → 验收 → 反馈 → 再执行」的循环,直到通过或者需要我拍板。

文末有一段完整的配置提示词,在新服务器的项目目录里打开 Claude Code,整段粘贴给它就能配好。

一、整体流程#

我:「写好计划,让 Codex 执行」
 └─ Claude Code:读代码,写计划和验收标准
     └─ ssh 到 Mac,用 nohup 独立运行 codex exec(计划从文件读入)
         (Claude Code 后台等待结果,结束时收到通知;Claude Code 中断了 Codex 也照常跑完)
     └─ 审查:逐个文件读 diff + 自己跑检查和测试,对照验收标准,结论记进运行目录
         ├─ 不通过 → codex exec resume <session id>,把必须改的问题发回去 → 再审查
         └─ 通过   → 做项目规定的收尾(构建、部署等),按固定格式汇报
     └─ 最多 3 轮还不通过,停下来问我
text

为什么能循环#

codex exec 看起来是一次性的:发一段提示、拿一段结果。但 Codex CLI 有 codex exec resume <SESSION_ID>,会接着同一个会话继续,前面读过的代码、跑过的命令它都记得。

实测(codex-cli 0.163.0):第一轮让 Codex 把文件改成打印 2 并运行;第二轮用 resume 发「把你刚才改的那个文件再改成打印 3,并告诉我上一轮看到的输出」,它改的是同一个文件,也答出了上一轮的输出 2。

循环由 Claude Code 驱动:Claude Code 这边始终是同一段对话,Codex 那边始终是同一个 session,每轮只补发一段反馈。

二、规则怎么放#

服务器上 Claude Code 的规则里写满了「先 ssh 到 Mac」「用 heredoc」「用 python 精确替换改代码」。这些对 Codex 是错的:Codex 就在 Mac 上,直接改文件就行。

解决办法不是写两套规则,而是按读者拆开。同一句「在仓库根目录运行 pnpm check」,Codex 读到直接执行;Claude Code 读到,按远程约定包一层 ssh 主机 bash -s 再执行。所以项目规则只要写成不提执行方式的中性写法,两边就能共用一份。

服务器可能多人共用,不一定能改 ~/.claude 下的用户级配置,所以 Claude Code 这边的东西全部放在项目级,也就是服务器上的项目目录里:

内容放在哪谁读
远程开发约定(ssh、heredoc、精确替换)+ Mac 主机和仓库路径服务器项目目录 CLAUDE.mdClaude Code
派活流程(写计划、启动、验收、续接、轮数上限)服务器项目目录 .claude/skills/codex-exec/SKILL.mdClaude Code
会话开始时读入 Mac 上的 AGENTS.md服务器项目目录 .claude/settings.json 的 SessionStart hookClaude Code
项目规则(版本、命令、测试、代码约定、禁忌)Mac 上仓库根目录的 AGENTS.md,唯一来源Codex 自动读;Claude Code 由 hook 读入
每次的计划、反馈、日志Mac 上 ~/.cache/cx-runs/<本次>/Codex / 留档

每个任务的运行目录记录了这个任务的全部状态:计划、每轮反馈、Codex 的事件流和总结、退出码、Claude 每轮的审查结论、最终汇报。几个作用:

  • Codex 的 session id 在 --json 事件流的第一行,续接要用。
  • Claude Code 只读 Codex 的最后一条回复(-o),不读整个事件流,省的是 Claude 的额度。
  • Claude Code 中断后,新会话靠这些文件判断任务进行到哪一步,接着往下做。

这些都不放进项目仓库,随时可以删。

三、配置提示词#

前提:服务器能免密 ssh 到 Mac,Mac 上已安装并登录 Codex CLI。

在服务器上进入项目目录(每个项目一个目录),启动 Claude Code,把下面整段粘贴进去。

它分两个阶段,以前没配过或配得不完整的项目也适用:

  1. 只读起草:检查环境,读已有的 CLAUDE.md 和 Mac 上的 AGENTS.md,把要写的内容全部起草好,连同改前改后的 diff、旧规则的去向、靠推测写的内容一起交给你审核,然后停下来。
  2. 批准后写入:你批准后才写,写之前先备份已有文件。你要求修改,它就改完再给你审核。

配置完退出重开 Claude Code,hook 和 skill 才会生效。

四、日常使用#

配置好之后,在服务器的项目目录里打开 Claude Code,用 /codex-exec 调用:

/codex-exec 给设置页加一个导出按钮
/codex-exec high 给设置页加一个导出按钮
/codex-exec gpt-6.1-sol high 给设置页加一个导出按钮
text

/codex-exec 后面的文字会整段交给 skill,不按位置切分。开头的模型名和思考强度都可以省略,顺序不限,剩下的就是需求。说「写好计划,让 Codex 用 high 执行」这样的自然语言也能触发,但要靠 Claude 自己判断该不该用这个 skill;/codex-exec 则一定会走这个流程。

三种用法:

用法怎么做会发生什么
直接执行/codex-exec [模型] [强度] 需求写计划 → Codex 执行 → 验收 → 不通过就续接,最多 3 轮 → 汇报。中间不停下来问你
先审计划先说「……,写计划给我看」,讨论定稿后 /codex-exec [模型] [强度] 按上面的计划执行用定稿的计划执行,不重写
继续改任务结束后说「让 Codex 按这些意见再改一下」续接同一个 Codex 会话,模型和思考强度不变
恢复中断/codex-exec 继续找到这个项目没结束的任务,从中断的那一步接着做

依据:Codex 按计划(目标、现状、步骤、不要做的、验收标准)和仓库的 AGENTS.md 干活。调用 /codex-exec 本身就表示同意直接执行。

审查和汇报#

每轮 Codex 跑完,Claude Code 都会审查:逐个文件读完整的 diff,按需求、正确性(边界情况、旧数据、失败路径)、范围、代码质量、测试(有没有靠删断言让测试通过)、安全(密钥、调试输出)几类检查,再自己跑一遍检查和测试,不采信 Codex 的自述。问题分成「必须改」和「建议改」:必须改的发回给 Codex 再改一轮;一两行的小问题 Claude 直接改;其余写进汇报。

汇报格式固定:结论(通过 / 未通过)、用的模型和轮数、每个文件改了什么、验证命令和结果、各轮发现的问题、Claude 直接改的、审查发现但没处理的、需要你确认或手动测试的。汇报同时存一份在运行目录的 report.md。

Claude Code 中断了怎么办#

Codex 在 Mac 上是独立运行的,Claude Code 停了(关掉终端、断网、服务器重启)它也会照常跑完。回来之后有两种接法:

  1. 恢复原来的对话:在项目目录运行 claude --continue(或者在 Claude Code 里用 /resume 选那段对话),然后说「继续」。对话的上下文都在,最顺。
  2. 开新会话:输入 /codex-exec 继续。Claude Code 会去 Mac 上找这个项目最近一个没结束的任务,读计划、每轮反馈和审查结论,判断进行到了哪一步:还在跑就接着等,跑完了就审查,审查完了就派下一轮或者汇报,Codex 中途被杀了就续接同一个 Codex 会话让它接着做。

实测:启动后马上断开 ssh,Codex 照常跑完;从另一个 ssh 连接能取到结果并续接第二轮;第二轮跑到一半把进程杀掉,能检测出「被中断」,第三轮续接后 Codex 先检查了工作区,再接着完成要求。

几点说明:

  • 不指定模型时,用 Mac 上 Codex 配置里的默认模型和思考强度。不管是不是你指定的,选定的值都会在第一轮记下来,之后每一轮都显式传同样的参数。这一步是必须的:实测(codex-cli 0.163.0)第一轮用 low,resume 时不带参数,第二轮就变成了配置里默认的 medium;带上参数后又回到 low。每一轮实际用的值都可以在 Codex 的会话记录里查到,skill 每轮都会核对。
  • 中途不换模型。 换了会让 Codex 的上下文缓存失效。如果你中途要求换,Claude Code 会先提醒你;要换就开一个新会话,把剩下的工作写成新计划。
  • Claude Code 自己用什么模型,照常用 /model 切换,和 Codex 用什么模型无关。
  • Codex 跑的时候 Claude Code 是空闲的,可以接着讨论别的,但不要让它改同一个仓库。
  • 每次运行的计划、反馈和日志都在 Mac 的 ~/.cache/cx-runs/ 里,想看 Codex 具体做了什么可以去翻。

Codex 运行时不会请示#

为了全自动,Codex 用的是 approval_policy=never 加 workspace-write 沙箱:执行任何命令前都不会问你,但写文件只限于仓库目录内(以及沙箱允许的临时目录)。这是全自动的代价。不放心的任务,先「写计划给我看」,审过再交给 Codex。

并行和冲突#

同一个仓库同时只允许一个进行中的任务。 两个任务同时改一个工作区,改动会互相覆盖;审查时 git diff 混着两个任务的改动,Claude 会把另一个任务的改动当成「计划外改动」让 Codex 撤销;测试结果也分不清是谁造成的。所以开新任务前,skill 会检查这个项目有没有没结束的任务,有就先问你:等它结束、接着做它,还是放弃它。不同项目之间互不影响,可以同时跑。

同时在 Mac 上手动用 Codex:

  • 不会读错 session。这套流程的 session id 只来自这次 codex exec 自己的输出,续接时指定 id,从不用「最近的会话」,核对模型时也只读带这个 id 的会话记录。你手动开的 Codex 会话和它互不相干。
  • 但工作区是同一个。手动开的 Codex 如果也改代码,就和两个任务并行是一样的问题。
  • 只做只读检查可以,建议用 codex -s read-only 启动,防止它误改。它看到的可能是改到一半的代码,结论要以任务结束后的状态为准。也不要让它跑构建和测试,这些命令会写构建产物,还会和流程里的测试抢同一个输出目录。
  • 你自己在编辑器里改同一个仓库也一样:任务进行中不要改。

以后的优化:同一个仓库并行多个任务。 思路是每个任务一个 git worktree(独立的工作目录和分支),改动完全隔离,审查时 diff 也只包含自己的改动。要解决的问题:

  • 每个 worktree 要单独装依赖;
  • 任务结束后要合并回主分支,并处理合并冲突,合并后还要再跑一遍测试;
  • 构建、部署到本地加载目录这类共享资源要排队;
  • 运行目录要记录对应的 worktree 和分支,恢复和清理时一起处理。

Codex 自带 --worktree 参数,但这里没有测过;由 Claude 自己用 git worktree add 建工作目录更好控制。现在先用单任务锁。

磁盘占用#

会增长的有两处:

  • ~/.cache/cx-runs/:这套流程自己的运行目录,会自动清理。任务结束时删掉体积最大的事件流,只留几 KB 的计划、反馈、审查和汇报;每次启动新任务时,删掉本项目 30 天前、已经结束的运行目录。没结束的任务不会被删,不影响中断续接。
  • ~/.codex/sessions/:Codex 自己的会话记录,平时直接用 Codex 也会写。续接要靠它,所以不能关,配置提示词也约定了不动 ~/.codex。它会随使用增长,需要清理时自己删旧文件,但不要删还没结束的任务对应的会话。
  • 新项目:在服务器上新建项目目录,再粘贴一次上面的提示词。
Claude Code 写计划、Codex 执行:跨机器自动派活与验收
https://lzwcc.xyz/blog/claude-code-plan-codex-exec/
Author LZWcc
Published at October 19, 2026