ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

DeepAgents + MCP + A2A + Skills:多Agent集群搭建实战

DeepAgents + MCP + A2A + Skills:多Agent集群搭建实战 最近我把手上散落的十几个Agent脚本整理成了一个集群过程中最大的感触是单Agent写demo确实爽但一旦要接十几个外部工具、让多个Agent互相配合、把一套经验沉淀复用立刻就乱了。这次用DeepAgents作为编排框架配合MCP统一工具接入、A2A打通Agent之间的通信、Skills承载可复用能力总算把整套东西跑通了。这篇文章就把整个项目从0到1的搭建过程、踩坑记录和架构取舍完整聊一遍适合已经跑通过单个Agent、正准备往多Agent或工程化方向走的同学参考。1. 先想清楚一个问题单Agent还够用吗为什么非要搞集群1.1 我遇到的三个真实瓶颈在动手之前我其实是有点抗拒多智能体这件事的总觉得是概念大于实效。但在持续维护几个Agent之后有三个问题绕不过去。第一个是工具墙。一个Agent要干活就得接各种外部能力浏览器操作、文件读写、API调用、数据库查询。如果没有一个统一协议每加一个工具就要写一遍接入代码、处理一遍认证。我最早写的一个爬虫类Agent代码里有几十个if-else分支来处理不同的工具调用后来加一个简单的读取PDF功能都得小心翼翼地改生怕碰坏其他逻辑。第二个是上下文墙。LLM的上下文窗口再大也是有限的。单个Agent既要携带系统提示词、工具说明、历史对话又要塞进业务规则一个长任务跑到一半就接近窗口上限了。更麻烦的是并发来了以后一个超长任务能拖垮整个进程其他任务全在后面排队。第三个是协作墙。当任务拆给不同Agent去做的时候中间结果靠人肉搬运、格式靠约定完全不可控。比如信息采集Agent把结果写到JSON文件里下游分析Agent又得写一套解析器字段名稍微对不上就静默出错。这本质上不是多一个Agent的问题而是Agent之间没有标准的协作方式。1.2 集群方案的三根支柱解决上面三个问题我最后落地的方案是三根支柱这也是这门课的项目名称里三件套的含义组件解决的问题一句话定位MCP (Model Context Protocol)Agent怎么用外部工具给Agent插上标准化的工具插座A2A (Agent-to-Agent)Agent之间怎么通信协作给Agent发名片、派活、回传结果Skills怎么沉淀一套可复用的做事方法把会做某件事打包成可共享的交付物这三者其实是不同层面的东西。MCP是工具层协议A2A是Agent协同层协议Skills是能力封装层。很多人把它们混在一起比较其实是没搞清分层。1.3 用硬件协议类比理解MCP到底是个什么概念热搜里有人问mcp是软件协议硬件协议那个概念叫什么来着我猜大家晕的点在于协议这个词太抽象。换个类比就好懂了MCP之于Agent很像USB接口之于电脑。USB不关心你是U盘还是键盘还是摄像头只要都按同一个电气和通信规范来插电脑就能识别、供电、传数据。MCP也一样它不关心你的工具是GitHub、数据库还是浏览器只要用同一套JSON-RPC格式去暴露能力Agent就能调用。A2A则更像网络里的HTTP。Agent是服务器彼此通过AgentCard主页介绍自己会干什么然后用类似HTTP请求的方式把一个任务发给对方异步回传进度和结果。Skills则更像安装包里附带的驱动和说明书——它不只是教模型要做什么更强调可执行的脚本、校验规则和验收标准。搞清楚分层之后后面每一步搭建就不会乱套了。2. DeepAgents把编排从代码里抽出来2.1 DeepAgents在集群里扮演的角色这套集群里我把DeepAgents定位成编排中枢。它干三件事接收任务、拆解调度、维护状态。它本身不代替LLM做决策而是给LLM提供运行环境和协同框架具体来说就是编排把用户发来的一句话任务拆成多个子步骤决定先后顺序和谁来执行。状态管理一个Agent任务执行到一半挂了编排层要知道它挂在哪一步、能不能重试、要不要回滚。节点管理A2A网络里哪些Agent在线、各自的能力是什么、负载如何。这部分就是热词里大家常说的agent框架与编排的核心。一开始我试过用传统工作流引擎类似BPMN、DAG拖拽编排来做这件事后来放弃了。原因在于LLM Agent的路径是动态的同一个任务模型这次可能走三步完成下次可能走五步中间还可能根据外部反馈临时调整。传统工作流要求把路径提前画死根本兜不住这种不确定性。所以DeepAgents的编排方式是策略驱动的定义好每一步的约束和策略至于具体怎么走让Agent做计划、编排层做监督。2.2 核心抽象概念Task、Step、Policy、Peer这套框架里我建议先把四个核心概念吃透Task一次任务的完整意图。比如检查这个页面上的文案是否合规。每个Task有全局唯一的TaskId这个Id是后面做幂等、做追踪的关键。StepTask拆出来的子步骤。一个Step可以对应一个Agent调用也可以对应一次MCP工具调用。Step之间可以有依赖关系但顺序不一定完全固定。Policy编排策略。比如这个Step超时30秒就重试一次失败3次就转人工只允许A类Agent执行。策略是写死的配置但决策是动态的。PeerA2A网络里的Agent节点。Peer通过AgentCard暴露自己会什么、接收什么格式的任务DeepAgents通过Peer信息来决定把Task派给谁。2.3 最小配置示例用YAML配置一个最简单的编排任务是这样的cluster: name: content-review-cluster peers: - id: visual-agent type: a2a endpoint: http://localhost:9101/ tasks: - id: page-visual-review policy: timeout: 60s retry: 2 assign: visual-agent steps: - name: fetch-page use: mcp://playwright/screenshot param: url: ${input.url} - name: review-layout use: skill://frontend-review这段配置的意思是创建一个内容走查集群注册一个visual-agent节点定义了一个页面视觉走查任务超时60秒、失败重试2次第一步用Playwright MCP截图第二步用前端审查Skill来做分析。DeepAgents拿到这个配置后会动态生成执行计划并分发给对应的Peer。实际跑起来之后你会发现流程不再是一张死板的设计图而是一个活的执行过程。2.4 为什么编排层不能直接用代码堆有人会说这些逻辑我不用框架直接写代码也能实现。确实能但代价是很快失控。我的教训是把编排逻辑散落在业务代码里等于把谁来干、什么时候干、挂了怎么办这些本该是配置的东西硬编码了。一旦要调整策略就得改代码、重新部署。而DeepAgents把编排抽成配置策略引擎之后调并发、改超时、换Agent节点都只需要改配置运行时不会受到影响。这对我后面解决Agent怎么扛并发的问题帮助极大。3. MCP实战让每个Agent用上外部工具3.1 MCP的本质与传输方式MCP走的是JSON-RPC 2.0核心是Client-Server模型。Agent这边是客户端工具那边是服务端中间还有一个Host比如IDE、桌面客户端、编排器负责管理会话。传输方式最常见的是两种stdioMCP Server以本地子进程方式运行通过标准输入输出通信。适合本地开发、工具数量不多的场景。HTTP/SSEMCP Server作为独立服务部署Agent通过网络调用。适合集群化部署、多个Agent共享同一组工具。实操中我的建议是开发阶段用stdio方便调试上线阶段全部切成HTTP因为编排层和Agent往往是分离部署的stdio没法跨机器。3.2 手写一个最小MCP Server不管社区里有多少现成的Server我还是建议亲手写一个最小的因为这样才能理解MCP的工作机制。下面是一个通过stdio返回当天天气的工具示例这里用Python基于官方MCP SDK的常见写法from mcp.server import Server import json app Server(weather) app.list_tools() async def list_tools(): return [ { name: get_weather, description: 查询指定城市的实时天气, inputSchema: { type: object, properties: { city: {type: string, description: 城市名称} }, required: [city] } } ] app.call_tool() async def call_tool(name: str, arguments: dict): if name get_weather: city arguments[city] # 这里替换成真实天气服务调用即可 result {city: city, temperature: 24, weather: 晴} return json.dumps(result, ensure_asciiFalse) # 通过stdio启动服务 if __name__ __main__: from mcp.server.stdio import run_server import asyncio asyncio.run(run_server(app))这段代码虽然简单但结构是完整的声明了工具名称、描述、参数Schema并实现了实际调用逻辑。把它注册到Agent的配置里Agent就能直接调用这个工具了。初次跑通之后你会明显感觉到MCP带来的不是调用工具这个动作而是**工具的描述、参数校验、调用方式全都有了一套统一约定**。3.3 现成Server盘点Playwright MCP、Browser MCP、Figma MCP社区里已有的MCP Server非常多但真正高频用的其实就那么几类我在项目里重点试了这几组名称定位优势适用场景Playwright MCP浏览器自动化操作能截图、点击、填表、读取DOM贴近测试操作页面走查、自动化测试、爬取Browser Use MCPAgent看网页并完成网页任务面向大模型优化了可访问性树减少无效信息Agent自主浏览、表单填写、信息提取Figma MCP读取Figma设计稿数据直接拿节点、样式、切图信息设计稿转前端、视觉还原GitHub MCP仓库与Issue/PR操作流程完整、鉴权简单代码审查、CI触发、Issue管理一个高频问题Playwright MCP和Browser Use MCP到底有什么区别我实际对比过。Playwright MCP更偏操作浏览器它就像一个遥控器Agent可以用它精准控制某个页面元素。Browser Use MCP则更偏用浏览器完成任务它会自动帮Agent理解页面结构把干扰信息过滤掉适合那种打开某网站、找到目标信息、把信息返回的开放任务。选型时我的经验是如果你的任务链路明确比如点这个按钮、等结果、截图用Playwright MCP如果任务开放比如帮我在这个网站上找到联系方式用Browser Use MCP更省Token也更容易成功。还有一个容易踩的坑是MCP授权。比如Codex CLI接入Figma MCP的时候经常出现找不到MCP或鉴权失败大多数情况下不是配置写错而是授权流程没走完。Figma走OAuth需要先在Figma侧创建应用拿到Client ID配置回调地址然后在本地完成OAuth登录。相比之下GitHub MCP用Personal Access Token就简单很多。我的建议是先用只读类工具如天气、搜索、GitHub只读跑通流程再逐步开放写操作的工具这样即使授权出问题也不会造成数据事故。3.4 MCP接入的常见问题最近看到社区里有人把MCP功能合入到RuoYi-Vue-Pro这类后台管理框架中这是个很有意思的方向以后管理后台的Agent可以直接以MCP方式调用业务模块而不是把所有业务逻辑卷进Agent里。我自己的经验是做这类集成时一定要先确认外部系统是否提供了OpenAPIMCP Server本质上只是API的翻译层如果底层接口本身混乱MCP再标准也没用。此外MCP Server应该独立部署、独立进程。不要把它塞进Agent的主进程里否则一旦某个工具调用死循环整个Agent都会被拖垮。独立进程的好处是出了问题只影响工具调用重启服务即可主Agent照常运行。4. A2AAgent之间怎么说人话4.1 A2A协议要解决的问题MCP解决了Agent用工具的问题但Agent之间协同还需要一套对话方式。A2AAgent2Agent是Google提出来的开放协议目标就是让不同的Agent框架能互相发现、互相派活。它的核心是三个概念AgentCard每个Agent对外发布的名片写清楚自己会做什么、接收什么类型的任务、回调地址是什么。相当于HTTP世界里的robots.txt加OpenAPI毛坯房。Task跨Agent的任务对象带状态。从submitted到working再到completed或failed整个过程可以被查询、被取消。Message与回调Agent之间通过消息交换中间结果支持异步Push通知不用双方一直轮询等待。我特别喜欢AgentCard这个设计。它把这个Agent能干什么变成了一种可发现可查询的信息编排器拿到所有Peer的AgentCard之后就能像一个服务目录一样做路由而不是在代码里写死调用关系。4.2 两种互通模式点对点调用与总线式路由我在集群里同时用了两种模式根据场景切换模式适用场景优点缺点点对点调用节点少、拓扑固定、双方都长期在线实现简单延迟低新节点需要手动改配置总线式路由注册中心消息队列节点动态伸缩、任务需要广播或负载均衡扩展性好、解耦引入中间件运维成本高前期节点少点对点完全够用到了十几个Peer之后我开始把AgentCard注册信息丢进Redis让编排器统一做路由。后来社区流行的Spring AI也推出了A2A支持Java技术栈的同学可以直接把一个Spring Boot服务声明成一个A2A节点自动发布AgentCard、处理任务请求省了很多底层协议的功夫。4.3 A2A与MCP的分工红线很多人刚开始会在这两个协议间纠结其实分工非常清晰MCP是Agent到工具的协议方向单一工具不关心谁在调它也没有会话状态概念。A2A是Agent到Agent的协议双方对等任务有生命周期需要维护状态、支持回调。举个实际例子走查Agent发现页面上某个按钮样式异常它希望让视觉设计Agent出个意见。这时走查Agent不能直接调用设计Agent的内部函数而是应该通过A2A创建一个Task附上截图和问题描述让设计Agent处理完毕后回调结果。整个过程中走查Agent是把设计Agent当作一个对等的协作者而非一个工具。4.4 一次A2A调用的实际时序文字描述一次完整流程我尽量不画图DeepAgents收到用户请求检查某个页面的视觉和文案质量。编排器读取所有Peer的AgentCard发现visual-agent和copy-agent都可用。编排器向visual-agent发送Task请求TaskId为task-001包含页面URL。visual-agent执行过程中使用了Playwright MCP截图、读取DOM状态从working更新到completed并回调返回初步检查结果。编排器发现需要文案方面的二次确认于是创建task-002发给copy-agent并附上visual-agent的结果摘要。copy-agent处理完回调返回文案修改建议。DeepAgents把两步结果聚合返回给用户。这套流程跑通之后我发现原来常做的人肉传JSON彻底消失了每个Agent的输入输出都变成了协议规定的数据结构。哪怕以后把某个Agent换成完全不同框架的实现只要它发布AgentCard、遵守A2A协议整个集群都不用改代码。5. Skills把经验打包成交付物5.1 Skill到底是什么热词里skills相关的搜索非常多前端开发skills、codex skills、claude agent skills、superpower skills……这说明社区对Agent技能这个概念正处于高度关注期。以我的理解Skill不是插件也不只是Prompt模板而是一套可执行的做事方法。说它不是Prompt模板是因为Skill里除了指令之外还有可执行脚本、校验规则、参考文件。说它不是插件是因为Skill不一定需要对外暴露远程工具它更多是教模型怎么把一件事做好。打个比方MCP Server是给了Agent一把电钻Skill则是如何使用电钻在特定墙体上打孔并验收的完整操作规程。前者是能力后者是方法论。像Claude的Agent Skills和Codex的Skills生态都遵循一个通用结构一个SKILL.md文件作为入口描述适用范围、步骤、验收标准旁边附带脚本和资源文件。我在项目里给团队沉淀了多个Skill最常用的两个是前端视觉走查Skill和技术方案评审Skill。5.2 Skill包的标准结构一个典型的Skill包目录大概是这样frontend-review/ ├── SKILL.md # Skill说明模型首先读这个文件 ├── scripts/ │ ├── layout-check.py # 布局校验脚本检查间距/对齐 │ └── contrast-check.py # 颜色对比度检查脚本 ├── schemas/ │ └── review-result.json # 输出结果的JSON Schema └── assets/ └── design-token.md # 设计规范参考其中SKILL.md是核心它要做三件事告诉模型这个Skill解决什么问题给出标准流程明确验收标准。我一般还会在里面写清禁止做的事避免模型自由发挥。5.3 写一个前端开发Skill的示例结合热词里大量前端开发skills搜索我分享一下最常见的场景让Agent把Figma设计稿转成Tailwind页面。这个场景是MCP Skill配合的典型MCP负责取数Figma MCP把设计稿的节点、颜色、间距、字号这些元数据取出来。Skill负责定规则告诉模型颜色必须用设计Token不要硬编码色值间距只能从8px基准间距里取先出静态HTML再谈交互。SKILL.md里可以这样写# Frontend Implementation Skill ## 适用场景 把Figma设计稿还原为Tailwind HTML页面。 ## 处理步骤 1. 使用Figma MCP读取画板整体结构先理解布局层次不要急着写代码。 2. 从设计稿提取颜色值映射到项目的design-token配置文件禁止硬编码色值。 3. 间距从8px基准栅格选取常用值为 8/16/24/32。 4. 先产出无JavaScript依赖的静态HTML核对布局后再添加交互。 5. 最终输出附上截图对比供走查Agent使用。 ## 验收标准 - 页面核心区块间距与设计稿一致误差不超过4px - 所有颜色均来自design-token.md - 输出结果符合schemas/frontend-result.json这写在Skill里的东西其实是平时开发规范里反复强调、但又很难每次都教给模型的东西。有了Skill这些规范就成了一个可加载、可版本化、可跨Agent共享的交付物。Skills和MCP的边界我用一张表总结这也是团队内部经常被问到的问题维度SkillsMCP Server解决的问题教Agent怎么做一件事给Agent提供外部数据和操作能力是否必须联网不需要本地文件和脚本即可通常要暴露网络服务或本地进程典型内容流程、规范、脚本、示例工具列表、输入输出Schema依赖关系Skill内部可以调用MCP ServerMCP Server一般不含业务流程顺便提一下热词里的harness和agent区别Harness是Agent运行的承载环境沙箱、目录、依赖、权限Agent是决策大脑。Skills往往和Harness绑定——Skill决定做什么、怎么做Harness保证在什么样的环境里做。生产环境里同一个Skill要在不同的Harness里跑出可复现的结果就需要把Harness也容器化、版本化否则我本地能跑、你那边跑不了会变成常态。6. 端到端实例把走查、文案、部署三个Agent拼成集群6.1 场景设定前面讲了理论这部分给一个能直接参照的完整实例。我搭的演示集群叫发布前自动走查集群解决的是每次上线前人工检查页面所花费的大量时间。集群里有三个Agent走查Agent负责页面视觉和布局检查使用Playwright MCP和前端开发Skill。文案Agent负责文案风格、错别字、敏感词合规检查使用写作类Skill。部署Agent负责触发CI、汇总检查结果、阻断或放行发布使用GitHub MCP。6.2 编排配置DeepAgents的配置大致如下cluster: name: release-review peers: - id: visual endpoint: http://localhost:9201/ - id: copy endpoint: http://localhost:9202/ - id: deploy endpoint: http://localhost:9203/ task_defs: release_review: assign: [visual, copy] policy: timeout: 120s concurrency: 2 aggregate: merge这里定义了三个Peer并声明了一个release_review任务由visual和copy两个Agent并行执行最后聚合结果。注意我用的是aggregate: merge也就是说编排器会等两个Agent都返回结果后再合并而不是串行执行。6.3 运行过程用户把一个URL扔给集群后实际执行过程是DeepAgents创建task-100同时发给走查Agent和文案Agent。走查Agent调用Playwright MCP对页面截图再加载前端开发Skill逐区块检查布局、对比设计Token把发现的问题按review-result的Schema输出。文案Agent用写作Skill对页面文案做审查同时调用语言模型的拼写检查能力输出修改建议。编排器收到两个结果后判断是否存在阻断级问题如果走查发现页面白屏直接终止流程不让部署Agent触发CI如果只是文案建议则放行并附上建议。整个流程的TaskId贯穿所有环节日志里可以清晰看到每个状态变化。这个demo实际跑通后我最大的体感是三个Agent的协同没有变成三个人的接力而是真正变成了流水线并行。视觉走查耗时最长浏览器截图和DOM解析文案Agent并行跑总耗时几乎等于最慢那个Agent的耗时而不是三者之和。6.4 集群怎么扛并发热词里有人问ai agent 怎么扛并发这个坑我踩得比较深。一开始我把每个Agent任务都当成普通线程去处理结果LLM调用是秒级甚至分钟级的长耗时操作浏览器截图又是资源大户很快进程就被打满了。后来总结出一套比较实用的做法异步事件驱动整个编排层用asyncio这类事件循环不要让Agent等待期间占用线程。线程是稀罕资源但协程不是。编排状态外置把Task状态放进Redis让多个运行时实例共享同一份状态这样编排层可以水平扩展而不是单节点硬扛。模型分级不是所有步骤都需要最强模型。比如提取页面标题这种简单步骤用快模型或规则即可只有给出设计方案这种复杂推理才调用大模型。这一步能把成本降低一大半同时显著提升吞吐。幂等与去重同一个TaskId只处理一次。如果某个Agent回调重复了编排层直接丢弃这在高并发和重试机制同时存在的场景下非常重要。方案并发能力复杂度何时选择同步阻塞调用低低仅内部demo、任务极少协程异步中高中单集群、中等并发协程Redis状态多实例高高生产环境、集群扩展6.5 边缘场景Docker里的Agent集群集群不只存在于云服务器。热词里有个docker容器里的ros2 humble, micro-ros agent这其实是另一个很有意思的方向把Agent集群推进到边缘和机器人场景。micro-ros agent负责让资源受限的MCU设备能接入ROS2而上层的DeepAgents可以通过MCP把传感器数据当作工具暴露出来让Agent感知物理世界。我在一个实验项目里试过类似架构把负责设备数据采集的Agent放进Docker容器通过MCP把传感器数据变成查询当前温度这样的工具调用上层决策Agent再通过A2A向它下发持续观察温度超过阈值就告警这种长期任务。这套架构的价值在于云端的强Agent和边缘的轻Agent可以通过标准协议协同而不是各自写私有接口。对做物联网和机器人的同学来说MCP/A2A这套东西完全可以复用到非Web场景。7. 生产环境必须盯住的三个坑权限、并发、可观测7.1 Agent安全权限最小化与沙箱隔离热词里agent安全关注度很高这也是生产环境最容易被忽略的问题。原因很简单Agent一旦通过MCP获得了工具调用能力它不只是一个聊天机器人而是一个可以执行命令、写数据、触发发布的自动程序。我的建议是MCP Server默认全只读。写操作工具单独放在另一个Server实例里显式声明写权限并走独立鉴权。A2A节点之间必须鉴权。至少用API Token生产环境建议双向TLS或mTLS不要裸奔在内网。外部命令在Harness沙箱里跑。Skill里的脚本可能会被模型传入不可预料的参数如果不隔离一句删除临时目录也可能变成灾难。每个Agent配独立的最小权限身份。不要所有Agent共用一个高权限账号这样一旦某个Agent被恶意提示词注入伤害也被限制在最小范围。7.2 可观测性从TraceId到全链路多Agent集群不比微服务简单甚至更复杂因为这里面有LLM的不确定性。可观测性是我们快速定位问题的唯一依靠。我给每个Task发一个TraceId贯穿编排、Agent执行、MCP调用、LLM请求全链路。日志里固定记录几个关键指标每个Step的耗时、LLM的token消耗、工具调用次数和结果、A2A消息状态变化。这样拿到一个Agent execution terminated due to error这类模糊报错时我能直接看日志定位而不是瞎猜模型问题。遇到Codex CLI无法找到MCP这类问题我的排查顺序是先看MCP配置文件里transport和command是否配对再看环境变量是否传入了正确的密钥最后看Server进程有没有启动。很多所谓的找不到MCP其实是Server根本没跑起来问题根本不在Agent这边。7.3 一次典型排错案例最近线上遇到一次故障走查Agent跑了一个小时还没结束最后报Agent execution terminated due to error。从日志看Task状态卡在working超过50分钟。我的排查链路是查编排日志发现走查Agent一直没有回调进度。直接看走查Agent的进程发现它在等Playwright MCP的截图返回但MCP Server所在进程已经因为内存泄漏被系统杀掉。查MCP Server的健康检查接口发现启动后存活时间只有十几分钟一跑长任务就崩溃。修复MCP Server的内存问题后同样任务在4分钟内完成。这个案例给我的教训是占满一个完整排查链路的往往是工具层和基础环境的稳定性而不是模型的聪明程度。所以搭建集群时一定要给每个MCP Server加上健康检查和自动重启这是性价比最高的稳定性投入。回到标题本身。DeepAgents、MCP、A2A、Skills这四个词代表的其实是Agent工程化的四个层面编排能力、工具接入、Agent互通、经验复用。我在这次项目里最大的体会是不要一上来就追求七个Agent同时协作这种宏大场面先用一个Agent、一个MCP Server、一个Skill跑通最小闭环再逐步增加节点。Skill从一开始就要写版本号A2A节点的AgentCard要维护干净这样后面集群长大了才不会被自己造的混乱拖住。这套东西目前虽然还在快速演进但用协议而不是硬编码来解决协作问题这个方向我认为是确定无疑的。
返回列表