ARTICLE DETAIL

资讯详情

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

从单体到集群:DeepAgents、MCP、A2A 与 Skills 构建可扩展 Agent 系统实践

从单体到集群:DeepAgents、MCP、A2A 与 Skills 构建可扩展 Agent 系统实践 去年年初我准备给团队搭一套能自动写行业分析报告、跟踪竞品动态的多 Agent 系统。最先的版本就是一把梭每个 Agent 都自己写死工具调用、自己维护上下文、自己决定任务步骤。跑通单点功能倒是挺快可一旦想扩展成五六个 Agent 协作问题就全冒出来了——A Agent 拿到的结果没法直接喂给 B Agent工具接入方式五花八门改一个公共逻辑要同步改四五个文件。那阵子我意识到问题不在单个 Agent 不够聪明而在于整个集群缺了三样东西统一的工具接口标准、Agent 之间的通信协议、以及能力封装的复用机制。所以后来接触 MCP、A2A、Skills 这套组合时第一反应是这回总算是把话说明白了。这篇文章算是我搭建可编排、可互通、可扩展 Agent 集群的实战笔记。内容会覆盖四个关键词——DeepAgents、MCP、A2A、Skills——分别解决什么问题它们在什么场景下配合使用以及在真实搭建过程中我踩过哪些文档里没写清楚的坑。适合已经在用或者准备用 Agent 做实际业务的开发者哪怕你只是刚听说 MCP 和 Skills只要照着本文的思路走也能避开大部分弯路。1. 这四件套到底各自解决了什么问题先别急着搭把分工搞清楚很多教程把 MCP、A2A、Skills 混在一篇里讲结果读者看完只知道它们都很重要却不知道哪一层管哪件事。我自己的理解是这样一个能打仗的 Agent 集群至少要有四个层次——接线层、通信层、能力层、指挥层。DeepAgents 负责指挥层和整体方法论MCP 管接线A2A 管通信Skills 管能力封装。1.1 MCP 不是协议本身而是插口规范先说 MCPModel Context Protocol模型上下文协议。很多人第一次接触时都会有个疑问MCP 到底是软件协议还是硬件协议其实它的设计思路借用了硬件接口的概念——你可以把 MCP 理解成 AI 世界的 USB-C。USB 标准本身不定义你插上去的是什么设备它只定义插口长什么样、数据怎么传输。MCP 也一样它不关心你的 Agent 背后的模型是谁也不关心你接入的工具是数据库查询器、浏览器控制还是代码执行器。它规定的是一个 AgentMCP Client怎样和一个工具服务器MCP Server建立连接客户端怎么发请求服务器怎么返回结果以及工具的描述信息用什么样的 JSON Schema 格式暴露出来。具体的传输机制是 JSON-RPC 2.0。默认有两种传输方式stdio 和 Streamable HTTP。stdio 适合本机直接拉起子进程比如你在终端里跑一个 Node 脚本这个脚本通过标准输入输出和 Agent 交互Streamable HTTP 适合远程部署比如你在一台服务器上跑一个 MCP ServerAgent 在另一台机器上通过 HTTP 调用。MCP 三个核心原语工具Tools可被模型调用的函数输入输出都走 JSON。资源Resources暴露数据内容让模型读取上下文比如文件内容、数据库记录。提示词模板Prompts预定义的提示词模板在模型和 UI 之间共享 prompt 结构。我第一次搭的时候只用了 Tools后来才发现 Resources 和 Prompts 的价值——Resources 适合读取大段不占 token 的上下文Prompts 适合多个 Agent 共用同一套指令开头。MCP 最吸引我的一点是它让工具接入从编码问题变成了配置问题。以前接一个新工具我要为 Agent 写一套函数调用逻辑模型不认的话还要调格式。现在只要配一个 MCP Server 地址工具列表自动就暴露出来了。迟到的收益是几个月后我看到之前同事写的各个工具都在用同样的接入方式脑子一下就清楚了。1.2 A2AAgent 之间的商务合作协议MCP 解决的是 Agent 连接工具的问题那 Agent 之间怎么连接这就是 A2AAgent-to-Agent协议登场的地方。A2A 是 Google 在 2025 年推的开放协议设计思路很像企业之间的商务对接。两家公司合作之前先要对齐几个问题你提供什么服务你的接口地址是什么你怎么响应我的请求A2A 用一份名为agent-discovery.json也常叫 Agent Card的 JSON 文件来暴露这些信息里面声明了 Agent 的能力、通信端点、认证方式。协议运行按 JSON-RPC 那套思路核心是任务Task会话双方交换的是 MessagesMessages 里可以带文本和 Artifacts工件比如生成的文件、图片、结构化数据。通信是异步的一端发一个 Task 给另一端对方可以在后台跑跑完了再通过回调或者主动推送把结果给回来。这跟人类的工作方式很像项目甲方把整个任务交给乙方乙方拆解执行中间可能会有进度汇报最终交付物是工件。A2A 把整条链路搬到协议里所以 Agent 之间不再是互相调用函数的关系而是互相委托任务的关系。1.3 Skills能力封装的配方包MCP 把工具标准化了但工具只是能力的零件。真正干活的时候Agent 需要一套配方——比如写一篇合格的技术博客光给一个生成文本的工具远远不够它还需要知道文章应该分几个部分、语气是什么、要不要加代码示例、元信息怎么填、写作风格如何。这就是 Skills 的定位。Skills 本质上是把 提示词 资源文件 脚本 工作流程 打包成一个可复用、可分享的单元。我习惯的 Skill 目录结构是skill-name/ ├── SKILL.md # 主文件声明该技能的描述、能力边界和使用指引 ├── scripts/ # 可执行脚本或 Python 代码 ├── references/ # 参考文档、模板、样式规范 └── assets/ # 静态资源图片、示例文件等SKILL.md 的开头通常有 YAML frontmatter 声明名称和描述正文则是给模型看的指令性文档。模型在决定调用这个 Skill 之前会先读 SKILL.md 来判断这个技能适不适合当前任务。所以写 SKILL.md 最重要的是描述准确——你说得太宽泛模型什么任务都想调用它说得太窄该调用时不调用只能干着急。Skills 和传统的 Function Calling 最大的区别在于Function Calling 告诉模型你能调什么函数Skills 告诉模型遇到任务该按什么流程处理。一个是原子操作一个是操作流程加上判断逻辑和参考资料的组合。1.4 DeepAgents把以上三样组装成指挥系统的方法论最后说 DeepAgents。在不少框架语境里DeepAgents 被当成一个具体的框架名但我更愿意把它理解为一种构建方式用深度而不是广度来组织 Agent 集群的方法论。广度指的是堆很多 Agent各有各的功能深度指的是每个 Agent 也许只负责一件小事但这件事它可以做得非常深——深到会自己规划、会调工具、会反思修正、会请求别的 Agent 协助。DeepAgents 的理念是把大任务解剖成解剖图一个主 Agent 负责规划拆解通过 A2A 协议把子任务派分给具备特定 Skills 的专用 Agent专用 Agent 通过 MCP 调用各自的工具执行执行完把结果回传给主 Agent。同时每个 Agent 都可以配备一组 Skills 来增强自己的深度不仅会调用工具还按照 Skill 里固化下来的人类经验去执行。这四个词连起来就是一套完整的集群构建思路MCP 解决Agent 怎么用工具A2A 解决Agent 怎么找同伴Skills 解决Agent 怎么把一件事做精DeepAgents 决定谁来做规划、谁来做执行、结果怎么汇总。2. 从单体 Agent 到集群的演进路径分层的组合方式和权衡分析好现在四件套的分工清楚了。但真正把它落地到一个项目里还是需要一个演进过程。我见过不少团队一上来就想搭八个 Agent 的超级集群结果编排出问题、通信各种卡壳最后全拆回单体。合理的路径是先把单体做扎实再逐渐把一层一层拆出来。2.1 单体 Agent 的三个明显痛点在做集群之前我们先复盘单体 Agent 到底痛在哪。工具耦合严重工具一变Agent 的调用逻辑就要改。代码里散着各种 try-catch 和特殊格式处理看着就头疼。能力复用困难写好的 Agent 逻辑没法给另一个 Agent 用同样一段查询竞品官网的功能换个 Agent 就得复制一份代码。上下文相互污染一个 Agent 里做多件事上下文长了之后指令容易被无关信息干扰模型表现也不稳定。尤其在模型参数量各异的情况下你想用一个通用能力给不同模型Claude、GPT 等单体方案的迁移成本很高。这时候把能力拆到 MCP Servers 和 Skills 里就显得特别值得——它们是模型无关的。2.2 四层架构工具层、能力层、通信层、编排层我最终用的架构是四层每一层的边界都尽量干净编排层DeepAgents主控 Agent、任务规划、状态监控 通信层A2A / AgentCardAgent 之间的路由、任务派发 能力层Skills一系列可复用的能力包 工具层MCP Servers各类外部服务接口对照表可以帮助理解每层的变化频率和职责层次解决的核心问题代表技术变更频繁度工具层如何打通外部系统MCP Server高工具集常加常改能力层如何把任务做精做专SkillsSKILL.md中流程优化迭代通信层Agent 之间如何协作A2A、Agent Card低协议相对稳定编排层谁决策、谁执行、谁收尾DeepAgents 框架/自定义编排中策略调整需求多这个分层的好处是新增一个工具我只需要写一个 MCP Server不需要动 Agent 本身的代码优化一个流程我改对应的 Skill 文件就行新加一个 Agent 角色只要初始化它的能力集再在通信层注册自己的 Agent Card 就可以接入集群。2.3 什么场景适合上集群什么场景单体就够不是所有项目都适合搞多 Agent 集群。我自己的判断依据单体够用单 Agent、单工具、任务线性比如一个内部问答机器人知识库加一个检索工具就完事。这时候引入 MCP 和 Skills 会带来不必要的复杂度。值得上集群任务链条长调研 → 分析 → 写报告 → 发通知或者同时依赖多个垂直能力数据库查询 网页搜索 代码执行 第三方 API或者需要并行执行多个子任务时才真正受益。MCP 是底线不管上不上集群只要你的 Agent 需要接多个工具建议都用 MCP 标准接管线规范化比追求全自动更重要。Skills 是复用刚需只要存在同一流程要跑多遍的场景就值得把流程封装成 Skill。比如舆情分析周报生成代码评审一次封装到处调用。A2A 是最后一步等你有两个以上互相需要协作的 Agent再引入 A2A 不迟。一上来就通信协议满天飞不如先把单个 Agent 能力打磨好。3. 实操记录搭建一个最小可运行、可编排、可扩展的 Agent 集群讲完理论部分我把我搭最小系统的全过程记录下来。之所以叫最小是因为这一套跑通之后后面所有扩展都只需要往框架里加料不需要动骨架。3.1 环境准备与选型时的取舍我建议起步阶段选 Python 加 FastAPI 这类轻量框架做 MCP Agent 宿主因为生态比较完善Node 生态也不错尤其在 Web 场景。下面是我的最小依赖清单Python 3.11异步支持好类型标注完善FastAPI/Uvicorn提供 HTTP 服务给 Agent 集群一个基础 Web 入口mcp 官方 Python SDK用来快速实现 MCP Server 和 ClientSkills 目录约定每个 Skill 一个文件夹SKILL.md 负责描述scripts 目录放可执行脚本A2A 只需要准备一份 agent-discovery.json 和一个接收 Task 的 HTTP 端点注意这里选 FastAPI 不是为了做 Web 应用而是让集群每个 Agent 都有独立的 HTTP 入口方便后续接 A2A 通信。如果你只用 stdio 模式做本地任务其实用 asyncio 就够了我仍然建议一开始就留 HTTP 端点插件生态的灵活性会高很多。3.2 注册一个真实可用的 MCP Server配置、调试与验证以我常用的一个网页搜索 MCP Server 为例。创建一个search_server.py核心代码逻辑如下展示结构思路实际 SDK 包名以官方文档为准from mcp.server import Server from mcp.server.models import InitializationOptions import mcp.types as types import httpx server Server(web-search) server.list_tools() async def list_tools(): return [ types.Tool( nameweb_search, description搜索网页返回前 n 条结果标题、链接、摘要。适合查找最新信息。, inputSchema{ type: object, properties: { query: {type: string, description: 搜索关键词}, max_results: {type: number, description: 返回结果条数}, }, required: [query], }, ) ] server.call_tool() async def call_tool(name: str, arguments: dict): if name web_search: async with httpx.AsyncClient() as client: # 实际对接搜索 API这里省略参数细节 resp await client.get(https://api.example.com/search, params{q: arguments[query]}) results resp.json().get(results, [])[:arguments.get(max_results, 5)] return [types.TextContent(typetext, textstr(results))] raise ValueError(fUnknown tool: {name}) # 入口可选 stdio 或 HTTP 方式 if __name__ __main__: from mcp.server.stdio import stdio_server import asyncio async def main(): async with stdio_server() as (read_stream, write_stream): await server.run(read_stream, write_stream, InitializationOptions(server_nameweb-search, server_version0.1.0)) asyncio.run(main())写完代码本地用 stdio 模式直接跑起来配到你的 Agent 里然后让 Agent 调用web_search试一下。如果 Agent 能拿回结果说明工具链路通了。这段代码里最容易忽略的是工具 description。很多教程的示例 description 都很敷衍比如搜索工具四个字。但实际调用中模型是靠描述来决定要不要调这个工具的描述越具体模型的调用准确率越高。我用过一段时间的感受是描述里写清楚适合什么场景、不适合什么场景、参数边界比在代码里写一百行防御逻辑都管用。3.3 把一个高频工作流封装成 Skill目录、Frotmatter 和内容要点假设我要把竞品动态日报这个工作流交付给团队。我不希望每次让 Agent 做日报时都从零讲一遍流程于是把它做成一个 Skill。Skill 目录结构示例competitor-daily/ ├── SKILL.md ├── scripts/ │ └── collect_updates.py └── references/ └── report_template.mdSKILL.md 的开头--- name: competitor-daily description: 生成竞品动态日报。输入竞品品牌列表输出按日期整理的动态汇总标记重点变化。 --- # 竞品动态日报生成流程 1. 读取 references/report_template.md确认日报结构。 2. 对每个竞品品牌调用 web_search 查询当天动态。 3. 通过 collect_updates.py 对搜索结果做去重和优先级排序。 4. 按模板生成日报重点信息放到醒目位置。当主 Agent 收到给我来一份今天的竞品日报这类任务时它读 SKILL.md判断这是不是该用这个 Skill然后按里面写好的流程一步一步执行。这个机制的价值在于流程优化的对象从对话变成了文件——你调整流程所有人的 Agent 都会用上不用到处改提示词。3.4 用 A2A 协议声明集群里的 Agent 能力Agent Card 示例接下来是 A2A 部分。为了让 Agent A 能发现 Agent B并且知道它可以干什么我给每个 Agent 准备了一个agent-discovery.json{ name: research-agent, description: 擅长行业资料检索、数据整理与归类返回结构化调研结果。, url: http://localhost:8011/a2a, capabilities: { task: { supported: true, streaming: true } }, skills: [ web-search, competitor-daily ] }这里有几个值得注意的细节。第一description要像写简历一样认真写。A2A 的路由和编排都靠它来判断把任务派给谁写得含糊编排层就会乱派。第二skills字段列出 Agent 可用的 Skills这不是协议必须的但加上之后编排层能更快知道这个 Agent 擅长什么。第三capabilities.task.streaming表示支持流式进度更新如果你的任务比较长建议开启方便上游 Agent 实时掌握进度。有了这份文件Agent 之间的协作关系就可以描述成下面的流程主 Agent 收到用户任务 → 拆解为子任务读取各 Agent 的agent-discovery.json→ 判断派给谁通过 HTTP 调用目标 Agent 的 A2A Task 端点 → 提交子任务目标 Agent 执行自己的流程调用 MCP / 读 Skills完成后返回结构化结果 → 主 Agent 汇总输出4. 真实踩坑记录来自实践链路中的配置问题与解决思路理论再通实操该踩的坑一个都不会少。这一节我把我自己的失败经验一条条列出来每一条都是反复折腾过才醒悟的。4.1 工具描述写得像废话Agent 根本不调你的工具我第一次写 MCP Server 时工具描述就一句话搜索工具。结果给 Agent 配置好之后任我怎么提问它都不调。看日志才发现模型根本不认为搜索工具适合回答今天有什么科技新闻这种问题——它觉得自己的内部知识够了不需要外部工具。后来我把描述改成下面这样搜索互联网并返回结果列表。当你需要获取最新信息、不熟悉的话题、 或者回答可能超出训练数据截止时间的问题时务必调用此工具。 输入 query 为搜索关键词max_results 为返回条数默认 5。改了描述之后调用率立刻上来了。经验总结MCP 工具的 description 应该包含什么时候用、什么时候不用的触发条件。只写功能不写场景等于没写。4.2 Skill 的边界画太宽主 Agent 反而变傻还有一次我把生成日报这个 Skill 的描述写成生成各种报告。结果主 Agent 遇到任何跟报告沾边的任务都优先调这个 Skill哪怕用户只是要求帮我算一下数据。因为 Skill 描述太宽模型无法判断这个任务不完全匹配于是强行套用流程输出结果反而更差。正确做法是把描述写窄、怎么办写清楚、放什么时候不要用。那次调整后我的 SKILL.md 描述变成了--- name: competitor-daily description: 按模板生成竞品动态日报输入竞品品牌列表。仅适用于每日固定格式的竞品动态汇总 不适合一般的数据分析或独立报告撰写。 ---4.3 A2A 协议跑通了不代表编排逻辑就稳了跨框架路由才是真问题A2A 协议本身我按照规范建了 Task 端点Agent 之间的消息也能传递。但以为万事大吉之后我遇到一个更隐蔽的问题上游 Agent 拿到下游 Agent 的返回值不知道下一步该做什么。比如我让 A 去调研市场然后让 B 基于调研结果写报告。A 的返回值里有文本、有链接、有表格B 拿到之后一通乱读输出和报告要求的格式完全对不上。后来发现关键在于下游 Agent 返回的结果结构必须事先约定。A2A 协议只管消息怎么传不管消息内容长什么样。两个 Agent 之间必须提前约定好工件Artifact的格式——调研 Agent 返回的必须是结构化的 JSON带summary、sources、key_points字段写报告 Agent 只需要这几个字段就能开工。4.4 本地 stdio 与远程 Streamable HTTP 的选择影响权限和配网决策MCP 的传输方式有时会直接影响 Agent 能做什么、不能做什么。最开始我图方便全用 stdio但后来一个工具需要给远程集群共享就发现 stdio 只能跑在本地机器远程访问走权限配置很麻烦。于是拆了一半服务改成 Streamable HTTP 模式。我的建议单机调试用 stdio零网络开销不涉及跨机器权限。需要跨机器共享、或有多个 Agent 都在用的通用工具用 Streamable HTTP并通过 API Key 或 OAuth 做认证。安全提示无论用哪种传输方式MCP Server 一旦暴露到网络就要做好认证。别图省事把工具裸跑在公网上数据泄露风险太大。5. 集群编排的实战心得怎么让 Agent 集群听话地干活最后再加上几个编排层面的心得这部分直接决定集群好不好用。5.1 编排器用什么模式规划器-执行器 vs 管道模式我用过两种编排模式。一种是规划器-执行器模式主 Agent 拿到任务后自己规划子任务清单再逐个派发另一种是管道模式一个 Agent 的输出直接作为下一个 Agent 的输入任务流是固定的比如搜索 → 总结 → 生成报告 → 发送。规划器模式灵活适合开放性的任务管道模式稳定适合流程固定的业务场景。我的建议是小范围跑通优先用管道模式——先把端到端的数据流打通再去追求动态规划。5.2 任务派发的往回看机制结果不够好时怎么重派最开始我的编排器很线性主 Agent 把任务派下去收到结果就直接进入下一步。后来发现下游 Agent 的结果经常缺失细节或格式不对但上游 Agent 没有返回重做的机制。之后我加了一层任务校验逻辑——主 Agent 收到下游返回的 Artifact 后先对比任务要求检查完整度不合格就带着反馈重新派一次任务最多重试两轮。这个再加工机制让整体输出的正确率明显提升代价是多消耗一些调用时长整体看还是值得的。5.3 观测与调优日志不只是排障用还是能力优化的依据集群跑起来之后最容易被忽视的就是观测。我维护了一套很简单的日志方案每次任务执行记录谁发的任务、发给谁、调用哪些 MCP 工具、哪个 Skill 被触发、耗时多少、返回结果是否达标。整理成表之后就能看出哪些 Agent 经常被派到不合适的任务、哪些 Skill 的触发率太低、哪些 MCP 工具调用失败了。观测数据就是集群调优的起点。比如我的一个信息提取 Skill 触发率很低打开日志发现主 Agent 总是更信任内置能力而不去调 Skill。后来我分析了原因这个 Skill 在 SKILL.md 里的触发条件和主 Agent 的任务描述匹配度不够。调整描述后触发率正常。没有日志这种问题我根本意识不到是描述匹配的问题。5.4 扩展性设计加一个新的 Agent 到什么成本最后聊一下扩展性。我搭这套集群的初衷之一就是加人方便。新加一个 Agent 的成本仔细算下来主要落在四件事上决定它负责什么领域、定义好 Agent Card 里的 description。把要用的工具接成 MCP Server或者复用已有的。把要执行的流程封装成 Skill。在编排器里登记新 Agent 的能力范围。如果以上四步都走标准流程一个 Agent 从零到接入集群大概一两天。相比之下之前单体架构加一个新工具都要改主代码。用这套分层的好处就是每一次扩展都只需要动对应层的东西不用推倒重来。我自己实际用下来最大的体会是DeepAgents MCP A2A Skills 这套组合真正解决的并不是如何让 Agent 更聪明这个宏大的问题而是让一批中等聪明的 Agent 凑在一起也能稳定产出这个工程问题。它把 Agent 集群从手工作坊变成了标准化生产线。如果你刚入门我建议的顺序是先老老实实把 MCP 的工具接入跑通再做一个简单的 Skill 封装自己的高频流程等有两个以上 Agent 协作再去碰 A2A。每一步都打通了你自然知道自己还需要什么而不是被各种概念拽着跑。
返回列表