news 2026/10/20 19:06:31

多智能体编排架构选型:自研与通用框架的混合之路

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多智能体编排架构选型:自研与通用框架的混合之路

大概半年前,我们团队接到一个活儿:把公司内部的客服工单处理流程,从“人肉流转”升级成一套多智能体协作系统。第一版技术评审的时候,会场上吵得最凶的两个字就是“编排”——工单进来之后,谁来决定先调哪个Agent、每个Agent干到什么程度算完、中途失败了怎么补救,这些问题绕不开编排。有人坚持自研编排,理由是业务规则太特殊,现成框架肯定兜不住;有人力推通用框架,理由是社区生态成熟,没必要重复造轮子。两边的Demo都跑过,各自都有亮点,也都有让人手心冒汗的瞬间。最后我们定下来的方案,既不是纯自研,也不是纯依赖某个通用编排框架,而是各让一步,搭了一套混合架构。这篇文章就把我们当时的决策过程、落地细节和翻车现场整理出来,希望能给同样在纠结的人一些参考。

1. 为什么会产生这次架构抉择:我们到底被什么问题卡住了

1.1 业务场景概述

我们处理的不是那种“问一句答一句”的聊天机器人,而是一个完整的工单闭环。工单从业务系统进来,先要判断类型和紧急程度,再分给不同的Agent去做信息抽取、方案生成、审批材料整理,最后由一个审查Agent把关,把结果送回业务系统。业务方提的要求很直接:流程要可追溯、操作要可回滚、权限要有边界。这意味着系统的难点不在单个Agent的聪明程度,而在多个Agent怎么被组织起来、怎么协作、怎么失败恢复。

我们调研了一圈市面上的方案,发现很多产品把多智能体系统做成了“乐高积木”,给你一堆Agent,让你自己拼。但我们这里的问题恰恰是:拼好之后,谁来监视它们?谁来决定下一步拼哪块?拼错了怎么拆?这些职责,就是我们说的“编排层”。它看起来只是系统里的一个管理层,但实际上一旦出问题,所有锅都会先砸到编排层头上。

1.2 三条硬约束

在这个前提下,我们给架构方案列了三条约约束:

  • 长尾能力扩展。业务方每隔一两个月就会提出新的工单类型,意味着要新增Agent,或者给已有Agent增加工具。也就是说,我们的架构必须允许“低成本加新玩具”。
  • 业务规则可演化。审批条件、超时时间、路由策略,这些在业务方看来都是“配置”,不能每次变都改代码发布。
  • 可观测性和可运维性。出了问题,我们要能在半小时内定位是哪个Agent、哪一步、哪个上下文出了问题,而不是翻半天日志都找不到任务轨迹。

这三条约束,在评审会上听起来都“合理但模糊”,真正落地的时候才发现,每一条都是在给架构出难题。长尾扩展要求低耦合,可演化要求动态配置,可观测性要求全链路链路追踪——每一条单独拎出来都能挡住一个方案。

1.3 两个阵营的初赛表现

我们当时做了两个对照Demo:一个用自研的极简编排器,跑通了一个三Agent协作任务;另一个用社区开源的通用编排框架,也跑通了同样的任务。Demo阶段两个方案都没有明显劣势,而且大家都在暗暗较劲。自研版的代码量多了一倍,但每一步都在掌控之中;框架版只需要一两百行配置,但在边界case里明显有点“使唤不动”。

这就进入了一个经典困境:看起来都能用,但都不知道往下走半年会变成什么样。选自研的人怕的是“掉进工程泥潭”,选框架的人怕的是“被框架的天花板卡住”,两边谁也说服不了谁。所以与其说是选型之争,不如说是在争夺一个确定性:我们到底能不能掌控这个系统的命运。

2. 自研编排路线的技术盘点:自由度、可塑性,以及被低估的工作量

2.1 自研的优势:主动权在自己手里

支持自研的同事有一个核心论点:业务规则是我们自己的,Agent之间的协作模式是我们自己的,凭什么让一个通用框架来定义?

