Codex 进阶指南:作为 Multi-Agent 编排控制平面

read 源线程→ 打包目标、已完成项、未完成项、Artifact→ create / resume 目标线程→ send 目标线程(或 thread/inject_items 直接注入上下文)→ Registry 切换 active owner

执行位置 Handoff 是现成的原语:

text


handoff_thread(threadId, destinationHostId)→ get_handoff_status(operationId, afterRevision, waitMs=30000~60000)→ 同一个线程在目标 Host 上继续

Fork 加 Worktree 的多方案竞赛

同一个问题让几个角色各写一版,互不干扰,最后挑最好的那版留下。

用得上它的场景是"谁也说不准哪个方案更好"。一个重构有三种设计思路,光在对话里争论不出结果,那就三种都实现出来,各自跑测试,拿 diff 和测试结果比。要做到互不干扰,每个候选必须待在自己的 Worktree 里、用自己的分支,否则它们会改到同一份文件上。

text


fork_thread × N,environment = worktree→ 各候选独立实现并测试→ 循环 wait 到全部终态→ detached Reviewer 比 diff 和测试结果→ 把胜出的那个 handoff 回 Local

前面提过的 Git 约束在这里生效:每个候选必须落在自己的分支上。

Race 与 Quorum

上一种是"比出最好的一版",这两种是"用冗余换确定性",判定规则不同。

Race 比谁先到。 派几个候选同时算,第一个交出能通过验证的答案就采纳,剩下的作废。适合那种"只要有一个能跑通就行"的活,比如一个偶发失败的测试,三种排查思路同时试,谁先复现出来就按谁的走。

Quorum 比谁一致。 让几个候选各自独立算,累计到 K 个给出相同答案才采纳。适合那种"答案对不对本身不好判断"的活,比如让它估算一次数据迁移的影响面,单次结果你没法验证,但三个独立跑出来是同一个数,可信度就高多了。关键在于候选之间必须真的独立。如果它们都从同一份被污染的上下文出发,三个一致也说明不了什么。这一点会影响你怎么承载候选:fork_thread 只有 threadId 和 environment 两个参数,它总是复制源线程的全部已完成历史,你没法控制候选继承多少上下文;想让候选各自从干净的上下文出发,得改用 spawn_agent 并把 fork_turns 给 none。

text


fork 多个候选→ wait-any→ 第一个通过 Verifier 的即 Race 胜出 或累计 K 个一致结果达成 Quorum→ 处理掉落后的候选

最后那一步要看你用什么承载候选。用子 Agent 承载,可以直接 `interrupt_agent` 掐掉落后的那几个;用持久 Task 承载,`codex_app` 那 13 个工具里没有任何线程级的中断能力,你只能任其跑完再 set_thread_archived 归档,或者下到 App Server 用 turn/interrupt。想省 token 就用子 Agent 做 Race,想让候选留痕可追就用持久 Task,代价是拦不住已经在跑的那几个。

选型:什么时候用哪个




你的任务

合适的原语


一两步的明确改动

单个 Task 自己做


需要读大量代码或日志才能得出短结论

子 Agent


几个模块并行、彼此独立

子 Agent Team


跨项目、跨主机、需要长期存在的角色

多个持久 Task


同一仓库多方案并行

Fork 加 Worktree


想问一句但不想脏了主线程

/side
侧边对话


要循环、要重试、要落盘的确定性流程

App Server 控制器




跨项目跨主机的具体用法



现实里的项目本来就是散在各处的:内网服务只能在公司开发机上跑,前端要在本机才能开浏览器看效果,重编译得挑台内存大的机器,长时间的发布验证又得放在一台常开的机器上。每个项目待在最适合它的那台机器上,这是自然形成的格局,谈不上什么架构设计。

麻烦的是这些项目偶尔需要打通。改完接口要让前端联调,编译产物要交给发布流程验证,这种时候按传统做法你得来回切窗口、来回 SSH、把上下文在几个终端之间搬。

Codex 在这里给出的答案是:任何一台机器上的会话,都能感知到其他机器上的会话。 主机退化成线程的一个属性,你在哪台机器的会话里说话都不影响你指挥别处,需要哪台机器的能力就把活派给待在那台机器上的会话。平时各自独立干活,需要打通的时候一条消息就够,不用切窗口也不用 SSH 过去。

按主机能力路由

多台 SSH 主机接进同一个 Codex App 之后,最直接的收益是可以按机器的特长分派工作。










一种典型的分工是这样:Local 负责 UI、浏览器和需要人盯着的前台协作;内网开发机负责需要内网访问的后端工作;大内存高核数的机器负责大型编译和集成测试;另一台常开的机器负责长时间任务和发布验证;同一仓库的多方案并行放 Worktree。任务中途需要换环境时用执行位置 Handoff,历史和 Git 状态都不用丢。

这套路由能成立,靠的是全局线程可见性:list_threads 返回的是全 App 范围的线程,read_thread 带上 hostId 就能读另一台主机上某个线程的进展,不需要 SSH 过去,也不需要打开那个会话。

前面说过这个可见性是双向的,放到具体场景里就是这样一条链路:你在内网开发机的会话里改完接口,让它直接把联调请求发给本机那个跑着 dev server 的会话,由本机会话打开浏览器验证,验完把结果回传。

text


