多代理协作
Codex 的多代理系统允许将复杂任务分解为独立的子任务,由专门的子代理并行执行。这对于大型代码库和多功能开发工作流至关重要。
核心概念
代理类型
| 类型 | 用途 | 何时使用 |
|---|---|---|
| 探索者 (explorer) | 只读分析:搜索文件、理解结构、回答具体问题 | 需要理解代码库某部分时 |
| 工作者 (worker) | 执行修改:编写代码、重构、修复 | 需要实际变更文件时 |
| 默认 (default) | 通用能力 | 无特定需求时 |
工作流程
分析阶段 执行阶段 集成阶段
(探索者) → (工作者) → (用户)
发现问题 修复问题 验证结果适用场景
场景 1:大型仓库重构
当重构涉及 10+ 个文件时,不要一次性完成:
步骤 1:探索者分析仓库结构,生成影响范围报告
步骤 2:并行工作者 — 每个工作者负责一个独立模块
步骤 3:用户集成 — 解决冲突,验证最终结果场景 2:安全扫描 + 修复
探索者: 分析安全扫描报告,提取关键发现
工作者: 按优先级逐个修复已确认的漏洞场景 3:多语言项目
工作者 A: 重构后端 API(Rust)
工作者 B: 更新前端类型定义(TypeScript)
工作者 C: 编写集成测试(Python)使用方式
通过技能触发
最简便的方式是使用 $dispatching-parallel-agents 技能:
> 使用 $dispatching-parallel-agents 并行重构 src/api/、src/components/ 和 src/utils/ 三个模块通过提示词编排
你也可以直接告诉 Codex 你的意图:
> 请分析项目中所有使用 moment.js 的模块,然后并行替换为 dayjs
> 任务:将所有使用 moment.js 的模块替换为 dayjs
> 约束:
> - 不改变公共 API 签名
> - 每个模块独立完成
> - 在所有模块完成后运行测试验证代理设计原则
高内聚、低耦合
每个子代理应该:
- 只负责一个明确的任务
- 与其他代理没有文件冲突
- 输出明确的结果验证方式
避免代理间通信
代理之间不直接通信。它们通过用户(主代理)间接地协调:
❌ 代理 A 需要等待代理 B 的结果
✅ 代理 A 和 B 各自完成工作,由用户合并结果写入范围隔离
多个工作者同时工作时,明确指定各自的文件范围:
工作者 1: 负责 src/api/ 目录
工作者 2: 负责 src/components/ 目录
工作者 3: 负责 src/utils/ 目录
规则:不修改其他代理负责的文件并行执行模式
批量独立任务
当多个任务完全没有依赖关系时:
并行执行:
- 修复 auth 模块的类型错误
- 修复 payment 模块的类型错误
- 修复 order 模块的类型错误分析后执行
当任务需要先理解再拆分时:
第一步(探索者):分析所有模块中使用的 ORM 查询
第二步(多个工作者):每个工作者重构一个模块的查询顺序验证
当并行任务完成后需要统一验证时:
并行:
- 工作者 A: 修改模块 A
- 工作者 B: 修改模块 B
顺序:
- 运行所有测试
- 解决冲突限制与注意事项
并发限制
子代理数量有上限。超出限制时需要分批执行。
文件冲突
如果多个工作者尝试修改同一文件,可能出现冲突。始终确保写入范围不重叠。
上下文窗口
每个子代理都共享主代理的上下文窗口。使用过多的子代理可能导致总体可用上下文减少。最佳实践是保持 3-5 个活跃子代理。
实际示例:Monorepo 重构
假设有一个 monorepo 需要将所有 JavaScript 文件迁移为 TypeScript:
# 1. 探索者分析
> 分析 packages/ 下所有包的 JS 文件,按复杂度排序
# 2. 生成迁移计划
> 生成迁移计划,每个包独立执行
# 3. 并行工作者
> 并行迁移以下包:
> - packages/shared-utils(低复杂度)
> - packages/api-client(中复杂度)
> - packages/logger(低复杂度)
# 4. 顺序处理高复杂度包
> 迁移 packages/data-models(高复杂度,需要先完成 api-client 的类型定义)
# 5. 集成验证
> 运行全量类型检查和测试调试子代理
子代理卡住
如果某个子代理长时间无响应:
- 检查其任务是否过于复杂——拆分为更小任务
- 检查是否有文件锁定或权限问题
- 使用
--verbose标志查看详细输出
子代理输出与预期不符
- 检查任务描述是否足够具体
- 检查是否遗漏了关键约束条件
- 检查写入范围是否正确分配