ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

多智能体系统落地架构实战:从协作模式到并发扛压的工程指南

多智能体系统落地架构实战:从协作模式到并发扛压的工程指南

多智能体系统这两年从论文里走出来,真正开始进入工程落地阶段,我参与过几个从零到一的多 Agent 项目,也接手过别人做了一半烂尾的架构。说实话,大部分失败案例不是因为模型不够强,而是架构设计从一开始就错了——把多智能体当成了"多个 Agent 各干各的然后拼起来",结果调试的时候根本不知道问题出在哪个环节。这篇内容我想把多智能体系统落地架构这件事拆开讲清楚,从协作模式选型、编排层设计、通信机制、状态管理到并发扛压,每个环节都给出我实际踩过坑之后总结的方案。适合正在做 Agent 开发、准备把 Demo 推向生产环境的工程师,也适合想理解多智能体系统到底怎么落地的人。

1. 先搞清楚多智能体系统到底解决什么问题

1.1 单 Agent 的能力天花板在哪里

很多人一开始会问:我一个大模型加一套工具调用不就能干活了吗,为什么要搞多个 Agent?这个问题问得对,因为如果你连单 Agent 都没跑通,上多智能体就是自找麻烦。单 Agent 的天花板主要体现在三个地方。

第一是上下文窗口的物理限制。一个 Agent 如果既要理解用户意图、又要检索知识库、又要调用工具、又要生成最终结果,所有中间过程都塞在一个上下文里,token 消耗会急剧膨胀。我实测过一个客服场景,单 Agent 处理一轮复杂咨询平均消耗 12000 token,其中超过 60% 是重复的工具返回结果和中间推理过程。上下文一长,模型注意力就会涣散,开始出现"忘记前面说过什么"的情况。

第二是职责耦合导致的提示词冲突。你希望 Agent 既能严谨地做数据分析,又能灵活地和用户闲聊,这两个目标写在同一个 system prompt 里会互相打架。模型在"严谨"和"灵活"之间摇摆,结果两头都不讨好。这是 prompt engineering 层面的根本矛盾,不是调参能解决的。

第三是错误无法隔离。单 Agent 一旦在某一步推理跑偏,后面全盘皆输,而且你很难定位是哪一步出的问题。多智能体架构的核心价值之一就是把错误限制在单个 Agent 内部,让整个系统的鲁棒性上一个台阶。

1.2 多智能体不是"多个 Agent 拼起来"这么简单

我见过最常见的错误认知就是:多智能体 = 把任务拆成几块,每块交给一个 Agent,然后串起来。这个理解只对了 30%。真正的多智能体系统要解决的是协作问题,而协作的难点在于:Agent 之间怎么通信、谁来决定下一步做什么、出现冲突怎么仲裁、状态怎么共享、失败了怎么回滚。

举个具体的例子。一个电商订单处理场景,你拆成了"意图识别 Agent""库存查询 Agent""价格计算 Agent""下单 Agent"。如果只是简单串联,意图识别错了后面全错;库存查询和价格计算如果并行,价格算出来库存已经没了怎么办;下单失败要不要回滚前面的操作。这些问题不是"多几个 Agent"能解决的,而是需要一套编排机制来协调。

所以我在做架构设计时,第一件事不是画 Agent 分工图,而是先想清楚:这个系统的控制流是什么样的,是中心化的还是去中心化的,是串行还是并行,有没有条件分支和循环。控制流想清楚了,Agent 的划分自然就出来了。

1.3 什么场景真的需要多智能体

不是所有场景都值得上多智能体。我的判断标准是三条:任务是否可以清晰分解为子任务、子任务之间是否有明确的依赖关系、单个子任务是否需要独立的工具集或知识库。

适合的场景比如:复杂研究报告生成(检索、分析、撰写、审校分离)、多步骤业务流程自动化(审批、查询、计算、执行)、需要多角色协作的模拟(辩论、评审、头脑风暴)。不适合的场景比如:简单的问答、单一工具调用、实时性要求极高的场景(多 Agent 通信本身有延迟开销)。

