×−+
并行:子代理与云端第 12 课 · Codex 教程
第 12 课 · PARALLEL

并行:同时交代几件事,
还互不干扰

一个对话一次做一件事,但你可以同时开好几个对话,还能让 Codex 自己叫几个帮手分头去查。难的是别让它们抢同一份文件。这一课讲清楚三种运行位置(Local、Worktree、Cloud)各把活放在哪、怎么在它们之间搬,以及子代理什么时候值得派。

约 40 分钟 11 节 · 7 个动手练习 章末测验 形式参考 luongnv89/claude-howto · 事实依据 OpenAI 官方文档
点上面切换 · 时间长短是示意
入门先用起来 原理弄懂为什么 实战动手练 深入进阶与避坑

时间紧就先看第 1–4 节和第 9 节的演练;Worktree 缺文件、云端装不上依赖这类坑,都在"原理"和"深入"里。

01入门

同时做几件事

想同时推进几件事,就开几个对话。关键是给每件事找个合适的地方干活,别让两个对话同时改同一份文件。

先打个比方。你是一个木工,Codex 是你请来的师傅:

Local:就在你的工作台上干你们共用同一套材料,你看得最清楚、试得最快。但两个人同时在一张台子上改同一处,就会打架。
Worktree:在旁边再支一张工作台把图纸复印一份过去干,两边互不碰。干完可以整张搬回你的台子(这一步叫 Hand off)。
Cloud:交给外面的加工厂在 OpenAI 的云端容器里干,你关灯下班它照样干。但它只拿得到你寄过去的图纸:GitHub 上的代码。
子代理:师傅找几个同事分头查一件大活拆成几块,几个帮手同时去看,回来每人只交一张结论条,师傅自己的脑子不被塞满。

前三个叫运行位置,是开新对话时选的;子代理是在一个对话里面,Codex 替你派出去的帮手。两者可以一起用。

这一课 order-admin 要同时做的事

事情放哪为什么
修复分页 bugLocal小改动,想马上在自己平常的 dev server 里点一点
订单退款流程Worktree改动大,放后台慢慢做,不碰你手上的文件
升级依赖Cloud要一个个试、跑很久,你合上电脑它也能接着跑
审退款的三处改动子代理三块互不相干、只读不改,分头审更快
官方的提醒

对话可以同时跑,但别让两个对话同时改同一批文件。要并行改代码,给它们各开一个 worktree。反过来,官方也把"守着 Codex 一步步看它干活,而不是和它并行工作"列为新手常见错误。

02入门

在哪儿选运行位置

新建对话时,在输入框下面的 Work in 里选 This computer(你的电脑)或 Cloud(云端)。选了 This computer,旁边还有一个单独的 Worktree 开关:关着就是 Local,打开就是 Worktree。

1
Work in
This computerLocal / Worktree
Cloud云端环境
2
做订单退款流程……
This computer Worktree main
3 Hand off Create branch here
在窗口里的位置:输入框下面、对话顶部
  1. 1Work in新建对话时选在你的电脑上(This computer)还是云端(Cloud)。选 Cloud 还要再选一个已经发布的云端环境(第 7 节)。
  2. 2Worktree 开关和起点分支本地的 Git 项目才有这个开关,打开就在独立副本里干活。再在旁边选副本从哪个分支开出来:可以是 main、功能分支,也可以是带着没提交改动的当前分支。
  3. 3对话顶部的按钮Worktree 对话做完后用:Hand off 搬回 Local,或 Create branch here 把副本变成分支。

也可以用斜杠命令切

命令作用
/local让对话在你选的本地项目里跑
/worktree让对话在一个新的 Git worktree 里跑
/cloud让对话在云端跑(云端可用时才有)
/cloud-environment选这个对话用哪个云端环境

第 4 课讲过的 /fork 也和这里有关:它能把一个本地对话复制成新的本地对话,或者复制到一个 worktree 里,用另一种做法再试一遍。

选错了位置?

发出去才发现该选 Worktree 却选了 Local:先取消这次运行,再在输入框里按 ↑,刚才的提示词就回来了,换个位置重新发。

