尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
多智能体系统架构选型:从自研编排到混合架构的实践之路
多智能体系统的架构抉择这两年几乎是做AI应用绕不过去的一道坎。我们团队在搭建一个面向企业内部知识助手项目时就卡在自研编排还是通用框架这个岔路口上反复论证了小两个月。一开始团队里偏向自研的人占多数理由很朴素框架抽象多、黑盒重出了问题不好排查。可真等第一版纯自研编排层跑起来我们又很快发现什么都能控和什么都得控是两回事。后来一步步把通用框架的成熟能力吸收进来同时保住了自研层的核心掌控才算理顺了这套系统。这篇文章就把我们这段纠结、试错、最终落地混合架构的过程原原本本写出来给正在做同样抉择的团队一个参考。1. 我们真正在纠结的其实是这三件事1.1 多智能体系统里编排层到底负责什么先交代一下项目背景。我们的系统不是那种跑通Demo就结束的玩具而是要把多个大模型Agent接进真实的业务流程里。系统里有好几个分工不同的Agent有的负责把用户的自然语言需求拆成结构化任务有的负责从企业内部文档库里检索相关资料有的负责写初稿还有的负责按一套业务规则做质检。如果全系统只有一个Agent问题很简单一个循环调用就结束了。但当Agent数量上到五六个彼此之间还有复杂的依赖关系事情很快就失控了。用户的一个问题进来可能要依次经过意图识别 → 任务拆解 → 并行检索 → 生成草稿 → 质检 → 修正 → 汇总出稿这一长串流程。这中间有顺序执行有并行调用有条件跳转有失败重试还要随时准备停下来等人工确认。把这些Agent之间怎么流转的逻辑管理起来的东西就是编排层。具体拆开编排层实际要干四类活第一流程路由决定下一步该调用哪个Agent走哪个分支第二状态管理记住当前这轮任务执行到哪一步了、已经拿到了哪些中间结果第三资源控制管理并发上限、限流策略、失败重试第四可观测性把每一次Agent调用的输入输出、token消耗、耗时都记录下来。这里我想多说一句很多团队一上来不重视可观测性觉得业务跑通就行。实际上多智能体系统上线之后80%的排查时间都花在看清某一次任务到底是怎么走的这个问题上。没有一套好用的链路追踪出了问题只能靠猜效率极低。1.2 那段时间我们评估过的几个典型选项我们的候选方案大概可以归成四类纯自研编排、纯通用框架、框架为主加局部自研、自研为主加局部框架。前两种是典型的单选题后两种本质上都是混合方案区别只在于主导方是谁。当时市面上的开源框架比如LangChain、AutoGen、CrewAI这一类的我们也简单跑过一轮。在跑Demo的阶段所有人都会觉得框架很香一个Graph定义下去节点和边清清楚楚自带重试和链路追踪社区里还有一堆现成的Agent模板可以直接抄作业。可越往生产环境靠越会发现框架在一些边缘场景下的行为是不可控的。我们团队里一位后端经验很扎实的同事当时说过一句话框架是给你省时间的不是给你省思考的。这句话后来基本成了我们选型的指导思想。1.3 一句话说清楚为什么不能照搬别人的架构我后来跟团队打过一个比方通用框架像一辆配置齐全的家用车自研编排像自己攒的越野车。家用车省油、好开、维护成本低但你要拉着设备进无人区很多原厂限制就会让你很憋屈自己攒的越野车底盘高度、悬挂、动力都可以按需调整但所有零件都得自己找出故障也得自己扛。多智能体系统的架构也一样没有绝对正确的答案只有是否匹配你的业务约束。我们当时梳理出三条硬约束第一业务流程会频繁调整业务方可能一周改两次拆分规则第二部分流程对状态准确性有硬性要求绝不能出现任务漏执行或重复执行第三部署环境是内网不能依赖任何闭源云服务也不能让框架偷偷联网。这三条约束直接决定了后面混合架构的切分方式。2. 自研编排控制力拉满但隐性成本远超预期2.1 一开始我们为什么想全部自研有几个很实际的原因让团队在项目初期几乎一边倒地倾向自研。第一是可控性。用框架时Agent的调用顺序由框架的Graph结构决定但Graph里某个节点如果出现异常跳转你很难在框架层拦截下来做自定义处理。自研就不一样所有路由逻辑都是自己的代码任何一个环节都能插桩出了任何问题都能在源码层面追到根。第二是部署环境。我们的目标环境是内网部分框架生态组件会在某些边缘功能里偷偷依赖外部服务要一个个排查非常烦躁。虽然主流框架都支持离线部署但支持和好用之间还有不小的距离这个距离只能靠踩坑去填。第三是团队惯性。我们团队里有几位后端功底很扎实的同事对自己造轮子这件事有天然的信心。后来复盘的时候我们都承认这第三点其实是最危险的风险源业务还没跑通大家就已经陷入我们要做一个优雅的编排引擎的自我感动里了。2.2 自研之后才会撞上的四堵墙等到第一版自研编排层真正跑起来我们很快撞上了四堵墙。第一堵墙是状态管理。多Agent之间要传递的中间结果五花八门有纯文本、有JSON结构化数据、有向量检索回来的片段还有Agent自己维护的短期记忆。自研一个状态管理器听起来不难但实际要处理的东西极其琐碎包括序列化、过期清理、断点恢复还有不同数据类型的转换和校验。我们用了整整两周才把这些边缘情况基本收拾干净而且后续还持续冒出新的状态同步问题。第二堵墙是重试与幂等。LLM调用天然不稳定同一个Prompt两次结果都可能有差异甚至会返回完全没有按指令走的格式。我们一开始只做了简单的超时重试结果某个Agent在重试时被重复调用了两遍把同一笔业务处理了两次。在工单场景里这是实打实的事故。第三堵墙是并发控制。多个用户同时发起任务时每个任务都是一套完整的Agent执行流。并发上限定多少、超出的请求怎么排队、Agent执行期间的中间状态怎么隔离这些都要自己设计。框架里一个线程池能解决的事自研时要考虑非常多的边界条件比如数据库连接池被Agent输出占满这种让人哭笑不得的问题。第四堵墙是可观测性。框架里有现成的trace和debug面板自研就什么都要从零开始画。我们花了不少时间接日志、做链路ID、把每次调用的输入输出落到存储里工作量比预期大得多。而且等到系统规模大了以后trace数据的存储和查询本身又是一个新问题。2.3 一个写起来很爽、跑起来很痛的真实片段举一个具体例子。我们第一版自研编排里有个动态路由模块会根据前一个Agent的输出来决定下一个该调用哪个Agent。这个模块的核心代码其实就是几张映射表加跳转逻辑写起来确实很优雅当时我们还专门写了详细的注释觉得这个设计非常干净。但上线第一天就出了状况。一个Agent在生成结果时突然输出了大段重复文本导致后续负责意图判断的Agent被误导任务走到错误分支上最后给用户返回了一份牛头不对马嘴的回答。这个问题本身是模型输出不稳定导致的但真正放大了事故的是我们的编排层这版自研路由完全没有输出校验机制Agent给的任何脏数据都直接成了路由决策的依据。如果是成熟的框架通常会在节点之间提供输出格式校验和修正的钩子。我们自研的第一版没有这个设计只能临时在路由逻辑里打补丁。补丁越打越多路由代码从最初的几百行膨胀到上千行后续几乎没人敢动那个文件——改一个分支就可能牵动三四处补丁。那次经历让我们真正意识到自研带来的自由是有代价的每一份自由背后都得用额外的工作量去换。3. 通用框架加速器不是万能钥匙3.1 框架带来的真香时刻在自研编排的泥潭里挣扎了一阵子之后我们决定认认真真做一次框架评估。当时选了一个社区活跃度很高的开源Agent编排框架搭了一个小范围验证项目。说实话真香的地方确实非常明显。第一是Graph定义直观。用框架先定义节点再定义节点之间的边顺序、分支、并行、循环一眼就能看明白。我们原先那套自研路由代码换成Graph描述之后逻辑清晰了一个量级。新同学接手框架项目时看一遍Graph大概就能说出整体流程。第二是组件生态成熟。LLM调用、工具调用、向量检索、短期记忆框架都有现成的封装。Prompt模板还提供了继承和叠加机制不用自己从零手写一套模板管理方案。第三是可观测性好。框架自带trace面板能看到一次任务执行里每一步的调用耗时、token消耗、输入输出。这个能力正好补上我们自研时最头疼的那块短板排障效率提升非常明显。验证项目两周就做出来了效果出乎意料地好。当时团队里几乎要达成一致干脆全部迁到框架上算了。3.2 上生产之后框架开始不听话但把验证项目往生产环境推的时候问题一个接一个浮出来。第一个问题是黑盒行为。框架的Graph里节点与节点之间的状态传递遵循它自己的一套序列化规则。我们的Agent输出经常带超长文本、嵌套JSON甚至二进制文件描述框架序列化到第三四层节点时经常出现内容被截断或者类型被强制转换的情况。查起来非常痛苦因为问题不在我们的业务代码里而在框架内部某个看不到的角落。第二个问题是版本迭代。框架的版本更新非常频繁有时候只是升一个小版本Graph的行为就变了。我们的一个流程在框架升级后某个节点的重试策略从失败重试三次悄悄变成了失败直接抛出差一点酿成线上事故。为了稳定我们只能把框架版本锁死但锁死的代价是后续的安全修复和新能力都进不来心里一直悬着。第三个问题是定制成本。我们有两条业务流程需要非常特殊的控制逻辑一条要按业务日历做工作日和非工作日路由另一条要等待外部系统的回调才能继续往下执行。这在自研里只是写一个if判断的事但在框架里要么费劲找插件要么直接改框架源码。改源码就意味着后续升级基本不可能团队得长期背负一个自己维护的框架分支。这三个问题加在一起让我们彻底放弃了纯框架这条路线。但同样地我们也不愿意退回纯自研的老路上去。这时候混合架构才真正被摆到桌面上。3.3 框架选型时容易被忽略的四个评估维度如果你也在做框架选型除了看功能、看社区活跃度有几个容易被忽略的维度我建议你重点考察。第一离线部署能力。别只看官网Demo把你最核心的那条流程放到完全断网的测试环境里完整跑一遍看哪些功能会悄悄失效。第二状态序列化方式。把你的真实Agent输出丢进去压测一下复杂数据类型在多层节点传递后会不会变形。第三升级策略。去看这个框架的版本发布频率和破坏性变更的比例太激进的框架在生产环境里不一定加分。第四问题排查手段。框架有没有独立的链路追踪面板支不支持自定义插桩这对后续排障非常重要。这些维度我们当时评估得不够细后面都变成了实打实的坑。4. 混合架构到底怎么切编排层拆成三条线4.1 我们的目标架构长什么样在纯自研和纯框架之间反复碰壁之后我们最终确定了一个原则稳定的部分用框架多变的部分用自研连接处用契约来隔离。具体到落地我们把整个编排层拆成了三条线。第一条线是基础支撑线负责LLM调用封装、向量检索、上下文记忆、重试策略、trace采集这些偏基础设施的能力。这一块我们最终交给了通用框架。原因是这一层的能力已经比较成熟自己重写既不经济也没有必要而且框架的最新能力更新我们还能持续白嫖。第二条线是业务编排线负责真正跟业务强相关的流程逻辑任务怎么拆解、Agent之间怎么路由、哪一步需要人工审批、哪一步要调用外部系统。这一块我们坚持自研写成一个轻量的流程引擎。核心只有状态机和策略表刻意不做通用化只服务我们自己的业务场景。这样业务方要调整流程时我们只需要改策略表不需要动底层引擎。第三条线是契约适配线。它本身不产生业务逻辑只在框架的通用能力和自研的业务流程之间做翻译。比如框架返回的Agent输出要先经过契约层标准化再交给自研流程引擎自研流程引擎决定该调用哪个Agent时也通过契约层把指令翻译成框架能识别的Graph调用。这个拆法的关键点在于框架的能力和自研的逻辑不直接纠缠所有交互都经过契约层而契约层的数据结构由我们自己定义、自己维护。这样未来即使换一个框架核心业务逻辑都不用动只替换适配层就行。4.2 哪些模块坚持自研哪些模块放心交给框架我整理了一个简化的划分表格供参考模块归属理由LLM调用封装框架成熟、跨厂商适配做得好向量管理与检索框架生态成熟需重点评估离线部署重试与限流策略框架通用能力足够使用Trace与日志聚合框架自研成本极高没必要任务拆解与路由自研强业务逻辑变化频繁且不可预期状态机与流程控制自研需要硬性掌控零容忍失控人工审批与外部回调断点自研框架的通用实现难以满足业务对象序列化自研需要稳定契约避免框架升级影响这个划分不是一步到位的中间调整过两次。最初我们曾把任务拆解也放到框架里后来业务方一周改了三次拆解规则每次都要改Graph定义痛苦得不行。迁回自研之后改动成本立刻降了下来。所以我们的经验是凡是业务上会频繁变化、而且变化方式不可预期的部分尽量自研凡是技术上通用、变化缓慢的部分尽量用框架。4.3 连接处的契约设计一个稳定的中间层契约层听起来抽象我直接给一段简化后的Python代码作为示意这是我们契约层的核心思路之一。# 契约层统一框架与自研流程引擎之间的数据格式 from dataclasses import dataclass, field from typing import Any, Optional dataclass class AgentTask: task_id: str agent_name: str # 由自研流程引擎决定调用哪个Agent inputs: dict # 传给Agent的输入参数 expected_output_schema: Optional[dict] None config: dict field(default_factorydict) dataclass class AgentResult: task_id: str success: bool data: Optional[Any] # 标准化后的输出数据 raw: Optional[str] # Agent原始文本仅用于排障 token_usage: dict field(default_factorydict) def normalize_result(raw_output: str, schema: dict) - AgentResult: 把框架返回的原始输出转成结构化数据失败时抛业务异常。 自研流程引擎只认AgentResult完全不感知框架内部细节。 # 这里做宽容解析先剥掉可能的Markdown围栏再做JSON解析 # 解析失败时抛出带上下文信息的异常方便trace排查 ...这个设计保证了两个重要的事。第一自研流程引擎里永远不出现框架的专用类型将来换框架只需要改契约层核心逻辑一行都不用动。第二框架那边的Agent输出必须先经过标准化清洗再脏的模型输出也进不了我们的状态机。这两个保证是混合架构能稳定的基础。5. 转型踩坑实录混合架构不是一混就灵5.1 坑一框架升级就像换了一个产品我们切到混合架构后框架版本还停留在验证期的版本。三个月后因为一个安全公告我们被迫升级框架补丁版本。契约层代码没有来得及做充分适配结果某个节点的输出格式从纯净JSON变成了带着Markdown围栏的JSON代码块契约层的解析器把围栏也当成了内容的一部分一连串任务全部被污染。我们花了整整一个下午才定位到问题根源——不是业务代码改了是框架输出了多包了一层。那次事故让我们定下两条规矩。第一所有框架升级不管大版本小版本都必须先在预发环境完整回放至少一周的真实流量确认契约层兼容性之后才能上生产。第二契约层解析器必须写宽容解析先剥掉可能的围栏再解析JSON而不是默认框架永远会输出纯净数据。现在我们的解析器对输入格式的容忍度高了很多反而更稳了。5.2 坑二状态同步的双份真相问题混合架构下自研流程引擎有自己的一套状态框架的Graph也有它的内部状态。如果一个节点的执行结果在两套状态里不一致后面所有判断都会出错。我们初期没有处理好这个问题出现过流程引擎认为任务已经完成框架那边却还在等一个后续调用的僵局整个会话卡死用户那边的请求一直挂起。这个问题的本质是双份真相——同一件事被两个地方各自记了一笔账且没有定义谁是权威来源。我们的解决方案是单一状态源原则框架的Graph状态只当作执行记录不参与任何业务决策业务决策只读自研流程引擎的状态。实现上就是契约层每次事件都回写流程引擎状态Graph本身不做条件路由只做机械执行。现在无论框架内部状态怎么变只要流程引擎的状态是对的整个系统就不会走偏。5.3 坑三人在回路的设计复杂度天差地别多智能体系统里有几条流程必须支持人工介入。比如质检Agent发现初稿有问题时需要停下来等人工确认确认通过后才能往下走。这个人等机器和机器等人的处理逻辑完全不同。我们最初想用框架自带的交互节点来实现发现每一轮的暂停恢复都得把整个Graph状态序列化保存实现非常绕而且很容易丢上下文。后来我们调整了设计把人工确认也封装成一个AgentTask由自研流程引擎统一控制调度。人工输入被包装成一次普通的事件注入框架那边完全无感只需要等待下一个AgentTask被触发即可。这个调整让人工审批链路稳定了很多调试时也能在流程引擎的状态里直接看到等人工这个中间态。6. 什么情况下你不该学我们6.1 决策不是看哪个最先进而是看哪个最匹配坦诚地说混合架构不是银弹。如果你的系统只有两三个Agent、流程相对固定、团队人手也比较紧直接用通用框架把业务跑起来很可能是性价比最高的选择。混合架构的维护成本是实打实的两套状态体系、一遍契约适配、框架升级带来的持续维护任务这些都会占掉原本可以花在业务逻辑上的精力。我们最终选混合架构核心驱动力是三条流程变动频繁、部署环境受限、对状态控制有硬性要求。如果你没有这三个约束那自研为主或者框架为主都可能是更简单的答案。不要看别人说混合架构好就强行往自己身上套。6.2 给团队的选型清单如果你正在做多智能体系统的架构选型我建议用下面这个清单自查一遍你们的业务流程多久变一次每周变还是每季度变变化方式是可预期的增删节点还是经常出现结构性调整部署机房里框架的所有生态组件能否完整离线运行有没有偷偷依赖外网的地方你是否需要精确控制Agent之间的状态流转还是说能跑通就行团队里有没有人能在两三天内把框架源码的某个核心模块读明白出了问题你能接受问题可能出在框架内部的排查成本和不确定性吗对这五个问题的回答基本能判断出你适合纯自研、纯框架还是混合架构。我们每条都踩过回头看如果项目初期就认真做一遍这个自查至少能省下三周的试错时间。6.3 最后说一点我们踩坑之后的心得架构选型这种问题最怕的不是选错而是选错之后没有留出回退的余地。我们在推进混合架构的过程中始终保留了一个开关契约层可以同时兼容框架执行和自研执行两种后端切换只需要改一个配置。这个开关在转型期救了我们很多次也让团队在争论的时候心态稳定了不少因为不会担心一旦走了这条路就回不了头。如果你最后也决定走混合路线我建议你把可回退当作第一原则来设计别一上来就把自己焊死在某一种实现上。架构是服务业务的不是用来证明谁的判断更正确的。
RELATED