提示:如果你用单 Agent 加几个工具就能搞定,千万别上多智能体。多智能体带来的调试复杂度、延迟开销、token 成本都是成倍增加的,收益不明显的时候就是负优化。

2. 协作模式选型:别一上来就上全自动

2.1 四种主流协作模式的适用边界

多智能体协作模式大致可以分成四类,我按控制强度从高到低排一下,方便你对照自己的场景选。

协作模式控制方式适用场景典型框架思路
流水线式固定顺序,前一个输出是后一个输入步骤明确、依赖线性的任务顺序编排
主管式一个协调 Agent 分配任务给执行 Agent任务可分解但顺序不固定中心化编排
黑板式所有 Agent 共享一块状态区,各自读写需要多轮迭代、信息汇聚共享状态
群集式Agent 之间自由通信,无中心探索性、开放性任务去中心化

流水线式最简单,也最容易被低估。我做过一个合同审核系统,就是"抽取条款 → 风险识别 → 合规检查 → 生成报告"四步流水线,稳定跑了半年没出过大问题。它的好处是每一步的输入输出都是确定的,调试的时候可以单独测每个环节。

主管式是目前企业级落地用得最多的。一个"调度 Agent"负责理解任务、拆解、分派、汇总,其他 Agent 只管执行。这种模式的好处是控制流集中,容易观测和干预。缺点是调度 Agent 本身可能成为瓶颈和单点故障。

黑板式适合那种需要反复迭代的场景,比如多轮辩论、方案评审。所有 Agent 往一块共享区域写自己的观点,然后有一个仲裁机制决定什么时候收敛。这种模式实现起来最复杂,因为要处理并发写入和冲突。

群集式我目前只在实验性项目里用过,生产环境慎用。Agent 之间自由通信很容易陷入无限循环或者话题发散,没有强约束的话基本不可控。

2.2 为什么我建议从主管式起步

如果你不确定选哪种,我的建议是从主管式开始。原因有三个。

第一,主管式最接近人类团队的工作方式,一个项目经理带几个执行者,这个心智模型容易理解也容易向业务方解释。第二,主管式的控制流是显式的,你可以在调度 Agent 里加日志、加断点、加人工审核节点,观测性最好。第三,主管式容易演进,后面如果某个执行 Agent 需要变成子团队,直接在那个节点挂一个子调度器就行,架构不用大改。

我实际项目里的做法是:调度 Agent 不直接干活,只做三件事——任务分解、结果汇总、异常处理。执行 Agent 各自封装好自己的工具和知识库,对外只暴露一个清晰的输入输出接口。这样调度层和执行层可以独立迭代,互不影响。

2.3 混合模式才是生产环境的常态

纯理论上的四种模式在实际项目里很少单独出现,大部分生产系统是混合的。我最近做的一个投研报告系统就是典型:顶层是主管式(一个总调度分派"数据收集""分析""撰写"三个子任务),数据收集内部是流水线式(先搜再筛再结构化),分析环节是黑板式(多个分析 Agent 往共享区写观点,最后仲裁收敛)。

这种混合架构的关键是每一层的协作模式要匹配那一层的任务特性。线性依赖的用流水线,需要分派的用主管,需要迭代的用黑板。不要为了架构统一而强行用一种模式,那样只会让某些环节别扭。

设计混合模式时有个经验:层数不要超过三层。超过三层之后,调试链路会变得极长,一个错误要穿过好几层才能定位。如果发现需要四层以上,说明你的任务分解粒度太细了,应该合并一些 Agent。

3. 编排层设计:整个系统的大脑

3.1 编排层到底管什么

编排层是多智能体系统里最容易被做薄的一层,很多人以为编排就是"按顺序调用 Agent",结果做出来的东西脆弱得不行。我理解的编排层至少要管四件事:任务路由、状态管理、异常处理、可观测性。

