我把一套项目内的 Codex 多代理配置整理成了开源项目:codex-astra-terra-orchestrator。它包含五个角色、一个明确调用的技能、项目规则入口和验证指南,可以审阅后合并进已有仓库。

这套方案的默认行为很简单:普通任务由主代理直接处理,只有明确要求协作时才启动子代理。 启用后,Astra 负责整体设计、复杂实现和最终交付,Terra 处理边界明确的调查、局部实现与验证,独立审查仍交给 Astra。

最初的参考是 donvito/codex-astra-luna-orchestrator。我保留了角色分工的思路,重新编写了精简配置与提示词,把普通角色统一改为 Terra / high,并按现有项目的工作方式加入显式触发、文件归属和验收要求。

先明确什么时候值得委派

在一个已经有需求文档、架构约束和未提交修改的工程里,多代理首先带来的是协调问题:谁可以改哪些文件,公共接口由谁确定,测试失败后谁处理,以及最终由谁确认交付完整。

如果这些问题没有答案,同时运行更多代理很容易增加返工。例如,一个代理改接口字段,另一个代理按旧字段写页面,两边各自检查通过,整合时仍然会失败。

所以我把适合委派的任务限定为目标清楚、输入充分、结果容易复核的工作:

  • 追踪一条调用链,找出相关需求和已有测试。
  • 按确定的接口修改几个明确分配的文件。
  • 执行一组针对性检查,报告真实失败。
  • 核实某个框架版本的官方接口。
  • 独立检查一份已经形成的差异。

涉及授权、数据隔离、事务、消息幂等、并发和公共契约的设计与复杂实现,仍由主代理承担。这样划分是这套配置的选择,不是对某个模型能力的普遍判断。

五个角色与一个交付责任人

角色请求模型与强度职责与写入范围
主代理Astra / high整体设计、复杂实现、公共文件协调、最终验收
explorerTerra / high只读追踪调用链、模块关系、需求与测试
workerTerra / high只修改明确分配的文件,完成局部实现
testerTerra / high执行验证;明确分配测试修改时才编辑测试源码
researcherTerra / high只读核实官方资料、版本与接口
reviewerAstra / 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
先用两个只读代理分别调查调用链和测试覆盖,再由独立审查代理复核。
仅处理我指定的模块,本轮不修改业务文件。

随后在隔离目录验证普通任务不委派、明确调用可以委派、冲突会返回、失败会报告,再进入真实业务写入。需要回退时,按差异移除新增配置、角色、技能和入口即可,保留之后其他任务的修改,没有业务数据迁移。

我更关注这套配置是否让任务范围、修改归属和验证结论变得清楚。单次测试的耗时没有单代理对照组,也没有成本基线,不能据此给出节省比例。让协作按要求发生,并留下可复核的结果,是这次接入的完成标准。