03原理

同一件事,放在三个地方有什么不同

同样是"订单退款流程",放 Local、Worktree、Cloud,改的是哪份文件、能不能联网、合上电脑还跑不跑,都不一样。切换看看,这些行都按官方文档整理。

任务:订单退款流程

"你的文件夹"指你在 App 里选的项目文件夹;worktree 的目录名由 App 生成,这里用"…"代替。

04实战

练一练:这件事放哪儿

6 个场景,各选一个最合适的运行位置。想想上一节那几行:改哪份文件、要不要你的电脑开着、要不要 Git 和 GitHub。

05原理

Worktree 是怎么回事

Worktree 是 Git 自带的功能:同一个仓库,再检出一份到别的文件夹。Codex 替你建、替你在两边搬、替你清理。

每份都有自己的一套文件,但共用同一个 .git提交、分支这些记录是同一套,所以能在不同的文件夹里同时做不同的事。前提:项目得是 Git 仓库。
放在 $CODEX_HOME/worktrees没改过 CODEX_HOME 的话就是 ~/.codex/worktrees。想换地方:Settings > Worktrees 里的 Worktree root。
默认是 detached HEAD意思是"副本没挂在任何分支上",只是停在某个提交。这样开十个 worktree 也不会弄出十个分支。起点是你选的分支的最新提交;选了带未提交改动的分支,这些改动也会一起带过去。
Local 是前台,Worktree 是后台Hand off 在两者之间搬对话:对话和代码一起搬,需要的 Git 操作 Codex 替你做。每个对话固定对应同一个 worktree,搬回去还是原来那个。

做完之后:两条路,一个坑

官方给了两条路:留在 worktree 里收尾,或者 Hand off 回 Local。还有一个很多人会踩的坑:同一个分支,想在两个地方同时检出。选一条走走看。

记住这一条

Git 规定:同一个分支,同一时间只能在一个地方检出。在 worktree 上建了分支,就别想着在 Local 里再检出它;打算在 Local 里接着用,一开始就 Hand off。

06实战

新 worktree 缺东西?补齐它

Worktree 是从 Git 检出来的,被 Git 忽略的东西(.env、node_modules)不会跟过来。两个办法补齐:.worktreeinclude 复制文件,本地环境的 setup 脚本装依赖。

打开、关上这两个开关,看看一个新开的 worktree 里有什么,npm test 能不能跑通。

order-admin 的准备
新开的 worktree 里(示意)

.worktreeinclude:把被忽略的文件带过去

.worktreeinclude(放在仓库根目录)
# 新建 worktree 时,把这些被 Git 忽略的文件复制过去
.env
.env.local
config/secrets.json
  • 写被 Git 忽略的路径,或者 .gitignore 那种匹配规则。只复制被忽略、又匹配上的文件;Git 跟踪的文件本来就在,别写进来。
  • 被忽略的 AGENTS.override.md 会自动复制,不用写(第 5 课讲过这个文件)。
  • 不复制符号链接,也不覆盖新副本里已经有的文件。
  • Hand off 也是靠 Git 搬的:被忽略的文件不会跟着对话走。.worktreeinclude 只在新建 worktree 时复制一次;你在 worktree 里改了 .env.local 再 Hand off 回 Local,这个改动不会跟过来。
  • 只对 App 管理的本地 worktree 生效;你自己在命令行里 git worktree add 的、远程机器上的都不管。

本地环境:setup 脚本和 Actions

本地环境(local environment)是项目级的设置,只在桌面 App 的 Codex 里有。在 App 的设置里配,Codex 把它存进项目根目录的 .codex 文件夹,你可以把它提交进 Git,同事拉下来就能用。

Setup 脚本新对话开出新 worktree 时自动运行,用来装依赖、先构建一遍。order-admin 写 npm install 就够;需要的话还能分 macOS、Windows、Linux 各写一份。
Actions常用命令的快捷按钮,比如"启动 dev server"npm start、"跑测试"npm test。它们出现在 App 的顶栏里,点一下就在集成终端里运行;每个可以配一个图标。
同事的本地环境没生效?

