我把一套项目内的 Codex 多代理配置整理成了开源项目:codex-astra-terra-orchestrator。它包含五个角色、一个明确调用的技能、项目规则入口和验证指南,可以审阅后合并进已有仓库。
这套方案的默认行为很简单:普通任务由主代理直接处理,只有明确要求协作时才启动子代理。 启用后,Astra 负责整体设计、复杂实现和最终交付,Terra 处理边界明确的调查、局部实现与验证,独立审查仍交给 Astra。
最初的参考是 donvito/codex-astra-luna-orchestrator。我保留了角色分工的思路,重新编写了精简配置与提示词,把普通角色统一改为 Terra / high,并按现有项目的工作方式加入显式触发、文件归属和验收要求。
先明确什么时候值得委派
在一个已经有需求文档、架构约束和未提交修改的工程里,多代理首先带来的是协调问题:谁可以改哪些文件,公共接口由谁确定,测试失败后谁处理,以及最终由谁确认交付完整。
如果这些问题没有答案,同时运行更多代理很容易增加返工。例如,一个代理改接口字段,另一个代理按旧字段写页面,两边各自检查通过,整合时仍然会失败。
所以我把适合委派的任务限定为目标清楚、输入充分、结果容易复核的工作:
- 追踪一条调用链,找出相关需求和已有测试。
- 按确定的接口修改几个明确分配的文件。
- 执行一组针对性检查,报告真实失败。
- 核实某个框架版本的官方接口。
- 独立检查一份已经形成的差异。
涉及授权、数据隔离、事务、消息幂等、并发和公共契约的设计与复杂实现,仍由主代理承担。这样划分是这套配置的选择,不是对某个模型能力的普遍判断。
五个角色与一个交付责任人
| 角色 | 请求模型与强度 | 职责与写入范围 |
|---|---|---|
| 主代理 | Astra / high | 整体设计、复杂实现、公共文件协调、最终验收 |
| explorer | Terra / high | 只读追踪调用链、模块关系、需求与测试 |
| worker | Terra / high | 只修改明确分配的文件,完成局部实现 |
| tester | Terra / high | 执行验证;明确分配测试修改时才编辑测试源码 |
| researcher | Terra / high | 只读核实官方资料、版本与接口 |
| reviewer | Astra / high | 只读审查实际差异、架构、安全与验证缺口 |
开源版使用 orchestrator_ 前缀,避免与客户端内置角色重名。一次最多同时运行两个子代理,并服从客户端更低的实际限制;不要求每个任务都启动全部角色,也不允许子代理继续创建代理。
独立调查可以并行。依赖同一接口的实现按顺序推进。主代理收回结果后检查实际差异,处理审查发现,再完成项目要求的最终验证。
配置应该放在目标项目里
我选择把它放在项目根目录,随项目一起维护:
your-project/
├── AGENTS.md
├── .codex/
│ ├── config.toml
│ └── agents/
│ ├── orchestrator_explorer.toml
│ ├── orchestrator_worker.toml
│ ├── orchestrator_tester.toml
│ ├── orchestrator_researcher.toml
│ └── orchestrator_reviewer.toml
└── .agents/skills/astra-terra-orchestrator/
├── SKILL.md
└── agents/openai.yaml
其中 .codex/config.toml 设置模型默认值和并发上限:
model = "gpt-6-astra"
model_reasoning_effort = "high"
project_doc_max_bytes = 65536
[agents]
enabled = true
max_concurrent_threads_per_session = 2
default_subagent_model = "gpt-5.6-terra"
default_subagent_reasoning_effort = "high"
每个角色文件再显式写出模型与推理强度。审查角色覆盖为 Astra,只读角色声明 sandbox_mode = "read-only",worker 和 tester 使用 workspace-write。
合并到已有项目时要逐项审阅,保留原有 Provider、审批策略、权限和其他设置。已有 [agents] 时合并字段,不能重复定义同一张 TOML 表。项目配置是否被信任、启动参数和界面是否覆盖了设置,也要通过实际客户端核实。相关字段以官方配置参考与子代理说明为依据。
根 AGENTS.md 只追加短入口:明确要求协作时,读取对应技能。原有业务规则与架构约束继续有效。开源仓库提供了单独的入口片段,不需要拿它的根规则替换你的项目规范。
显式触发需要两层配合
技能元数据里设置:
policy:
allow_implicit_invocation: false
这控制技能是否被自动选中,含义是默认不隐式加载,仍可通过 $astra-terra-orchestrator 明确调用。它不是所有委派行为的总开关,不能替代主代理的入口规则。技能加载机制可参阅官方技能文档。
因此,根规则和技能正文还要说明授权边界:
| 用户请求 | 是否启动协作 |
|---|---|
| “修复这个错误” | 否,由主代理处理 |
| “多代理方案适合这个项目吗?” | 否,这是讨论 |
| “explorer 这个角色负责什么?” | 否,只是在询问角色 |
| “使用子代理调查这条调用链” | 是,范围是本次调查 |
| “让 orchestrator_reviewer 审查本次差异” | 是,范围是本次审查 |
明确调用 $astra-terra-orchestrator 并给出任务 | 是 |
授权延续到同一目标的后续修正,不自动扩展到新的无关任务。用户取消委派后,主代理停止后续创建,并协调结束已经运行的子任务。
这是一组协作约定。它没有额外实现一个授权网关,文件归属也没有变成操作系统文件锁;验收时需要观察真实行为。
一份可执行的委派契约
只给子代理一句“帮我看看这个模块”通常太宽。更有用的任务应该包含足够的输入,同时明确停止的位置。
下面是一个只读调查示例,路径需替换为实际项目文件:
角色:orchestrator_explorer
请求模型与强度:gpt-5.6-terra / high
目标:确认订单状态展示从接口到页面的调用链。
范围:只读 src/orders/、tests/orders/ 和对应需求文档。
允许修改:无,不得创建子代理。
上下文:附适用项目规范、状态定义和接口签名。
基线:附本轮开始时的工作区差异摘要。
约束:不编辑文件,不启动或重建共享服务,不安装依赖。
验收:指出状态来源、转换逻辑、展示入口和测试位置。
返回:结论、准确路径与符号、证据、检查结果和未解决问题。
局部实现还要列出准确的可写文件和接口依据。主代理先记录已有修改,保证同一文件同时只有一个写入者。公共 SDK、Schema、依赖和锁文件、需求索引及导航由主代理协调。
子代理发现文件归属冲突时返回主代理,不撤销其他任务的修改。共享 Compose 环境、数据库初始化和全量集成测试也由主代理统一调度,避免多个代理同时重建同一套环境。
传递上下文时只提供必要材料,不默认复制整段历史。若委派接口支持 fork_turns,可以使用 none 并补齐任务材料;需要显式模型覆盖时,也要确认它与当前接口的历史继承方式兼容。
实测中两个容易忽略的问题
文件写好了,末尾规则却没有进入提示输入
源项目的根 AGENTS.md 已经超过 32 KiB。追加入口后,文件本身完整,静态检查也无法发现加载截断,但客户端的默认项目指令预算不足以容纳全部内容。
这次接入将 project_doc_max_bytes 设为 65536,再查看真实提示输入,确认末尾入口已经加载。
这里的单位是字节,设置的是项目指令读取预算,不是模型上下文窗口。64 KiB 也不是所有项目都适用的固定答案。验收应确认需要的规则实际进入上下文,而不是只检查某个配置数字。
命令行与应用内置客户端的版本不同
本次环境中的命令行 Codex 0.152.0 请求 Astra 时,被服务端拒绝并提示升级。应用内置的 0.153.0 可以成功发起请求,后续新会话验证使用了这一版本。
这个结果只说明当时两套客户端在该账号下的表现,不能推出一个通用的最低支持版本。排查时应记录实际执行的客户端及版本,再验证模型请求,而不能仅凭桌面应用已经升级就判断终端调用也已更新。
怎样描述“验证通过”才准确
这次验证分成静态检查、客户端加载、委派行为和权限边界几层。
| 检查 | 源项目中的观察结果 |
|---|---|
| 配置与技能 | 六份 TOML 解析通过,技能校验通过,客户端可以发现技能 |
| 有效配置 | 返回 Astra/high 主模型、Terra/high 默认子模型和并发上限二 |
| 普通任务与方案讨论 | 新会话没有创建子代理;讨论场景未隐式选中技能 |
| 明确调用 | 技能正文被选中,具名角色实际创建并完成任务 |
| 首轮只读协作 | 两个独立调查角色返回可复核结果,审查角色复核,整轮约 143 秒 |
| 文件归属冲突 | worker 报告文件被另一 active owner 持有,没有写入 |
| 缺失输入 | tester 的真实检查失败,没有补造文件或跳过断言 |
| 工作区保全 | 隔离夹具哈希不变,原工作区基线中的无关修改得到保全 |
冲突与失败回报那一轮约 110 秒。它只允许代理读取夹具目录,没有提供完整项目上下文;代理报告了材料缺失且未越界。因此,这轮可以支持“冲突与失败被如实回报”的结论,不能被记作“全部前置阅读都完成”。
还有两个没有完整验证的部分。
第一,子代理调用事件记录了请求模型与 high,也确认了具名角色创建和完成,但没有返回独立的实际模型与推理强度快照。尝试读取临时子会话也没有取得该快照。因此,请求了 Terra/high 不等于已经独立证明最终运行的是 Terra/high。这一项保留为“无法验证”,不采用代理自述来补齐证据。
第二,只读角色没有修改文件,并不能证明沙箱一定拦截写入。角色配置是否被加载、父会话实时权限是否继续作用于子代理,要看实际客户端证据。这次没有完整验证沙箱写入拦截,也没有尝试超过两个子代理的并发上限。
如果某个委派接口不能选择自定义角色,只能传入角色指令和模型参数,还应说明这是受限方式,不能声称已经加载同等角色沙箱。
源项目同时执行了自己的文档、前端和 Compose 检查;后端仍有失败项。没有在干净基线上复现的失败,不能直接称为“历史问题”。这些业务检查与通用模板的验证也要分别记录,局部协作成功不代表整个工程已经交付。
把配置接入自己的项目
完整文件、入口片段、任务示例和验证指南都在 GitHub 开源仓库,采用 Apache-2.0 许可。
git clone https://github.com/lucaslz2020/codex-astra-terra-orchestrator.git
cd codex-astra-terra-orchestrator
python3 scripts/check_config.py
检查脚本需要 Python 3.11+,只使用标准库。它检查 TOML 配置的一致性,不负责安装,也不证明实际模型路由或沙箱生效。Codex 使用模板本身不依赖 Python。
接入时,先记录目标项目的已有差异,再合并 .codex/config.toml、复制五份角色文件和技能目录,最后追加 AGENTS.md 入口。同名文件需要逐项审阅,不覆盖原有规则,不写入全局配置。
开源版对角色名前缀和项目引用做了通用化。前面的运行结果来自源项目的那次接入;通用版静态检查通过,不代表更名后的配置已经在每个目标客户端运行验收。首次使用可以从这条明确、只读的任务开始:
$astra-terra-orchestrator
先用两个只读代理分别调查调用链和测试覆盖,再由独立审查代理复核。
仅处理我指定的模块,本轮不修改业务文件。
随后在隔离目录验证普通任务不委派、明确调用可以委派、冲突会返回、失败会报告,再进入真实业务写入。需要回退时,按差异移除新增配置、角色、技能和入口即可,保留之后其他任务的修改,没有业务数据迁移。
我更关注这套配置是否让任务范围、修改归属和验证结论变得清楚。单次测试的耗时没有单代理对照组,也没有成本基线,不能据此给出节省比例。让协作按要求发生,并留下可复核的结果,是这次接入的完成标准。
DISCUSSION
讨论与反馈