ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

MCP+A2A双协议:企业级多智能体集群架构设计与落地实践

2026/9/11 20:15:57 拓冰建站 浏览量
MCP+A2A双协议:企业级多智能体集群架构设计与落地实践 如果你还在用单一Agent去打通企业里的CRM、ERP、审批流和物流系统你大概已经撞到过三面墙上下文窗口不够装下所有业务数据系统权限没法细粒度管控Agent一多又互相抢任务、来回踢皮球。我最近在推进DeepAgents 21.3这个项目时把MCP与A2A双协议同时引入集群才真正把“多智能体协作”从Demo推到了生产可用。今天这篇东西就是把这一轮的架构决策、协议拆解、落地步骤和踩坑记录摊开来讲。适合已经在做Agent框架选型、或者准备把多智能体集群接入企业核心系统的工程师们。1. 单Agent的边界已现企业业务必须走向多智能体集群1.1 一个Agent包打天下先看看企业业务链条有多长企业级业务和C端玩具的差别往往不在模型能力而在业务链路的复杂度。拿客户投诉处理来说一个完整的闭环要经过CRM识别客户身份、订单系统查询历史订单、物流系统追踪包裹轨迹、知识库检索售后政策、财务系统判断退款金额、审批流推送主管确认、最后还要发短信和邮件通知客户。这条链路涉及至少六个内部系统每个系统的数据模型、权限模型、接口风格都不一样。单一Agent如果硬着头皮把所有这些系统全部接进来很快会暴露三个硬伤。第一上下文是有限的六套系统的字段、规则、客户资料全部塞进去对话还没开始模型先懵了。第二权限没法收敛一个Agent要具备所有系统的读写能力等于把万能钥匙交给一个司机。第三故障扩散任何一个系统接口变慢整个Agent的响应时间都会被拖垮。这也是为什么我越来越倾向于用“集群”而不是“单体”来组织智能体。集群不是简单部署多个Agent实例分担流量而是让不同技能、不同权限、不同生命周期的Agent组成一张协作网络。每个Agent只负责一个能力域通过标准和受控的方式互相调用。这样单个Agent的上下文压力被拆碎权限边界清晰了故障也可以被隔离到某个节点。1.2 多智能体带来的新麻烦连接爆炸和协作无序不过Agent一旦多起来新问题马上出现如果没有统一的协作协议每新增一个Agent就要跟已有的N个Agent分别对接连接数呈N平方增长。更麻烦的是不同团队开发的Agent内部用了完全不同的通信方式有人用HTTP回调有人用消息队列有人直接共享数据库表最后形成一张谁也理不清的蜘蛛网。我们早期就吃过这个亏。当时四个Agent做一个小流程光是联调就花了两周因为Agent A期望Agent B返回JSONAgent B却返回了一段自然语言Agent C通过数据库轮询获取任务状态Agent D却用Webhook推送。每次新增能力都要重新开会协商接口规范聊崩了又得升级。后来我意识到多智能体集群的核心难点根本不是模型怎么选而是“Agent之间怎么说话、Agent和能力之间怎么连接”这件看起来基础的事。只有把通信和接入标准化协作才能变成可维护的工程。1.3 DeepAgents 21.3把“协议”当作第一优先级的架构实践DeepAgents 21.3本质上不是某个开箱即用的软件而是一套关于“如何构建企业级多智能体集群”的架构方法。它最核心的主张是不要从Agent的交互逻辑开始设计而要先定义两层协议——一层是Agent与工具/系统之间的MCP另一层是Agent与Agent之间的A2A。MCP解决的是“手脚”的问题它让Agent能用统一方式调用企业内部的数据库、接口、知识库相当于给每个系统做了一个标准插头。A2A解决的是“协作”的问题它让Agent之间能发现彼此、派发任务、回传结果相当于打通了人与人之间的对话规则。一个管能力接入一个管智能体互联二者叠加才是完整的企业级多智能体基础设施。我们内部把这两层比喻成USB-C和TCP/IP。MCP就像主板上统一的USB-C接口键鼠、显示器、U盘、读卡器只要接口标准一致插上就能用A2A就像电脑之间的网络协议大家遵循同一套寻址和数据包规则才能真正互联互通。只用MCP你有一堆工具但Agent之间还是“孤岛”只用A2AAgent们能聊天了但谁都没有手去干活。21.3这套东西的全部秘密就是让它们各司其职。2. 协议拆解MCP如何收拾“工具孤岛”A2A如何打通“Agent孤岛”2.1 MCP不是另一个API网关它是“功能发现加协议执行”的统一层很多团队一看MCP就跑来问这不就是API网关吗还真不是。API网关解决的是路由、鉴权、限流的问题但它不会告诉Agent“这个系统支持哪些能力、每个能力怎么调用”。MCP设计的核心是动态发现Agent启动后可以先向MCP Server询问“你有哪些Tools、Resources、Prompts”然后按返回的接口描述去调用。这让Agent不再需要把每个系统的SDK写死在代码里等于把“写死调用”变成“按需发现”。在企业级落地时我强烈建议用远程MCP Server而不是本地的stdio模式。因为集群环境下会有几十甚至上百个Agent实例同时去连一个能力系统如果每个实例都拉起一个本地子进程内存和进程数会直接失控。远程MCP Server用HTTP/SSE承载服务端可以复用连接池、做限流和统一鉴权。具体的部署形态可以是容器化微服务前面挂负载均衡后面连接具体的数据库或业务系统。MCP Server暴露的三类原语里Tools最常用对应可执行的动作比如“创建订单”“查询库存”Resources用于暴露数据资源比如一份PDF合同、一张报表Prompts用于保存可复用的提示词模板。对企业而言Tools和Resources的权限边界一定要分开。比如一个MCP Server既有“读订单”又有“写订单”的Tool就一定要通过配置严格区分哪些Agent能调用哪些Tool不能让客服Agent拿着写权限去改价格。2.2 A2A协议模型Agent Card、Task、Artifact、MessageA2A协议解决的是Agent之间的互操作它不关心Agent内部是LangChain写的、是自研框架还是调用了Claude API只要Agent能对外暴露一个A2A端点就能被集群里的其他Agent发现和调用。整个A2A模型里有几个核心概念我建议在做架构前先彻底吃透。Agent Card是Agent的“门面”一份JSON文档描述Agent是谁、具备哪些技能、入口URL、支持的协议版本、认证方式。它相当于Agent界的OpenAPI描述文件。整个A2A通信围绕Task展开Task是Agent之间一次具体的工作请求拥有完整状态机submitted、working、input-required、completed、failed、canceled。为什么要这么设计因为Agent之间的协作往往是异步和长耗时的你不可能让发起方一直同步等待结果必须靠状态机把任务的当前状态“钉”住双方都能随时查询和续跑。Message和Artifact用来承载任务中的输入输出。Message是“对话性质”的短信息Artifact则是“交付物性质”的结构化产物比如一份质检报告、一张退款单、一个知识库条目。A2A协议还允许Agent在任务进行中请求人工介入通过input-required状态暂停任务等人给完信息再继续。这一点对企业级流程来说太重要了退款审批、合同签署这些环节绝对不能自动化到没有刹车。2.3 为什么必须是MCPA2A而不是单一协议包打天下我见过不少团队试图用MCP一统天下把所有其他Agent也封装成MCP的Tool。他们觉得既然Agent能调用Tool那我把“另一个Agent”也当作Tool暴露出来不就完了这个思路有一个致命问题MCP的Tool调用是单向的、函数式的调用方发起一个请求后被调方给出一个结果整个过程没有“双向协商”和“任务生命周期”的概念。但在企业业务里Agent A委托Agent B处理的事往往不是一步就能完成的B需要向A追问信息、汇报进度、请求确认甚至中途改变执行路径。这些用MCP的Tool模型表达起来极其别扭。反过来只用A2A也不行。A2A不解决Agent如何与内部系统对接的问题它假设Agent自己有办法完成工作。如果整个集群的Agent都只通过A2A互相聊天却没有人去统一Agent和数据库、ERP、审批系统之间的接入方式那每个Agent还是各自为政集成复杂度一点都没降。所以DeepAgents 21.3的逻辑是这样的一个Agent既要“向下连接”企业能力也要“水平连接”其他Agent。向下用MCP简化和标准化能力的接入水平用A2A规范化和统一化Agent间的协作。二者不是替代关系而是像垂直的桥墩和水平的桥面一样互补。3. DeepAgents 21.3集群架构分层设计、核心组件与协议映射3.1 整体分层接入层、编排层、工具层、状态层、治理层一个生产级的多智能体集群绝不能仅仅是一堆Agent进程放在Kubernetes里就完事了。需要把不同职责拆到清晰的分层里每一层有自己的扩展路径和容灾方式。我在21.3实践中最终落地的分层结构如下分层核心职责主要组件与协议接入层Agent注册、发现、统一入口、协议校验Agent Registry、A2A Endpoint网关编排层任务拆解、路由、DAG执行、人工介入决策Orchestrator、任务状态机工具层连接企业系统封装为可调用的统一能力MCP Server集群状态层会话上下文、任务快照、消息循环、幂等记录Redis、PostgreSQL、Kafka治理层身份认证、权限控制、审计、限流、Token预算OAuth2、mTLS、审计日志系统这个分层结构最大的好处是每层可以独立演进。比如工具层今天要接入一个新的SAP系统只需要新增一个MCP Server在Agent Registry里登记一下编排层完全不用改代码状态层想从Redis切换到TiKV只要保持接口兼容上层无感。对于企业来说这种可替换性意味着选型风险大大降低。3.2 接入层A2A框架下的Agent注册与发现每个Agent在启动后要做的第一件事不是去连接数据库而是向接入层的注册中心发送自己的Agent Card。Agent Card里最关键的信息是“技能描述”它是语义路由的依据。比如一个Agent的Card里写着“能处理售后质检判定输出退货或换货或维修建议”另一个Agent写着“能生成退款单并推送到财务系统”编排层就能通过意图识别或向量召回把“判断质量”的任务分配给前者把“执行退款”的任务分配给后者。注册中心的实现可以是简单的HTTP服务加数据库但如果集群规模超过几十个Agent建议引入基于标签的索引和基于语义Embedding的检索。当Agent的能力描述写得足够规范时甚至可以实现“零代码热接入”新Agent上线时提交Card编排层立刻就能把匹配的任务路由过去不需要发布任何代码。这一点在业务经常变动的企业环境里特别有价值。3.3 编排层任务拆解、DAG依赖与终止条件编排层是所有多智能体系统里最容易做坏的地方。很多人把编排做得过于“智能”交给大模型自动决定下一步调用谁结果模型一个幻觉就调错Agent或者陷入死循环。企业级场景下我更倾向于“基础流程用确定性编排异常分支才交给模型兜底”。具体来说把一个复杂业务拆成DAG节点是原子任务边是依赖关系。比如售后流程中“质检判定”必须在“退款计算”之前完成“退款计算”完成后才允许“生成退款单”。DAG里的每个节点都对应一个A2A Task由编排层负责创建和推进。DeepAgents 21.3要求每个Task必须带一个全局唯一的taskId并且由编排层统一维护状态机流转不让Agent之间直接改对方状态。终止条件必须提前写在编排定义里这是防止集群失控的保命符。条件包括最大迭代轮数超过20轮直接终止并通知人工、总Token预算超过预算自动熔断、单任务超时时间比如整条链路最长30分钟、以及必须经过的人工审批点。没有这些约束Agent会在边界场景里无限重试把集群或第三方系统的资源全部耗光。3.4 工具层MCP Server的拆分原则与企业封装MCP Server不是越多越好也不是越全越好。拆得太细Agent为了完成一个小需求要连十几个Server延迟和复杂度都会上来拆得太粗一个Server里塞了几十个Tool模型function calling的选择准确率会迅速下降。我的实践是按“业务能力域”拆分比如订单域、物流域、财务域、知识库域。每个MCP Server只负责一个域的CRUD和决策支持。封装内部系统时有几个细节特别重要。第一Tools的命名要直白并避免歧义像“process_order”这种名字不如拆成“get_order_detail”“update_order_status”“create_order”清晰。第二每条Tool的description不能只写“这是订单接口”要说明什么场景适合调用、输入参数格式、典型示例、以及什么情况下不要调用。模型读不懂暗示只读得懂明示。第三MCP Server要自带熔断和降级在底层系统响应超时时返回结构化错误码而不是原始异常堆栈方便Agent据此调整策略。3.5 状态与记忆层集群一致性和长上下文问题多智能体集群中Agent实例是可以随时扩缩容的这意味着上下文绝对不能只存在进程内存里。DeepAgents 21.3的架构里会话状态和任务状态全部沉淀到外部存储Redis缓存热数据PostgreSQL存储任务快照Kafka承载异步消息。一个Agent在A处挂了重启后的新实例能够通过sessionId和taskId从存储里拉回上下文继续未完成的工作。长上下文是企业级落地最容易忽视的问题。让A2A消息携带全部中间结果是最省事也最糟糕的方案。正确做法是消息体只传“引用”比如一个对象存储路径、一个数据库主键需要具体内容时再通过MCP去读取。这样消息体始终控制在KB级别既节省模型Token也避免网络传输成为瓶颈。对需要保留的大体积产物放入Artifact存储服务通过Artifact ID访问。3.6 治理层身份、权限、审计与安全边界企业级集群没有治理层就像公司没有门禁和财务制度。每个A2A调用都必须能追溯到“发起方Agent”和“最终的人类用户”。我们的做法是用户在入口Agent上完成身份认证后生成一个包含租户ID、用户ID和权限范围的短时Token这个Token会随A2A消息头透传到下游Agent下游Agent调用MCP Server时把该Token映射成对应后端系统的最小化权限账号。这样既不会给Agent超范围权限也能在出问题时查明“是谁让Agent做了什么”。审计日志至少需要记录六项调用方Agent名、接收方Agent名、taskId、请求时间、状态流转序列、消耗Token总量。在涉及财务或敏感数据的节点还要额外记录输入输出的哈希值。所有日志只允许追加不允许修改。集群的监控告警则围绕任务失败率、队列积压深度、Token消耗速率三个指标展开任何一个指标异常都说明编排或工具层有问题。4. 从架构到可用系统一个售后工单自动闭环的落地示例4.1 场景模型售后工单从提交到闭环的完整链路空谈架构没有说服力我拿一个已经跑通的售后工单场景来做演示。业务假设是这样的客户在App提交“购买的商品出现质量问题要求退货退款”背后的目标是自动判断是否符合退货政策、自动进行质检判定、自动计算退款金额、推送给人工审核、审核通过后自动退款并同步物流信息。过去这个链路需要客服、质检员、财务专员、仓储专员四个人手工协作现在用DeepAgents 21.3将四个人的角色抽象成三个Agent加若干人工节点。链路拆解后是这样的入口Agent“售后助手”负责接待用户、收集订单号、识别用户意图质检Agent负责依据质检规则对退货申请做判定输出退货/换货/维修建议履约Agent负责调用ERP和物流接口生成退款单或换货单。人工审批节点插在退款生成之前避免自动化造成资金风险。4.2 Agent目录设计与Agent Card配置我们先定义三份Agent Card。以下是一个简化但真实可用的示例展示了质检Agent的接入配置{ name: aftersale-quality-agent, description: 负责售后质检判定输入订单号与问题描述输出推荐处置方案, url: https://agent.internal/aftersale-quality/a2a, protocolVersion: 0.1, skills: [ { id: quality_check, name: 质检判定, description: 判断商品问题是否在退货范围建议退货、换货或维修 } ], authentication: { scheme: bearer } }Agent Registry会把这份Card解析进索引库当编排层收到“这个订单该退还是该修”这类语义请求时通过技能描述匹配到质检Agent并把A2A Task发给它。同理履约Agent的Card里包含“generate_refund”和“generate_delivery_order”两个技能标记允许的操作范围。4.3 MCP Server落地封装三个后端系统在这个售后场景中我们需要三个MCP Server订单MCP Server连接订单数据库和订单生命周期接口物流MCP Server连接物流商接口用于查轨迹和下发补发指令审批MCP Server连接内部审批流系统负责发起退款审批和拉取审批结果。每个MCP Server都封装成独立服务通过HTTP/SSE对外提供Tools。举个订单MCP Server的Tool定义例子{ name: get_order_detail, description: 根据订单ID获取订单完整信息包括商品、金额、状态。用于售后场景的订单校验。不要用于修改订单。, inputSchema: { type: object, properties: { order_id: { type: string } }, required: [order_id] } }这里的description写得足够明确加了“不要用于修改订单”的负面约束。实际测试中这种写法的工具选择准确率比只写“获取订单信息”高出不少。4.4 编排流程一个工单是如何在多Agent之间流转的整个业务链路通过编排DAG驱动具体步骤如下用户向售后助手Agent发送消息“我的订单No.20241107空调有问题想退货”。售后助手通过订单MCP调用get_order_detail拿到订单信息和金额。售后助手判断订单满足初步退货条件后创建一个A2A Task发给质检AgenttaskId由编排层生成状态设为submitted。质检Agent接收Task调用质检规则MCP判断问题归属判定为“质量问题且七天无理由”将Task状态更新为completed并返回Artifact内含质检结论JSON。售后助手收到结果后向用户二次确认退款金额和方案。用户确认无误售后助手调用履约Agent发起“生成退款单”任务。履约Agent调用审批MCP创建一个退款审批流程。由于涉及资金审批MCP返回input-required任务停在等待人工审批状态。主管在审批后台点击通过审批MCP回调编排层编排层再把Task状态推进到completed履约Agent随后调用ERP MCP生成退款单并同步物流信息。所有步骤的上下文通过Redis持久化每个状态流转事件写入审计日志。这条链路中MCP负责“订单查询、质检规则、审批、ERP”这四类能力接入A2A负责“售后助手→质检Agent→履约Agent”的水平协作。可以清楚看到MCP和A2A各管各的互不替代但配合起来才形成完整闭环。4.5 集群部署要点容器、调度、弹性和高可用落地这套系统我们用了Kubernetes作为基础设施底座。每个Agent类型和每个MCP Server都做成独立Deployment不混部。Agent Registry和编排器部署为多副本使用PodDisruptionBudget保护关键组件不被节点排空时全部干掉。A2A消息的异步部分用Kafka传递确保削峰填谷和失败重试。弹性伸缩上不能只看CPU要看业务指标。我们的策略是按队列积压深度和平均任务响应时间联动扩缩容。比如质检Agent的积压超过100个任务时自动扩容两个副本积压低于10个任务并稳定持续5分钟后缩容。Kafka Consumer的lag也纳入HPA指标避免消费者跟不上生产者的速率导致链路堵塞。高可用方面每个A2A调用都必须配置超时和重试重试间隔用指数退避并加入抖动。更重要的是幂等同一个taskId重复送达时接收方直接返回上一次的处理结果绝不重复执行业务逻辑。这样即使Kafka出现事务性重复投递也不会产生重复退款单。5. 翻过协议坑之后企业级多智能体集群的落地经验复盘5.1 MCP Server的并发模型决定了集群的生死第一次把集群从三个Agent扩展到二十个Agent时质检MCP Server发生OOM罪恶源头就是MCP连接方式选错了。开发期图省事Agent本地直接跑stdio模式拉起MCP子进程扩展后每个Agent实例会拉起五六个子进程一台机器同时跑几十个进程内存瞬间被打爆。换成远程MCP Server模式后连接池统一由服务端维护问题才消失。建议所有准备上集群的团队直接从远程MCP模式开始不要在stdio上浪费时间。5.2 A2A的Task回调不做鉴权迟早会出事我们在一次内部安全巡检中发现测试环境的A2A回调接口竟然不带任何凭证。这意味着任何内网服务只要知道URL就可以伪造“退货完成”的回调把任务状态推进到completed甚至触发退款。整改方案是所有A2A endpoint启用OAuth2 client credentialsAgent之间通过服务账号认证回调消息必须带taskId和nonce字段服务端校验nonce防重放并且对重复回调做幂等返回。这个坑希望大家别走一遍。5.3 上下文全量透传是一种低效到可怕的协作方式早期设计里售后助手Agent会把订单的全部字段、质检报告全文、物流轨迹列表全部打包进A2A请求体传给下一个Agent。这个做法在数据量只有几十条时看起来没问题一旦订单有几百个SKU、质检报告有十几张图片消息体积直接膨胀到上百KB。模型输入输出变慢网络也扛不住。后来改成“Artifact引用传递”消息体只放文件ID或数据库主键下游需要时再通过MCP读。这个优化让单条A2A请求平均耗时下降了差不多一半。5.4 工具描述“过度营销”模型会选错工具我手下一名工程师在封装MCP工具时图省事把“查询订单”“修改订单”“删除订单”三个操作合成一个Tool。结果模型经常为了只读需求调用修改操作造成数据被误改。后来把工具拆成细粒度并且在每个Tool的description中明确写出适用场景、输入输出和负面约束误调用率才降下来。这提醒我在MCP的语境里工具描述就是模型唯一的操作说明书写得越像“写给一个比较粗心的人看的指引”上线后越不容易出幺蛾子。5.5 人工审批关口缺失自动化越彻底风险越大最初版本的售后链路把退款审批完全自动化了质检Agent判定可退履约Agent就直接生成退款单整条流程无人把关。结果在一次活动大促期间系统被风控识别出多笔异常退款虽然金额不大但也让我们紧急切断了自动退款链路。现在的铁律是凡是涉及资金、合同、隐私数据外发的高风险动作必须由编排层将Task停在input-required状态等待符合授权的人类用户审批审批通过后才能进入下一步。自动化负责效率人工负责兜底这才是企业级该有的姿态。回到标题里的21.3这个数字其实不代表什么突发技术而是我在这个版本的迭代周期里从单体Agent走向MCPA2A双协议集群的完整复盘。如果你也正在从单个Agent往多Agent方向迁移我建议第一步不要急着写业务代码先把MCP Server的边界钉清楚再把Agent Card和Task状态机定下来。协议理顺了后面的复杂业务不过是搭积木。