混合大模型架构实战:多Agent协同、模型路由与高可用体系搭建 📅 发布时间:2026/9/6 4:19:35 👁 浏览次数: 大家做混合大模型架构多数是被现实逼的。我自己最早接触这个方向是因为手上的业务方拿着纯云端API方案来找我说这个月账单又超了而且客户要求数据不出内网那时候才意识到单靠一个云厂商的模型服务根本撑不起生产级系统。本地/云端混合部署不是赶时髦而是成本、隐私、延迟、可用性这几个硬约束在背后互相拉扯之后必然长出来的形态。这篇文章就是我踩了大半年坑之后的完整复盘重点讲清楚三件事多Agent到底怎么协同才不会乱、路由层怎么像网络交换机一样把请求精准送到对的模型、以及高可用体系怎么搭才能扛住真实故障。内容偏工程实践适合正在搭LLM基础架构的团队参考也适合刚接触这一块、想搞明白为什么不能所有请求都走同一个API的开发者。1. 混合部署的价值坐标成本、隐私与延迟互相拉扯1.1 纯云端API的单点脆弱性与账单焦虑先说为什么不能All in云端。很多团队第一版系统都是直接接商业大模型API跑Demo阶段确实爽代码量少、效果还行、上线快。但一旦进入生产第一个炸的点就是成本。我见过一个客服问答项目上线三个月以后月度Token消耗翻了几十倍账单从几千跳到十几万业务方直接看傻了。更麻烦的是预算不可控你要是不做请求级别的管控模型API的计费根本不是一个能预测的量。第二个问题是数据隐私。金融、医疗、企业内部知识库这类场景客户会明确要求数据不能出内网或者至少核心数据不能发往第三方模型服务。这时候纯云端方案直接出局不是你技术选型的问题是合规上根本不给你选。第三个是延迟。云端模型再好一次完整的流式响应也要经过公网遇到高峰时段、跨地域链路抖动响应时间飘到用户不可接受的程度。这三个痛点叠在一起本地部署一部分模型云端保留一部分模型就成了非常自然的妥协方案。1.2 本地小模型能接住哪些真实业务本地部署不是让你把Llama 3 405B这种级别的稠密模型硬扛在单机上的。真正务实的做法是把业务请求按难度分级简单任务用本地小模型消化复杂推理再上云。拿我自己经手的实际业务举例意图识别、实体抽取、信息分类、格式整理这一类结构化任务7B到14B的开源模型跑在单张A100或者双卡4090上效果和云端大模型差距已经很小有些场景甚至因为微调过反而更好。真正需要云端出手的是长文总结、复杂推理、代码生成、角色扮演这类对聪明程度有硬性要求的任务。还有一类是流式语音交互对首token延迟极其敏感用本地模型效果显著优于公网转发。所以我在设计混合架构的时候第一原则就是能力分级、流量分层。这句话听起来简单落到工程上就是要在请求入口做一次完整的分类和路由让80%的简单流量沉淀在本地剩下20%需要重火力的请求再上云。这跟计算机网络里的路由转发思路本质上是同构的只不过这里路由的对象不是IP包而是带业务语义的推理请求。1.3 先路由再调度才是混合架构的核心动作很多人把混合部署理解成本地一套服务、云端一套服务、中间用代码判断一下转发这个理解太浅了。真正生产级的设计必须在本地和云端前面加一层独立的模型网关Model Gateway / LLM Router所有请求统一进网关由网关根据路由策略决定发去本地还是云端。这一层承担的不只是转发还包括协议转换、负载均衡、健康检查、熔断降级、流量观测。没有这一层你的高可用和成本控制都是空谈。我自己最开始图省事直接在业务代码里写了个if-else判断模型归属前两周跑得挺欢第三周本地推理服务一重启业务代码全部报错排查了半天才发现是一个服务依赖另一个服务中间没有任何隔离。从那以后我就把路由层必须独立成服务这件事列为铁律。业务方只认一个统一的推理接口至于请求去了本地还是云端、用的哪个模型、有没有降级都是网关内部的事。2. 多Agent协同三种编排模式与并发控制的真实参数2.1 流水线、编排器与联邦式选型逻辑多Agent是混合架构里最容易做得失控的部分。Agent不是一个模型而是一个模型提示词工具调用记忆的组合体。多个Agent一起工作的时候首先要回答的问题是它们怎么组织。我在实践里把常见的编排模式分为三类。第一类是流水线模式Agent按固定顺序执行前一个Agent的输出交给后一个Agent适合流程非常稳定的场景比如先做意图识别再调用对应技能Agent生成回答。优点是简单可靠缺点是灵活性差一旦流程中间有分支判断流水线就僵住了。第二类是编排器模式也叫路由器或指挥官模式一个主Agent负责任务规划和分解把子任务分发给其他Agent再把结果汇总返回。OpenAI后来的function calling思路本质也是这个。这种模式适合任务复杂度高、需要动态拆分的场景但主Agent很容易成为瓶颈它自己的能力直接决定整个系统上限。第三类是联邦式模式多个Agent各自独立运行、通过消息总线或共享黑板机制协作没有一个中心节点适合异步、松耦合的场景但是调试难度大我在实践里用得最少。我的选型建议很朴素业务方只要一个稳定输出的服务就别上太复杂的编排如果你对Agent自由协作产生涌现能力没有确切的业务验证也别硬上联邦式。先把流水线跑通再用编排器模式做动态扩展是一个不容易翻车的路线。2.2 上下文传递Agent之间到底传什么多Agent的第二个核心问题是上下文传递。这里我踩过的坑特别多最典型的是把用户原话从头传到尾导致每个Agent都在处理大量无关信息Token消耗翻倍而且上下文一长模型很容易丢失关键信息。正确的做法是设计一个标准化的Agent消息结构包含任务ID、角色来源、意图标签、需要传递的结构化数据字段、以及裁剪后的摘录文本。我在实际项目里用的是类似OpenTelemetry的trace模型思路一个根任务会展开成多个子任务span每个span里记录子任务输入输出的结构化摘要而不是把原文一路带着跑。子Agent需要的背景信息由父Agent显式拼接最重要的原则是每个Agent只看到它完成任务所需的最小上下文。通信方式上我倾向于在Agent之间通过一个轻量级消息队列RabbitMQ或者Redis Stream都可以传递任务消息而不是直接HTTP互相调。原因有两点一是解耦Agent实例可以独立扩缩容而不互相感知二是天然支持异步和重试消息失败不会把整条链路拖死。当然了如果你的Agent数量很少、逻辑都在同一个进程内那直接函数调用也没问题别过度设计。2.3 并发配置线程池、信号量与超时的联动多Agent的并发控制是agent多并发配置热搜背后真正的工程难点。很多团队把并发数简单理解成线程池大小调大点结果一压测就炸。我之前线上事故有一半跟并发配置相关。我的经验是多Agent并发要同时管理三个维度Agent内部的模型请求并发、Agent之间的任务队列并发、以及对外部依赖本地模型服务、云端API的流量控制。以一次请求进来为例编排器Agent可能需要并发调用三个子Agent每个子Agent又要调本地模型服务如果内层模型服务只支持10个并发而你给编排器配了50个并发那么排队和超时必然发生然后用户侧表现为接口变慢重试一上来系统直接雪崩。所以我在生产里给出的初始参数通常是这样的编排器线程池大小为20子Agent线程池大小为50本地模型服务并发上限为16根据GPU显存和推理引擎实际压测得出云端API并发上限为32总入口并发用信号量控制为100。超时配置上下两层联动子Agent的调用超时为30秒编排器总超时为60秒重试次数不超过1次且只在可重试错误码上重试。这些数字不是拍脑袋而是压测环境下一轮轮调出来的不同团队的硬件不同但分层限流、先内后外的思路是通用的。3. 模型路由层把网络路由的思路搬进大模型网关3.1 从静态路由到策略路由规则怎么定模型路由是混合架构里最像网络工程的部分。我经常和团队说大模型网关本质就是一张路由表只不过表项不是目的网段而是请求特征到模型服务的映射。最低级的路由是静态路由直接在网关里写死HOST、路径和模型名的对应关系。比如业务A的查询请求一律走本地模型A业务B的生成请求一律走云端模型B。这种方案适合模型数量少、业务变化缓慢的阶段跟我们做静态路由实验一样能在ensp上配通就算入门。但生产环境很快会暴露问题模型有多个版本、有灰度发布的诉求、有故障时需要切换、不同的请求负载时段成本策略不同静态表项根本扛不住。这时候就要上策略路由Policy-Based RoutingPBR。PBR的核心是路由决策不只依赖目的地址而是根据一组策略条件进行判断。在模型网关里这些条件包括请求类型标签、Token预估成本、响应延迟目标、数据敏感级别、当日预算消耗比例、模型可用状态等。我设计的路由策略表大概是这样的优先级匹配条件目标模型动作10请求类型意图识别本地小模型A转发20请求类型代码生成 且 来源内部研发平台云端大模型B转发30数据敏感级别高本地大模型C转发40预算消耗比例80% 且 请求类型摘要本地小模型A降级转发50本地模型A 不可用云端大模型D转发故障转移表项从上往下匹配命中即停。这套规则放在一个YAML配置文件里网关启动时加载配置热更新走etcd订阅改策略不需要重启服务。落地的时候有几个细节必须注意一是规则顺序很重要和防火墙规则一样是先匹配先生效二是每条规则必须能解释为什么命中方便问题排查三是每个目标模型必须关联独立的健康状态规则匹配到不健康的服务时必须能跳到下一个可用目标。3.2 按能力标签与成本因子做动态权重静态策略之外我还做了基于权重的动态路由主要用于两个场景版本灰度发布和成本倾斜。版本灰度发布的场景很常见。新微调版本的本地模型上线不能直接百分百流量可以先切5%的请求过去观察指标没有问题再逐步放大。这个在网关里实现很简单就是为同一能力配置多个模型地址各带一个weight权重网关按权重负载均衡。我实际使用的权重配置models: - name: local-model-a-v3 endpoint: http://10.0.1.10:8001/v1 weight: 5 - name: local-model-a-v2 endpoint: http://10.0.1.11:8001/v1 weight: 95成本倾斜是另一件事。云端模型价格高、本地模型价格低两者的真实时延和效果差异在不同业务下表现不同。我让路由层定期从监控系统读取每个模型的平均响应时间和每百万Token成本再按一个可调的成本敏感系数计算综合得分把流量按得分比例分发。说白了这跟链路负载均衡里的加权轮询是同一个思路只是权重不只是固定配置而是动态计算的。还有一个容易被忽略的点动态权重不能只盯成本和延迟还要看效果指标。我在网关里额外接入了每个模型在黄金测试集上的效果得分效果跌到阈值以下的路由自动摘除。这样做的好处是即使新模型发布后看着快又便宜但如果回答质量崩了系统也能及时发现并切回旧版本。3.3 路由失效兜底降级链路必须提前设计路由层做得再完善也要面对一个残酷的事实你依赖的所有模型服务本地也好云端也好都可能不可用。本地推理机器会宕机显存会OOM云端API会限流甚至会直接报5xx。所以路由层如果没有兜底设计一切转发规则都是空中楼阁。我的经验是给每个业务请求预设一个降级链路。所谓降级链路就是一条按最优-次优-保底排列的路径。最理想的路径是本地能力足够的模型次选是云端同能力模型保底是规则引擎或者固定模板回答。比如某个智能客服请求正常走本地微调模型本地故障时切云端通用模型云端也故障时返回一个预设的安抚话术并转人工。这个降级链路不是临时想的而是在架构设计阶段就定义好并且每个环节都要做压测。理由很简单故障发生时你没有时间冷静设计只能执行预案。兜底设计还有一个边界要注意降级不能盲目。如果业务是交易场景模型回答错了会造成真金白银的损失那么宁可快速失败返回错误码给用户也不要拿一个低质量回答糊弄过去。在我负责的系统里降级策略是分等级配置的L0业务禁止自动降级到低质量模型L1业务可以降级但必须记录日志并告警L2业务允许任意降级。把降级权和责任边界定义清楚比把所有请求都强制高可用更有工程意义。4. 高可用矩阵探活、熔断、限流与故障转移的配合4.1 三层高可用模型服务、网关、业务侧各管什么高可用是个系统工程不是某一层能独立扛住的。我在混合大模型架构里把高可用拆成三层各管一段。第一层是模型服务层管的是本地推理服务和云端API本身的可用性。本地侧要做多副本部署、GPU健康监测、进程守护和自动拉起云端侧能做的就是请求重试、区域切换和账号切换。第二层是网关层管的是探活、熔断、限流、优雅降级和流量切换这一层是我投入精力最多的也是路由和高可用交汇的地方。第三层是业务侧管的是超时控制、重试策略、缓存和用户可见的降级提示。三层之间通过标准化错误码和健康状态接口联动。跟搭建MySQL MGR或PostgreSQL高可用集群的思维类似模型服务也需要一个副本状态同步主从切换的机制。不过模型服务和数据库有一个关键区别模型服务大多是纯无状态的如果你不做会话记忆切换成本低得多。这意味着我们甚至可以不做复杂的主从选举只要有一个健康检查机制能发现实例挂了流量能自动转移到剩余实例就行。但也要反过来想正因为切换成本低很多团队反而忽视了自动化靠人肉改配置切换这在半夜故障时就是灾难。4.2 健康检查与熔断参数怎么定才不误伤健康检查是高可用的眼睛。我在生产里用的探活方式不是简单的ping端口而是有业务语义的推理探活定期向模型服务发一个极小的推理请求判断响应是否正常、耗时是否在阈值内。之所以不用ping或者HTTP HEAD是因为很多模型服务进程活着但推理功能已经退化比如显存泄漏导致OOM前兆、推理引擎线程卡死端口探活根本发现不了。探活参数我建议这样设置每10秒探活一次连续3次失败标记为不健康连续2次成功恢复健康。超时阈值设为正常推理耗时的3倍以上避免偶发慢请求造成误判。这里有个特别容易踩的坑探活请求必须走和真实请求一样的数据路径不能走旁路或者内部短链。我踩过一次探活脚本直接访问模型实例的内网IP绕过了网关的限流队列结果探活全绿真实请求却因为队列积压大量超时最终被用户投诉了才查出来。熔断器的参数同样需要精细化。我用的参数组合是滚动窗口10秒内错误率超过50%触发熔断熔断持续时间30秒半开状态下放行少量试探测请求成功比例超过70%则恢复全量。这些参数不是从书上抄的是通过模拟故障压测定出来的。关键点是熔断阈值要分模型设置云端大模型API的错误容忍度可以放高一点网络抖动造成的偶发错误常见本地模型服务的阈值要严格得多内部链路不应该频繁出错出错就说明有问题。4.3 一次完整故障转移的时序复盘聊完参数我拿一次真实的故障转移流程来复盘这样更直观。某个工作日下午运行本地模型A的两台GPU服务器中的一台出现故障显存ECC报错导致推理服务崩溃。故障转移的完整时序是这样的第0秒到第3秒客户端开始出现部分超时错误网关的负载均衡器把请求打到宕机实例上报错率上升。第5秒健康检查连续3次失败网关把宕机实例标记为不健康从服务池摘除。第5秒到第8秒剩余流量全部打到存活实例单机负载上升但还在承受范围内。第12秒进程守护脚本尝试重启失败确认实例彻底不可用。第20秒存活实例的请求延迟开始超过告警阈值触发了网关的过载保护部分非核心任务的请求被降级到云端模型B。第35秒运维收到告警开始介入排查硬件问题。整个过程用户的体感是少量请求变慢、极少数请求失败业务没有中断。这个流程能跑通靠的是每个环节都提前设好了触发条件和动作。如果健康检查周期太长比如60秒故障持续的时间就会拉长到分钟级如果没有过载保护单实例强撑可能导致连锁雪崩。我后来把这段复盘的结论写进了团队的故障演练文档每个月会做一次故障注入演练随机杀掉一个模型实例看整个链路能否自动恢复。这种事前演练比事后补窟窿高效得多强烈建议做。5. 生产环境排障手记五个典型事故的根因与修复5.1 多Agent并发飙升导致上游限流第一个想写的事故是某次做活动推广流量突然涨到平时的5倍多Agent编排器的并发策略没扛住导致它的所有子任务都开始排队最终把上游云端API的限流阈值打满了。表面上看是上游限流问题实际根因是我们自己的编排器并发数没有随流量自动伸缩导致请求在内部无限排队而这些排队请求又拿着占用的连接不放最终拖死了整个服务。修复动作有两个一是给编排器加上基于队列长度的自动扩缩容机制队列积压超过阈值就自动增加Agent实例二是在网关层对所有业务请求设置一个排队上限超出上限直接快速失败绝不无限等待。快速失败虽然会让部分用户看到错误但总比整个系统打挂好。5.2 路由优先级写反导致的成本翻倍第二个事故非常丢人。某次我们上线了一条新的成本优化策略本意是低优先级的摘要请求全走本地模型结果配置的时候把路由表项的优先级数字写反了导致所有摘要请求都先命中云端大模型跑了一整天才在账单上发现异常。那一天的成本是平时的3倍。这个事故给我的教训是路由配置必须做上线前验证和灰度发布。后来我加了一个路由规则的影子模式新规则先在真实流量上跑影子只记录如果这条规则生效请求会被路由到哪不实际转发跑一段时间对比实际路由结果和期望路由结果一致了才正式切换。另外成本监控必须做到小时级别别等日报日报出来的时候钱已经烧完了。5.3 缓存误导健康检查引发雪崩第三个事故和缓存有关。我们在网关层做了一层语义缓存相同意图的请求直接命中缓存返回不打到模型服务。这本是降本的好手段但问题出在健康检查的探活请求也符合缓存命中条件于是一个已经挂掉的模型服务因为探活请求全部命中缓存返回了正常结果被误判为健康。等缓存过期后真实请求瞬间涌入这个假健康的实例彻底被击穿连锁引发雪崩。修复方案是在探活请求里加一个特殊的no-cache标记同时探活响应必须校验模型服务实例自身的标识信息确保这个探活响应真的是这个实例生成的而不是缓存伪造的。从那以后我把所有监控探活路径都梳理了一遍凡是经过缓存的路径全部加白名单绕开这条经验我认为值得每个做模型网关的团队抄一遍。5.4 超时设置一刀切拖垮本地推理第四个事故是超时配置过于粗暴。当时为了省事我把网关到所有模型服务的超时都统一设成了60秒结果本地模型处理短任务只需2秒云端大模型处理复杂任务需要40秒两者混在一个超时池里本地服务的线程迟迟不释放造成大量线程被无效占用GPU利用率上不去整体吞吐反而下降。修复方法很直接按模型服务能力分别设置超时。本地小模型8秒、本地大模型30秒、云端大模型60秒、流式任务单独用空闲超时控制。超时粒度越细资源利用越充分。这个事让我明白一个道理在LLM架构里的所有时间参数都必须按路径单独设置任何统一配置的偷懒都会在流量上来时加倍偿还。5.5 模型版本漂移与路由规则脱节第五个坑比较隐蔽路由规则里写死了模型版本号而模型服务端已经灰度更新了新版本两边脱节了。比如路由规则说意图识别请求走model-a-v2实际上model-a-v2已经被v3替代下线了但是网关还在往旧地址转发旧地址的上游负载均衡器做了兼容处理导致系统没有立刻报错但行为已经和预期不一致。等到旧版本彻底下线时才爆发大量404错误。这类问题的根因是配置管理没有跟上发布流程。我的修复方案是给模型版本建立注册表模型服务的注册信息里必须包含版本号和兼容能力标签路由规则只匹配能力标签最低版本号不写死具体版本。这样模型服务升级时只要兼容能力标签不变路由规则就无需修改。这套机制类似于动态路由协议相比静态路由的核心优势网络拓扑变了路由能自动收敛而不是靠人肉改表。6. 可复用的基线配置与最终建议6.1 网关路由与高可用的最小配置最后给出一份我在生产里落地过的核心配置骨架可以直接作为起点。模型网关用的是基于FastAPI自研的轻量网关路由引擎和熔断逻辑自己实现配置存在etcd里。router: rules: - priority: 10 match: { type: intent, sensitivity: low } target: local-small-a fallback: cloud-large-b - priority: 20 match: { type: codegen, source: internal } target: cloud-large-b fallback: local-large-c - priority: 30 match: { sensitivity: high } target: local-large-c fallback: none weights: local-small-a: { v3: 5, v2: 95 } cloud-large-b: { primary: 90, backup: 10 } healthcheck: interval: 10s timeout: 8s fail_threshold: 3 success_threshold: 2 no_cache: true circuit_breaker: window: 10s error_rate_threshold: 0.5 cooldown: 30s half_open_requests: 5 recovery_success_rate: 0.7 rate_limit: global_qps: 200 per_business_qps: 50 queue_max: 100 overflow_action: fast_fail6.2 Agent并发参数的推荐初始值多Agent侧我建议从以下初始值开始压测调优不要一上来就抄大厂公开的方案大厂的硬件和业务模型跟你不一样。参数推荐初始值调整依据编排器线程池20压测时观察CPU和依赖调用延迟子Agent线程池50根据模型服务并发上限联动调整本地模型服务并发上限16用压测工具打到GPU利用率80%为止云端API并发上限32根据云厂商配额和预算设置子Agent调用超时30s正常P95延迟的2-3倍编排器总超时60s必须大于子任务链路总耗时重试次数1只在429/5xx/连接错误上重试这些数字跑通后要按月复盘调整。模型升级、数据量增长、业务变化都会让最优参数漂移高可用体系不是配置一次就完事的静态系统。6.3 我对这套架构的总体评价与后续演进做了大半年混合架构我的整体感受是这套方案的复杂度的确比单纯接云端API高一个量级但投入到一定程度后回报非常明显。成本上本地模型承接了大约65%的请求量整体推理成本降了接近70%稳定性上有了网关这层缓冲云端API的抖动对业务的影响基本被隔离了最大的隐性问题——多Agent编排的调试复杂度——则要靠完善的链路追踪来缓解。我个人在实践中最想强调的一点是不要把路由和高可用拆成两件事分别做它们本质是同一个系统的一体两面。路由负责把请求送到该去的地方高可用负责当那个地方不可用时还能送到别的地方没有可观测性的路由是盲目的。所以如果你只从这篇文章带走一个行动项我会建议先在你的模型调用入口前面加一层带全链路追踪的网关哪怕规则很简单也比没有强。先把这条链路立起来成本、稳定性、多Agent协同的能力都从这一层长出来。