多Agent架构设计实战:角色定义、通信协议与任务编排
发布时间:2026/10/12 13:14:23 锦皓数字建站

1. 先想清楚一件事你真的需要多Agent吗先说个实在的判断标准。我见过太多人一听说多Agent这个词就觉得单Agent不够高级恨不得把手里所有任务都拆给好几个大模型结果做出来的东西不但没有变强反而更慢、更贵、更不可控。所以这篇博文的第一件事不是讲怎么搭多Agent而是帮你判断该不该用多Agent。多Agent本质上解决的是单Agent的三个硬瓶颈。第一个瓶颈是上下文窗口。单个Agent能承载的上下文始终有限你要让同一个模型既做全局规划、又读大量资料、还要输出精细结果很快就会把上下文塞满然后开始忘事或者胡说八道。把不同职责拆给不同Agent每个Agent各自维护自己相关的上下文表面上看起来是多了几个人实际上是把一个撑爆的脑子拆成了几个分工明确的脑子。第二个瓶颈是角色冲突。一个Agent同时扮演执行者和质检者或者同时做信息搜集与最终决策它很难诚实地批评自己。就好像一个人写代码又自己给自己做Code Review往往会越看越顺眼。把监督、批判、执行拆给不同Agent让它们互相审视反而能逼出更高的准确率。第三个瓶颈是并行与等待。单Agent只能串行思考多Agent可以让信息搜集、草案生成、数据分析同时进行在任务拆解合理的前提下整体耗时有明显下降。这个在需要汇总多路信息的场景里尤其值钱。那什么样的场景不该用多Agent呢我建议你先对照这张表做一次冷静评估场景特点建议方案任务步骤固定、输入输出简单单Agent加提示词模板就够了需要大量背景知识才能回答的问题优先做检索增强而不是拆多Agent强依赖全局一致性不允许各说各话慎用多Agent除非设计严格的共享状态预算非常敏感每次调用都嫌贵先算账多Agent通常意味着更多轮模型调用任务天然可分、分头处理再汇总这是多Agent的主场可以上判断的核心原则只有一个多Agent是架构手段不是目标。如果你的问题没有可拆分性和角色冲突上多Agent只会徒增复杂度。顺带说一句适用人群。这篇内容适合正在做Agent应用的开发者、技术负责人以及想从单Agent往协作式架构迁移的团队。如果你只是刚接触大模型建议先把单Agent的提示工程和工具调用跑熟再回来看这篇会比较轻松。2. 架构设计先把人和组织架构定下来很多新手犯的第一个错误就是一上来就写代码想着我创建三个Agent一个做A一个做B一个做C然后让它们自由对话。这样做的结果是Agent之间互相扯皮、反复确认、不断偏题跑出来的东西和预期完全不是一回事。好的多Agent设计80%的工作发生在写代码之前。你要先把自己当成一家公司的架构师设计好这家公司的岗位、汇报关系、协作规则然后才轮到Agent上场。2.1 角色定义是第一步角色不是随便起的名字它决定了三个关键要素职责边界、可用工具、输出契约。我习惯用一张角色卡片来定义每一个Agent字段含义示例角色名称一句话说明身份需求分析师核心职责必须完成的任务列表拆解用户需求、输出任务清单、识别缺失信息输入来源它读取谁的消息上游Planner、用户消息输出对象它的产物交给谁下游执行Agent、评审Agent可用工具允许调用哪些外部能力搜索引擎、代码解释器、向量数据库输出契约必须遵循的格式模板返回结构化JSON字段包括task_id、描述、优先级禁止事项不允许做什么不可以直接生成最终回复、不可以越过Router联系其他Agent举一个我实际用过的例子。做一个市场分析报告生成系统我这里只说方案不涉具体客户信息我定义了四个角色Planner负责把用户的宽泛问题拆成市场概况、竞品动态、用户反馈、风险建议四块并生成任务卡。Researcher负责按任务卡分头检索信息输出带来源标注的事实清单。Analyst负责对事实清单做交叉分析、提炼结论输出图表数据。Critic负责审查Analyst的分析是否逻辑自洽、是否有数据支持、有没有遗漏关键角度。这四个角色的设计逻辑是信息搜集归信息搜集分析归分析审查归审查。任何一个角色跟我说我要做所有事情我都会直接砍掉因为那又回到了单Agent。2.2 四种编排模式与选择角色定下来之后还要决定它们之间怎么协作。我把常见模式归纳为四类串行流水线式A做完交给BB做完交给C适合步骤固定、依赖明确的流程。优点是简单可控缺点是一旦中间某个环节出错后面全跟着错而且整体耗时是所有环节之和。并行扇出式一个Router把任务拆给多个同质Agent分头处理最后再汇总。适合同一任务多路信息源的场景比如同时读多份文档、同时调研多个方向。这种模式之所以常见是因为它能显著缩短耗时但汇总环节容易成为瓶颈需要设计好合并策略。主管-下属式一个Supervisor Agent负责任务分配、结果验收、决定谁下一步行动下属Agent只负责执行。这种模式适合任务复杂度高、需要动态决策的流程。它是目前多Agent系统里稳定性最好的形态之一因为决策权和执行权分离了不容易出现群龙无首的场面。黑板式所有Agent共享一块公共黑板共享状态区谁有产出就往上写谁需要信息就来读。这种模式适合创新探索类任务比如头脑风暴、多方案对比但缺点也明显全局状态很容易冲突需要花大力气做并发控制和版本管理。我在实际项目中的选择偏好比较明确能串行就不并行能主管-下属就不让Agent自由聊天。因为模型不是人自由聊天意味着大量无意义的寒暄和确认而主管-下属式至少还有一个人盯着全局。2.3 一个经过验证的最小可用拓扑如果你刚起步我建议直接照搬这个最小拓扑不要自己发挥用户消息 └── Router意图识别 任务拆解 ├── Worker A执行任务块1可用工具检索 ├── Worker B执行任务块2可用工具代码解释器 ├── Worker C执行任务块3可用工具数据查询 └── 结果送入 Merger合并子结果生成统一格式 └── Critic质检通过则输出不通过则退回对应WorkerRouter、Worker、Merger、Critic四个角色就够。这个拓扑的好处是引入角色少通信路径短每一环都有明确的输入输出。我最早自己做的系统是6个Agent乱聊后来全部推翻改成这个结构之后才跑稳。提示Agent数量不是越多越好。我的经验是核心执行角色控制在3到5个以内超过8个通信和调试成本会急剧上升收益反而递减。所谓人多力量大在Agent协作里并不成立。2.4 先画协作拓扑图再写代码这个方法论值得多说一句。写代码之前我会先在白板上画一张协作拓扑图每个Agent是一个节点每条通信是一条边边上标注传递的消息类型和触发条件。这张图至少能回答三个问题消息会不会出现环A依赖BB又依赖A有没有角色接收到的信息超过它能处理的量哪个Agent是单点故障它挂了全链停摆这些问题在代码里发现再去改架构代价很大在图上发现几分钟就能调整。3. 通信协议与共享状态多Agent的信息总线说完角色和流程接下来是很多人最容易糊弄的部分Agent之间到底怎么说话、怎么传递状态。不少团队的做法是让大模型自然语言聊呗结果聊着聊着就聊飞了。你以为多Agent是几个聪明人在开研讨会实际上一旦没有强约束它更像一群人在没主持人的会议室里各说各话而且每句话还要收一次钱。所以通信协议必须设计得具体、沉重而不是自由发挥。3.1 消息格式别整散文要整结构我要求所有Agent之间的通信一律使用结构化JSON消息。以一条任务分配消息为例{ message_id: msg_20240101_001, msg_type: task_assign, sender: Router, receiver: Worker_A, timestamp: 2024-01-01T10:00:00Z, payload: { task_id: task_json_001, task_description: 抽取用户需求中的关键实体与关系, input_refs: [context://user_request], output_refs: [context://entity_graph], priority: 1, deadline_tokens: 2000, constraints: [必须使用提供的抽取模板, 输出字段必须包含entity_name], tools_allowed: [http_client, code_interpreter], reject_policy: 如果需求描述不完整返回need_more_info } }看到没有一条消息里明确定义了这条任务是什么、输入去哪里取、产出去哪里写、能用哪些工具、token限制是多少、什么条件可以拒绝执行。我特别想让新手重视的是output_refs这个字段。它表示你的产出写到哪个上下文槽位而不是让Agent把结果直接发给另一个人。这样做的好处是Agent不需要在消息里携带大量正文只需要带上引用地址需要的时候去读这能省大量token。3.2 上下文的分层管理多Agent系统里上下文如果全部共享那必然是灾难。每个Agent都会往里面塞东西最后谁看到的状态都是半新不旧的还会互相覆盖。我用的是三层上下文模型全局上下文系统级信息比如用户原始需求、全局约束、时间截止所有Agent都可读但只有Router有写权限。任务上下文每个任务单独立一份包含该任务的目标、输入引用、中间产出。任务上下文默认只有执行该任务的Agent和它的直接主管可读写。私有上下文某个Agent的思考过程、临时笔记、个人偏好只对本人可见不允许其他Agent读取。这三层隔离在我做过的项目里非常关键。尤其是私有上下文它的存在让Agent敢在内部先打草稿不需要把不成熟的中间想法暴露给全系统最终输出的质量明显更稳。3.3 上下文预算给每个Agent发钱大模型的上下文长度是成本的核心变量多Agent系统如果不做预算管理很容易出现对话轮数没多少花费却翻了很多倍的情况。我的做法是给每个Agent分配明确的token预算。Router在每轮任务开始时会做一个预算表Agent输入上下文预算输出token上限说明Router40001500只做拆解和决策不承载长文本Worker A60002000读取检索结果做信息抽取Worker B80003000生成大段分析内容Critic30001000只看关键结论不读全文超过预算的Worker系统会强制截断或要求其先做摘要再继续。这听起来粗暴但实测下来能有效抑制Agent越聊越长、越聊越偏的通病。模型没有危机意识你不替它做资源控制它就替你失控。3.4 同步与异步通信怎么选在通信时机上我的经验是任务链里的关键节点用同步普通消息传递用异步。同步调用意味着我把消息发给你然后在那里等你的结果适合上游需要下游产出才能继续的情况异步意味着我把消息放进你的信箱你去处理别的事适合互不依赖的分头执行。多Agent系统里最常见的性能瓶颈就是所有通信都用同步导致系统变成了排队等答复的串行流程。我见过一个项目明明拆了5个Agent做并行但因为通信设计全是同步实际耗时比串行还长。后来我把每个Worker内部处理改成异步轮询工作流的整体耗时降了40%以上。4. 任务编排与执行细节让Agent真正跑起来光有架构和通信还不够落地执行的时候任务编排的质量直接决定了系统能不能稳定运转。这个环节我踩过的坑最多也是我认为整个多Agent设计里最见功力的地方。4.1 任务卡最小可用字段所谓编排本质上就是把大目标拆成小任务然后按依赖关系调度。我给每个任务设计了一套任务卡模板核心字段包括任务目的、输入数据、输出数据、验收标准、依赖任务、尝试次数上限、可调用工具、超时策略。其中验收标准这个字段最容易被省略但它恰恰最重要。没有验收标准Agent做完一个任务你根本不知道该不该放行它进入下一个环节。我通常会要求任务卡里至少写两个可验证的验收条件比如输出必须包含超过3个有效来源链接结论必须引用了输入摘要中的至少两个数据点。4.2 调度与重试机制任务跑起来之后会遇到各种意外某个Worker超时、某个工具返回异常、某个模型输出格式不对。如果整个系统没有重试与熔断机制一次小失败就会拖垮整条链路。我的调度器逻辑一般长这样async def dispatch_task(task_card, agent): max_retries task_card.max_retries # 默认2次 for attempt in range(max_retries): try: result await agent.run(task_card) if validate_result(result, task_card.acceptance_criteria): return result else: log_failure(attempt, reason验收未通过) except ToolException as e: log_failure(attempt, reasonf工具异常: {e}) except TimeoutError: log_failure(attempt, reason任务超时) # 重试仍然失败走降级策略 return degrade_task(task_card)这里说几个关键点重试不是无脑重跑。如果Agent上一次已经给出了接近合格的答案重试时应把上一次输出连同失败原因一起塞进提示词让它基于上次的未通过原因进行修订。纯重跑大概率还会犯同样的错。失败降级要有兜底策略。如果Worker A彻底失败至少要有一个预设的Plan B比如改用更简单的方法生成结果、或者把该子任务标记为跳过并在最终输出中明确提示缺失。绝不能假装没发生过。日志里要同时记录成功和失败路径。这为后续调优提供了非常重要的依据。我后面会详细说怎么基于日志迭代。注意多Agent系统里出错的往往不是大模型笨而是你给它的任务本身就含混不清。排查问题时先把任务卡里的描述和验收标准重新读一遍大概率能找到根源。4.3 工具使用与权限边界每个Agent能调什么工具必须白名单化这既是安全需要也是成本控制手段。我见过一个系统所有Agent共用所有工具结果一个负责文案的Agent闲着没事调了三次数据接口账单直接翻倍。工具权限设计至少要考虑三个维度只读还是可写、数据导出范围、调用频次限制。Router可以有全局权限Worker一般只有只读和检索权限只有特定执行Agent比如写文件、发请求的才开放写权限。4.4 人工介入与断点续跑多Agent系统再复杂也不能是全自动黑箱。我强烈建议在流程里预留几个人工检查点尤其是在以下场景最终输出要直接对外的比如生成合同、发邮件必须加人工审核。任务链超过5个节点时在中间节点加一个Human-in-the-loop确认避免错误一路传导到末端。涉及外部真实操作的扣款、发消息、改数据必须双人复核或至少二次授权。断点续跑是另一个容易被忽略的细节。系统执行到一半失败时不应该从头再跑一遍而应该能恢复上次的上下文从失败节点继续。我在设计调度器时会在每个任务完成时把任务上下文和产出物持久化下来重跑时直接加载最近的持久化状态而不是重新让Router再拆一遍。5. 记忆机制设计不是所有东西都要塞进上下文多Agent系统跑久了会出现一类共性症状Agent忘记了项目早期的需求约束或者某条结论被反复重新争论。这个问题本质上就是记忆机制没设计好。大模型本身没有记忆所有记忆都是你主动写进上下文的东西。所以记忆机制设计得好不好决定了系统是越来越聪明还是原地打转。5.1 三种记忆类型分别管理我把多Agent的记忆分成三类分开存储、分开读写。短期工作记忆当前任务链开始后产生的事实和中间结论任务结束就清空。它对应前面说过的任务上下文。长期档案记忆关于用户偏好、项目背景、领域术语、历史决策的记录。比如用户不喜欢过于夸张的措辞这个项目的目标受众是技术决策者。这类记忆要持久化由Router在每次任务初始化时决定要加载哪些相关档案。共享项目知识所有Agent共同积累的事实库比如已经验证过的数据结论、已经否决过的方案。这是多Agent系统最值得投资的部分因为它能让不同Agent在关键事实上达成共识避免互相矛盾。5.2 写入与召回机制记忆写入不能靠模型自动写那样会写进很多垃圾。我的做法是设置一个记忆管理Agent在关键节点新结论产生、需求变更、用户反馈触发写入而且写入前要过一遍格式校验哪些事实值得写入长期记忆我会看三个指标这个事实会不会影响后续决策会不会被多个Agent重复引用会不会被时间快速淘汰三个条件至少满足两个才允许写入。召回策略上按需召回比全量加载划算得多。每个新任务初始化时Router从长期档案里做一次相似度检索选出与当前任务最相关的记忆片段塞进相关Agent的上下文再通过向量数据库存储记忆。我推荐用一个简易的向量数据库或索引结构来管理长期记忆这样召回时能按相关性排序让每个Agent看到的是它最需要的那一小块而不是整个项目历史。5.3 防止记忆污染记忆污染是多Agent系统里最隐蔽的坑。某个Agent在某一次任务中得出一个错误结论如果没有经过验证就被写入共享知识库之后所有Agent都会被这个错误污染而且污染还会自我强化因为多个Agent引用同一个错误来源看起来就像多方交叉验证了。我在实践中总结出几个防污染规则结论型记忆必须经过Critic或人工审核才能入库。记忆里注明来源和时间设置有效期。过期的共享结论要自动降权。支持记忆版本回滚一旦发现某条记忆导致了下游任务失败能快速定位并删除。这个部分文字不多但值得花大量时间打磨。记忆系统做得好多Agent才有成长的可能而不仅仅是每次重新思考。6. 评估体系怎么证明你的多Agent系统是有效的这是很多做多Agent的团队跳过去的一步也是最危险的一步。没有评估体系你根本不知道改动是变好了还是变差了只能靠感觉更像人了这种玄学判断。6.1 离线评估三板斧我每次调优之前都会先固定一组评估指标至少覆盖三个维度任务完成质量最终输出是否满足用户的原始意图这里可以用人工打分也可以用一组预设的验证用例来跑端到端通过率。协作效率整个系统跑完花了多少时间、调用了多少次模型、消耗了多少token。多Agent系统最大的风险是协作成本吞噬收益所以这个指标必须记账。失败模式分布统计运行日志中各种失败原因的出现次数比如任务描述不清晰工具超时验收不通过上下文超预算。这个分布能直接告诉你系统最弱的环节在哪。6.2 用模拟场景做压力测试我会准备一组标准测试用例每个用例覆盖一种典型场景单轮简单任务多Agent系统不能比单Agent慢太多、贵太多。多路信息汇总任务测试并行分头处理和汇总质量。带明确约束的复杂任务如不能超出预算输出格式必须符合API规范测试约束传递能力。歧义输入用户需求没说清楚测试Agent识别缺失信息并及时追问的能力。每一次架构调整都跑同一组用例对比前后指标。没有这套压测基线你有任何改动心里都没底。提示评估用例不要只用你自己手写的那三五条尽量收集真实用户问题去扩充。真实问题里才有各种你意想不到的边界条件和表达方式。6.3 迭代调优先看失败模式再看模型调优顺序上我的经验是先改架构和提示词再换模型。多数失败并非模型能力不足而是任务卡描述不清、上下文引用错误、工具权限管太死。直接把锅甩给模型换一个更强的既贵又未必见效。具体的调优循环是收集失败样本归类失败模式针对高频失败点做修正可能是改任务卡、改验收标准、加工具、调记忆再用标准测试用例回归。这个循环走三四轮之后系统往往会稳定很多。有些团队会做自动评估器用一个大模型评估另一个大模型的输出我试过能跑但不可全信尤其是涉及事实准确性和逻辑严谨性时自动评估器也会犯迷糊。建议关键指标保留人工抽检自动评估只用来做粗筛。7. 常见问题与排查技巧实录最后这部分我整理一下多Agent系统落地时最常遇到的几类问题以及我实际排查时的做法。这份速查表能帮你省很多弯路。7.1 高频问题速查表现象典型原因排查方向Agent互相甩锅或无限对话通信协议缺少终止条件角色边界不清检查消息格式是否有最终回复标记收紧角色禁止事项多Agent输出比单Agent还差拆解过度子任务之间信息断层检查任务卡的input_refs是否完整Merger是否拿到全部关键结果上下文越来越大token消耗暴涨没有做上下文预算和记忆隔离给每个Agent设token上限改用引用而非正文传递分工了但还是串行跑同步通信用得太多弱化了并行检查调度器是否等待了不需要等待的依赖中间结论与最终输出矛盾关键约束信息在链路中丢失把全局约束写进每个Agent的system prompt而不是只在开头给一次某个Agent死活不按格式输出提示词里的格式说明太靠后模型注意不到把格式要求放到提示词最前部并且给出一个完整示例重试后结果更差无脑重跑没有带上历史失败原因改造成将上次结果与失败原因一并作为上下文再尝试记忆被污染系统越来越糊涂未经验证就写入共享记忆库加上写入审核、来源标注、有效期与版本回滚7.2 排查方法论从哪个环节先查遇到系统行为不对我建议按这个顺序排查第一看任务卡和验收标准。多数Agent不听话其实是任务编得含糊。第二看消息传递记录。从Router到Worker的每一条实际消息对比任务卡和最终产出看信息在哪一环丢失或变形。第三看上下文内容。把执行Agent的最终输入上下文完整打印出来人工读一遍很多时候一眼就能看出该有的信息压根没给它。如果这三步走完还没有头绪再考虑换模型或者调参数。我一直认为多Agent系统的调试本质上是信息流追踪而不是玄学调参。7.3 三个亲测有效的优化技巧最后分享三个我在实际项目中反复验证过的小技巧。第一给关键Agent加节流阀。当一个Agent需要更新共享状态时不要直接写入而是先生成一个变更提案等Router或Critic确认后再正式写入。这能明显减少共享状态的混乱和覆盖。第二在每个Agent的system prompt里固定一段开场白模板。让Agent在开始执行前先复述一遍它理解的任务目标、约束条件和预期输出。这个复述-对齐的过程只需要额外消耗一点点token却能把大量因为误会需求而失败的案例扼杀在摇篮里。第三设置最低质量线。在Merger合成最终结果之前先让Critic做一次快速检查不合格的直接打回对应Worker而不是把不合格的内容送到用户面前。打回时附上明确修改意见比只说不合格重做有效得多。踩过几次坑之后我的体会是多Agent没有银弹但那些该有的笨功夫——清晰的角色定义、结构化的消息、分层的上下文、严格的验收标准、持续的压测回归——一个都不能少。把这些基本功做到位多Agent才能真正发挥协作的价值而不是变成一堆聊天的模型来回消耗你的预算。最后再分享一个小技巧刚开始做多Agent时别急着追求超大系统先把一个最小闭环跑通比如Router加两个Worker加Critic。等这个闭环稳定了再往里加Agent、加工具、加记忆会从容得多。好的多Agent系统不是设计出来的是一轮一轮跑出来、改出来的。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。