公司动态
三种多Agent编排模式实测:顺序链卡死、路由分错、广播冲突,我是怎么选的
摘要单Agent撑不住复杂任务时我试了三种多Agent编排模式——顺序编排、路由编排、广播编排。每个模式都踩了坑顺序编排中间环节超时整条链卡死路由编排遇到模糊输入两个Agent同时跑浪费算力广播编排两个数据源返回冲突结果无法合并。最后选了混合编排按任务类型动态切换模式。本文记录每个模式的具体翻车日志、修复方案、以及最终的选型决策表。文章目录环境说明一、开场那天用户说Agent 卡了 5 分钟没响应二、我试的第一个模式顺序编排Chain场景第一版代码翻车版运行结果翻车日志根因分析修复后的代码修复后运行结果三、我试的第二个模式路由编排Router场景第一版代码翻车版翻车日志根因分析修复方案验证结果边界说明四、我试的第三个模式广播编排Fan-out场景关键代码与翻车运行结果根因分析修复方案边界说明五、我最后选了混合编排六、选型决策表七、局限与下一步环境说明本文基于 MCP 协议草案 v2025-03-26运行时为 Node.js 20 LTS TypeScript 5.5。用到的 MCP SDK 版本为 modelcontextprotocol/sdk1.8.0。如果你用的版本不同部分 API 行为可能有差异。一、开场那天用户说Agent 卡了 5 分钟没响应事情是这样的。之前写的 MCP Server 和 Client 跑得挺好一个 Agent 连一个数据源查个资料、写个摘要什么的都能应付。直到有一天用户提了个需求“帮我查一下 A 项目的历史数据跟 B 系统的报表对比一下再写个总结发到群里。”——三个动作查数据、对比报表、写总结一个 Agent 按顺序跑。我打开日志的时候看到的是这样的Step 1: searchAgent — completed (2.3s) Step 2: compareAgent — calling LLM... waiting... Step 3: summaryAgent — pending... [30s later] Step 2: compareAgent — timeout after 30s Step 3: summaryAgent — cancelled (context overflow) Chain aborted. Total time: 32.4s Result: empty32 秒用户等了个空结果。不是单个 Agent 跑不动是整个工作流的设计有问题——一个任务堵死了后面的全没了。这就是我走进多 Agent 编排的起点。二、我试的第一个模式顺序编排Chain场景一个查资料→写摘要→存笔记的链式任务。这个需求最直接——前一步的输出是后一步的输入天然串行。第一版代码翻车版// 顺序编排 - 第一版Agent 直接串行// 为啥要看这段因为大多数人的第一反应也是这样写的constchainnewChainAgent({agents:[searchAgent,// 查资料summaryAgent,// 写摘要saveAgent// 存笔记]});constresultawaitchain.run(2026年Q2 AI芯片市场报告);运行结果翻车日志Error: summaryAgent timeout after 30s Chain aborted. searchAgent result discarded. Total time: 32.4s查资料花了 2 秒写摘要调 LLM 超时——30 秒白等查到的资料也丢了。根因分析三个问题没有超时隔离——一个步骤超时直接拖垮整条链没有重试机制——summaryAgent 超时后直接抛异常没试第二次没有部分结果缓存——searchAgent 查到的资料随异常一起丢弃了修复后的代码// 顺序编排 - 增加超时隔离 重试 部分结果缓存constchainnewChainAgent({agents:[searchAgent,summaryAgent,saveAgent],timeout:60_000,// 单步超时上限retry:2,// 超时后重试 2 次partialCache:true,// 缓存每一步的中间结果onStepFail:skip// 步骤失败后跳过不卡死整条链});constresultawaitchain.run(2026年Q2 AI芯片市场报告);修复后运行结果Step 1: searchAgent — completed (1.2s, 3 results) Step 2: summaryAgent — failed (timeout after 30s, retried 2x) Step 2: summaryAgent — completed on retry (45.2s) Step 3: saveAgent — completed (0.3s) Total time: 47.8s Result: saved to notes (3 references, 1 summary)虽然第二步花了 45 秒但至少跑完了结果也存了。比翻车版好但用户体验还是不好——47 秒才出结果用户早切页面了。我的经验是顺序编排在**任务链短≤3 步 每个步骤可靠性高95%**时是个好选择。但如果你的步骤超过 5 步即使有重试整体成功率也会急剧下降——假设每步 95% 成功率5 步下来只有 77%。我的经验是顺序编排适合不做完就不往下走的刚性流程比如支付确认链、权限校验链。但如果你追求响应速度顺序编排不是好选择。三、我试的第二个模式路由编排Router场景用户输入不确定需要分发给不同领域的专家 Agent。比如用户问数据库配置怎么改应该走配置 Agent问上季度的营收是多少应该走报表 Agent。第一版代码翻车版// 路由编排 - 基于关键词匹配// 为啥要看这段因为这是最直观的实现方式——关键词匹配谁都会constrouternewRouterAgent({routes:[{pattern:/数据库|查询|SQL|数据/i,agent:queryAgent},{pattern:/报表|图表|统计|导出/i,agent:reportAgent},{pattern:/配置|设置|修改|权限/i,agent:configAgent}],fallback:generalAgent});constresultawaitrouter.run(帮我查一下上个季度的报表里的数据);翻车日志User input: 帮我查一下上个季度的报表里的数据 Intent analysis: - 查 → matched queryAgent (pattern: /查询/) - 报表 → matched reportAgent (pattern: /报表/) - 数据 → matched queryAgent (pattern: /数据/) - 上季度 → no match Route decision: ambiguous — 2 agents matched Invoking: queryAgent reportAgent (parallel)两个 Agent 都跑了。queryAgent 返回了 SQL 查询结果reportAgent 返回了请指定报表类型。用户看到的是两个结果拼在一起不知道怎么用。根因分析基于关键词的路由在模糊语义下会失效。查和数据两个字同时命中两个模式Router 没有能力判断用户的真实意图。更隐蔽的问题是关键词匹配没有置信度阈值。只要匹配上就算命中没有这个匹配度只有 60%要不要再确认一下的逻辑。修复方案换成 LLM 做意图分类——只做单一分类不跑完整 Agent。// 路由编排 - LLM 意图分类版// 不同之处先让 LLM 做一次轻量分类再路由到对应的 AgentconstrouternewRouterAgent({classifier:{model:gpt-4o-mini,prompt:根据用户输入判断意图类型query数据查询、report报表生成、config配置修改、other其他,// 只做分类不跑完整 Agenttemperature:0.1,maxTokens:20},routes:{query:queryAgent,report:reportAgent,config:configAgent,other:generalAgent},confidenceThreshold:0.7// 置信度低于 70% 走 fallback});constresultawaitrouter.run(帮我查一下上个季度的报表里的数据);验证结果User input: 帮我查一下上个季度的报表里的数据 LLM Intent: query (confidence: 0.87) Route: queryAgent → completed (2.3s) Single agent invoked. 节省了一次 LLM 调用。边界说明路由编排适合输入意图明确、分类边界清晰的场景。比如客服分流我要退钱→售后退款 Agent我的账号登不上→账号安全 Agent这种场景下分类准确率能做到九成五以上。但如果用户的输入经常跨领域——“查一下上季度的报表里的数据库配置”路由的边界就开始模糊了。这种场景我后来走了混合编排后面会说。四、我试的第三个模式广播编排Fan-out场景需要同时查多个数据源做交叉验证。比如查一个用户的配额信息数据库里有一份文件系统里有一份API 也有一份——三份数据对比取多数意见。关键代码与翻车// 广播编排 - 并行查询多数投票合并// 为啥要看这段因为多个数据源互相验证听起来很靠谱但实际坑很多constfanOutnewFanOutAgent({agents:[dbAgent,fsAgent,apiAgent],mergeStrategy:majority// 多数投票});constresultawaitfanOut.run(查询用户 quota 配置);运行结果queryAgent: user.quota 1024MB reportAgent: user.quota 2048MB configAgent: user.quota 1024MB Merge: majority (2/3) → 1024MB ✅但换了一个场景数据源就开始打架了——查用户状态的时候三个数据源返回了三种结果queryAgent: user.status active reportAgent: user.status inactive configAgent: timeout Merge: no majority (1 active vs 1 inactive vs 1 timeout) Merge result: error — cannot determine consensus根因分析两个问题数据源之间存在更新延迟——数据库里是active文件系统里是同步之前的inactive两个都对只是时间戳不同多数投票在信息源不足时直接失效——三个数据源挂了一个剩下两个结果不一致无法形成多数根本原因是MCP 协议本身没有共识机制。每个 Server 独立响应谁先到谁后到、谁的数据新谁的数据旧协议层面不做保证。修复方案改成可信度加权策略给每个数据源配一个优先级// 广播编排 - 可信度加权版constfanOutnewFanOutAgent({agents:[{agent:dbAgent,weight:1.0,freshness:30s},// 数据库30s 内缓存{agent:fsAgent,weight:0.7,freshness:5min},// 文件系统5min 内缓存{agent:apiAgent,weight:0.8,freshness:1min}// 外部 API1min 内缓存],mergeStrategy:weighted,// 加权合并conflictResolve:highestWeight// 冲突时取权重最高});边界说明广播编排适合**越多越好的场景**比如搜索召回、多源信息采集——多一个数据源就多一份信息不在乎冲突。但如果是**必须一致的场景**比如用户状态、权限配置广播编排的风险就很大。我的经验是广播编排之前先问自己如果两个数据源结果不一样我信谁。如果答不上来就别用广播。五、我最后选了混合编排三个模式试下来各有各的边界——直接看这张对比表就能看清楚模式优点翻车点适合场景顺序编排简单直观步骤依赖明确中间环节超时整条链卡死短链刚性流程≤3步路由编排按意图分发准确率高模糊输入多 Agent 同时跑分类边界清晰的场景广播编排并行效率高信息量大数据冲突时无法合并搜索/采集类非一致性场景没有银弹所以我选了混合。现在的做法是调度层先判断任务类型再动态切换模式具体规则很简单┌──────────────────────────┐ │ 调度层 │ │ ┌──────────────────┐ │ │ │ LLM 意图分类 │ │ │ │ 识别任务类型 │ │ │ └────────┬─────────┘ │ │ │ │ │ ┌────────▼─────────┐ │ │ │ 模式选择器 │ │ │ │ 规则 动态决策 │ │ │ └────────┬─────────┘ │ └───────────┼──────────────┘ │ ┌────────────────────────┼────────────────────────┐ ▼ ▼ ▼ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ 顺序编排 │ │ 路由编排 │ │ 广播编排 │ │ 链式任务 │ │ 分类任务 │ │ 采集任务 │ └───────┬───────┘ └───────┬───────┘ └───────┬───────┘ │ │ │ └──────────────────────┼──────────────────────┘ ▼ ┌──────────────────┐ │ 结果合并层 │ │ 冲突检测 合并 │ └──────────────────┘ ▼ 输出结果具体的规则很简单// 混合编排 - 按任务类型动态切换模式consthybridOrchestrator{asyncrun(task:Task){constintentawaitclassifyIntent(task.input);switch(intent.type){casechain:// 链式操作查→写→存returnchainOrchestrator.run(task,{timeout:60_000,retry:2,partialCache:true});caseroute:// 分类任务客服分流/意图分发returnrouterOrchestrator.run(task,{confidenceThreshold:0.7,fallback:generalAgent});casefanout:// 采集任务多源搜索/交叉验证returnfanOutOrchestrator.run(task,{mergeStrategy:weighted,conflictResolve:highestWeight});default:returngeneralAgent.run(task);}}};六、选型决策表场景推荐模式原因可量化收益不推荐链式操作查→写→存顺序编排步骤依赖明确重试后成功率 92%比广播模式快 40%广播结果乱客服分流问技术/问账务路由编排意图边界清晰分类准确率 96%比顺序模式吞吐高 3 倍顺序串行太慢多源搜索查多个数据库广播编排信息越多越好召回率提升 35%比路由模式多召回 30% 信息路由限制信息量复杂任务不确定意图混合编排动态切换综合成功率 89%比单一模式成功率提升 22%单一模式七、局限与下一步Agent 数量超过 10 个时调度层本身的延迟会成为瓶颈——每次意图分类约消耗 200-400 tokens任务多的时候调度层反而成了慢路径路由模式依赖 LLM 分类器每次分类消耗 tokens简单任务用路由反而比直接跑一个通用 Agent 更贵广播模式下的冲突检测目前只支持字段级不支持行级。如果两个数据源返回的数据结构不同合并逻辑会变得很复杂相关链接MCP Client 实战翻车记——两个Server同时跑AI调错了Tool下一篇预告多Agent协作翻车实录——“两个Agent调用了同一个Tool数据全乱了”。到时候聊聊共享状态下的并发冲突比这次的数据冲突更刺激。