ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

多智能体重构实战:DeepAgents+MCP+A2A+Skills落地指南

多智能体重构实战:DeepAgents+MCP+A2A+Skills落地指南 上个月我把一个企业内部采购助手从单Agent彻底重构成了多智能体架构。重构之前那个Agent又要分析需求、又要管供应商、又要审合同结果在长对话里经常“精神分裂”刚才还在认真查物料编码下一秒就开始编合同条款而且改一个流程就要重新调一版Prompt。重构之后我拆了四个Agent用DeepAgents的思路做深度任务分解用MCP把ERP、企业微信、合同模板库这些工具统一接进来用A2A协议让Agent之间互相派单再用Skills把审批口径和话术框架沉淀成可复用包。跑通那一刻我意识到DeepAgents MCP A2A Skills这套组合确实是把多智能体从演示推向生产最顺的一条路。这篇文章不是21章课程的目录复述而是我把整条链路拆开揉碎的实战记录。你会看到多智能体为什么难搞、MCP要怎么接、A2A的Agent Card到底写什么、Skills该怎么设计最后还有一份21章实战地图和排坑清单。无论你是后端开发、AI应用工程师还是正在带AI产品的技术负责人照着这套思路走都能少踩几个坑。1. 多智能体不是堆Agent四个绕不开的难点1.1 单Agent为什么会在长流程里“翻车”很多人刚接触多智能体时第一反应是“多加几个Agent不就行了”但真实情况远没有这么简单。我那个采购助手在单Agent阶段最典型的问题有两个一是上下文污染同一个上下文里既塞了需求分析规则又塞了合同审核规则模型很容易把两个领域的知识混着用二是工具调用串味同一段对话里Agent为了完成“查询供应商”这个动作可能顺手把“发送企业微信通知”的工具也调用了因为两者的tool description在模型看来边界不够清晰。单Agent还有一个隐性问题角色稳定性。让一个Agent既当“需求分析师”又当“合规审计员”切换次数多了之后模型的注意力会被早期的角色设定带走后续任务经常被当成前一个任务的延续来处理。这不是模型能力不够而是任务本身的角色冲突和上下文长度约束造成的结构性缺陷。拆成多Agent之后每个角色拥有独立的上下文、独立的工具集、独立的记忆问题才从根上缓解。1.2 多智能体首先要回答的四个问题多智能体系统本质上是在解决四个问题通信、编排、状态、复用。通信解决的是Agent之间怎么传递任务和结果编排解决的是谁先执行、谁后执行、谁来汇总状态解决的是任务执行到哪一步、每个子任务的结果存在哪里复用解决的是某个Agent总结出来的经验怎么让另一个Agent也用得上。这四个问题里通信和编排最容易被低估。很多人一开始用自然语言让Agent互相发消息短期跑demo没问题但一旦任务量上来消息格式不统一、任务ID丢失、回调结果找不到对应请求整个系统就乱成一锅粥。所以我后来的原则是Agent之间能不能用自然语言交流能但必须有协议兜底消息里必须带任务ID、消息类型、角色标识这些结构化字段自然语言只是内容载体不能是格式本身。1.3 框架选型我为什么绕过“全家桶”热词里有人问多智能体框架到底用哪个Agentscope 2.0、dsh、Harness架构到底有什么区别。我的理解是Agentscope这类框架擅长把多Agent的编排、监控、通信底层封装好适合快速搭一套完整的实验环境dsh更偏分布式场景下的调试和观测而Harness架构则强调用一个可控的执行循环把模型、工具、技能串成一条流水线。三者不是简单的替代关系而是层次和侧重点不同。我在生产项目里没有把所有东西都绑到一个“全家桶”框架上而是选择“协议层自组装”核心编排自己写、通信走A2A、工具走MCP、能力沉淀走Skills。这样做的好处是任何一个组件坏了都可以单独替换不会出现“框架升级导致整个Agent体系重写”的灾难。代价是前期要多写一些胶水代码但长线来看非常值得。2. DeepAgents、MCP、A2A、Skills分别解决什么问题2.1 DeepAgents把“深度推理”当第一公民标题里的DeepAgents我个人的理解是它代表一种Agent形态以深度推理为核心面向长程任务能够把一个大目标拆成多个子目标并持续追踪每个子目标的完成状态。它和普通Agent循环的区别在于普通Agent常常是有问就答DeepAgents则会在每个关键节点先停下来做规划、评估风险、决定下一步动作然后再执行。用采购场景举例普通Agent拿到“帮我找供应商”这个指令可能会直接调供应商查询接口把结果原样返回DeepAgents会先分析采购需求里的品类、预算、区域、资质要求生成一个筛选策略再决定调用哪个MCP工具、按什么顺序调用、拿到结果之后要不要二次校验最后才形成结论。这套“先想清楚再动手”的机制是深度智能体区别于普通聊天机器人的核心。2.2 MCP给Agent一个统一的工具箱MCPModel Context Protocol解决的是工具接入的碎片化问题。以前每接一个新工具都要给Agent单独写一套调用逻辑和Prompt说明工具一多维护成本直线上升。MCP把工具封装成标准化的serverAgent通过统一的client协议去发现工具、调用工具、获取结果不需要知道工具背后的实现细节。打个比方MCP就像给电脑配了一个标准USB-C接口不管你是显示器、硬盘还是手机只要都支持这个协议插上就能用。在实际项目中我们通过MCP把ERP系统、企业微信机器人、合同模板库、蓝湖设计稿、Figma文件、Blender场景全部接进了同一个Agent环境每个工具都是独立的server互相不干扰调用方只关心工具的名字和参数。这个体验比维护一堆自定义function call舒服太多了。2.3 A2A让Agent之间说“普通话”如果说MCP解决的是“Agent怎么用工具”A2AAgent2Agent解决的就是“Agent怎么找Agent、怎么把任务交给另一个Agent”。A2A协议定义了Agent Card智能体名片、Task任务、Message消息这些标准对象让不同团队、不同框架实现的Agent能够互相发现、互相通信。我在重构采购助手时需求分析Agent和供应商筛选Agent就是两个独立的服务一个用Python写的一个用Node写的。两者之间没有任何共享代码纯粹靠A2A协议通信需求分析Agent发一个包含结构化参数的task给筛选Agent筛选Agent处理完把结果以task message的形式回传。整个过程像两个不同国家的工程师用同一种国际语言对需求能对齐是因为协议把语言统一了。2.4 Skills把可复用经验从代码里解放出来Skills这个名字听起来玄乎说白了就是把“某个场景下该怎么干活”的方法论封装成一个可以被复用的技能包。它和普通Prompt的区别在于Skills通常包含结构化的说明、示例、资源文件甚至可以带一段脚本或配置文件是一个完整的能力单元而不只是一段文字。热词里有人问Agent Skill和MCP到底有什么区别这是一个非常关键的问题。我的回答是MCP回答的是“Agent能调用什么”是工具接口层Skills回答的是“Agent该怎么干”是流程经验层。一个场景往往两者配合比如“写一份技术方案”这个Skill里面规定了方案的结构、风格、需要检查的要点而“读取公司知识库里的一段资料”这个动作则交给MCP工具去执行。把这两层分开设计系统才能既灵活又稳定。3. MCP从0到1把REST接口发布成MCP3.1 MCP的基本结构和调用链路MCP采用C/S架构有两端宿主应用比如Claude Desktop、自研Agent环境作为MCP Client工具提供方作为MCP Server。传输方式常见的有stdio和HTTP两类stdio适合本地子进程方式HTTP适合远程部署。链路是这样的Client先向Server发送initialize请求做协议握手然后双方交换capabilities接着Client调用tools/list获取工具列表再通过tools/call去执行具体的工具。这个“先握手、再发现、后调用”的设计保证了工具接入是标准化的。你不需要给Agent写一堆“这个工具怎么用”的PromptAgent通过tools/list返回的schema就能知道每个工具的输入参数和功能描述。这也是MCP能替代大量自定义function call的根本原因。3.2 用TypeScript快速实现一个MCP Server我用TypeScript写一个最简单的MCP Server把“查询供应商”这个REST接口包装成MCP工具。import { McpServer } from modelcontextprotocol/sdk/server/mcp.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; const server new McpServer({ name: purchase-assistant-mcp, version: 0.1.0 }); server.tool( query_supplier, { supplierId: string, category: string }, async ({ supplierId, category }) { const url https://erp.internal.example.com/api/supplier/query?supplierId${encodeURIComponent(supplierId)}category${encodeURIComponent(category)}; const resp await fetch(url); const data await resp.json(); return { content: [{ type: text, text: JSON.stringify(data) }] }; } ); const transport new StdioServerTransport(); await server.connect(transport);这段代码的运行机制是Server启动后通过stdio与Client通信Clinet调用listTools时它返回“query_supplier”这个工具的信息调用callTool时执行我们定义的回调函数把REST接口返回的JSON包装成MCP的标准content格式。如果你不习惯写TypeScript官方SDK还提供Python、Java、.NET等语言版本核心概念完全一致。3.3 Java项目如何把REST接口包装成MCP很多企业的核心系统是Java写的热词里也有人在问“Java将REST接口发布为MCP”。这件事完全可以做而且不复杂。思路是引入MCP Java SDK在Spring Boot工程里定义一个ToolCallback把已有的Service方法暴露成工具再通过SDK内置的ServerAutoConfiguration把工具注册到MCP Server中。Configuration public class McpToolConfiguration { Bean public ToolCallback querySupplierTool(SupplierService supplierService) { return new ToolCallback() { Override public String getName() { return query_supplier; } Override public JsonSchema getInputSchema() { return JsonSchema.builder() .addProperty(supplierId, JsonSchema.stringType()) .addProperty(category, JsonSchema.stringType()) .required(List.of(supplierId, category)) .build(); } Override public String call(String arguments) { // 解析参数并调用已有REST/Service逻辑 SupplierQuery query JsonUtils.parse(arguments); return supplierService.query(query).toJsonString(); } }; } }这里的关键是getInputSchema定义好参数声明call方法里完成原有业务逻辑的复用。很多团队担心“改造风险大”其实完全不用动原有REST接口MCP工具只是在外层多套了一个适配器老接口继续给Web端用新工具专门给Agent用。两类用户互不影响风险可控。3.4 常见MCP Server速查生态里已经有不少开箱即用的MCP Server我整理了一份速查表方便你按场景找。名称适用场景接入方式Figma MCP读取设计稿节点、图层信息辅助前端生成代码远端HTTP蓝湖MCP获取设计稿标注、切图辅助设计交付与前端开发远端HTTPBlender MCP在Blender中创建、修改3D场景stdio本地Burpsuite MCP安全测试中自动化发送请求、读取测试结果远端HTTPCodex MCP将Codex环境能力暴露给外部Agent调用stdio/HTTP企业内部门户MCP把工单系统、审批流、文档库封装成工具内网HTTP接入原则很简单外部SaaS服务优先用远端HTTP本地专业软件优先用stdio。还有一点要注意凡是涉及鉴权的MCP Server在生产环境务必用OAuth或Token机制保护不要让一个内网MCP裸奔到公网这个坑我在测试环境踩过一次后面专门做了网关加固。4. Skills封装实战从Prompt到技能包4.1 一个东西该不该做成Skill不是所有Prompt都值得封装成Skill我判断的标准有三条第一这个任务是不是高频出现第二这个任务的完成方法是否相对稳定第三这个任务的执行是否依赖多个步骤或专用资源。三条同时满足才值得做成Skill。比如“周报生成”“供应商资质评分”“数学建模题目分析”都属于典型的Skill场景。如果只是某一次对话里临时用到的指令直接写Prompt就够了。过早把临时Prompt封装成Skill不但增加维护成本还会让Skill库变得臃肿Agent在选择技能时反而容易选错。我见过一个团队把几十个一次性Prompt做成了Skill库最后Agent经常匹配到不合适的技能效果还不如不封装。4.2 Skill包的结构设计一个典型Skill包通常包含三部分描述文件、示例脚本、参考资源。描述文件用Markdown写说明这个Skill的用途、适用条件、输入输出、执行步骤示例脚本可以是一段代码、一个模板或者一个JSON示例参考资源可以是表格、知识库链接、历史优秀案例。结构上推荐按目录组织比如skills/math-modeling/SKILL.md、skills/math-modeling/templates/、skills/math-modeling/examples/。SKILL.md开头要写清楚触发条件和禁用条件避免Agent在错误场景下使用。我习惯在SKILL.md里加一段“反模式”明确写“本技能不适用于XX类问题”相当于给Agent立规矩实测能显著降低误判率。4.3 拿数学建模Skill练手数学建模相关的Skills是热词里被问得最多的因为它非常适合做案例步骤固定、输出结构化、评判标准明确。我在封装数学建模Skill时把流程拆成“题目理解→变量定义→模型假设→模型建立→求解与验证→结果分析→报告撰写”七个步骤每个步骤都给模型一条专门的指令和示例。例如在“变量定义”这一步SKILL.md里会要求模型先列出所有已知量、未知量、常量并区分决策变量和状态变量在“模型假设”这一步会要求模型明确说出每个假设的理由避免后续被评审挑刺。这套Skill我用在一个数据分析Agent上效果立竿见影生成数模报告的结构完整度比直接给Prompt高出不少这也侧面说明技能包的价值不在于“更聪明”而在于“更规范”。4.4 Skills和MCP怎么配合Skills和MCP的配合在我的架构里是分层关系。Skill负责定义流程和思路MCP负责提供执行能力。以“编码辅助”场景举例我写一个“代码审查Skill”里面规定审查的顺序、关注的安全点、代码风格要求但真正去读取Git仓库的内容、查询代码规范文档、调用编译检查工具靠的是对应的MCP Server。Skill不直接写死工具调用方式而是通过引用的方式让Agent自己去MCP里找合适工具。这样做的好处是解耦。如果我把工具调用细节写死在Skill里那么工具地址一换Skill就废了现在Skill只写“去MCP工具列表里找读取代码文件的工具”底层工具怎么换都不影响技能包的稳定性。这也是我在项目里推荐的做法。5. A2A协议实战多Agent之间怎么对话5.1 从0.3到1.0A2A到底改了什么A2A协议从0.3到1.0最大的变化是对象模型更清晰了。0.3版本里Agent Card、Task、Message这些概念已经有了雏形但字段定义不够统一不同实现之间互操作容易出问题。1.0版本则把这些对象完全标准化加了protocolVersion约定要求Agent Card必须声明自己支持的协议版本能力协商更规范。对于开发者来说最直观的感受就是对接成本降了。以前两个Agent框架要想互通经常要写不少适配代码现在只要双方都实现1.0版本的A2A规范通过Agent Card就能互相识别对方能干什么、支持什么传输方式任务交互直接按标准格式来。如果不是做协议层开发你不需要关心底层实现只要跟着规范走就行。5.2 Agent Card到底怎么写Agent Card之于A2A就像MCP里的tools/list返回是Agent向外界展示自己的能力名片。这里给一个简化示例{ protocolVersion: 1.0, name: supplier-screening-agent, description: 负责供应商资质筛选与评分接收采购需求返回合格供应商候选列表。, url: https://agent.internal.example.com/a2a, version: 1.0.0, provider: { organization: example-company }, capabilities: { streaming: true, pushNotifications: false }, skills: [ { id: supplier_screen, name: 供应商筛选, description: 根据需求字段筛选合格供应商并输出评分, tags: [purchase, supplier] } ] }注意protocolVersion要写1.0表明你的Agent支持的是哪个版本的通信协议capabilities里声明是否支持流式输出、是否支持服务端推送skills数组列出这个Agent具备哪些能力维度。这相当于给Agent做了一套公开的“服务目录”别的Agent拿到这份Card就知道该不该把任务派给你。5.3 一次完整的跨Agent任务派发实际通信流程类似JSON-RPC核心调用是tasks/send把Task和Message封装成标准格式发给目标Agent。一次派单的请求大致长这样{ jsonrpc: 2.0, id: task-001, method: tasks/send, params: { taskId: task-001, message: { role: user, parts: [ { type: text, text: 帮我筛选华东区注册满三年的原材料供应商预算500万以内 } ] } } }目标Agent收到请求后会创建一个Task记录执行内部流程然后把结果通过Task Message回传。整个过程的核心是taskId所有后续的查询、更新、取消操作都围绕taskId展开。这套设计保证了即使Agent之间使用异步通信双方也能准确对得上“哪条消息属于哪个任务”。我在实践中强烈建议不要把A2A消息当聊天记录存储要按Task维度存储每个Task独立建索引这样出了问题才好回溯。6. 21章实战地图从环境准备到生产部署6.1 21章全景目录结合我上面的实操我把整套课程/项目的地图拆成21章分五个阶段。这21章不是看完就完的每一章都要落到代码和部署上。阶段章节主题基础篇第1-3章环境准备与框架选型、单Agent Hello World、Agent核心循环拆解MCP篇第4-8章MCP协议速通、写第一个MCP Server、REST接口转MCP、接入外部MCP、MCP安全加固Skills篇第9-12章Skills与Prompt/MCP的边界、Skill包结构、数学建模/编码Skill实战、Skill组合与版本管理A2A篇第13-15章A2A协议演进、Agent Card编写、跨Agent任务派发与结果聚合综合实战篇第16-21章企业级架构设计、采购助手实战、网文创作流水线实战、数据分析报告实战、可观测性、上线优化6.2 推荐的学习节奏我建议不要线性从第1章看到第21章那样很容易前学后忘。更高效的方法是“螺旋式推进”先把第1-3章基础跑通理解单Agent是怎么工作的然后立刻跳到第4章做个MCP Server做完MCP再回来看Skills你会发现工具和技能的边界非常清晰最后进入A2A让两个Agent真正对话。整套流程我亲自走下来最快节奏大概三到四周能完成前提是你对Python或TypeScript至少熟练一门。如果是零基础建议把时间放宽到六到八周MCP篇和A2A篇各留足两周不要赶进度。6.3 一个完整案例采购助手多智能体架构以采购助手为例子我最终的架构包含四个Agent需求分析Agent负责把用户的粗需求拆成结构化的采购参数供应商筛选Agent负责调用MCP工具查询ERP、给供应商打分合规审计Agent负责检查采购流程中的资质和预算限制报告生成Agent负责汇总前三个Agent的输出生成采购建议书。这四个Agent通过A2A串成一条流水线需求分析Agent完成后主动把任务派给筛选Agent筛选结果出来后再触发合规Agent最后交给报告Agent。每个Agent都有自己独立的上下文不会相互干扰每个Agent各自挂载专属的MCP Server比如筛选Agent只挂ERP和供应商库的MCP合规Agent只挂审批流和政策库的MCP。这套设计跑通后整个采购流程的透明度和出错率都明显优于单Agent方案。6.4 上线前一定要做的四件事第一给所有Agent加超时控制避免某个Agent卡死导致整条流水线阻塞。第二把每个Agent的输入输出都落到日志系统保留原始消息和最终结果方便追溯。第三对MCP Server做巡检确保每个工具的鉴权不过期、网络不断连。第四做一个“逃生舱”当某个Agent连续失败三次自动把任务降级给人工处理而不是让系统无限重试。这四件事我在第一次上线时只做了前两件结果后来线上有一个MCP Server的Token过期导致Agent连续重试了一个小时任务积压严重。补上巡检和降级机制之后系统才真正算可用。7. 常见问题与排查技巧实录7.1 高频问题速查表我把这段时间里被问得最多的问题整理成了表格按“症状、原因、解法”三列给出。症状原因解法Agent调不到MCP工具Server未启动或协议版本不匹配检查Server端日志确认握手成功、tools/list返回正常Agent调用工具参数频繁报错Schema声明与实际参数不一致严格按REST接口的字段类型声明避免用模糊描述多Agent任务结果找不到对应请求缺少taskId关联统一使用A2A标准Task按taskId落库Skill经常被选错Skill描述不清晰、缺乏触发条件在SKILL.md里加适用条件和反模式说明Agent上下文越来越慢历史消息无限累积对中间结果做摘要只保留关键状态A2A消息丢失异步通信没有消息确认实现任务状态回调必要时要重发7.2 几个很有用的排查手段排查多智能体问题最忌凭感觉猜。我自己的经验是所有Agent请求都打一份traceId从入口到出口全链路透传MCP Server的每次调用记录工具名、参数、耗时、返回码A2A的每条消息记录taskId、发送方、接收方、处理状态。有了这三层日志出问题基本可以在十分钟内定位到具体环节。另外遇到模型行为异常时不要急着改Prompt先看是不是工具返回的数据结构变化了。我踩过一个大坑外部供应商接口悄悄在JSON里多了一个嵌套字段导致Agent解析失败我以为是模型理解能力退化排查了半天最后才发现是数据结构变更。所以定期对MCP Server做契约测试非常必要。7.3 关于“多智能体框架到底用哪个”的个人建议综合我这段时间的实践如果你在公司里做一个严肃的多智能体项目我的建议是优先用MCP A2A Skills这套协议层方案把核心逻辑握在自己手里而不是从一开始就绑死在某个大而全的框架上。框架可以帮你快速起步但协议才是真正保证你不被绑定的东西。如果团队没有太多工程资源想先快速验证业务价值那么选Agentscope这一类开箱即用的框架会更高效。至于Harness架构更适合你有明确的长程任务执行场景希望通过一个受控执行循环来管理模型、工具和技能的组合。总之框架是手段协议是底座Skills是资产最终能沉淀下来的是什么才是你真正的竞争力。我在实际项目中还有一个体会多智能体的价值不在于让模型“看起来更像人”而在于让系统变得可拆分、可测试、可复用。每次重构都问自己“这个改动是否让某个Agent更独立、某个技能更通用、某个协议更标准”如果答案都是肯定的那方向就不会错。最后再分享一个小技巧前期把Agent之间的通信协议定得严格一点宁可多写几个字段也不要图省事只传一句话后面扩展时你会感谢当初的自己。
返回列表