相关推荐

BackTrader量化回测实战:从核心概念到完整策略搭建

BackTrader量化回测实战:从核心概念到完整策略搭建

1. 为什么选择 BackTrader 作为量化回测的起点1.1 从一次策略失效说起几年前我写了一个双均线策略,在历史数据上跑出了年化 40% 的收益曲线,兴奋得不行,直接上了实盘。结果三个月亏了 15%。回头复盘才发现,我的回测代码里犯了一个…

📅 2026/10/13 20:03:41
AI编程工具的正向价值与工程风险:一线开发者实操指南

AI编程工具的正向价值与工程风险:一线开发者实操指南

1. 从两个真实场景说起:AI编程工具到底在帮什么忙 去年秋天,我接手了一个遗留系统的重构任务。代码库是五年前搭建的,技术栈混杂,文档几乎为零。按照传统做法,我需要花至少两周时间通读核心模块、画调用关系图、梳理数…

📅 2026/10/13 20:03:41
AI长期记忆系统实战:从架构设计到检索优化的完整指南

AI长期记忆系统实战:从架构设计到检索优化的完整指南

1. 为什么“长期记忆”是AI应用绕不开的坎做过对话类AI应用的人都有一个共同体会:用户今天跟你聊过的事情,明天再打开,它忘得一干二净。这不是模型不够聪明,而是它的“记忆”机制天生就是短视的。大语言模型本质上是一个无状态的函…