这个论点在初期确实很有说服力。我们需要把某些工单按来源路由给特定Agent,需要按业务方的时间窗口做批量调度,甚至把审批人角色动态塞进会话上下文——这些在自研里都是“改代码”的事。而且我们可以完全控制任务的执行顺序,想同步就同步,想异步就异步,想并行就并行。

这种自由度在架构讨论里很诱人。很多团队选择自研,不是因为框架不够好,而是因为想要那种“想怎么调度就怎么调度”的掌控感。掌控感本身不是坏事,但问题是,自由度的背面往往写着“所有问题都是你的”。

2.2 一个可用编排层要写多少东西

很多人一听到“编排”两个字,脑子里想的是“调几个API,串一下流程”。但实际上,一个能在生产环境扛住压力的编排层,远不止串流程那么简单。我把我们在自研过程中需要解决的组件列了个清单:

组件要解决的核心问题踩过才知道的坑
任务队列谁先执行、谁后执行、并发上限队列积压、优先级反转、消费幂等
状态存储Agent执行到哪一步了,结果放哪状态与外部副作用不一致
上下文管理一个任务从开始到结束的上下文传递上下文膨胀、token开销爆炸
工具调用协议Agent怎么安全地调用外部系统接口版本、权限校验、超时处理
失败重试出错之后怎么恢复、重跑哪一段重试与副作用叠加,造成重复执行
审计日志每个环节谁在什么时候做了什么日志链路断裂、格式不统一
并发控制多个任务同时跑不会互相干扰锁粒度控制、死锁、事务边界

单独看每一项,工作量都不算大。但把它们组合在一起,就是一套需要长期维护的分布式系统。最坑的是,这些组件每一个都有成熟中间件可以抄,但抄过来之后还要和我们的Agent逻辑适配,这个适配成本远超预期。

2.3 我们写的mini编排器长什么样

为了验证自研路线的可行性,我们当时的架构师花了不到两周,写了一个迷你编排器。核心逻辑其实不复杂:一个任务状态机加一个路由策略模块加一个事件总线。任务进来先转成统一结构,状态机根据当前节点决定下一步动作,路由策略决定把任务交给哪个Agent,事件总线负责在各模块之间传消息。

第一版跑通的时候,大家都很兴奋,觉得“自研也不过如此”。但随着我们往里加需求,情况开始失控。原来只要维护状态机的几个节点,后来要在每个节点上记录输入输出、处理超时、支持人工干预,还要把状态持久化到数据库,这样进程挂了才能恢复。

代码量几倍几倍地涨,最后已经没办法一个人维护了。最要命的是,每加一个新的Agent类型,就要同时改状态机的节点定义、数据库迁移脚本、前端调试面板的展示逻辑。业务方等得直挠头,问我们“加一个Agent怎么要两周”。

2.4 踩过的坑

这个过程中,有几次翻车让我印象特别深。

第一次是状态不一致。我们把每一步的状态都存在数据库里,然后从库里恢复。结果有一个Agent的工具调用是有副作用的——它会给外部系统发消息。如果这个Agent执行到一半进程挂了,我们重跑时,外部系统就会收到两条相同消息。后来我们不得不给所有工具接口都设计幂等键,但这让Agent的调用逻辑变得极其臃肿。

第二次是日志链路断。自研状态下,每次重启、恢复、重试都会产生新的执行片段,原本设计好的调用链很容易断开。排一次问题,要从数据库状态反推执行过程,再翻服务器日志找对应时间点。查一次问题半天起步,业务方已经黑脸了。

第三次是迭代速度。每加一个长尾场景,就要动整个编排器的前前后后。我们清楚的认识到一件事:编排层真正的复杂度,根本不在“流程怎么串”,而在于“工程可靠性”。这部分是一个持续投入的黑洞,如果全部自研,我们团队至少需要再增加两到三名专职后端工程师才能扛住。

3. 通用编排框架的实测体验:开箱即用的甜点与隐形天花板

3.1 为什么我们曾高度倾向通用框架

支持通用框架的同事,理由也很真实:社区生态成熟,内置状态图、检查点、人工介入、可视化调试这些能力,如果完全自研,保守估计要半年。