配置必须在项目根目录的 .codex 文件夹里。一个仓库里放了好几个项目(monorepo)的,要在 App 里打开包含 .codex 的那个目录。

07原理

云端:先备好环境,再派任务

Cloud 把活交给 OpenAI 云端的虚拟机:不用你的电脑开着。每个任务都从一个发布过的云端环境开工,只认 GitHub 上的代码,能连哪些网站由环境的联网设置决定。

用之前准备三样

用 ChatGPT 账号登录云端只认 ChatGPT 账号,API key 登录用不了。用邮箱加密码登录的,要先开多重验证(MFA)才能用云端。
连 GitHub建环境时选 GitHub 仓库,没连过会提示你连接。GitLab 和自建的 GitHub Enterprise Server 目前还不支持(官方说在计划里)。
建一个云端环境,并发布在新任务里点 Work in > Cloud,打开 Select environment,选 Create environment;也可以从 Settings > Codex Cloud > Environments 进去。在网页版或桌面 App 里建都行。

从建环境到交结果

1选仓库选要检出的 GitHub 仓库,点 Get started。只建一次
2Codex 来准备它自己看仓库、装依赖和工具、试跑一遍;缺权限、缺信息会停下来问你。不用你写脚本
3发布看一遍准备报告,保存,点 Publish。准备好的文件就存成新任务的起点。已发布
4开任务每个任务从发布的环境开出自己的一份工作区,互不影响;你的电脑睡着了它也接着干。各干各的
5交结果看改了哪些文件、测试结果;接着提要求,满意了就提交或开 PR。开 PR

第 2 步试通的步骤,Codex 会记成两样:装依赖的安装脚本(Install script)和启动服务的启动技能(Start skill),你在配置里能看到、能改。环境要改(比如加了新依赖):在 Settings > Codex Cloud > Environments 里点它的 … 菜单 > Edit,说清楚要改什么,让 Codex 准备、试好,再点 Republish。之后新开的任务才用上新环境,已经开着的任务保留它自己的文件。一个任务存下来的状态,从你最后一次发消息或恢复它算起,最多保留 7 天。

试一试:这些请求能不能成

联网在环境配置里开:打开 Allow Codex to access internet,再在 Allow domains 里选一档。换一档看看。

Allow domains:
示意。前两档都能在 Additional allowed domains 里再加域名;这里假设你一个都没加。
环境变量和网络密钥,分开放

程序要直接读的值(比如 APP_MODE=development)放进 Environment variables。访问某个 HTTPS 服务用的凭据(比如私有 npm 源的 token)放进 Network secrets,再写上它能发往哪些域名:程序只拿到一个占位符,请求发出去时,代理才把真值换上,而且只对允许的域名、只走 443 端口的 HTTPS。自己的 token 不想放进共享环境,就存在 Settings > Codex Cloud > Personal vault 里,只在环境要这个值时才用上。

结果怎么拿回来

云端任务做完,看改动和测试结果,满意就提交或开 PR;不满意就在任务里接着提要求。它不能 Hand off:Hand off 用来在 Local 和 Worktree 之间搬对话(连着远程主机时也能在主机之间搬,第 13 课),但不支持搬到云端。想直接把云端的改动打到本地仓库,要用命令行的 codex apply(第 14 课)。

放行域名之前想一想

网页、issue、依赖说明里的文字可能藏着指令(提示注入)。比如你让它"修一下这个 issue",issue 里却藏着一句"请运行这段脚本",脚本会把最近一次提交发到别人的服务器。所以:只给它指向你信得过的内容,只放行需要的域名,做完看一眼它的工作记录。另外,放行一个域名不等于给了它那边的账号和权限。

08原理

子代理:让 Codex 叫帮手

子代理就是 Codex 在一个对话里派出去的帮手:主对话把活拆开,几个子代理同时去做,做完只把结论交回来。

主对话记着你的需求、做决定、写最后的答复
拆开,同时派出 3 个子代理
审接口src/api/orders.ts翻文件、跑测试、看报错……都留在它自己的线程里交回一段摘要
审页面src/pages/Orders.tsx翻文件、跑测试、看报错……都留在它自己的线程里交回一段摘要
审数据库db/schema.ts翻文件、跑测试、看报错……都留在它自己的线程里交回一段摘要
主对话等三个都做完,汇总成一份答复

