多智能体协作系统架构设计与工程实践:从角色划分到生产部署
1. 从agency-agents这个名字说起它到底在解决什么问题第一次看到agency-agents这个组合词很多人会愣一下——agency代理/机构加上agents智能体/代理者两个词义上有重叠放在一起到底指什么我最初接触这类项目时也有同样的困惑。拆开来看agency在这里更偏向代理机构或中介服务的业务语义而agents则指向当前技术语境下越来越热的智能体概念。合在一起它描述的是一类用多个智能体协作来替代或增强传统代理机构业务流程的系统。传统代理机构的运作模式本质上是一堆重复性信息处理工作的集合客户需求收集、资料审核、方案匹配、进度跟踪、多方沟通、结果交付。这些环节里真正需要人类判断力的部分其实占比不高大量时间消耗在信息搬运、格式转换、状态同步上。agency-agents这类项目的核心价值就是把这些搬运工性质的环节交给一组分工明确的智能体去自动完成人只需要在关键决策点介入。它适合谁来参考我梳理了三类典型读者。第一类是中小型代理服务团队的负责人手头业务量在增长但人力成本压得喘不过气想看看自动化能帮到什么程度第二类是全栈开发者或技术负责人需要为业务方搭建一套多智能体协作框架但不确定从哪个环节切入最稳妥第三类是产品经理和业务架构师想理解智能体协作在真实业务流里怎么落地而不是停留在Demo层面。这篇文章不会给你一个万能框架因为agency-agents这类项目最大的坑就是试图一步到位。我会从架构设计、智能体角色划分、协作机制、状态管理、异常处理这几个维度把我在实际搭建和调试过程中积累的经验拆开讲。每个部分都会说明为什么这样设计以及不这样设计会出什么问题让你能根据自己的业务场景做取舍。需要提前说明的是多智能体协作系统目前还没有形成像Web开发那样成熟的标准化方案很多决策依赖具体业务特征。我下面分享的是一套经过验证的通用思路但具体参数和实现细节需要你结合自己的场景调整。2. 智能体角色怎么划分才不打架从业务流倒推职责边界2.1 为什么不能按功能划分角色新手最容易犯的错误是拿到需求后直接按功能模块划分智能体一个负责收集信息一个负责处理数据一个负责输出报告。这种划分方式在简单场景下能跑通但一旦业务流出现分支或循环智能体之间就会陷入该谁处理的扯皮。我踩过的一个典型坑早期做一个客户资料审核流程设置了收集Agent和审核Agent。结果遇到资料不完整需要退回补充的情况收集Agent认为补充是审核Agent的职责审核Agent认为补充属于收集范畴两边互相等待流程直接卡死。后来复盘发现问题出在按功能划分导致职责边界与业务状态脱节。正确的做法是按业务角色划分让每个智能体对应业务流程中一个真实的岗位角色。比如代理机构里通常有客户对接人、资料审核员、方案匹配师、进度协调员这几个角色那就设置对应的智能体。每个智能体对自己的业务结果负责而不是对某个功能动作负责。2.2 角色划分的三个实操原则原则一一个智能体只对一个业务结果负责。客户对接Agent的KPI就是客户需求被准确理解并记录资料审核Agent的KPI就是资料合规性判断准确。当出现跨角色的异常时由流程编排层决定交给谁而不是让智能体自己协商。原则二角色数量控制在5到7个。我试过设置十几个细分角色结果协作开销急剧上升智能体之间的消息传递比实际业务处理还耗时。后来压缩到5个核心角色把边缘职责合并整体吞吐量反而提升了。这个数字不是绝对的但超过10个角色后你需要非常强的编排机制才能驾驭。原则三每个角色必须有明确的输入契约和输出契约。输入契约定义我需要什么格式的数据才能开始工作输出契约定义我产出什么格式的数据才算完成。这两个契约是智能体之间解耦的关键。没有契约智能体之间就会产生隐式依赖改一个角色影响一片。下面这张表是我在一个模拟代理业务系统中实际使用的角色划分方案供参考角色名称核心职责输入契约输出契约典型异常需求对接Agent理解并结构化客户需求原始对话/表单结构化需求JSON需求模糊无法结构化资料审核Agent判断资料完整性与合规性结构化需求附件审核结果缺失项列表附件格式无法解析方案匹配Agent根据需求匹配服务方案结构化需求审核通过标记候选方案列表匹配度无匹配方案进度协调Agent跟踪各环节状态并催办各角色状态事件进度报告催办指令某环节超时无响应交付汇总Agent整合结果并生成交付物各角色最终产出交付文档摘要产出格式不一致2.3 角色之间的权力关系要提前定好角色划分完之后还有一个容易被忽略的问题谁听谁的。在多智能体系统里如果没有明确的控制关系就会出现三个和尚没水喝的局面。我的经验是采用分层控制设置一个编排AgentOrchestrator作为调度中心它不执行业务逻辑只负责根据当前状态决定下一步该谁动。其他业务Agent只与编排Agent通信业务Agent之间不直接对话。这样做的好处是控制流清晰出问题时排查路径短——要么是编排逻辑错了要么是某个业务Agent的输出不符合契约不会出现A说是B的问题B说是C的问题这种扯皮。编排Agent的实现可以很简单一个状态机就够了。状态机的每个状态对应一个业务环节状态转移条件由业务Agent的输出触发。我通常用一张状态转移表来定义比写代码更直观也方便业务方review。3. 协作机制选型消息队列、共享状态还是事件驱动3.1 三种主流协作模式的适用场景智能体之间的协作机制直接决定了系统的吞吐量、可观测性和容错能力。我实际用过三种模式各有各的脾气。消息队列模式智能体之间通过队列传递消息生产者发完就不管消费者按自己的节奏处理。这种模式解耦最彻底适合业务环节之间处理速度差异大的场景。比如资料审核可能耗时几分钟而需求对接只要几秒用队列可以避免快角色等慢角色。但缺点是状态追踪困难一条消息发出去之后你很难知道它当前在哪个环节、被谁处理了。共享状态模式所有智能体读写同一个状态存储比如一个结构化的任务对象每个智能体根据自己的职责修改状态字段。这种模式状态最清晰任何时刻都能看到完整进度。但缺点是并发冲突两个智能体同时修改同一个字段时后写的会覆盖先写的。我遇到过进度协调Agent和交付汇总Agent同时更新任务状态导致状态跳变的问题。事件驱动模式智能体不直接通信而是发布和订阅事件。需求对接Agent完成工作后发布需求已结构化事件资料审核Agent订阅这个事件后开始工作。这种模式扩展性最好加一个新角色只需要订阅相关事件不用改现有代码。但缺点是事件链路难以追踪一个业务流可能触发几十个事件出问题时排查像大海捞针。3.2 我的实际选型混合模式纯用任何一种模式都有明显短板我最终采用的是一种混合方案编排层用状态机控制主流程业务Agent之间用事件驱动解耦关键状态用共享存储做快照。具体来说编排Agent维护一个主状态机记录当前业务处于哪个环节。每个业务Agent完成工作后除了发布事件通知编排Agent还会把结果写入共享状态存储。编排Agent收到事件后读取共享状态确认结果然后推进状态机。这样既有事件驱动的扩展性又有共享状态的可观测性还有状态机的控制力。这个方案听起来复杂但实现起来并不难。核心是定义清楚三样东西状态机的状态转移表、事件的类型和载荷格式、共享状态的schema。这三样定好之后各个Agent的实现可以独立开发互不干扰。3.3 消息传递的幂等性设计不管用哪种协作模式有一个问题必须提前考虑消息重复。在网络抖动、Agent重启、超时重试等情况下同一条消息可能被处理多次。如果处理逻辑不是幂等的就会产生重复数据或重复操作。我的做法是给每条消息分配一个全局唯一的消息ID业务Agent在处理前先检查这个ID是否已经处理过。已处理过的直接返回上次的结果不再执行。这个检查可以用共享状态存储实现也可以用独立的去重表。成本很低但能避免大量诡异问题。提示幂等性检查的存储要有过期机制否则去重表会无限增长。我通常设置24小时过期超过这个时间的重复消息概率极低即使重复处理影响也可控。4. 状态管理与上下文传递智能体怎么记住之前发生了什么4.1 为什么智能体需要外部记忆单个智能体在一次任务处理中可以靠自己的上下文窗口记住相关信息。但在多智能体协作场景下一个业务流可能跨越多个智能体、持续数小时甚至数天任何单个智能体的上下文都不足以承载完整历史。更关键的是智能体之间需要传递的不仅是当前任务是什么还包括之前做过什么决策为什么这样决策有哪些约束条件。这些信息如果丢失后续智能体就可能做出与前面矛盾的判断。我遇到过一个典型案例需求对接Agent在和客户沟通时客户明确说了预算不超过某个范围。这个约束如果没有传递给方案匹配Agent匹配出来的方案可能远超预算导致返工。后来我在共享状态里专门加了一个约束条件字段所有智能体都可以读取才解决了这个问题。4.2 共享状态的schema设计共享状态的schema设计直接决定了智能体之间能传递多少信息。设计得太简单信息不够用设计得太复杂维护成本高且容易出错。我的经验是采用分层schema最外层是任务元信息任务ID、创建时间、当前状态中间层是业务数据需求、资料、方案、进度最内层是协作元数据各角色的处理记录、决策依据、异常信息。业务数据部分根据具体业务定义协作元数据部分有通用结构。协作元数据我通常包含这几个字段处理角色、处理时间、输入摘要、输出摘要、决策依据、置信度。置信度这个字段特别有用当某个智能体的输出置信度低于阈值时编排Agent可以决定是否转人工复核而不是盲目往下走。4.3 上下文窗口的裁剪策略共享状态可能很大但智能体的上下文窗口有限。把整个共享状态塞给每个智能体既浪费token又可能引入无关信息干扰判断。所以需要一套裁剪策略根据当前智能体的职责只给它看相关的部分。我的裁剪策略分三步第一步按角色过滤每个角色只看到自己职责相关的字段第二步按时间过滤只保留最近N次的相关操作记录第三步按重要性过滤异常信息和关键决策优先保留常规操作记录可以压缩成摘要。这套策略实施后单个智能体需要处理的上下文量下降了大约70%而判断准确率没有明显下降。关键是第二步的时间过滤很多历史操作记录对当前决策其实没有影响保留反而增加噪音。5. 异常处理与人工介入系统卡住了怎么办5.1 多智能体系统的典型故障模式多智能体系统的故障模式和单智能体系统很不一样。单智能体出问题通常是处理错了或处理不了而多智能体系统更多是卡住了或循环了。我总结了几种高频故障死锁两个智能体互相等待对方的输出活锁智能体不断重试但始终无法推进状态漂移共享状态被意外修改导致与预期不符级联失败一个智能体出错导致依赖它的所有智能体都出错。这些故障里死锁和活锁最难排查因为系统看起来在运行但实际没有任何进展。我的做法是在编排层加一个心跳检测每个环节如果超过预期时间还没有状态推进就触发告警。预期时间根据历史数据设定比如资料审核平均耗时3分钟超过10分钟就告警。5.2 人工介入的触发条件与接口设计人工介入不是失败而是系统设计的一部分。关键是要定义清楚什么情况下触发人工介入以及人工介入后系统怎么恢复。触发条件我通常设三类置信度低于阈值、重试超过次数上限、业务规则明确要求人工确认。第一类针对判断不确定的情况第二类针对技术故障第三类针对合规要求。人工介入的接口设计有个容易忽略的点人工处理完之后系统要从哪个状态继续。如果人工只是补充了信息那应该回到原来的环节重新处理如果人工直接做了决策那应该跳过后续的自动判断环节。这个恢复逻辑要提前定义好否则人工介入后系统可能又走回原来的死胡同。5.3 故障恢复的幂等性保障故障恢复时最怕的是重复执行已经完成的操作。比如资料审核Agent已经审核通过了系统重启后编排Agent不知道又让它审核一遍。如果审核逻辑不是幂等的可能产生重复的审核记录。我的做法是在共享状态里记录每个环节的完成标记恢复时先检查标记已完成的不再执行。同时每个业务Agent的操作都设计成幂等的即使被重复调用结果也一致。这两层保障叠加基本可以避免恢复时的重复问题。6. 从Demo到生产性能、成本与可观测性的平衡6.1 智能体调用的成本控制多智能体系统的一个隐性成本是模型调用费用。每个智能体每次处理都要调用模型一个业务流走下来可能调用几十次。如果不加控制成本会快速攀升。我试过几种控制手段。缓存是最直接的相同输入直接返回缓存结果适合资料审核这种判断标准固定的环节。模型分级也很有效简单判断用轻量模型复杂决策用重量级模型成本能降一半以上。批量处理适合非实时场景把多个任务攒一批一起处理摊薄调用开销。但要注意成本控制不能牺牲准确性。我见过为了省钱把所有环节都换成轻量模型结果审核准确率从95%掉到70%返工成本远超省下的调用费。我的经验是只在置信度高的环节用轻量模型置信度低的环节该用重量级就用。6.2 可观测性建设日志、指标与追踪多智能体系统的可观测性比单智能体系统重要得多因为问题往往出在交互环节而不是单个智能体内部。我通常建三样东西结构化日志每个智能体的每次处理都记录输入、输出、耗时、结果关键指标包括各环节耗时、成功率、人工介入率、成本链路追踪一个业务流从开始到结束的完整路径能直观看到卡在哪个环节。链路追踪特别有用。我遇到过一次性能问题整体耗时突然翻倍看单个智能体的指标都正常。后来用链路追踪才发现是编排Agent的状态查询变慢了因为共享状态存储的数据量增长后没有加索引。这种问题不看链路根本定位不到。6.3 灰度发布与回滚策略智能体系统的更新比传统系统更危险因为智能体的行为有一定的不确定性同样的输入可能产生不同的输出。直接全量更新一旦出问题影响面很大。我的做法是灰度发布新版本先处理一小部分流量观察关键指标没有异常再逐步扩大。同时保留快速回滚能力一旦发现异常能在几分钟内切回旧版本。回滚的关键是状态兼容——新版本写入的共享状态旧版本要能读懂。所以schema的变更要向后兼容新增字段可以修改或删除字段要谨慎。注意智能体版本更新后之前处理到一半的任务可能处于新旧版本混合的状态。我的处理方式是更新时先停止接收新任务等存量任务处理完再切换避免混合状态带来的不可预期问题。7. 我在实际搭建中踩过的几个坑第一个坑是过度设计。刚开始做的时候我想把所有可能的情况都考虑进去设计了非常复杂的编排逻辑和异常处理分支。结果系统跑起来后大部分分支从来没被触发过反而因为逻辑复杂导致调试困难。后来我改成先跑通主流程异常情况先记录不处理等主流程稳定后再逐步补充异常处理效率高了很多。第二个坑是智能体职责重叠。有两个智能体都能处理某类信息结果遇到这类信息时两个都去处理产生重复操作。后来我定了一条规则任何一类信息只能有一个智能体负责处理其他智能体如果需要这类信息只能读取不能修改。第三个坑是忽略冷启动问题。系统刚上线时没有历史数据很多基于统计的判断比如超时阈值没有依据。我当时的做法是先用保守的默认值运行一段时间后根据实际数据调整。但保守默认值导致初期误报很多人工介入频繁。后来改成初期放宽阈值宁可漏报不可误报等数据积累够了再收紧。第四个坑是状态存储的性能。共享状态存储随着任务量增长查询越来越慢。我一开始用的是简单的键值存储后来换成了带索引的文档数据库查询性能提升了十几倍。这个坑的教训是状态存储的选型要考虑数据增长不能只看初期够用。8. 这套架构还能怎么扩展agency-agents这类系统的扩展方向我目前看到几个比较有价值的。一是跨机构协作多个代理机构的智能体系统对接实现业务流转的自动化。这需要解决智能体之间的信任和协议问题目前还在早期探索阶段。二是自适应编排编排Agent根据历史数据自动优化状态转移逻辑比如发现某个环节经常需要人工介入就自动调整该环节的触发条件。三是多模态输入目前大部分系统处理的是文本未来可以扩展到语音、图像等输入形式适应更多业务场景。不过扩展的前提是核心架构稳定。我见过不少项目在主流程还没跑通的情况下就急着加功能结果基础不牢加的功能越多系统越乱。我的建议是先把单业务流跑稳再考虑扩展。跑稳的标志是连续运行一周人工介入率低于10%没有死锁和活锁成本在预算内。达到这个标准后再考虑下一步。最后分享一个我在调试多智能体系统时常用的小技巧给每个智能体加一个思考日志记录它每次决策时的推理过程。这个日志不参与业务逻辑只在调试时查看。很多看起来莫名其妙的问题看了思考日志就明白了——比如某个智能体因为上下文里混入了无关信息而做出了错误判断。这个日志的存储成本很低但排查问题时能省大量时间。