我当时去翻了一下某个开源编排框架的文档,确实被它的能力清单打动。它把一个Agent内部的执行流程建模成状态图,节点之间通过事件跳转,还提供了持久化检查点,进程挂了可以从某个节点恢复。最吸引我的是它自带可视化界面,每一步的输入输出、工具调用结果都展示得很清楚。这些恰恰是自研方案里最难搞的那部分。

3.2 实测的优点

我们拿同样的工单场景做了验证,效果非常直观:

  • 跑通demo的时间从两周缩到了两天,因为状态图、节点、工具调用协议都是现成的。
  • 调整业务流程时,只需要改图定义,重新加载配置就能生效,不需要发布代码。
  • 内置的工具调用模块可以直接对接一批常用的外部API,省去了很多胶水代码。

在这个阶段,框架带来的幸福感是真实的。团队里甚至有人说“早知道何必纠结,直接用框架不就行了”。但人就是这样,demo里看不见的问题,只有真正往生产环境推的时候才会浮出水面。

3.3 深入之后的天花板

我们拿着框架去做更复杂的场景,大概三周后,问题开始出现。

第一个是对“图”的表达假设。框架的核心抽象是图,默认节点和边是静态的。但我们的工单流程是动态的,有时候要根据模型的输出决定下一个动作,有时候要在运行时才确定需要哪些工具,有时候要临时并发多个Agent再聚合结果。这些场景在框架里要么写一堆自定义节点,要么绕过框架的调度逻辑,套一层自己的壳。一旦开始套壳,当初“省事”的优势就消失了一半。

第二个是跨节点的共享状态管理。框架的检查点机制是针对整个会话的,它的设计思路是“整个会话作为一个执行单元”。但我们希望每个Agent有独立的持久化上下文,而且部分上下文要跨Agent共享。这个需求和框架的会话模型不吻合,导致我们只能把上下文对象在每个节点的input/output里传来传去,非常笨拙,而且很快遇到了token开销问题。

第三个是多实例并发的控制。框架默认一个会话对应一个执行链,同一时间只有一个节点在跑。但我们的业务里,同一个工单可能同时需要分诊Agent和检索Agent并行工作,最后再聚合成结果。这种并行聚合的场景,框架不直接支持,需要靠外部机制来补,优势又被削弱了。

第四个是版本演进带来的升级负担。框架迭代太快,接口经常变,我们试用期内就碰到了两次不兼容更新。第一次影响不大,第二次直接把我们的一个关键节点实现报废了。这种层面的不可控,对于一个要长期维护的业务系统来说,是很危险的。

3.4 关键结论

测试了一圈之后,我们的结论是:通用框架适合流程相对固定、长期变化少、团队不想深耕Agent工程化的项目。它可以快速搭建一个可用的多智能体应用,但对于我们这种“流程复杂、长期演进、强治理需求”的业务系统,单押框架的风险太高。

风险具体来自两个地方:一是框架的抽象模型和我们的业务模型存在错位,这个错位靠配置补不回来,只能靠改造;二是框架的升级节奏不在我们手里,一旦上游做出不兼容变更,整个系统的技术债就要被迫兑现。对一个要服务业务方好几年的系统来说,这两点都是硬伤。

4. 混合架构的切分逻辑:编排层与执行层各自该干什么

4.1 总体设计思路

折腾了两轮之后,我们决定不再做二选一,而是把系统拆成两层,各用各的。

  • 全局编排层(自研):这是一个轻量的调度服务,负责任务拆分、跨Agent路由、全局会话状态、业务参数管理、对外API、审计与权限校验。它只关心“下一步该干什么”,不关心“某个Agent内部怎么干”。
  • Agent执行层(基于通用框架):框架负责单个Agent内部的工具调用组装、上下文切片消费、状态图执行、局部检查点保存。它只关心“这个Agent收到输入之后怎么产生输出”,不关心全局还有哪些Agent在跑。

这个划分看着简单,实际上是把两边的复杂度都压到了各自最擅长的地方。自研部分不再需要处理Agent内部的复杂状态流转,框架部分也不需要理解全局路由策略,两个系统各干各的,之间的接口清晰到可以用一张表写明白。

4.2 切分边界表