任务路由决定一个输入该交给哪个 Agent,或者一组任务该怎么分派。这里有个常见误区是用大模型来做路由,觉得灵活。但大模型路由有两个问题:一是慢,每次路由都要一次推理;二是不稳定,同样的输入可能路由到不同地方。我的做法是规则路由优先,大模型路由兜底。能明确判断的用规则,判断不了的才交给模型。

状态管理是编排层的核心。多智能体系统里,每个 Agent 都有自己的局部状态,但整个任务有一个全局状态。全局状态要记录:当前进行到哪一步、每步的输入输出、中间产物、错误信息。这块设计不好,后面做断点续跑、人工干预、结果追溯都会很痛苦。

3.2 用工作流引擎还是自己写编排

这是被问得最多的问题。我的答案是:看你的任务复杂度。

如果任务流程是固定的、分支不多的,直接用代码写编排逻辑就行,一个状态机加几个 if-else 足够,引入工作流引擎反而是负担。我见过有人为了一个五步的固定流程引入了一套重型工作流框架,结果配置比代码还长。

但如果任务流程是动态的、分支多、需要人工审核节点、需要可视化流程,那工作流引擎就值得引入。它能帮你处理状态持久化、重试、超时、人工节点这些通用问题,不用自己造轮子。

我自己的判断线是:流程分支超过 5 个,或者需要人工介入节点,就上工作流引擎。低于这个复杂度,自己写更轻更快。

3.3 编排层的状态持久化怎么做

状态持久化这块我踩过坑,值得单独说。早期项目我把状态放在内存里,结果服务一重启,所有进行中的任务全丢了。后来改成持久化,又遇到状态膨胀的问题——一个长任务跑下来,状态数据能到几十 MB。

我的方案是分层持久化:全局状态(任务 ID、当前步骤、状态标记)存数据库,轻量且频繁读写;中间产物(大文本、结构化数据)存对象存储,只在状态里存引用。这样状态表始终很小,查询快,中间产物也不占数据库空间。

还有一个细节:状态要设计成可重放的。也就是说,给定一个状态快照和后续的输入,系统能重新推导出后续所有状态。这样出问题的时候可以回放排查,也方便做断点续跑。实现上就是把每个 Agent 的调用设计成纯函数式的——相同输入必然产生相同输出,副作用(比如写数据库、发消息)单独抽出来。

4. Agent 之间的通信与状态共享

4.1 消息传递还是共享内存

Agent 之间怎么交换信息,有两种基本范式:消息传递和共享内存(共享状态区)。

消息传递就是 Agent A 把结果打包成消息发给 Agent B。好处是解耦彻底,A 不需要知道 B 的存在,只认消息格式。坏处是消息格式一旦变更,所有相关 Agent 都要改。而且消息传递是异步的,调试的时候追踪一条消息的完整链路比较麻烦。

共享内存就是所有 Agent 读写同一块状态区。好处是信息天然同步,一个 Agent 写了另一个马上能读到。坏处是并发写入要加锁,而且状态区容易变成"什么都往里塞"的垃圾桶,最后没人说得清里面有什么。

我的实践是混合用:控制信息(任务分派、状态变更)用消息传递,数据信息(中间产物、共享知识)用共享状态区。控制信息量小、需要明确追踪,适合消息;数据信息量大、需要多方访问,适合共享。

4.2 通信协议的设计要点

不管用哪种方式,通信协议的设计有几个硬性要求。

第一,消息必须自描述。每条消息要带:发送者、接收者、消息类型、时间戳、关联的任务 ID、payload。没有这些元信息,出了问题根本没法排查。我见过一个系统消息里只有 payload,结果线上出问题的时候完全不知道这条消息是谁发的、属于哪个任务。

第二,消息要幂等。同一个消息被处理两次,结果应该和处理一次一样。因为分布式环境下消息重投是常态,不幂等的消息会导致重复执行。实现上就是给每条消息一个唯一 ID,接收方记录已处理的消息 ID,重复的直接丢弃。