📅 2026/10/13 20:03:41
MORE NEWS

更多资讯

📰

神龙卡新一代驱动:解决玄学掉卡与批量部署稳定性实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

CAN Signal Layout排查指南:DBC字节序与起始位如何影响信号解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Github子模块(submodule)使用介绍

目录 一.子模块使用场景 二.子模块(submodule)概念的引入 三.添加子模块 四.查看子模块 五.更新子模块 ■更新项目内子模块到最新版本 ■更新子模块为远程项目的最新版本 六.克隆包含子模块的项目 方法一:先克隆父项目,再更新子模块 ■克隆…

📰

GIT Manual

Git && Github 應用示例客戶端切換不同用戶使用说明從git全新pull一個新項目修改eclipse 的 tokengithub 生产token事先pull,push后synch创建Project本地初始化查看当前文件夹下的文件管理状态把所有的文件添加到本地仓库管理界面更改Branch把本地文件push到…

📰

react源码学习笔记

1、virtual domReactNode分为以下几类React$Element:其属性有export type ReactElement {$$typeof: any,type: any,key: any,ref: any,props: any,// __DEV__ or for string refs_owner: any,// __DEV___store: {validated: 0 | 1 | 2, ...}, // 0: not validated,…

📰

Cartographer实战指南:环境配置、TF坐标系与建图参数调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