关注点全局编排层(自研)Agent执行层(通用框架)
任务分配决定下一个Agent是谁不感知全局,只做输入到输出
状态管理全局会话状态 + 业务参数Agent局部上下文 + 工具侧中间结果
失败重试编排层发起重试、补偿、人工干预报告失败原因,支持定点续跑
上下文传递分配切片上下文给执行层消费编排层下发的上下文切片
可观测性分配traceID、记录节点审计日志局部埋点、工具调用日志透传trace
权限与合规前置校验、结果放行工具调用权限校验、输出脱敏

这张表贴在我们内部Wiki上,之后所有新增Agent的开发都按照这个边界去对齐,很少再出现跨层代劳的情况。

4.3 为什么这个切分刚好

很多人会问:为什么不直接让框架管全局,或者干脆全自研?我们的答案是:把复杂度放在它最合适的位置上。

自研需要维护的规模被砍掉了很大一块——不用再写Agent内部的状态机、工具调用协议、检查点恢复机制,这部分直接用框架的。框架的天花板也被绕开了——它不需要懂全局路由和跨Agent状态,只需要把“单个Agent的事”做好。

这个切分还有另一个好处:责任边界清晰了。出了问题,先看是编排层的路由问题,还是执行层的Agent内部问题,排查范围直接小了一半。业务方提新需求时,如果只是新加一个Agent类型,只需要在编排层注册一条路由规则,然后在执行层加一张图定义,两边互不干扰。

4.4 一次真实任务流转

为了说清楚这个架构跑起来是什么样子,我描述一次真实的工单处理流程:

  1. 编排层收到业务系统的工单,先做意图归一化和分诊,产出任务计划。
  2. 编排层生成一个全局任务ID,把需要传给首个Agent的上下文切片好,调用执行层接口。
  3. 执行层启动对应Agent,加载框架里的图定义,开始执行工具调用。每完成一个关键步骤,回调编排层一次,上报执行状态和中间结果。
  4. 编排层根据回调结果,判断下一步是让这个Agent继续,还是切换到另一个Agent,或者是多个Agent并行执行。
  5. 最终执行完成,编排层做汇总,把结果写回业务系统,同时归档审计日志,整条链路有一个贯穿始终的traceID。

整个流程看下来,执行层像一个“被点名的执行者”,只负责把自己那一段做好;编排层像一个“项目经理”,负责盯进度、管状态、做决策。这种角色划分也让人力安排更清晰——框架部分可以交给Agent开发同学,编排层由后端工程师维护,两边技能栈不重叠,反而减少了相互等待的时间。

5. 落地过程中真正难搞的工程问题:跨层通信、上下文切片与可观测性

5.1 跨层通信协议

方案定了之后,第一个实际要解决的工程问题是两层之间的通信协议。我们最终用了JSON格式,配合事件回调接口,每个接口都有三个核心字段:task_id、agent_id、trace_id。其中task_id对应全局任务,agent_id对应执行层里的某个具体Agent,trace_id贯穿全链路。

协议设计里最容易忽略的是版本兼容。执行层的框架升级后,接口可能悄悄变化,所以我们在协议里加了version字段,编排层统一负责做版本适配。这个适配层大概只有几百行代码,但它在后期框架升级时帮我们挡了几次灾。

5.2 上下文切片与传递

上下文管理是混合架构里最需要小心的地方。我们把它分成了三层:

  • 全局上下文:来自业务系统,比如工单原文、客户ID、历史处理记录。它只在编排层维护,不会被推到Agent内部。
  • 运行期上下文:编排层在任务推进过程中生成的临时信息,比如分诊结果、路由决策、中间评审意见。这部分编排层自己存。
  • Agent内上下文:执行层里框架管理的那部分,包括Agent当前状态、工具调用参数、局部中间结果。

传递时有一个“序列化边界”很重要。最初我们的做法是把整个全局上下文直接塞给Agent,结果token开销爆炸,一个月光模型调用费就让人头疼。后来我们做了上下文压缩策略:摘要加截断加分段检索。只把当前Agent需要的那一小段原文传给它,其他信息按需从外部知识库检索。这个优化带来的收益,比我们花两周调调度策略大得多。

5.3 可观测性

