1. 多 Agent 协作到底解决什么问题如果你已经用 Open Agent SDK 跑通过单 Agent大概率会遇到一个瓶颈一个 Agent 既要探索代码库、又要写实现方案、还要改代码上下文越堆越长工具调用越来越乱最后它自己都忘了最初的任务是什么。这不是模型不行而是职责没有拆开。多 Agent 协作的核心思路很朴素让一个主 Agent 当协调者把探索、规划、编码这些活分给不同的子 Agent每个子 Agent 只带自己需要的工具和提示词干完把结果交回来。主 Agent 负责汇总和决策。这样每个子 Agent 的上下文都是干净的工具集也是收敛的出错时更容易定位是哪一环的问题。Open Agent SDK 把这套机制拆成了三层子 AgentSubAgentSpawner AgentTool解决“谁干活”Task 系统解决“活干了多少”Team Mailbox 解决“谁跟谁一组、怎么通信”。这篇就按这三层往下走给出可复制的配置骨架和验证步骤让你在本地把多 Agent 协作跑起来。适合谁看已经能跑通单 Agent、想进一步拆分职责的开发者正在设计 Agent 工作流、纠结要不要上多 Agent 的架构同学以及被“Agent 套 Agent 递归失控”坑过的人。2. 前置准备TaoToken 接入与 SDK 环境多 Agent 协作会频繁调用模型子 Agent 每次 spawn 都是一次独立的模型请求token 消耗比单 Agent 高不少。所以先把接入层配好避免后面调试时被额度或鉴权问题打断。TaoToken 的接入方式兼容 OpenAI 风格的 base_urlSDK 里只需要改 baseURL 和 apiKey 两个字段。先去控制台创建一个 API Key建议单独建一个用于多 Agent 场景的 Key方便按项目统计消耗。创建 Key 的入口在控制台的 API Keys 页面生成后复制保存页面关闭后不再显示完整值。接入文档里有各语言的最小示例Swift 项目直接看 baseURL 配置那一段即可。注意多 Agent 场景下子 Agent 会继承父 Agent 的 apiKey 和 baseURL所以只需要在创建主 Agent 时配置一次不用给每个子 Agent 单独传。这一点在 DefaultSubAgentSpawner 的实现里已经处理好了。环境上确认三件事SDK 版本支持 AgentTool 和 TaskStore较新的版本才有本地能正常访问 API 端点项目里已经有一个能跑通的最小 Agent 示例作为基线。如果基线还没跑通先回到单 Agent 那篇把基础流程走完否则多 Agent 出问题时你分不清是协作配置错了还是基础接入就没通。3. 可复制配置settings.json 与 config.toml 关键字段SDK 的配置分两层一层是项目级的 settings.json管模型、权限、工具白名单一层是运行时的 AgentOptions管单次会话的参数。多 Agent 协作主要动的是 AgentOptions但 settings.json 里的工具权限会直接影响子 Agent 能拿到哪些工具。先看 settings.json 里和多 Agent 相关的字段{ model: claude-sonnet-4-6, permissions: { allow: [Read, Glob, Grep, Bash, Agent, TaskCreate, TaskUpdate, TaskList], deny: [Write, Edit] }, agent: { maxTurns: 20, subagentMaxTurns: 10, allowSubagentSpawn: true } }这里有几个点值得说。allow里必须显式包含Agent否则主 Agent 拿不到 AgentTool就没法委派子 Agent。subagentMaxTurns控制子 Agent 的轮次上限默认 10探索类任务够用编码类任务可能要调到 15 到 20。allowSubagentSpawn是个总开关关掉后即使工具列表里有 Agent 也不会真正 spawn。如果你用 config.toml 管理配置对应的字段是这样[model] default claude-sonnet-4-6 subagent claude-sonnet-4-6 [agent] max_turns 20 subagent_max_turns 10 allow_subagent_spawn true [tools] base_tier core extra [Agent, TaskCreate, TaskUpdate, TaskList, TeamCreate, SendMessage] [team] default_leader self mailbox_enabled true[tools].extra里列的是在核心工具集之外额外注册的工具。多 Agent 协作至少需要 Agent、TaskCreate、TaskUpdate、TaskList 这四个如果要上团队协作再加 TeamCreate 和 SendMessage。运行时创建主 Agent 的代码骨架let taskStore TaskStore() let mailboxStore MailboxStore() let teamStore TeamStore() let agent createAgent(options: AgentOptions( apiKey: apiKey, baseURL: https://taotoken.net/api, model: claude-sonnet-4-6, agentName: coordinator, systemPrompt: You are a coordinator. Break complex tasks into subtasks, \ delegate each to a sub-agent via the Agent tool, then synthesize results. , maxTurns: 20, tools: getAllBaseTools(tier: .core) [ createAgentTool(), createTaskCreateTool(), createTaskUpdateTool(), createTaskListTool() ], taskStore: taskStore, mailboxStore: mailboxStore, teamStore: teamStore ))注意taskStore、mailboxStore、teamStore这三个是共享实例主 Agent 和子 Agent 用的是同一份。子 Agent 通过 ToolContext 拿到这些 store 的引用所以任务和消息是全局可见的。4. 子代理注册与任务分发流程子 Agent 的生成不是 AgentTool 直接 new 一个 Agent中间隔了一层 SubAgentSpawner 协议。这个协议定义在 Types 层具体实现在 Core 层通过 ToolContext.agentSpawner 注入。这样 Tools 层不需要导入 Core 层是典型的依赖倒置。DefaultSubAgentSpawner 在 spawn 时做了四件事过滤掉 AgentTool 防止无限递归按 allowedTools 过滤工具按 disallowedTools 再过一遍优先级更高创建子 Agent 并 await 执行。关键点是子 Agent 默认继承父 Agent 的所有工具但永远拿不到 AgentTool所以不会出现 Agent 套 Agent 套 Agent 的情况。AgentTool 内置了两种预定义子 Agent 类型。Explore 用于代码库探索工具集是 Read、Glob、Grep、BashmaxTurns 为 10。Plan 用于软件架构设计工具集相同但系统提示词是架构师角色。LLM 调用时通过 subagent_type 字段指定{ prompt: Explore the project structure and find all Swift source files, description: Explore codebase, subagent_type: Explore }任务分发的完整链路是这样的用户发 prompt主 Agent 判断需要探索代码库调用 AgentToolAgentTool 通过 spawner 生成 Explore 子 Agent子 Agent 用 Glob/Grep/Read 执行探索结果返回给主 Agent主 Agent 汇总后回复用户。如果你想注册自定义子 Agent 类型可以在 AgentTool 的 BUILTIN_AGENTS 之外扩展。自定义类型的核心是定义 name、description、systemPrompt、tools、maxTurns 五个字段。description 很重要LLM 是根据它来决定什么时候用哪个子 Agent 的写得太模糊会导致委派错误。任务分发时主 Agent 通常会配合 Task 系统一起用。典型流程是TaskCreate 创建任务Agent 委派子 Agent 执行TaskUpdate 标记完成并写入 output。这样每个子任务的执行结果都有记录主 Agent 汇总时不用靠记忆。5. 验证请求与成功结果配置写完后怎么确认多 Agent 协作真的生效了光看最终输出不够因为主 Agent 可能自己把活干了。要看中间过程。最直接的方式是监听 stream 消息打印 toolUse 和 toolResultfor await message in agent.stream( Explore the current project directory. Find all Swift source files, \ examine the project structure, and provide a summary. \ Use the Agent tool to delegate this task to an Explore sub-agent. ) { switch message { case .toolUse(let data): if data.toolName Agent { print([Sub-agent Delegation: \(data.toolName)]) } case .toolResult(let data): print([Result: \(data.content.prefix(200))]) case .result(let data): print(Turns: \(data.numTurns), Cost: $\(data.totalCostUsd)) default: break } }成功的标志是看到[Sub-agent Delegation: Agent]这行输出。如果只看到 Read、Glob 这些工具调用没有 Agent说明主 Agent 自己干了要么是系统提示词没写清楚要么是 AgentTool 没注册进去。另一个验证点是 Task 状态。跑完后调 TaskList 看任务列表let tasks await taskStore.list(status: nil, owner: nil) for task in tasks { print(\(task.id) - \(task.status.rawValue) - \(task.subject)) }正常应该看到任务从 pending 流转到 completedowner 字段是子 Agent 的名字。如果任务一直是 pending说明子 Agent 没被正确 spawn或者 spawn 后没调 TaskUpdate。日志层面SDK 会输出子 Agent 的 spawn 记录包含 subagent_type、model、maxTurns 这些参数。如果日志里没有 spawn 记录但最终结果是对的那基本可以确定是主 Agent 自己完成的。6. 本篇常见错排查错误一AgentTool 未注册主 Agent 无法委派。症状是主 Agent 一直自己调 Read/Grep从不调 Agent。检查 tools 列表里有没有 createAgentTool()以及 settings.json 的 allow 里有没有 Agent。两者缺一不可。错误二子 Agent 递归失控。症状是 token 消耗异常高日志里出现多层 spawn。正常情况下 DefaultSubAgentSpawner 会过滤掉 AgentTool子 Agent 拿不到 Agent 工具。如果你自定义了 spawner 实现确认过滤逻辑还在。另外检查 allowSubagentSpawn 是不是被误开了递归。错误三TaskUpdate 报 invalidStatusTransition。症状是 LLM 收到错误提示任务状态没更新。原因是试图把 completed/failed/cancelled 这些终态改成其他状态。终态不可逆转是设计约束LLM 需要先 TaskList 看当前状态再决定操作。如果频繁出现在系统提示词里加一句“更新任务前先查询当前状态”。错误四SendMessage 校验失败。症状是消息发不出去返回错误。SendMessageTool 有三层校验必须有 MailboxStore、必须有 TeamStore、发送者必须在某个 Team 里、收件人必须是同 Team 成员。任何一层不满足都会失败。排查时先确认 TeamCreate 是否成功再看发送者和收件人是否都在 members 列表里。广播用 * 作为收件人不需要校验成员关系。错误五子 Agent 拿不到父 Agent 的工具。症状是子 Agent 执行时报“工具不存在”。子 Agent 默认继承父 Agent 的工具集除了 AgentTool但如果你在 spawn 时传了 allowedTools就只会保留白名单里的工具。检查 spawn 参数里的 allowedTools 和 disallowedToolsdisallowedTools 优先级更高会覆盖 allowedTools。错误六Mailbox 读取后消息丢失。MailboxStore.read() 是破坏性读取读一次邮箱就清空了。如果 Agent 读了消息但没处理完就崩溃消息就没了。这是拉取模式的固有代价设计上假设 Agent 读取后会立即处理。如果需要消息持久化得自己在 read 之后做备份。7. 下一步从跑通到用好跑通最小协作场景后下一步是把它用到实际工作流里。三个方向可以按需选。如果你主要做代码探索和重构重点打磨 Explore 和 Plan 两种子 Agent 的提示词让它们输出的结果格式统一主 Agent 汇总时更省 token。如果你要做长期运行的编码任务考虑上 Coding Plan它把多轮编码的上下文管理和任务编排做了封装比手写 Task 流转省事。如果你还在验证模型选型和协作效果先用模型对话把不同模型的委派决策质量对比一下再决定生产环境用哪个。接入相关的 Key 管理和文档入口API Keys 在控制台创建接入文档有各语言的最小示例。多 Agent 场景建议单独建 Key方便按项目统计消耗。最后说一个实测下来的经验多 Agent 协作的收益不是线性的。两个 Agent 协作可能比单 Agent 快 30%但四个 Agent 可能因为协调开销反而变慢。先从两个角色拆起一个探索、一个执行确认协作链路稳定后再加角色。任务编排的复杂度要匹配任务本身的复杂度别为了多 Agent 而多 Agent。
