1. 多Agent协作到底在解决什么问题
单Agent跑任务,跑到一定复杂度就会撞墙。这不是模型能力不够,而是上下文窗口、任务耦合度和错误累积三个瓶颈同时发作。我最早做多Agent是在一个研报自动生成的项目里,单个Agent要同时负责数据清洗、趋势分析、图表生成和文案撰写,结果就是:上下文塞满之后,前面读进去的数据细节全被挤掉,生成的分析前后矛盾,而且一旦某一步出错,后面全盘崩。
多Agent协作的核心思路,说白了就是把"一个全能选手"拆成"一个项目组"。每个Agent有自己的角色、自己的上下文、自己的工具集,通过一套协作架构和任务调度机制串起来。这样做的好处很直接:
- 上下文隔离:每个Agent只关心自己那部分信息,窗口利用率高,不会被无关内容稀释注意力。
- 错误可控:某个Agent输出有问题,可以在调度层拦截、重试或换人,不会污染全局。
- 并行加速:没有依赖关系的子任务可以同时跑,整体耗时大幅下降。
- 可观测性:每个环节的输入输出都留痕,排查问题时有据可查。
但这里有个常见的误解需要先破掉:多Agent不是简单地把一个Prompt拆成几个Prompt分别调用。如果只是拆开调用、最后拼起来,那叫"批处理",不叫协作。真正的协作架构要解决三个问题——谁来决定任务怎么分、Agent之间怎么传递信息、出现冲突时谁来裁决。这三个问题对应到工程上,就是协作架构模式、通信协议和调度策略。
我在实际项目里踩过最典型的坑是:一开始觉得Agent越多越好,搞了七八个角色,结果调度逻辑复杂到没法维护,Agent之间互相等待,整体延迟比单Agent还高。后来砍到三个核心角色加一个调度器,反而跑得又快又稳。所以多Agent的第一原则不是"多",而是职责边界清晰、通信路径最短。
下面这张表是我总结的单Agent和多Agent的适用边界,你可以对照自己的场景判断该不该上多Agent:
| 维度 | 单Agent适用 | 多Agent适用 |
|---|---|---|
| 任务步骤 | 3步以内线性流程 | 多分支、有依赖的DAG |
| 上下文需求 | 单窗口能装下 | 超出单窗口或需要隔离 |
| 工具数量 | 少于5个 | 多工具集且分属不同领域 |
| 错误容忍度 | 出错可整体重跑 | 单点错误需局部修复 |
| 并行需求 | 无 | 存在可并行的子任务 |
| 维护成本 | 低 | 需要调度层和监控 |
判断标准很简单:当你发现一个Agent的Prompt里开始出现"如果...则...否则..."的大量分支,或者需要它同时扮演多个角色时,就该考虑拆了。
2. 四种主流协作架构的取舍逻辑
多Agent的协作架构,业界目前比较成熟的有四类。我不打算只列概念,而是结合我在项目里的实际选型过程,讲清楚每种架构什么时候该用、什么时候是坑。
2.1 流水线架构:最稳但最不灵活
流水线(Pipeline)就是A做完交给B,B做完交给C,像工厂流水线。这是最容易实现的架构,每个Agent只需要定义好输入输出格式,串起来就行。
我在一个合同审核项目里用过这个架构:提取Agent负责从PDF里抽出关键条款,比对Agent负责和标准模板对比找差异,风险Agent负责对差异项做风险评估,最后汇总Agent生成审核报告。四个环节严格串行,每个环节的输出就是下一个环节的输入。
这种架构的好处是调试极其简单,哪个环节出问题一目了然。但缺点也很明显:没有反馈回路。如果风险Agent发现某个条款需要重新提取更细的信息,它没法回头让提取Agent重做,只能把问题抛给人工。所以流水线适合步骤确定、无回溯需求的场景。
提示:流水线架构里,每个Agent的输出格式一定要用结构化数据(JSON最稳),不要传自然语言。我早期用自然语言传递,下游Agent经常误解上游意图,改成JSON Schema约束后,错误率下降了一个数量级。
2.2 层级调度架构:复杂任务的主力方案
层级架构(Hierarchical)是我目前用得最多的。它有一个调度Agent(Orchestrator)在最上面,负责把大任务拆成子任务,分给下面的执行Agent(Worker),然后收集结果、判断是否完成、决定是否继续拆解。
这个架构的关键在于调度Agent的拆解能力。我的经验是,调度Agent的Prompt里必须包含三样东西:任务分解规则、子任务完成标准、失败重试策略。缺一个都会导致调度失控。
举个实际例子,我做论文辅助写作系统时,调度Agent收到"写一篇关于某主题的综述"这个任务,它会拆成:文献检索、大纲生成、各章节撰写、引用校对、质量审核。其中"各章节撰写"又可以并行拆给多个写作Agent。调度Agent在每个子任务完成后检查输出质量,不达标就打回重做,最多重试两次,两次还不行就标记为需要人工介入。
层级架构的坑在于调度Agent容易成为瓶颈。如果所有决策都经过它,它的上下文会迅速膨胀。我的做法是给调度Agent设置决策摘要机制——它不需要记住每个子任务的完整输出,只需要记住"任务X已完成,质量评分Y,关键结论Z"这样的摘要。完整输出存在外部存储里,需要时再取。
2.3 黑板架构:适合探索型任务
黑板架构(Blackboard)的思路是:所有Agent共享一块"黑板"(共享内存/状态存储),每个Agent都可以读取黑板上的信息、贡献自己的结果,由一个控制Agent决定什么时候哪个Agent该上场。
这种架构适合没有固定流程、需要多轮迭代的任务,比如复杂的问题诊断、创意方案生成。我在一个故障根因分析的系统里用过:多个诊断Agent各自从不同角度分析(日志、指标、变更记录),把发现写到黑板上,控制Agent综合所有发现,判断是否需要触发新的诊断方向。
黑板架构最大的问题是状态管理复杂。多个Agent并发读写共享状态,很容易出现覆盖和冲突。我的解决方案是给黑板加上版本号和锁机制,每个Agent写入时带上自己的版本,控制Agent负责合并冲突。这块实现起来不轻松,如果团队没有分布式系统的经验,建议慎用。
2.4 对等协商架构:理想很丰满
对等架构(Peer-to-Peer)里没有中心调度,Agent之间直接通信、协商分工。听起来很美好,但实际落地非常难。通信开销大、容易死锁、难以调试,我在实验环境试过一次就放弃了。
目前我唯一会考虑对等架构的场景是Agent数量少(2-3个)且角色对等的情况,比如两个Agent互相审查对方的输出。超过三个,协商复杂度就指数级上升。
选型建议总结成一句话:能用流水线就别用层级,能用层级就别用黑板,对等架构除非有明确必要否则不碰。架构越复杂,维护成本越高,而多Agent系统本身的调试难度已经够大了。
3. 任务调度:多Agent系统的心脏
协作架构决定了Agent怎么组织,任务调度决定了任务怎么流动。这块是多Agent系统里最容易出问题、也最考验工程能力的地方。我见过太多项目,架构设计得很漂亮,一到调度就乱套。
3.1 任务分解的粒度控制
调度第一步是任务分解。分解粒度太粗,单个子任务还是超出Agent能力;太细,调度开销和通信开销吃掉所有收益。
我的经验法则是:每个子任务的预期执行时间控制在30秒到2分钟之间。低于30秒说明拆得太碎,可以考虑合并;高于2分钟说明可能还需要再拆,或者这个任务本身就该用更强的模型。
分解方式有两种:静态分解和动态分解。静态分解是提前把任务DAG定义好,适合流程固定的场景;动态分解是调度Agent根据任务内容实时决定怎么拆,灵活但不可控。
我现在的做法是混合式:顶层用静态分解定义大阶段,每个阶段内部用动态分解。比如论文写作系统,顶层固定是"检索→大纲→撰写→校对→审核"五个阶段,但"撰写"阶段内部拆几章、每章怎么分配,由调度Agent动态决定。
3.2 依赖管理与执行顺序
任务之间有依赖关系,调度器必须能正确处理。我用的是**DAG(有向无环图)**模型,每个任务节点记录它的前置依赖,只有所有前置完成才能执行。
实现上,我用一个就绪队列加完成计数器:每个任务维护一个未完成依赖计数,前置任务完成时递减,减到零就加入就绪队列。调度器从就绪队列取任务分配给空闲Agent。
这里有个细节很容易被忽略:循环依赖检测。动态分解时,如果调度Agent不小心拆出了循环依赖,整个系统会死锁。我的做法是在添加依赖边时做一次拓扑排序检查,发现环就拒绝这次分解并让调度Agent重新拆。
3.3 并发控制与资源分配
多个Agent并发执行时,要控制并发度。并发太高,API限流、成本飙升;太低,加速效果不明显。
我的配置是并发度 = min(可用Agent数, API速率限制/单任务平均调用次数, 预算约束)。实际项目里,我一般把并发控制在5-10之间,这个区间在成本和速度之间比较平衡。
资源分配上,不同任务对模型能力的要求不一样。我的策略是分级调度:简单任务(格式转换、信息提取)用便宜的小模型,复杂任务(推理、创作)用强模型。这样能在保证质量的前提下把成本压下来。具体分级标准可以看这张表:
| 任务类型 | 推荐模型档位 | 典型场景 |
|---|---|---|
| 格式转换、字段提取 | 轻量模型 | JSON解析、正则匹配 |
| 信息检索、摘要 | 中等模型 | 文档摘要、关键词提取 |
| 推理分析、内容创作 | 强模型 | 逻辑推理、长文撰写 |
| 质量审核、冲突裁决 | 强模型 | 终审、仲裁 |
3.4 失败重试与降级策略
多Agent系统里,失败是常态。API超时、输出格式错误、内容质量不达标,都会导致任务失败。调度器必须有完善的重试和降级机制。
我的重试策略是指数退避 + 最大次数限制:第一次失败等2秒重试,第二次等4秒,第三次等8秒,最多三次。三次都失败,触发降级——要么换一个Agent重做,要么降低质量要求接受当前结果,要么标记为人工介入。
注意:重试时一定要把失败原因反馈给Agent。我早期重试就是原样再调一次,结果Agent犯同样的错误。后来改成把上次的错误信息拼进Prompt里,重试成功率明显提升。
降级策略要提前设计好,不能等出问题了临时想。我在项目里定义了三级降级:L1换Agent重试、L2降低输出要求、L3转人工队列。每级降级都记录日志,方便后续分析哪些环节最脆弱。
4. Agent之间的通信与状态共享
Agent之间怎么传信息,直接决定了系统的可靠性和可维护性。这块我踩过的坑最多,值得单独拿出来讲。
4.1 消息传递的格式约定
最基础的通信方式是消息传递:上游Agent把结果打包成消息,发给下游Agent。消息格式我强烈建议用结构化Schema,不要用自由文本。
我现在的标准做法是每个Agent定义两个Schema:输入Schema和输出Schema。输入Schema规定它需要哪些字段,输出Schema规定它必须产出哪些字段。调度器在传递消息前做一次Schema校验,不符合的直接拦截重试。
这样做的好处是错误在边界处就被发现,不会一路传到下游才暴露。我见过一个项目,上游Agent输出少了一个字段,下游Agent用空值继续跑,跑了五六个环节才发现结果全错,白白浪费了大量调用。
消息里除了业务数据,还要带上元信息:任务ID、来源Agent、时间戳、置信度。置信度这个字段特别有用,下游Agent可以根据上游的置信度决定是否需要额外验证。
4.2 共享状态的读写冲突
如果用黑板架构或者需要共享上下文,就会遇到并发读写问题。我的解决方案是乐观锁 + 版本号:每个状态块有版本号,Agent读取时记下版本,写入时检查版本是否变化,变了就重新读取再写。
更简单的方案是分区共享:把共享状态按Agent职责分区,每个Agent只写自己的分区,读可以跨区。这样从根本上避免了写冲突。我在大多数项目里用的都是分区方案,实现简单,效果够用。
4.3 上下文传递的裁剪策略
Agent之间传递上下文时,不能把上游的全部输出都塞给下游,那样上下文会爆炸。必须做裁剪。
我的裁剪策略是三层过滤:第一层只传下游明确需要的字段(按输入Schema);第二层对长文本做摘要,只传关键结论;第三层保留原始数据的引用(存储路径或ID),下游需要时再取。
这里有个经验:摘要要用同一个模型做,保证语义一致。我试过用不同模型做摘要,结果下游Agent理解出现偏差。统一用调度Agent或专门的摘要Agent来做,一致性有保障。
5. 从零搭建一个多Agent协同系统的实操路径
前面讲的是原理和取舍,这一节讲具体怎么落地。我以一个"技术调研报告自动生成"系统为例,完整走一遍搭建流程。这个系统要完成:给定一个技术主题,自动检索资料、分析对比、生成结构化报告。
5.1 角色划分与职责定义
第一步是定角色。我的原则是角色数量控制在3-5个,每个角色有明确的输入输出和不可替代的职责。这个系统我定了四个角色:
- 调度Agent:接收主题,拆解任务,分配执行,汇总结果,质量把关。
- 检索Agent:根据主题和子问题,调用搜索工具获取资料,输出结构化摘要。
- 分析Agent:对检索结果做对比分析,提取关键维度,输出分析结论。
- 撰写Agent:根据分析结论,生成报告正文,保证逻辑连贯和格式规范。
每个角色的Prompt都要写清楚:你是谁、你负责什么、你的输入是什么格式、你的输出必须是什么格式、遇到不确定怎么办。这五要素缺一不可。
5.2 调度器的核心逻辑实现
调度器是整个系统的大脑,我用Python实现,核心是一个状态机加任务队列。伪代码逻辑如下:
class Orchestrator: def __init__(self): self.task_queue = [] self.completed = {} self.max_retry = 3 def decompose(self, topic): # 调用调度模型拆解任务 subtasks = call_llm( prompt=DECOMPOSE_PROMPT, input=topic, output_schema=TASK_DAG_SCHEMA ) return subtasks def schedule(self, subtasks): ready = [t for t in subtasks if not t.dependencies] while ready or self.has_running(): for task in ready: agent = self.select_agent(task) result = agent.execute(task) if self.validate(result): self.completed[task.id] = result self.unlock_dependents(task) else: self.retry_or_degrade(task) ready = self.get_newly_ready()关键点在于validate和retry_or_degrade。validate做Schema校验和基础质量检查,retry_or_degrade按前面说的三级降级策略处理。
5.3 各Agent的Prompt工程要点
每个Agent的Prompt我都是反复调过的,分享几个关键要点:
检索Agent的Prompt里必须强调"只输出找到的事实,不要编造",并且要求它标注每条信息的来源。我还会让它对每条信息打一个置信度分,低置信度的信息在后续分析中会被降权。
分析Agent的Prompt要引导它按维度对比,而不是泛泛而谈。我会在Prompt里给出分析框架(比如技术成熟度、生态完善度、学习成本、适用场景),让它按框架填充。
撰写Agent的Prompt要控制结构和风格。我会给它一个报告模板,规定每部分的字数和要点,避免它自由发挥导致结构混乱。
调度Agent的Prompt最难写,核心是拆解规则和完成标准。我的做法是给它几个Few-shot示例,展示什么样的任务该怎么拆、拆到什么程度算合适。
5.4 跑通之后的性能调优
系统跑通只是开始,调优才是重头戏。我一般从三个维度优化:
延迟优化:分析每个环节的耗时,找出瓶颈。常见瓶颈是串行环节太多,能并行的没并行。我把检索和分析的部分子任务改成并行后,整体延迟从3分钟降到1分半。
成本优化:统计每个Agent的Token消耗,把简单任务下沉到便宜模型。这个系统优化后成本降了约40%,质量没有明显下降。
质量优化:收集失败案例,分析是哪个环节的问题,针对性改Prompt或加验证。我建了一个失败案例库,每次调优都从里面找模式。
6. 那些只有踩过才知道的坑
这一节讲几个我在多Agent项目里真实踩过的坑,都是文档里不会写、但实际会要命的问题。
6.1 Agent之间的"踢皮球"现象
有次做审核系统,审核Agent发现内容有问题,打回给撰写Agent,撰写Agent改完又交给审核Agent,审核Agent还是不满意,又打回。两个Agent来回踢了七八轮,Token烧了一大堆,问题没解决。
根因是审核标准不明确,审核Agent说不清哪里不行,撰写Agent也不知道该怎么改。后来我在审核Agent的Prompt里强制要求输出具体的修改建议,而不是只说"不合格",问题就解决了。
提示:任何有反馈回路的环节,都要确保反馈是可执行的。只说"不行"不说"怎么才行",必然导致死循环。
6.2 上下文污染导致的"集体失智"
有次系统跑着跑着,所有Agent的输出质量突然下降。排查发现是某个Agent输出了错误信息,这个信息被传递到下游,下游基于错误信息继续推理,错误像滚雪球一样放大。
解决方案是在每个环节加一道事实校验。对于关键事实(数字、名称、结论),下游Agent必须独立验证,不能直接采信上游。这道校验增加了成本,但避免了灾难性的错误传播。
6.3 调度器的"决策疲劳"
调度Agent如果连续做太多决策,它的输出质量会下降。我观察到跑了几十个任务后,调度Agent开始出现拆解不合理、分配错误的情况。
原因是上下文里积累的历史决策太多,干扰了当前判断。我的解决方法是定期重置调度Agent的上下文,只保留必要的状态摘要,历史决策归档到外部存储。重置后调度质量明显回升。
6.4 成本失控的隐形杀手
多Agent系统最容易成本失控的地方是重试和循环。一次失败重试看起来不多,但如果失败率高,重试成本会迅速累积。我见过一个项目,因为一个环节的Schema定义有歧义,导致30%的任务需要重试,成本直接翻倍。
控制成本的关键是监控失败率和重试率,设置告警阈值。我的经验是失败率超过10%就要停下来排查,不要让它一直跑。
7. 多Agent系统的监控与迭代
系统上线不是终点,持续监控和迭代才能让它稳定运行。这块我总结了一套自己的做法。
7.1 必须监控的核心指标
我监控的指标分三类:性能指标(延迟、吞吐)、质量指标(成功率、重试率、人工介入率)、成本指标(Token消耗、单任务成本)。
其中最重要的是人工介入率,它直接反映系统的自动化程度。我的目标是把这个指标压到5%以下,超过就说明某个环节需要优化。
7.2 失败案例的归因方法
每次失败都要归因,我用的方法是按环节统计 + 按错误类型统计。先看是哪个Agent出的问题,再看是什么类型的错误(格式错误、逻辑错误、事实错误)。归因清楚了,优化方向就明确了。
我建了一个简单的表格记录每次失败,跑一段时间后就能看出规律。比如发现检索Agent的事实错误最多,那就重点优化它的Prompt和验证逻辑。
7.3 渐进式迭代的节奏把控
多Agent系统的迭代不能太激进,一次改太多变量,出了问题都不知道是哪个改动导致的。我的节奏是一次只优化一个环节,改完观察一周,确认有效再动下一个。
这个节奏看起来慢,但实际比频繁大改要快,因为避免了反复回滚。我在项目里坚持这个节奏后,系统的稳定性提升非常明显。
8. 关于多Agent能力边界的一点个人判断
聊了这么多架构和实操,最后说点我自己的判断。多Agent不是银弹,它有明确的能力边界。
它擅长的是:任务可分解、步骤可定义、质量可验证的场景。比如文档处理、数据分析、内容生成这类结构化程度高的工作。
它不擅长的是:需要强创造性、需要实时交互、需求频繁变化的场景。这些场景下,多Agent的调度开销和协调成本会超过它带来的收益。
我现在的做法是先用单Agent跑,跑到撞墙再考虑多Agent。不要一上来就搞复杂架构,那是给自己找麻烦。多Agent的价值在于解决单Agent解决不了的问题,而不是为了显得技术先进。
另外,多Agent系统的维护成本比单Agent高一个数量级。调度逻辑、通信协议、状态管理、监控告警,每一样都要投入精力。如果团队没有相应的工程能力,建议先从简单的流水线架构起步,跑稳了再逐步复杂化。
我在实际项目里最大的体会是:多Agent系统的质量上限取决于最弱的那个环节,而不是最强的那个。所以与其花时间增强某个Agent的能力,不如先把每个环节的下限提上来。一个每个环节都80分的系统,比一个有的环节95分、有的环节60分的系统要可靠得多。