Agent 做到一定复杂度,会遇到一个很现实的瓶颈:任务太多、信息太杂,单个 Agent 处理不过来。

问题通常不在于模型不够聪明,而在于 context window、执行链路和注意力都有上限。强行把所有材料、所有步骤、所有判断都塞进同一个 Agent,短期看起来省事,长期很容易带来三个后果:上下文超限、质量下降、执行时间被拉长。

所以,并行编排不是为了显得架构复杂,而是为了解决一个朴素的问题:当一个 Agent 承担不了全部工作时,怎样把任务拆开,又能把结果收回来。

把工作分出去,而不是堆在一起

解决思路其实很直接:拆。

一个任务如果可以分解成几个相对独立的子任务,就没有必要让同一个 Agent 串行处理。更合理的方式是把每个子任务分配给专属的 子 Agent,让它们并行推进,再由 主控 Agent 负责调度、校验和汇总。

Anthropic 把这种模式称为 多智能体编排,也就是 Multiagent Orchestration。它的整体结构大致如下:

┌─────────────────────────────────────┐
│           主控 Agent                 │
│   接收任务,分解,分配,汇总结果        │
└──────┬──────────┬──────────┬────────┘
       │          │          │
       ▼          ▼          ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 子 Agent │ │ 子 Agent │ │ 子 Agent │
│  子任务A  │ │  子任务B  │ │  子任务C  │
│ 独立执行  │ │ 独立执行  │ │ 独立执行  │
└──────────┘ └──────────┘ └──────────┘
       │          │          │
       └──────────┴──────────┘
                  │
                  ▼
        ┌──────────────────┐
        │    汇总 / 输出    │
        └──────────────────┘

这个结构的重点不是多开几个 Agent,而是把职责边界先划清楚。每个子 Agent 只处理自己负责的那块信息,不需要理解全局背景;主控 Agent 不亲自陷入所有细节,而是保持对目标、进度、质量和依赖关系的控制。

主控和子 Agent 各自做什么

主控 Agent 的职责主要是三件事:分解任务、分配工作、整合结果。它需要理解全局目标,也需要判断哪些任务可以并行,哪些任务必须等待前置结果。

子 Agent 的职责则更窄:把分配给自己的那块任务做好。比如一个子 Agent 负责读代码,一个子 Agent 负责查文档,一个子 Agent 负责跑验证,一个子 Agent 负责做反向审查。它们不需要知道整个系统最终要怎么交付,只要把自己的输入、输出和边界处理清楚。

这种分工带来一个关键收益:子 Agent 的上下文只装自己的任务材料,不会被其他子任务的信息污染。任务越复杂,这个收益越明显。因为复杂任务里真正拖垮质量的,往往不是某一个步骤太难,而是无关信息太多,导致注意力被反复稀释。

但这里也有一个边界:主控不能只会分派任务,还要能判断子任务之间的依赖关系。如果两个子任务其实强依赖,硬拆成并行执行,就会产生重复劳动、结果冲突,甚至出现子 Agent 各自都正确、合在一起却不成立的情况。

模型选型不能只看强弱

并行编排里有一个容易被忽视的优化点:模型选型。

很多人会默认全链路使用同一个最强模型,这当然简单,但不一定划算。主控 Agent 需要做全局判断、任务拆分和结果取舍,通常更依赖推理和规划能力;子 Agent 如果只是执行明确的小任务,未必每个都需要最强模型。

Anthropic 的案例里,Spiral 这个写作工具就采用了分层设计:主控 Agent 用 Haiku 做任务路由和分发,子 Agent 用 Opus 做正式写作。路由工作更偏判断和调度,成本敏感;写作工作更依赖生成质量,所以使用更强模型。

┌─────────────────────────────────┐
│    主控 Agent(轻量模型)         │
│    路由、分发、汇总               │
│    决策简单,成本敏感             │
└──────┬──────────────┬───────────┘
       │              │
       ▼              ▼
┌────────────┐  ┌────────────┐
│ 子 Agent   │  │ 子 Agent   │
│(强模型)   │  │(强模型)   │
│ 执行复杂    │  │ 执行复杂    │
│ 子任务      │  │ 子任务      │
└────────────┘  └────────────┘