第三,要有超时和重试机制。Agent 调用可能因为各种原因卡住,没有超时机制的话整个流程就挂在那里。我的默认配置是单次调用超时 30 秒,重试 2 次,重试间隔指数退避。超过重试次数就标记为失败,交给编排层处理。

4.3 共享状态的并发控制

共享状态区最大的坑是并发写入。多个 Agent 同时往同一块区域写,不加控制的话数据会互相覆盖。

最简单的方案是加锁,但锁的粒度要控制好。粗粒度锁(整个状态区一把锁)会导致所有 Agent 串行化,失去并行的意义。细粒度锁(每个字段一把锁)实现复杂,容易死锁。我的做法是按逻辑分区加锁,比如"库存区""价格区""订单区"各自一把锁,Agent 只锁自己操作的分区。

另一个方案是乐观并发控制:每个状态带一个版本号,写入时检查版本号是否变化,变了就重试。这个方案适合读多写少的场景,避免了锁的开销。我一般对高频写的区域用锁,对低频写的区域用乐观控制。

注意:共享状态区一定要有 schema 约束,不能随便往里塞。我建议用结构化的数据格式(比如 JSON Schema 或者 Protobuf)定义每个字段的类型和含义,写入前做校验。没有约束的共享状态区,三个月后就是一团乱麻。

5. 并发扛压:多智能体系统的性能命门

5.1 多智能体系统的并发瓶颈在哪

多智能体系统的并发瓶颈和普通 Web 服务不一样。普通服务的瓶颈通常在数据库或者网络 IO,多智能体系统的瓶颈主要在三个地方:模型调用配额、编排层吞吐、状态存储读写。

模型调用配额是最硬的瓶颈。每个模型 API 都有速率限制,多智能体系统因为 Agent 多、调用频繁,很容易撞到限制。我做过一个统计,一个中等复杂度的多智能体任务,平均要调用模型 15 到 30 次。如果并发 100 个任务,就是每秒上千次调用,大部分 API 配额都扛不住。

编排层吞吐是第二个瓶颈。编排层要做任务路由、状态更新、消息转发,如果这些操作都是同步阻塞的,编排层很快就会被拖垮。我的做法是编排层尽量无状态化,所有状态操作走异步,编排层本身只做轻量的路由和转发。

状态存储读写是第三个瓶颈。前面说了状态要持久化,但持久化就意味着每次状态变更都要写存储。如果状态变更频繁,存储压力会很大。解决方案是批量写入加缓存:状态变更先写内存缓存,定期批量刷到存储,读的时候优先读缓存。

5.2 限流、排队、降级的组合拳

扛并发不是靠单一手段,而是限流、排队、降级三件套组合。

限流是在入口处控制进入系统的任务数量。我的配置是按模型配额反推:假设模型 API 每秒允许 100 次调用,一个任务平均 20 次调用,那系统每秒最多处理 5 个任务。超过的任务直接拒绝或者排队。

排队是把超出的任务放进队列,等系统有空闲再处理。队列要有优先级,重要任务优先。还要有超时,排队超过一定时间的任务直接失败,避免用户无限等待。

降级是系统压力大的时候降低服务质量。比如把一些非核心的 Agent 调用跳过,或者用更小的模型替代大模型,或者减少重试次数。降级策略要提前设计好,不能等系统崩了才临时想。

这三件套的组合逻辑是:入口限流挡住大部分突发流量,排队消化正常波动,降级应对极端情况。三者配合,系统才能在压力下保持可用。

5.3 实测中的并发调优经验

分享几个我实测出来的调优经验。

第一,Agent 调用要池化。不要每次调用都新建连接,用连接池复用。我实测连接池能把单次调用的开销降低 30% 到 50%。

第二,批量化能省很多。如果多个 Agent 的调用可以合并成一次批量调用(比如批量 embedding、批量分类),一定要合并。批量调用的吞吐量比单次调用高一个数量级。