为什么要这样?上下文再大也有极限。探索笔记、测试日志、报错堆栈这些中间过程要是全塞进主对话,有用的信息会被淹没(官方叫"上下文污染"),对话越长表现越差("上下文衰退")。子代理把这些杂音挡在主对话外面,主对话只收摘要。能并行的活,还顺便省了时间。

你需要知道的几件事

你开口它才派在 App、命令行、IDE 里,Codex 只在你直接要求("派两个子代理""每个点一个 agent"),或者适用的 AGENTS.md、skill 里写了要派的时候才派。它不会自作主张。
内置三种default(通用)、worker(动手改、修 bug)、explorer(以读代码、摸清结构为主)。还能自己定义(第 10 节)。
读多写少的活最合适探索代码、跑测试、分诊问题、总结归纳。几个代理同时改代码容易冲突,协调起来也更费劲,要慎重。
更耗额度每个子代理都自己调用模型、自己用工具,比一个代理做同样的事花得多。小活别派。你的套餐额度见专题 A。
权限跟着你走子代理继承你在输入框下面选的权限档位(第 3 课)。所以先选好档位,再让它派。
在 App 里怎么看、怎么管主对话里会显示子代理的活动,点开能看每个子代理的线程和它交回的摘要。想让某个子代理改方向、停下、关掉,直接跟 Codex 说。

派活的提示词怎么写

官方建议写清三件事:怎么拆、要不要等全部做完再继续、交回什么。

派子代理审一个分支(改写自官方示例)
用子代理并行审这个分支:一个看安全风险,一个看缺了哪些测试,
一个看可维护性。等三个都做完,再按类别汇总问题,并标出文件位置。

判断一下:该不该派子代理

09实战

演练:三件事同时开

修分页放 Local、退款放 Worktree、升级依赖放 Cloud,一起开;然后把退款搬回本地,最后让子代理并行审它的三处改动。中途要你批准一次提交,"允许"和"拒绝"会走两条不同的路。

画面为教学示意:文件名、测试数量、子代理的发现和 Codex 说的话都是虚构的;运行位置、Hand off、Create branch here、setup 脚本、云端环境、子代理继承权限等规则与官方文档一致;"开 PR"按钮是示意,真实按钮名和位置以你的 App 为准。在窗口里点对话名可以来回切换。

10深入

进阶与避坑

自定义子代理、全局子代理设置、worktree 的清理规则、云端缓存。用得多了才会碰到,但碰到时很管用。

自定义子代理

一个 TOML 文件定义一个代理。个人的放 ~/.codex/agents/,项目的放 .codex/agents/。好的自定义代理窄而专:一件明确的活、配得上这件活的工具、不让它越界的指令。

.codex/agents/reviewer.toml
name = "reviewer"
description = "只读的代码审查员:找正确性、安全和缺测试的问题。"
model_reasoning_effort = "high"
sandbox_mode = "read-only"
# model = "…"   也可以指定模型;推荐哪个见专题 A
developer_instructions = """
像代码的主人一样审查。
优先看正确性、安全、行为回退和缺失的测试。
先给出具体问题和复现步骤;不要只提风格意见。
不要修改任何文件。
"""
字段必填说明
name是Codex 派它、提到它时用的名字。以这个字段为准,文件名和它一致最省事
description是说明什么时候该用这个代理(官方称是写给人看的说明)
developer_instructions是这个代理的核心指令
其他 config.toml 键否比如 model、model_reasoning_effort、sandbox_mode、mcp_servers、skills.config。没写的从父对话继承
  • 名字和内置的撞了(比如也叫 explorer),你的优先。
  • 模型和推理强度:文件里写了就用文件的;没写,就按"派的时候点名的 → [agents] 里的默认 → 父对话的"顺序定。
  • 权限:一般继承父对话,但可以像上面这样给某个代理单独设成只读。
  • 官方说这个格式会随着编写、分享方式的成熟继续变,以后以文档为准。