可观测性这块,我们的经验是:traceID必须由编排层在任务入口统一生成,然后透传到所有层。执行层里所有日志、框架检查点日志、工具调用日志,都必须带上这个traceID。只有这样,出问题时才能从编排层的一个任务入口,通过一个ID把所有相关日志拉出来。

我们埋点的标准是:每个Agent启动、每个工具调用、每个人工干预动作、每个重试行为,都要记录事件类型、耗时、结果、错误码。一开始有人觉得埋点太繁琐,后来一次线上事故,我们用traceID定位到某个Agent在某个工具节点反复重试,花了不到十分钟就找到了根因。那次之后,再没人抱怨埋点麻烦。

5.4 失败重试与幂等

混合架构下的失败重试,比单层系统要复杂得多。因为重试可能发生在编排层,也可能发生在执行层。最开始我们没有约定好,结果某个Agent执行失败后,框架内置重试触发了三次,编排层又把它重新调度了两次,等于一个副作用操作被执行了五次。

我们的解决方案是:约定重试只发生在执行层,编排层只负责“重调度”,不负责“重执行”。也就是说,执行层内部失败,框架自己重跑那个节点;如果整个Agent的任务彻底失败,它向编排层回报一个失败事件,由编排层决定是否换个Agent重做,还是转入人工处理。同时,所有工具调用接口都要求设计幂等键,同一个request_id不能产生两次外部副作用。

5.5 压测情况与参数选择

最后说一组我们在项目里的实测数据,供参考。并发40个工单,平均每个工单会触发6到8个Agent节点,单Agent平均响应时间约2秒。在混合架构下,编排层的CPU占用大约15%,执行层是主要开销。也就是说,瓶颈既不在自研编排层,也不在框架本身,而在底层模型调用的耗时上。

这个结果让我们松了一口气。之前担心的“自研层会不会成为性能瓶颈”并没有出现,因为编排层每个决策任务的计算量很小,真正耗时的是Agent内部与模型、工具打交道的部分。这也验证了我们的切分是合理的——把计算密集的部分交给执行层,把决策密集的部分留在编排层,两边各走各的路,互不拖累。

6. 复盘:这套混合架构的适用边界,以及我们主动留下的后门

6.1 混合架构真正解决的问题和没解决的问题

跑了大半年之后,我们回头做了个复盘,把混合架构的好处和它没能解决的问题都列了一遍:

真正解决的问题还没有解决的问题
编排自由度:全局路由、跨Agent协作完全可控模型输出的随机性仍然会导致流程漂移,需要护栏和大量样本测试
长尾扩展:新增Agent只需注册路由 + 加图定义框架升级依然要跟版本,只是影响被限制在执行层
可观测性:traceID贯穿两层,排查效率明显提升上下文压缩策略的效果依赖知识库质量,检索不准时会掉链子
团队分工清晰:Agent开发与后端维护互不干扰编排层代码逐渐膨胀,需要定期重构,否则也会变成无人区

这个表格在我们内部讨论时冲击力很大。特别是最后一行“编排层代码逐渐膨胀”,因为它意味着我们不能因为用了混合架构,就觉得自己彻底安全了。自研编排层依然需要维护,只不过它的复杂度被控制在了可接受的范围内。

6.2 什么样的场景适合这种架构

根据我们的实际体验,混合架构比较适合下面几种情况:

  • 业务有长尾,Agent类型会持续增加,而且每次增加都希望不影响主流程。
  • 流程本身复杂,存在并行、聚合、人工介入、条件分支等动态行为。
  • 系统要长期演进,不只是做个demo,而是要服务业务方很多年。
  • 团队有足够的工程能力,至少能养一个两到三人的后端小组来维护编排层。

如果这几条都满足,混合架构会是一个很舒服的选择,因为它的核心价值就在于“把不确定性留给了自己,把确定性交给了框架”。

6.3 什么样的场景不适合

反过来,有些场景其实不适合混合架构:

  • 只是想快速验证一个多智能体想法,流程固定,变化少,那直接用通用框架就行,没必要多维护一个自研服务。
  • 团队本身不具备很强的后端能力,那自研编排层会成为包袱,倒不如找个现成平台先用起来。
  • 流程极其简单,比如固定三步走,那混合架构反而是过度设计,多出来的两层通信成本完全是浪费。