第三,异步化要彻底。编排层到 Agent 的调用、Agent 到模型的调用、状态写入,全链路异步。只要有一个环节是同步阻塞的,整个链路的并发能力就被那个环节限制住。

第四,压测要模拟真实分布。不要用均匀的请求压测,真实场景的请求分布是长尾的,有大量简单任务和少量复杂任务。压测的时候要按真实分布来,否则压出来的数据没参考价值。

6. 落地时最容易翻车的几个地方

6.1 Agent 职责划分的粒度陷阱

Agent 划分太粗,等于没拆;划分太细,通信开销爆炸。我见过一个项目把"读取用户输入"都单独做了一个 Agent,结果一个简单任务要经过七八个 Agent,延迟高得没法用。

我的经验法则是:一个 Agent 应该对应一个明确的、可独立测试的能力单元。判断标准是,这个 Agent 能不能单独写单元测试,输入输出是不是清晰的。如果一个 Agent 的职责需要看其他 Agent 的代码才能理解,那就是划分有问题。

另一个经验是先粗后细。一开始划分得粗一点,跑起来之后发现哪个 Agent 太忙或者职责太杂,再拆。反过来先细后粗,合并起来会很痛苦,因为接口已经散出去了。

6.2 错误传播与死循环

多智能体系统最怕两种错误:错误传播和死循环。

错误传播是指一个 Agent 的错误输出被下游 Agent 当成正常输入继续处理,错误像滚雪球一样越滚越大。防范方法是在每个 Agent 的输出上加校验,格式不对、内容异常的直接拦截,不让它流到下游。校验可以是规则的(格式检查),也可以是模型的(让一个校验 Agent 判断输出是否合理)。

死循环是指 Agent 之间互相调用形成环,或者一个 Agent 反复重试同一个失败的操作。防范方法是设置最大迭代次数和最大调用深度。我的默认配置是单个任务最多 50 次 Agent 调用,超过就强制终止并报错。这个数字要根据任务复杂度调,太低了正常任务跑不完,太高了死循环要很久才能发现。

6.3 可观测性:出问题能查到根因

多智能体系统如果可观测性做不好,出了问题就是黑盒。我要求每个项目必须做到三件事:全链路追踪、关键节点日志、状态快照。

全链路追踪是给每个任务一个 trace ID,所有 Agent 调用、模型调用、状态变更都带上这个 ID,这样能还原一个任务的完整执行路径。关键节点日志是在任务开始、Agent 调用前后、任务结束这些节点打日志,记录输入输出和耗时。状态快照是定期把全局状态存下来,出问题的时候可以回放。

这三件事做下来,排查问题的效率能提升好几倍。我接手过一个没有可观测性的系统,排查一个偶发错误花了两天,后来加上追踪之后,同类问题十分钟就能定位。

7. 从 Demo 到生产的演进路径

7.1 分阶段演进而非一步到位

多智能体系统不要想着一步到位做成生产级。我的建议是分三个阶段演进。

第一阶段是验证阶段,目标是跑通核心流程。这个阶段用最简单的架构,主管式加几个执行 Agent,状态放内存,不做持久化,不做并发控制。重点是验证任务分解是否合理、Agent 之间的接口是否清晰。

第二阶段是加固阶段,目标是让系统稳定。这个阶段加状态持久化、加错误处理、加重试和超时、加基础的可观测性。并发能力先不做优化,能扛住小规模流量就行。

第三阶段是扩展阶段,目标是扛住生产流量。这个阶段做并发优化、做限流排队降级、做完整的可观测性、做容量规划。

每个阶段都有明确的验收标准,不要跳阶段。我见过太多项目在第一阶段还没跑通的时候就想着做第三阶段的优化,结果基础不牢,后面全是返工。

7.2 哪些能力可以后补,哪些必须一开始就有

有些能力可以后补,有些必须一开始就设计好。

可以后补的:并发优化、限流降级、可视化界面、多租户支持。这些是在系统跑通之后逐步加的,不影响核心架构。