这个例子想说明的不是主控一定要用轻量模型、子 Agent 一定要用强模型,而是要按任务性质选模型。路由、分类、格式检查、简单抽取这类任务,可以考虑轻量模型;复杂写作、深度推理、代码修复、方案审查这类任务,再交给能力更强的模型。

换句话说,并行编排不只是为了提高速度,也是在做成本和质量的分层管理。同一条工作流里,不同角色应该承担不同难度的决策。

子 Agent 怎么通信

并行运行的子 Agent 彼此独立,但实际工作中经常需要共享中间结果。比如一个子 Agent 处理完日志分析,另一个子 Agent 需要基于这份分析继续定位问题;一个子 Agent 提取了接口清单,另一个子 Agent 要用这份清单生成测试设计。

比较稳定的通信方式是 共享文件系统:子 Agent 把自己的输出写到约定好的位置,需要这份输出的子 Agent 再直接读取。它不依赖额外网络服务,也不需要引入消息队列,结构简单,问题也容易排查。

相比之下,通过 context window 传递信息容易遇到长度限制;通过主控 Agent 中转又会增加主控负担,让主控从调度者变成搬运工。共享文件并不高级,但在 Agent 编排里很实用,因为它把中间结果变成了可检查、可复用、可追踪的材料。

当然,共享文件也要有基本约束。文件命名、输出格式、完成标记和错误信息都要提前约定,否则多个子 Agent 同时写入,很容易出现覆盖、误读和版本混乱。工程里很多麻烦不是来自工具太弱,而是来自协议太含糊。

主控必须看得见执行过程

并行编排里最容易出问题的环节,是主控 Agent 对子 Agent 执行状态的掌握。

如果子 Agent 只返回最终结果,主控 Agent 就是在盲调度:不知道任务跑到哪一步,不知道失败发生在哪里,也不知道结果是一次成功还是多轮修补后的产物。一旦最终输出有问题,只能整体重跑,排查成本很高。

更好的做法是让每个子 Agent 记录 执行日志,主控 Agent 可以在任意时间点查询某个子 Agent 的状态,而不是等所有任务结束后才知道发生了什么。日志不一定要很复杂,但至少要包含任务输入、当前阶段、关键决策、失败原因和最终产物位置。

这和软件测试里的思路是一致的:可观测性不是事后补救手段,而是设计阶段就应该放进去的能力。没有状态记录的并行编排,跑得越快,失控也越快。

哪些任务适合并行编排

不是所有任务都适合拆开跑。并行编排真正有收益,通常出现在这几类场景里:

适合并行编排的场景:

1. 数据量大,可以分批处理
   → 不同批次分给不同子 Agent 并行处理

2. 多个数据源需要同时查询
   → 各自负责一个数据源,结果汇总给主控

3. 同一任务需要多个视角
   → 不同子 Agent 从不同角度分析,主控综合

4. 多个独立子任务没有强依赖关系
   → 直接并行,互不干扰

反过来,如果子任务之间有严格前后依赖,或者任务本身太简单,不值得拆成多个执行单元,并行编排的收益就很有限。为了并行而并行,最后往往不是提升效率,而是增加调度、同步、排错和汇总成本。

一个比较实用的判断标准是:如果拆出去的子任务有清晰输入、独立产出、低耦合依赖,并且主控能明确验收结果,那就适合并行;如果子任务需要频繁互相确认,或者每一步都依赖全局判断,就更适合串行处理。

小结

并行编排的核心,是把 一个 Agent 做所有事 变成 主控 Agent 协调多个专注的子 Agent。主控负责全局目标、任务拆分、依赖控制和结果验收;子 Agent 负责局部执行、产物输出和状态记录。

真正值得关注的不是启动了多少个 Agent,而是任务边界是否清晰、通信协议是否稳定、执行过程是否可观测、模型分工是否合理。只有这些基础做好了,并行编排才会从形式上的多线程,变成真正可控、可扩展的工程能力。


FunTester 名片|万粉千文,百无一用


↙↙↙阅读原文可查看相关链接,并与作者交流