我们当时如果只做一个简单的工单问答demo,绝不会选择混合架构。正是因为我们明确知道自己要长期演进、要处理复杂动态流程,这个决策才成立。所以架构选择这件事,永远先看场景,再看技术。

6.4 给想抄作业的人的建议

如果你看完文章,觉得混合架构这条路可以试试,这里有几条我们踩出来的经验可以直接拿走:

  1. 预留好抽象接口。我们特意在编排层和执行层之间定义了一层薄薄的“运行时适配”,未来即使换掉框架,也只影响执行层,不会把编排层一起拖下水。
  2. 锁定框架版本。不要一有新版就急着升级,先看清楚不兼容变更,再评估影响面。我们后来直接在CI里卡了版本号,只有通过回归测试才允许升级。
  3. 先跑通最小闭环再铺开。不要上来就铺十个Agent,先把一个工单类型从入口到出口完整走一遍,验证通信、上下文、重试、可观测性都到位,再往外扩展。
  4. 给业务方留配置入口。路由策略、超时时间、审批人角色这些,尽量做成配置项,不要写死在代码里。否则每个需求都要排期改代码,业务方等不起。
  5. 每周留出固定时间review编排层代码。这个层容易在不知不觉中膨胀,需要定期把“怎么减少样板代码、怎么收敛路由逻辑”当成正常迭代的一部分来做。

6.5 一点个人体会

现在回头看这次架构抉择,我最大的体会是:选择混合架构不是因为它技术更先进,而是因为它和我们的问题更匹配。自研编排给我们掌控感,框架执行层给我们效率,两者之间的那条边界,恰好把我们能控制的和不用控制的分开了。

如果你们也正面临同样的选择,我建议先别急着二选一,花一周时间把业务里的“长尾”列出来,看看未来的流程会有多动态,再决定把边界画在哪。架构本身就是一种取舍,想清楚自己愿意承受哪边的复杂,答案自然就出来了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 19:04:23

Rubin架构深度解析:算力跃迁背后的芯片互连与工程逻辑

当时我拿到那块布图文件的第一反应,和大多数人想的一样:下一代硅片,又把面积拉满了。真正一层层翻完供电网格、缓存阵列和交换拓扑之后,才意识到这一代值得聊的东西完全不在晶体管数量上。Rubin架构把“算力跃迁”的着力点&#x…

作者头像 李华
网站建设 2026/10/20 19:04:23

Selenium商城自动化测试框架从零搭建实战与踩坑记录

做了几年电商系统的自动化测试,我越来越觉得商城类项目是练手 Selenium 的最佳土壤——页面多、流程长、业务逻辑重,登录、搜索、购物车、下单、支付哪怕只是一个小改动,回归测试都能跑出几十条用例。早就想写一篇从零到一搭建 Selenium 自动…

作者头像 李华
网站建设 2026/10/20 19:02:40

Hermes Agent 轻量级智能体框架实战:从安装配置到任务编排

刚接触智能体(Agent)开发的时候,我踩过不少坑:要么被各种抽象概念绕晕,要么卡在环境配置上半天跑不通一个Demo。今天这篇就专门聊聊 Hermes Agent,一个面向任务编排和工具调用的轻量级智能体框架。我会从项…

作者头像 李华
网站建设 2026/10/20 19:02:09

大模型学习避坑指南:这套高效进阶路线让你少走弯路

最近几个月,找我聊大模型学习的兄弟特别多,问来问去就一句话:怎么入门才不踩坑?我特别理解这种焦虑,大模型相关的内容铺天盖地,今天这个框架火了,明天那个模型刷榜了,后天又有人晒出…

作者头像 李华
网站建设 2026/10/20 19:02:08

STM32F4固件库实战:从GPIO到DMA的寄存器级解析

简介:STM32F4固件库是意法半导体为STM32F4系列微控制器提供的官方软件开发包,面向嵌入式软件工程师,旨在简化外设初始化、驱动调用与项目开发流程。资源压缩包约47.1MB,共两千四百二十五个文件,以C语言源文件、头文件、…

作者头像 李华