必须一开始就有的:Agent 的接口设计、状态的数据结构、错误处理的基本框架、trace ID 的贯穿。这些是架构的地基,后面改起来伤筋动骨。特别是 trace ID,如果一开始没设计,后面想加就要改所有 Agent 的代码。

我的做法是在第一阶段就把 trace ID 和状态数据结构定下来,哪怕实现很简单,但结构要在。这样后面加固和扩展的时候,不用动地基。

7.3 团队协作与迭代节奏

多智能体系统的开发对团队协作有特殊要求。因为 Agent 之间是解耦的,不同人可以并行开发不同的 Agent,但接口必须先对齐。

我的做法是先定接口再并行开发。接口包括:Agent 的输入输出格式、消息协议、状态字段定义。接口定下来之后,每个人可以独立开发自己的 Agent,用 mock 数据测试。等所有 Agent 都开发完,再做集成测试。

迭代节奏上,我建议小步快跑。每次只改一个 Agent 或者一个环节,改完立刻测,测完立刻上。不要攒一大堆改动一起上,那样出问题很难定位是哪个改动引起的。

8. 一些实战中的零散心得

8.1 关于模型选型

多智能体系统里不同 Agent 对模型的要求不一样。调度 Agent 需要强推理能力,用大模型;执行 Agent 如果任务简单,用小模型就够。我实测下来,把执行 Agent 换成小模型,整体成本能降 60% 以上,效果损失很小。

还有一个经验是同一个 Agent 的不同环节可以用不同模型。比如一个 Agent 先做意图理解(需要强模型),再做格式化输出(小模型足够),分开用能省不少。

8.2 关于提示词管理

多智能体系统里提示词数量多,管理不好会乱。我的做法是提示词集中管理,版本化。所有提示词放在一个地方,每个提示词有版本号,Agent 调用的时候指定版本。这样改提示词的时候可以灰度,出问题可以回滚。

另外,提示词里要包含 Agent 的职责边界说明。明确告诉模型"你只负责什么,不负责什么",能减少模型越界的情况。

8.3 关于测试

多智能体系统的测试比普通系统难,因为输出是不确定的。我的做法是分层测试:单元测试测单个 Agent 的输入输出格式和基本逻辑,集成测试测 Agent 之间的协作流程,端到端测试测完整任务的完成质量。

端到端测试不能只看最终结果对不对,还要看中间过程是否合理。我会用 trace 数据检查每个 Agent 的调用是否符合预期,有没有多余的调用或者跳过的步骤。

8.4 关于成本控制

多智能体系统的成本很容易失控,因为调用次数多。我的成本控制手段有三个:缓存、批量化、模型分级。缓存是相同输入直接返回缓存结果,避免重复调用;批量化是能合并的调用合并;模型分级是不同 Agent 用不同档次的模型。

还有一个容易被忽略的成本是重试成本。失败重试会成倍增加调用次数,所以要把失败率控制住。我的经验是失败率超过 5% 就要排查,超过 10% 就要停下来优化,不然成本会失控。

8.5 关于人工介入

生产环境的多智能体系统一定要留人工介入的口子。有些任务 Agent 处理不了,或者处理结果不确定,需要人来判断。人工介入节点要设计成流程的一部分,而不是事后补救。

我的做法是在关键决策点设置人工审核,比如金额超过阈值、涉及敏感操作、Agent 置信度低的时候,自动转人工。人工处理完的结果要回流到系统,作为后续优化的依据。

多智能体系统的落地架构没有标准答案,每个场景的最优解都不一样。但有些原则是通用的:控制流要清晰、状态要可追溯、错误要能隔离、并发要能扛住、可观测性要做好。把这些地基打牢,上面的 Agent 怎么加都不会塌。我在实际项目里最大的体会是,多智能体系统的复杂度不在 Agent 本身,而在 Agent 之间的协调,把协调机制设计好,整个系统就稳了。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进