(当前会话跑在 SSH dev 上)list_threads # 看到本机那个前端会话→ send_message_to_thread(threadId, prompt, hostId="local") # 派给本机会话去验→ wait_threads(, timeoutMs) # 等它验完→ read_thread(threadId, hostId="local") # 读浏览器验证结论

跑在远端的那个会话,它的 shell 和文件都在远端,但它调的这几个工具由 Codex App 提供,所以它能指挥本机。反过来也一样。真正需要把执行位置也换过去的时候才用 handoff_thread,只是要一个结果就发消息,成本低得多。

跨项目软件交付

一个全局 Supervisor 同时管后端、前端、SDK、文档、测试、发布这几个 Project Task,每个 Project Task 再各自派子 Agent。项目之间通过结构化消息传播契约、schema、版本和产物,全局层只管依赖顺序和验收。

text


Supervisor 建立依赖 DAG 与验收矩阵→ 并行让各项目 Task 分析自己那一侧→ 各自把结论写成 Artifact→ Supervisor 汇总冲突与依赖→ 并行实现(各自 Worktree)→ 跨项目集成测试→ 失败项定点回传给对应项目 Task→ 全绿之后 handoff 给发布 Task

跨仓库契约迁移

改一个被多个仓库消费的 API,形状是先扫再定再改:

text


Explorer 并行扫生产者和所有消费者→ Architect 产出唯一的契约 Artifact→ 各仓库在自己的 Worktree 里并行实现→ 每仓一个 Worker-Critic 循环→ 集成机上跑跨仓测试→ 发布 Task 生成发布顺序

关键在第二步只能有一份契约。多个 Agent 各自理解契约,最后一定对不上。

多主机故障排查

每台主机开一个调查 Task,用统一的输出 schema,wait_threads 渐进收集,再并行生成根因候选,最后让 Verifier 去复现或证伪。Supervisor 最后交出一张证据矩阵,每个根因候选后面都跟着复现或证伪的结果。

批量升级与长期运维

50 个仓库升同一个依赖,做法是先试点 5 个摸清坑,再按语言和主机能力分波次路由,每仓独立 Worktree,Worker-Reviewer 有界修正,分批出 PR。

长期运维则交给 Automation:Heartbeat 持续盯部署、CI 或 Incident,Cron 每日扫代码、依赖、测试和文档一致性,Goal 保存长期目标,关键状态通过通知回到人这边,需要特定环境时 Handoff 到对应主机。

CLI 与脚本化编排



前面讲的大多是 App 里的能力。想把编排写成脚本,CLI 提供了另一组入口。

bash


codex exec "..." # 非交互跑完一整个 agent loopcodex review # 非交互跑一次代码评审codex fork --last # 分叉最近一个会话codex resume --last # 恢复最近一个会话codex apply # 把 agent 产出的 diff 应用到工作树codex sandbox <cmd> # 在 Codex 沙箱里跑命令codex mcp-server # 把 Codex 自己当成 MCP server 暴露出去codex app-server daemon # 起 app-server 守护进程codex remote-control start # 起带远程控制的 app-servercodex remote-control pair # 生成短时效配对码codex features list # 看能力开关codex doctor # 体检安装、配置、认证、运行时

几个全局选项在编排场景里很实用。-c key=value 能覆盖任意配置项,值按 TOML 解析,所以 -c model="gpt-5.6-sol" 和 -c 'sandbox_permissions=' 都行。--enable 和 --disable 按 feature 名开关能力,等价于 -c features.<name>=true。--remote ws://host:port 能把 TUI 接到一个远端 app server 上,配合 --remote-auth-token-env 传 bearer token。

最朴素的脚本化编排就是拿 codex exec 当积木:

bash


# fan-out:每个模块起一个独立进程for m in auth billing search; do codex exec "只读分析 $m 模块的错误处理,给出 file:line 证据" > "out_$m.md" &donewait # 屏障# reduce:把结果合起来再起一个codex exec "综合这三份分析,按严重程度排序:$(cat out_*.md)" > report.md

这套写法和 App 里的子 Agent 编排是同构的,& 加 wait 就是 wait-all,$(cat ...) 就是变量插值。差别在于每个 codex exec 是独立进程独立会话,要重新加载配置、MCP、登录态,比进程内的子 Agent 重不少;换来的是它能被 CI 调度、能写进 Makefile、能加重试。

结语



Agent 的能力边界在哪、什么活值得拆出去、拆几路合适、指令写到多细它才不跑偏,这些都得自己试出来。找一些手上真实的有两三条独立支线的事情,现在就开几个会话让它们跑一遍,比再读十篇指南都管用。

要增强与 Agent 协作的能力,只有两个字:多练。

参考资料




Subagents(子 Agent、自定义 Agent 与 agents 配置)
App Server(Thread / Turn / Item 可编程模型)
Hooks(十一个生命周期事件与输入输出契约)
Worktrees(Git 工作树与 Handoff)
Remote connections(远程连接与 SSH 主机)
Long-running work(Goal 模式与长任务)
Scheduled tasks(Heartbeat 与 Cron 自动化)
Developer commands(全部斜杠命令)
Sandboxing(沙箱档位与推荐组合)
Model Context Protocol(MCP 配置与 server instructions)
Skills & Plugins
Configuration Reference(配置项全量参考)
Codex 文档首页
openai/codex(CLI 仓库)
Context Rot(Chroma 的上下文腐化研究,官方文档引用来源)

分类