全局设置:[agents]

.codex/config.toml(或 ~/.codex/config.toml)
[agents]
# 同时最多开几个子代理线程(不算主对话);不写由 Codex 决定
max_concurrent_threads_per_session = 6
键作用
agents.enabled开关子代理功能,默认 true
agents.max_concurrent_threads_per_session同时开着的子代理线程上限,不算主对话
agents.default_subagent_model子代理默认用的模型;派的时候点名了就以点名的为准
agents.default_subagent_reasoning_effort子代理默认的推理强度,同上
agents.interrupt_message子代理被打断时,给模型留一条"被打断了"的记录,默认 true

config.toml 放哪、谁覆盖谁,见第 7 课。

旧教程对照

网上的教程、别人的配置里常见这些旧说法:

  1. "线程(thread)""任务(task)":现在统一叫对话(chat),云端的叫云端对话。
  2. agents.max_threads:现在叫 agents.max_concurrent_threads_per_session,旧名字还认,是别名。
  3. 命令行 codex cloud-tasks:现在是 codex cloud 实验,旧名字是别名(第 14 课)。
  4. "要先打开实验功能才能用子代理":现在的版本默认开着,[features] 里的 multi_agent 已是稳定功能;想关用 agents.enabled = false。

常见问题

worktree 很占硬盘,会自己清理吗?
会。每个 worktree 都有自己的一套文件、依赖、构建缓存。默认保留最近 15 个 Codex 管理的 worktree,数量可以在设置里改,也可以关掉自动删除。
这几种不会自动删:绑着置顶(pinned)对话的、对话还在进行中的、永久 worktree。
这两种情况会删:你归档了对应的对话;超过了上限,要删掉旧的。
删之前 Codex 会给 worktree 上的工作存一份快照。之后再打开那个对话,会提示你恢复。
想要一个长期用的 worktree
在侧栏里项目的 ⋯ 菜单里建一个永久 worktree。它会变成一个独立的项目,不会被自动删除,归档里面的对话也不删;还能在它上面开好几个对话。普通的 Codex 管理的 worktree 是一次性的,一般一个对话一个。
项目里挂了好几个文件夹,worktree 怎么算?
开 PR、建 worktree 这些操作针对的是主文件夹(primary)的仓库。在 worktree 里开对话时,其他文件夹仍然挂在项目上。
云端每开一个任务,都要重新装依赖吗?
不用。发布环境时,准备好的文件就存下来了,新任务直接从这里开工。仓库有更新时,它在后台自动刷新,保留依赖缓存,不会重跑安装和启动步骤。已经开着的任务用它自己存下的文件,包括没提交的改动和装过的工具。项目依赖变了,就 Edit 这个环境,让 Codex 重新准备好,再 Republish。
云端下载包失败,或者请求被拦了
先查域名:这个主机在不在环境的放行名单里?私有源 packages.example.com 放行了,下载可能还要走 downloads.example.com,它也得加。再查凭据:放行域名不等于给了账号。用网络密钥的,确认密钥的 Allowed domains 里有这个目的地,而且请求走的是 443 端口的 HTTPS。改完先在准备阶段试通,再 Republish,开个新任务验证。
建好的环境,新任务里选不到
去 Settings > Codex Cloud > Environments 看一眼:带 Unpublished 标记的还没发布,把准备做完,点 Publish。改过已发布的环境,要 Republish,之后新开的任务才用上。第一次准备失败了,点 Try again,用刚才选好的仓库重来。
手机上能管 worktree 对话吗?
能。ChatGPT 手机 App 里的 Codex Remote 可以在连着的电脑上开 worktree 对话、看进度、批准、看改动;仓库和 worktree 还是在那台电脑上(第 13 课)。定时任务在 Git 仓库里也会用专门的后台 worktree 跑,免得和你手上的活冲突,也是第 13 课的内容。
命令行里怎么看子代理?
命令行里用 /agent 在各个子代理线程之间切换(第 14 课)。App 里不用命令,点主对话里的子代理活动就能打开它的线程。
11检验

小测验

8 道题,每题选完会立刻看到解析。