智能体协议选型指南:MCP、A2A、ANP对比与实战
发布时间:2026/10/14 13:57:47 锦皓数字建站

简介深入对比模型上下文协议MCP、智能体间协作协议A2A与智能体网络协议ANP的 PPT面向大模型应用开发者、AI 架构师及关注智能体互联的技术决策者。内容覆盖三种协议的定位、核心概念、工作流程与优势短板MCP 逐一拆解 Root、Sampling、Prompt、Resource、Tools 五类要素以及初始化、操作、关闭三个核心阶段A2A 聚焦企业内部的基于任务交互模式强调智能体创建、状态管理与任务分配ANP 则瞄准数十亿智能体互联提出开放、安全、高效的基础网络架构。PPT 还结合数据孤岛、互联互通、标准化协议等挑战分析了未来智能体网络所需的 AI 原生连接方式与协议演进方向帮助读者建立清晰的选型判断也能为后续深入研究具体协议提供切入点。压缩包共 1 个 PPTX 演示文稿大小 5.23MB可直接演示、按页拆解或用于团队技术分享。已有 219 人学习适合作为智能体协议入门与选型参考。1. 智能体协议对比不是选最火的而是先分清你在哪一层三个协议我一开始都试过接真实项目。MCP 已经成了 LLM 用工具的事实标准A2A 是 2025 年 Google 推的 Agent 间协作协议ANP 则把智能体通信放到一个去中心化消息网络上。踩了一圈坑后最真实的感受是把 MCP、A2A、ANP 放在一张表里比谁强是个方向性错误。它们不是一个层级的东西比之前先问自己一个问题——我到底在接工具、接同事还是在接网络?答案不同结论就完全不同。这篇文章按三条路线分别拆也讲讲什么时候你根本不用上贵的方案。给模型《深入对比智能体协议MCP、A2A、ANP》这个标题做内容时最怕的不是资料不够而是拿着工具协议的标准去量协作协议最后量出一堆没法落地的伪差异。2. 先用 MCP 盘活工具接入最小 Server、工具定义与三个必调参数2.1 MCP 到底解决什么问题上下文注入、工具调用与权限边界MCP 全称 Model Context Protocol它解决的是“给大模型接上现实世界”这件事。在 MCP 出现之前每个应用都要自己写一套 function calling 的封装把天气、数据库、文件系统、浏览器操作逐个暴露给模型。MCP 把这一层抽成了统一协议模型客户端发起 tools/list 拿工具清单tools/call 带着参数调用对应工具工具执行完把结果作为消息返回。这套交互让 Cursor、Claude 客户端、IDEA 插件都能像插 USB 一样复用同一套生态这也是 Figma MCP、Blender MCP、Playwright MCP 能快速普及的直接原因。MCP 的设计里有个容易被忽略的点它是被动的。MCP Server 自己不会主动找模型聊天模型发出一个请求工具才执行一次。所以它特别适合“在 LLM 推理循环中按需拉数据”的场景。权限边界则落在两个地方一是客户端决定暴露哪些 server、哪些工具给模型二是 transport 层面决定了工具作用域——stdio 本地进程内、HTTP SSE 走本地或远端。从落地角度我自己最常用的连接方式有两类。一是本地进程型开发机上的 MCP Server 用 stdio 启动工具直接操作同机文件、终端省去网络配置。二是远端资源型比如把团队内部的 12306 查票脚本、数据库查询接口封装成 MCP Server客户端通过 HTTP 连接服务器端统一鉴权。二者选型的核心依据是“工具数据离谁近”——数据在本地就用 stdio数据在远端就用 HTTP。2.2 写一个最小 MCP Server直接手写协议比想象中简单常见做法是直接用官方 SDK但很多 MCP 教程把 SDK 包装成了黑匣子一报错就抓瞎。我建议新手手写一个最小 server把协议跑通再引入框架。MCP 底层是 JSON-RPC 2.0一个最简单的 HTTPSSE transport 的 MCP Server 只需处理三条消息initialize、tools/list、tools/call。用 Python 实现一个最小 MCP Server 的第一步是搭建一个同时处理 POST 和 GET 的 HTTP 服务。基础框架如下。import json import uvicorn from fastapi import FastAPI from fastapi.responses import StreamingResponse app FastAPI() # MCP 工具定义——供模型读取能力清单 TOOLS [ { name: get_weather, description: 查询指定城市的实时天气, inputSchema: { type: object, properties: { city: {type: string, description: 城市名如 北京} }, required: [city] } } ] # MCP 协议核心处理 JSON-RPC 请求 app.post(/mcp) async def handle_mcp(payload: dict): method payload.get(method) msg_id payload.get(id) # 初始化握手返回协议版本和 server 能力 if method initialize: return {jsonrpc: 2.0, id: msg_id, result: { protocolVersion: 2024-11-05, capabilities: {tools: {}}, serverInfo: {name: minimal-mcp, version: 0.1.0} }} # 工具列表——模型决定调什么就看这里 if method tools/list: return {jsonrpc: 2.0, id: msg_id, result: {tools: TOOLS}} # 真正的工具调用入口 if method tools/call: params payload.get(params, {}) tool_name params.get(name) args params.get(arguments, {}) if tool_name get_weather: result f模拟天气数据{args.get(city)} 晴 24℃ return {jsonrpc: 2.0, id: msg_id, result: { content: [{type: text, text: result}] }} return {jsonrpc: 2.0, id: msg_id, error: {code: -32601, message: Method not found}}这段代码里有几个关键参数。inputSchema是给模型看的标准格式属性名、类型、必填项直接影响大模型生成的参数是否合法protocolVersion在 MCP 演进中很关键不同客户端会按这个字段判断用哪种注册方式tools/call 返回的 content 数组可以包含多段内容不只是文本——图片、日志、结构化 JSON 都可以拆开放。实际生产多用 SDK 包一层但你会抓协议了SDK 报错时能一眼定位是参数校验还是 transport 问题。起一个这个服务标准命令就是uvicorn main:app --port 8765跑起来然后把 endpoint 配到客户端里。执行时注意 MCP 的 tools/call 是同步等待的如果工具长耗时必须在客户端做重试策略服务端也要考虑把任务转成异步再立刻返回。这就是 MCP 协议和 A2A 最大的差异MCP 假设工具快速返回而 A2A 从设计上就是异步的。2.3 客户端接入与 3 个必调参数transport、timeout、schema 校验MCP 客户端配置以 Cursor 使用的.mcp.json为例这是常用接法。{ mcpServers: { local-weather: { command: uvicorn, args: [main:app, --port, 8765], env: {}, timeout: 30 }, remote-api: { type: sse, url: http://localhost:8765/mcp, headers: {Authorization: Bearer xxxx}, timeout: 60 } } }客户端配置里最容易出问题的三个参数基本按以下顺序排查。第一个是transport本地进程用command方式远端服务用sse/http配错会直接连不上。第二个是timeoutMCP 本地工具的常规 30 秒超时如果你的工具是查 Elasticsearch、跑推理这种慢操作必须把这个值调到 60 秒以上。我曾遇到一个团队把所有 timeout 都设 30 秒多毛几次后才发现是被超时杀掉不是服务挂了。第三个是输出校验很多工具返回了非 JSON 结构模型拿不到字段名直接翻车所以要在 tools/call 返回前做一次类型强校验宁可报错也不要给模型一个结构不稳定的结果。提示:如果客户端日志里出现tools/list超时或Server not compatible先检查 initialize 握手是否完成HTTP/SSE 的 MCP Server 必须在初始化阶段正确返回 protocolVersion否则后续所有请求都会被客户端拒绝。3. A2A 与 MCP 的关键差异Agent Card、任务协作与跨应用通信3.1 A2A 的定义把 Agent 当作可协作的“同事”而不是被调用的工具A2A 全称 Agent2Agent解决的是另一个层级的问题让不同厂商、不同框架实现的智能体互相发现、互相派活。MCP 是“模型去找工具”A2A 是“Agent 去找 Agent”。它不需要双方共享同一个模型、同一个知识库只要双方实现了 A2A 协议就能完成任务协作。A2A 里的核心抽象是 Task一个 Task 代表一次完整的协作——发起方创建任务执行方更新任务状态双方通过 message 交换中间结果和产物 artifact。A2A 和 MCP 最本质的区别在于异步和状态。MCP 的 tools/call 是一次同步请求模型等着结果回来。A2A 的 task 提交后立刻返回一个 task ID执行方可能跑几秒、几小时甚至几天中间通过推送或拉取把状态变化同步给发起方。协议还专门定义了 push 通知机制执行方在任务状态变化时主动发 JSON-RPC 通知给发起方不需要另一端一直轮询。这意味着你设计协作 Agent 时要转变思维不能假设“发一个请求就同步拿结果”所有协作都要围绕任务状态流转去做。A2A 的另一个关键设计是 Agent Card。每个 A2A Agent 必须暴露一个包含自身能力、接口地址、认证方式的公开卡片。发起方先读 Agent Card判断对方具备哪些技能、支持哪些传输方式再决定是否发起协作。这套机制让 A2A 天然具备“可发现”的特征——你的智能体在一个组织内可以被别的智能体检索到而不是只能被预先写死在代码里。3.2 起一个 A2A Agent 的最小实现Agent Card 与任务处理A2A 的接入姿势不复杂核心是两件事暴露一张 Agent Card处理任务消息。用 FastAPI 实现一个最小 A2A Agent你只需要三个端点/.well-known/agent.json返回卡片/task/new接收任务/task/{id}查询状态。下面是一个最小实现的关键代码。from fastapi import FastAPI from pydantic import BaseModel app FastAPI() # 1. Agent Card告诉别的 Agent 你是谁、能干什么 AGENT_CARD { name: customer-service-agent, description: 处理订单查询与售后问题, url: https://a2a.example.com/, skills: [ { id: order_status, name: 订单状态查询, description: 根据订单号返回物流状态 } ], authentication: { schemes: [bearer], credentials: https://a2a.example.com/.well-known/oauth } } # 2. 任务状态流转A2A 协议要求的状态机之一 class Task(BaseModel): id: str status: str # submitted | working | completed | failed artifacts: list [] app.get(/.well-known/agent.json) async def agent_card(): return AGENT_CARD # 3. 接收 A2A 任务如果用 task/new 创建任务 app.post(/task/new) async def create_task(task_request: dict): task_id ftask_{abs(hash(task_request))} # 实际业务把订单号传给内部服务 return { id: task_id, status: submitted, message: 任务已受理处理中 }这段代码展示了 A2A 和 MCP 在结构上的差异每个 Agent 都必须能回答“你是谁、能做什么、怎么验证你”然后才谈任务接收。实际部署时skills字段的粒度直接影响协作成功率skill 写得太粗、对方不知道什么任务该发给你写得太细Agent Card 维护成本极高。我建议把 skill 定义在“业务动作”粒度比如“订单状态查询”而不是“物流信息获取”“仓库状态确认”这种细碎描述。A2A 的 Agent Card 是给另一个大模型读的不是给人读的描述要用机器容易解析的短语不要写长句。3.3 A2A 的认证、委派与人机回环部署时最容易被忽略的三件事A2A 落地时最容易被忽略的是认证。早期联调时大家内网互相直连不验身份到了生产环境多个组织交换 Agent Card 就成了事故现场。A2A 规范里对认证要求明确Agent Card 必须声明自己的认证方案调用方必须携带凭证才能访问任务接口。你现在在本地内网可以跳过这步但对外部署至少要加一层 API Key 验证否则你暴露的不只是数据还有对所有接入 Agent 的调用权限。A2A 支持的复杂任务编排中经常遇到委派场景:A 接到用户大任务拆分后把子任务派给 BB 执行完把结果回报给 AA 再汇总返回用户。这种父子任务链要求任务消息里带上 parent_task_id实现时不传会断链。还有一个诡异的坑——push 通知的配置。A2A 的 push 依赖发起方暴露一个回调地址执行方在这个地址上推状态。但如果发起方在 NAT 后面回调地址配了本地 IP执行方根本推不进去。遇到这种情况我一般直接降级为 pull 模式:发起方定期 GET 任务状态比修网络穿透快得多。人机回环在 A2A 里也要在设计期定清楚。当任务的某个步骤需要人工审批时协议提供needsHumanInput标记。这个标记会告诉调用方“这个任务现在卡住等人工你别催也别自动重试。”很多人不做这个标记结果就是 Agent 把人工审批的元数据当成报错疯狂重跑白烧预算。正确做法是任务在提交时就声明是否需要人工介入需要的话任务状态停在input-required等待外部触发。4. ANP 的价值边界消息路由、去中心化网络与适用场景4.1 ANP 和 MCP/A2A 根本不在一个层它管的是智能体怎么“连上彼此”ANP 全称 Agent Network Protocol和前两者的最大区别是它解决的问题不是“怎么调用”而是“怎么找到”和“怎么传”。MCP 里模型和工具的地址是配置好的A2A 里 Agent 的 URL 也是写死的。而 ANP 引入了一个去中心化的消息网络每个 Agent 作为网络节点注册通过统一的命名和路由机制发现彼此消息在节点间转发不依赖某个中心服务器。这有点像给智能体装了一套自有的寻址系统Agent 之间通过 node id 直接通信节点可以动态加入和退出。ANP 不是要替代 MCP——实际上 ANP 节点内部完全可以跑 MCP Server对外用 ANP 封装一层。常见架构是每个节点内挂载 MCP Server 提供服务节点之间用 ANP 协议互相发现和转发请求。所以 ANP 对开发者最大的价值在于当你的 Agent 数量多了或者 Agent 分布在不同网络、不同部门、不同团队的服务器上时让它们通过 ANP 自动组网而不是把每个 Agent 的地址硬编码在调用方配置里。从我接触的 ANP 实现看典型的网络结构允许所有节点互连没有主从节点消息通过节点间路由转发。这种架构的额外收益是单点故障被分散某个节点下线消息会自动找其他路径不会像中心化调度那样整体停止服务。代价也很直接——运维时你要监控的不再是“一个服务挂没挂”而是“整个网络的连通性”。这个复杂度在高密度场景超大规模 Agent 协作里划算在几十个 Agent 的小系统里不划算。4.2 接入 ANP 节点的最小流程注册、命名、收发消息ANP 的接入路径大致分三步配置节点信息、注册到网络、定义收发规则。下面是一个示例配置结构。{ node_id: service-agent-01, node_role: provider, network: { bootstrap_nodes: [ anp://node-a:8080, anp://node-b:8080 ] }, capabilities: { services: [order_management, inventory_query] }, registration: { ttl_seconds: 300, auto_renew: true } }这套配置里核心字段是node_id、bootstrap_nodes和capabilities。node_id是全网唯一标识注册和寻址都靠它bootstrap_nodes是节点入网时的初始连接点新节点先连上这些已知节点获取全网节点列表capabilities声明本节点能提供的能力网络按这个字段做服务发现。registration.ttl_seconds是注册租约时长超过这个时间必须续约否则其他节点认为你离线。逻辑上bootstrap_nodes不需要多三到五个足够。这里很容易踩一个坑把全部节点都填进 bootstrap 列表误以为越多越好。实际上 bootstrap 只负责引导入网入网后节点之间会交换路由信息bootstrap 过多反而增加握手开销。ttl_seconds也别设太长太长则下线节点会被持续路由到请求超时才暴露问题太短则节点需要频繁续约日志会被注册请求刷屏。经验值是内部网络 300 秒、跨公网 60 到 120 秒按实际心跳间隔调。消息收发层面ANP 节点间传递的是标准消息体包含消息类型、源节点、目标节点和业务负载。发起方不需要知道目标节点的准确地址只需要知道目标 node_id网络层负责把消息送达。这层抽象让上层业务逻辑干净很多但也意味着你排查问题时少了很多抓手——报错只告诉你“消息未送达”不会告诉你具体断在哪个节点。所以在设计阶段就要把消息追踪字段加上给每条消息打上全局唯一的 trace id。4.3 ANP 什么时候真的值得上什么时候是过度设计综合多个线上案例我认为 ANP 的启用标准只有三条第一Agent 数量或服务数量到一定程度配置中心开始成为瓶颈第二Agent 分布在多个部门、多个数据中心跨域发现需求频繁第三业务要求网络具备容错性不允许某个中心节点挂掉就全盘停摆。如果你不满足这三条用静态配置加 HTTP 直连反而更稳。我的原则是能用 MCP 一个 tool 解决不要引 ANP。ANP 的价值在动态性和容错代价是网络层引入的复杂度。一个团队如果只是把两三个内部 Agent 串起来用 A2A 就够了上 ANP 意味着要额外维护节点注册、租约续订、消息路由观测运维成本立刻涨一个量级。反过来如果你已经开始用 Consul 之类的服务发现体系来管理 Agent而配置还在那里不断膨胀那正是 ANP 的适用面。它把“服务发现、健康检查、消息路由”这三件事收敛成一个网络不再靠运维脚本硬撑。提示:ANP 的上手路径里最容易翻车的是“你觉得自己需要它”。先画一张部署图把所有 Agent 之间的连接线数一遍少于 10 条线就别上网络层。5. MCP、A2A、ANP 到底怎么选场景对照与避坑清单5.1 三协议选型对照一张表说清分工先把三个协议的适用层级厘清这是本文最核心的一张对照表。维度MCPA2AANP核心解决的问题模型调用工具/数据Agent 间任务协作Agent 网络发现与消息传输通信双方模型客户端 ↔ 工具服务端Agent ↔ Agent节点 ↔ 节点主要交互模式同步请求/响应异步任务 状态轮询/推送异步消息转发状态管理无状态调用完即结束Task 状态机驱动节点注册与路由状态典型配置项transport、timeout、tools 列表Agent Card、auth、task schemanode_id、bootstrap、ttl适用规模单机/小团队内的工具接入跨应用/跨团队的多智能体协作大规模、跨地域的智能体网络上手成本低半天能跑通中需要设计任务流高需要理解网络层和 Agent 的关系给 Agent 装手让 Agent 变同事给 Agent 建办公室实际工作中这三者可以共存且经常要共存。典型架构是:Agent 内部用 MCP 调工具和其他 Agent 用 A2A 协作整个 Agent 网络挂在 ANP 上做动态发现。你选择的不是“用一个替代另一个”而是“在不同层级选正确的组件”。很多架构评审为什么吵到面红耳赤就是有人拿 A2A 的标准质疑 MCP 的实现层级都不对齐自然谁都说服不了谁。5.2 避坑清单五个常见的翻车现场以下是我在不同项目里踩过、或者帮别人排查过的真实问题按现象、原因、解决整理成五条。第一MCP 工具调用时所有请求都成功就是结果不对。现象是 tools/list 正常、tools/call 正常但模型生成的参数格式和 inputSchema 不匹配。原因多半是 inputSchema 没定义required模型漏传关键参数走默认值。解决把必填参数显式列全并在服务端做参数白名单校验拒绝多余字段。第二A2A 任务一直停留在 submitted 不推进。现象是发起方提交任务成功但等不到结果。原因在于执行方没有正确触发任务状态更新或者代理配置缺失——执行 Agent 内部还在同步阻塞地等结果没意识到 A2A 是异步语义。解决在服务端确认任务收到后立刻返回 task id把耗时操作丢进后台线程或消息队列真正的负责人是那个后台任务不是 HTTP 处理器。第三A2A 的 push 通知丢失导致协作卡死。现象是任务明明完成了发起方还显示 working。原因多是发起方提供的 callback URL 不可达或者 push 事件格式不符。解决实现端实现两态兼容——既接收 push也在任务超时阈值内做一次主动 GET 兜底用轮询保底是最成熟的做法。第四ANP 的节点莫名其妙离线。现象是节点日志没有任何报错但注册中心里已经看不到它。原因多半是 ttl 时间设置过短而续约线程的间隔没有相应缩短中途断了一次就过期了。解决把 ttl 设置成心跳间隔的至少 3 倍以上或者直接在注册配置里开启自动续约不要自己写定时器。第五三协议混跑时同一个功能在 A2A 里实现了MCP 那边又要重复开发。现象是团队给 Agent 接工具用 MCP给 Agent 之间协作又用 A2A但底层的同一套业务逻辑写了两遍暴露逻辑。原因是没有把“能力层”和“协议层”分开设计。解决统一抽象业务服务层一个业务服务同时挂 MCP 暴露工具、挂 A2A 暴露任务能力不要为每种协议写一套独立的业务代码。6. 部署前验证用最小样例快速判断该上哪个协议在正式起项目之前我推荐做一次 30 分钟的协议选型验证而不是拍脑袋。三个测试用例每个都能在半天内跑通。第一测试 MCP 的必要性。选一个你最常用的内部操作比如查订单、查日志写一个 MCP Server用客户端手动调用一次。如果这个操作本身是“查询—返回”模式MCP 是最短路径。如果调用一次耗时超过 30 秒你需要认真评估同步接口是否合适不要硬扛。第二测试 A2A 的协作复杂度。写两个极简 Agent一个负责生成任务一个负责执行任务让它们通过 A2A 跑一次完整的任务生命周期。重点观察任务中断恢复怎么做、执行 Agent 崩溃后任务状态怎么收敛。如果这两个问题你的团队答不上来说明还没到上 A2A 的阶段。第三测试 ANP 的网络收益。把三个 Agent 分别部署在三台机器上先静态配置互联做一轮再切换到 ANP 节点注册的方式做同样的事。对比两类指标配置变更耗时和故障恢复耗时。如果静态配置在这两个维度上和你需求的差距不到 20%ANP 带来的额外复杂度大概率不值。这套验证方法我基本每次做智能体架构评审都会带着团队过一遍多数时候结论都是“先用 MCP 把业务跑起来等 Agent 数量超过五个再启动协作战”极少有一上来就全协议铺满的场景。协议选型没有银弹核心还是看你要解决的链路瓶颈在哪里——工具调用慢就优化 MCPAgent 协作乱就优化 A2A网络发现难再想起 ANP。我自己在智能体架构上吃过不少亏最深刻的一条是不要因为论文里写了某个协议很优雅就引入生产协议是帮业务解决问题的不是帮简历增加关键词的。从最小的接入开始验证让业务指标告诉你什么时候该升级。希望这篇文章能帮你在 MCP、A2A、ANP 的三岔路口少走一段弯路。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。