news 2026/10/12 7:31:32

智能体协议选型指南:MCP、A2A、ANP 核心区别与落地实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
智能体协议选型指南:MCP、A2A、ANP 核心区别与落地实践

简介:这份PPT资料面向大模型与人工智能方向的开发者、架构师及技术决策者,系统梳理智能体通信协作领域的三大主流协议——MCP、A2A与ANP。内容从未来智能体互联网对协议的需求切入,逐一剖析MCP的Root、Sampling、Prompt、Resource、Tools等核心概念与初始化、操作、关闭三大流程,A2A基于任务的企业内部智能体协作模式,以及ANP面向数十亿智能体构建开放协作网络的愿景,并对比三者的差异、优缺点与未来角色。资源包为1个pptx文件,约5.23MB,结构清晰、图文并茂,适合用于技术分享、方案选型或团队内部培训。目前已有219人学习下载。通过这份资料,读者可快速建立对智能体协议体系的整体认知,理解数据孤岛、互联互通与标准化三大挑战的应对思路,为后续架构设计与技术选型提供参考。

1. 三份 PPT 拆开看:MCP、A2A、ANP 到底谁管哪一段

上周帮一个做企业知识库的团队做架构评审,他们已经在用 MCP 把内部检索、数据库、工单系统接进了大模型,跑得挺顺。结果老板突然提了个需求:让销售侧的智能体直接去调用供应链侧的智能体,跨部门自动对账。团队第一反应是「再写个 MCP Server 不就行了」,结果卡了两周——因为 MCP 压根不是干这个的。这就是我拿到《深入对比智能体协议:MCP、A2A、ANP.pptx》这份资源时的真实背景。它把三个最容易混淆的智能体协议放在同一张对比表里讲清楚了:MCP 解决的是「智能体怎么调用工具和数据」,A2A 解决的是「智能体之间怎么互相调用」,ANP 解决的是「智能体怎么在网络里被发现、被信任、被组合」。如果你正在做 Agent 落地,分不清这三者的边界,选型阶段就会埋雷。这份 PPT 适合已经上手过至少一个 Agent 框架、需要做协议选型或架构对齐的工程师,也适合想快速建立全局认知的技术负责人。

2. MCP 协议拆解:从工具描述到一次完整调用链

2.1 MCP 的设计动机与核心抽象

MCP 全称 Model Context Protocol,它要解决的核心痛点是:大模型应用每次接一个新工具(数据库、文件系统、API),都要写一套定制化的适配代码。工具多了以后,代码里全是胶水逻辑,换一个模型或换一个框架就得重写。MCP 的做法是把「工具」抽象成标准化的 Server,把「调用方」抽象成 Client,中间用 JSON-RPC 2.0 通信。这样工具提供方只需要实现一次 MCP Server,任何支持 MCP 的 Client 都能直接接入。

PPT 里把 MCP 的核心抽象拆成四层:Resources(资源,类似文件或数据记录)、Tools(可执行函数)、Prompts(预置提示模板)、Sampling(让 Server 反向请求 Client 的模型能力)。实际落地中最常用的是 Tools 和 Resources,Prompts 和 Sampling 用得少但有特定场景。理解这四层的关键在于:Resources 是「读」的语义,Tools 是「做」的语义,两者在权限控制上要分开处理。

2.2 手写一个最小 MCP Server

下面用 Python 写一个最小可用的 MCP Server,暴露一个查询订单状态的工具。这段代码可以直接跑,依赖只有mcp包。

# minimal_mcp_server.py # 依赖: pip install mcp import asyncio from mcp.server import Server from mcp.server.stdio import stdio_server from mcp.types import Tool, TextContent app = Server("order-service") # 模拟订单数据 ORDERS = { "ORD-1001": {"status": "shipped", "eta": "2025-06-20"}, "ORD-1002": {"status": "pending", "eta": None}, } @app.list_tools() async def list_tools() -> list[Tool]: """声明本 Server 提供哪些工具,Client 启动时会拉取这个列表""" return [ Tool( name="query_order", description="根据订单号查询订单状态和预计到达时间", inputSchema={ "type": "object", "properties": { "order_id": { "type": "string", "description": "订单号,格式 ORD-XXXX" } }, "required": ["order_id"] } ) ] @app.call_tool() async def call_tool(name: str, arguments: dict) -> list[TextContent]: """实际执行工具调用,返回结果给 Client""" if name != "query_order": raise ValueError(f"未知工具: {name}") order_id = arguments.get("order_id", "") order = ORDERS.get(order_id) if not order: return [TextContent(type="text", text=f"订单 {order_id} 不存在")] return [TextContent( type="text", text=f"订单 {order_id}: 状态={order['status']}, 预计到达={order['eta'] or '待定'}" )] async def main(): # 通过 stdio 传输层启动,Client 以子进程方式拉起本 Server async with stdio_server() as (read, write): await app.run(read, write, app.create_initialization_options()) if __name__ == "__main__": asyncio.run(main())

逻辑说明:list_tools返回工具清单和 JSON Schema 格式的参数定义,Client 拿到后会把工具描述注入模型的上下文,模型决定是否调用。call_tool是实际执行入口,参数由模型生成、Client 转发。传输层用 stdio 是最简单的本地调试方式,生产环境常见做法是换成 SSE 或 Streamable HTTP。

参数说明:inputSchema必须符合 JSON Schema 规范,required字段决定模型是否必须提供该参数。TextContent的type目前支持text和image,返回图片时传 base64。注意description写得好不好直接影响模型调用准确率——这是血泪经验,描述含糊的工具模型经常不调用或传错参数。

2.3 用 Client 验证调用链

写完 Server 后,用官方提供的 Client 做一次端到端验证:

# 安装 MCP Inspector,可视化调试工具 npx @modelcontextprotocol/inspector python minimal_mcp_server.py

启动后浏览器打开 Inspector 界面,能看到工具列表、手动触发调用、查看原始 JSON-RPC 消息。这一步很关键——很多「模型不调用工具」的问题,其实是 Server 返回的 Schema 有问题,用 Inspector 能快速定位是 Server 端还是 Client 端的问题。

如果要在代码里集成,Client 侧大致是这样:

# mcp_client_demo.py from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def run(): params = StdioServerParameters( command="python", args=["minimal_mcp_server.py"] ) async with stdio_client(params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() # 拉取工具列表 tools = await session.list_tools() print("可用工具:", [t.name for t in tools.tools]) # 直接调用工具 result = await session.call_tool( "query_order", {"order_id": "ORD-1001"} ) print("调用结果:", result.content[0].text) import asyncio asyncio.run(run())

这段代码展示了 MCP 调用的完整生命周期:建立传输连接 → 初始化会话 → 拉取工具列表 → 调用工具 → 拿到结果。实际接入大模型时,中间多一步「把工具列表转成模型能理解的 function calling 格式」,但底层走的还是这套流程。

3. A2A 协议拆解:智能体之间的任务委派怎么落地

3.1 A2A 与 MCP 的本质区别

A2A 全称 Agent-to-Agent Protocol,它和 MCP 最容易混淆,但定位完全不同。MCP 是「智能体 → 工具」的纵向调用,A2A 是「智能体 → 智能体」的横向协作。PPT 里用了一个很准确的类比:MCP 像是给电脑装驱动,A2A 像是两台电脑之间组网。

具体来说,A2A 要解决的是:一个智能体如何发现另一个智能体的能力、如何把任务委派过去、如何追踪任务状态、如何处理长任务和流式返回。它的核心抽象是 Agent Card(能力声明)、Task(任务对象)、Message(消息)和 Artifact(产出物)。Agent Card 是一个 JSON 文件,通常放在/.well-known/agent.json路径下,描述这个智能体的名称、能力、支持的输入输出格式和认证方式。

3.2 定义一个 Agent Card

Agent Card 是 A2A 的入口,没有它别的智能体就找不到你。下面是一个典型的 Agent Card:

{ "name": "supply-chain-agent", "description": "供应链对账智能体,支持订单核对和差异分析", "url": "https://supply.example.com/a2a", "version": "1.0.0", "capabilities": { "streaming": true, "pushNotifications": false }, "skills": [ { "id": "reconcile-orders", "name": "订单对账", "description": "接收销售侧订单列表,与供应链记录比对,返回差异明细", "inputModes": ["application/json"], "outputModes": ["application/json"] } ], "authentication": { "schemes": ["Bearer"] } }

逻辑说明:capabilities.streaming表示该智能体支持流式返回中间状态,长任务场景必须开。skills数组列出具体能力,每个 skill 有独立的 id 和输入输出格式声明。authentication声明认证方式,A2A 本身不定义认证协议,只声明要求,具体走 OAuth2 还是 API Key 由实现方决定。

参数说明:url是 A2A 服务的端点,Client 会向这个地址发 JSON-RPC 请求。inputModes和outputModes用 MIME 类型标注,常见的是application/json和text/plain。如果智能体要接收文件,加application/pdf之类的类型。

3.3 发起一次 A2A 任务委派

A2A 的调用流程比 MCP 多一层任务管理。下面用 Python 演示如何向一个 A2A 智能体发起任务:

# a2a_client_demo.py # 依赖: pip install httpx import httpx import uuid AGENT_URL = "https://supply.example.com/a2a" async def send_task(): task_id = str(uuid.uuid4()) payload = { "jsonrpc": "2.0", "id": task_id, "method": "tasks/send", "params": { "id": task_id, "message": { "role": "user", "parts": [ { "type": "text", "text": "请对账以下订单:ORD-1001, ORD-1002, ORD-1003" } ] } } } async with httpx.AsyncClient() as client: resp = await client.post( AGENT_URL, json=payload, headers={"Authorization": "Bearer <token>"}, timeout=60.0 ) result = resp.json() # 任务可能直接完成,也可能返回 working 状态 print("任务状态:", result["result"]["status"]["state"]) return result["result"]["id"] async def poll_task(task_id: str): """长任务需要轮询状态,直到 completed 或 failed""" payload = { "jsonrpc": "2.0", "id": str(uuid.uuid4()), "method": "tasks/get", "params": {"id": task_id} } async with httpx.AsyncClient() as client: resp = await client.post(AGENT_URL, json=payload) return resp.json()["result"] import asyncio task_id = asyncio.run(send_task()) print("任务已提交:", task_id)

逻辑说明:A2A 用 JSON-RPC 2.0 作为基础协议,tasks/send提交任务,tasks/get查询状态。任务状态机包括submitted、working、input-required、completed、failed、canceled。input-required是个关键状态——智能体执行到一半需要补充信息时,会暂停并返回这个状态,Client 需要再发一条消息补充输入。

参数说明:message.parts是消息内容数组,支持 text、file、data 三种类型。timeout要设够,跨智能体调用往往比本地工具调用慢。如果 Agent Card 里声明了streaming: true,可以用tasks/sendSubscribe方法建立 SSE 连接,实时接收状态更新,避免轮询。

3.4 A2A 的适用边界

A2A 不是万能的。PPT 里明确列了几个不适合用 A2A 的场景:单智能体内部调用工具(用 MCP)、纯数据管道(用消息队列)、需要严格事务保证的同步调用(用 gRPC)。A2A 最适合的是「多个智能体分属不同团队或不同系统,需要松耦合协作」的场景。比如销售智能体和供应链智能体分属两个部门,各自迭代,通过 A2A 协议对接,谁也不用改谁的代码。

4. ANP 协议拆解:智能体网络里的发现与信任

4.1 ANP 要解决的是什么问题

ANP 全称 Agent Network Protocol,它比 MCP 和 A2A 更上层。MCP 解决工具接入,A2A 解决点对点协作,ANP 解决的是「当网络里有成百上千个智能体时,怎么发现谁、怎么信任谁、怎么组合成更大的能力」。PPT 里把 ANP 的核心归纳为三个机制:去中心化身份(DID)、能力发现(基于语义描述)、信任传递(基于可验证凭证)。

这个定位决定了 ANP 的落地门槛比前两者高。MCP 和 A2A 可以单点接入,ANP 需要整个网络层面的基础设施。但如果你的场景是「构建一个开放的智能体市场」或「跨组织的智能体协作网络」,ANP 是绕不开的。

4.2 DID 与可验证凭证的落地方式

ANP 用 DID 标识每个智能体,用可验证凭证(VC)表达信任关系。下面是一个简化的 DID 文档示例:

{ "@context": "https://www.w3.org/ns/did/v1", "id": "did:example:supply-chain-agent-001", "verificationMethod": [ { "id": "did:example:supply-chain-agent-001#key-1", "type": "Ed25519VerificationKey2020", "controller": "did:example:supply-chain-agent-001", "publicKeyMultibase": "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK" } ], "service": [ { "id": "did:example:supply-chain-agent-001#a2a", "type": "A2AService", "serviceEndpoint": "https://supply.example.com/a2a" } ] }

逻辑说明:verificationMethod声明公钥,其他智能体用这个公钥验证该智能体签名的消息。service声明服务端点,这里指向 A2A 端点,说明 ANP 和 A2A 是互补关系——ANP 负责发现和信任,A2A 负责实际通信。

参数说明:publicKeyMultibase是 Multibase 编码的公钥,z前缀表示 base58btc 编码。type字段决定签名算法,Ed25519 是目前主流选择,性能好且密钥短。实际部署时 DID 文档通常托管在区块链或分布式存储上,但也可以先用 HTTPS 托管做原型验证。

4.3 能力发现与语义匹配

ANP 的能力发现基于语义描述,不是简单的关键词匹配。每个智能体在 DID 文档或独立的服务描述里声明自己的能力,其他智能体用语义相似度找到最合适的协作者。常见做法是用向量数据库存能力描述,查询时做相似度检索。

# capability_discovery.py # 依赖: pip install sentence-transformers numpy from sentence_transformers import SentenceTransformer import numpy as np model = SentenceTransformer("all-MiniLM-L6-v2") # 模拟网络中的智能体能力描述 agents = [ {"did": "did:example:agent-001", "capability": "订单对账和差异分析"}, {"did": "did:example:agent-002", "capability": "库存查询和补货建议"}, {"did": "did:example:agent-003", "capability": "物流轨迹追踪和异常预警"}, {"did": "did:example:agent-004", "capability": "财务报表生成和合规检查"}, ] # 预计算能力向量 capability_texts = [a["capability"] for a in agents] capability_vectors = model.encode(capability_texts, normalize_embeddings=True) def find_agent(query: str, top_k: int = 2): """根据自然语言查询找到最匹配的智能体""" query_vec = model.encode([query], normalize_embeddings=True) scores = np.dot(capability_vectors, query_vec.T).flatten() ranked = np.argsort(scores)[::-1][:top_k] return [ {"did": agents[i]["did"], "score": float(scores[i])} for i in ranked ] # 测试:找一个能做对账的智能体 results = find_agent("我需要核对销售订单和供应链记录") for r in results: print(f"{r['did']} 相似度={r['score']:.4f}")

逻辑说明:用 Sentence Transformer 把能力描述和查询都编码成向量,做余弦相似度匹配。normalize_embeddings=True让向量归一化,点积直接等于余弦相似度。实际生产环境会把向量存进 FAISS 或 Milvus,支持百万级智能体的毫秒级检索。

参数说明:all-MiniLM-L6-v2是轻量模型,384 维向量,适合原型验证。生产环境可以换更大的模型提升语义匹配精度,但要注意推理延迟。top_k控制返回候选数量,通常取 3 到 5,太少容易漏,太多增加后续验证成本。

5. 避坑与常见问题:协议选型和落地中的真实翻车记录

5.1 用 MCP 做智能体间通信,结果任务状态全丢了

现象:团队用 MCP 的 Tools 机制让智能体 A 调用智能体 B,简单场景能跑通,但一旦 B 执行超过 30 秒,A 就超时了,而且拿不到 B 的中间状态。

原因:MCP 的 Tools 调用是同步语义,设计上就是「调用-返回」的短交互模式。它没有任务状态机,不支持长任务和流式中间状态。A2A 才有working、input-required这些状态。

解决:智能体间通信一律走 A2A,MCP 只用于智能体调用无状态工具。如果暂时不想引入 A2A,至少把长任务拆成「提交任务返回 task_id」+「轮询状态」两步,但这本质是在 MCP 上重新实现 A2A 的任务管理,不如直接用 A2A。

5.2 Agent Card 路径写错,发现机制直接失效

现象:A2A 智能体部署好了,但其他智能体死活发现不了它,日志里全是 404。

原因:A2A 规范约定 Agent Card 放在/.well-known/agent.json,但有些框架默认路径是/.well-known/agent-card.json或/agent.json。不同实现之间路径不统一,导致发现失败。

解决:部署后用curl https://your-domain/.well-known/agent.json验证路径可访问。如果框架默认路径不同,在反向代理层加一条 rewrite 规则统一到标准路径。这个坑很隐蔽,因为本地测试时如果 Client 和 Server 用同一个框架,路径一致就不会暴露问题。

5.3 MCP Server 的工具描述太模糊,模型调用率极低

现象:MCP Server 接入了 10 个工具,但模型实际只调用了其中 2 个,其他工具明明该用却不用。

原因:工具的description写得太笼统,比如「查询数据」「处理请求」这种。模型在选择工具时依赖描述做语义匹配,描述不具体就无法准确判断该用哪个。

解决:每个工具的 description 要写清楚「做什么、输入什么、输出什么、什么场景用」。比如把「查询数据」改成「根据订单号查询订单状态,输入 ORD-XXXX 格式订单号,返回状态和预计到达时间」。另外inputSchema里每个参数的 description 也要写,模型生成参数时同样依赖这些描述。

5.4 ANP 的 DID 解析在离线环境不可用

现象:在内网环境部署 ANP 智能体网络,DID 解析全部失败,智能体之间无法互相发现。

原因:DID 解析通常依赖外部解析器或区块链节点,内网环境访问不了。有些实现虽然支持本地缓存,但首次解析仍然需要外部访问。

解决:内网场景用did:web方法替代did:example,把 DID 文档托管在内网 HTTPS 服务上,解析走标准 HTTP 请求。或者部署本地 DID 解析缓存服务,预热常用 DID 文档。选型阶段就要确认 DID 方法是否支持离线解析,别等部署了才发现。

5.5 三个协议混用时认证体系冲突

现象:MCP Server 用 API Key 认证,A2A 智能体用 OAuth2,ANP 用 DID 签名,三套认证体系混在一起,调用链上认证信息传丢了。

原因:三个协议各自定义认证声明方式,但没有规定互相之间怎么传递认证上下文。MCP 的 API Key 不会自动转成 A2A 的 Bearer Token,ANP 的 DID 签名也无法直接用于 MCP 的认证。

解决:在网关层做认证转换,统一用一套内部认证体系(比如 JWT),各协议端点的认证在网关终止,内部调用携带统一的 JWT。这样每个协议对外保持自己的认证声明,对内统一。别试图让三个协议直接互认认证信息,那是自找麻烦。

6. 协议选型的决策框架与验证清单

选型这件事,PPT 里给了一张对比表,但表格只能看个大概,真正做决策需要落到具体场景。我一般会按下面这个流程走一遍。

第一步,明确交互类型。如果是「智能体调用工具/数据源」,选 MCP。如果是「智能体调用智能体」,选 A2A。如果是「在开放网络中发布和发现智能体」,选 ANP。三者不是互斥关系,一个系统里可以同时用:用 ANP 做发现,用 A2A 做协作,用 MCP 做工具接入。

第二步,确认任务时长和状态需求。短任务(秒级返回)MCP 够用。长任务(分钟级以上、需要中间状态)必须用 A2A。这一步判断错了,后面全是坑。

第三步,评估网络规模。点对点协作(几个到几十个智能体)A2A 足够。开放网络(上百个以上、需要动态发现)才需要 ANP。别为了「看起来先进」上 ANP,它的基础设施成本不低。

第四步,验证认证体系兼容性。把三个协议的认证方式列出来,看是否有冲突。有冲突就在网关层统一,别在协议层硬解。

下面这张表是我自己用的验证清单,每次选型后逐项过一遍:

验证项MCPA2AANP
工具/能力描述是否完整检查 inputSchema 和 description检查 Agent Card 的 skills检查能力向量覆盖度
长任务支持不支持,需自行封装原生支持状态机依赖底层 A2A
发现机制手动配置 Server 地址Agent Card 路径可访问DID 解析可用
认证方式API Key / OAuthBearer / OAuth2DID 签名 + VC
流式返回部分支持支持 SSE依赖底层 A2A
离线可用性本地 stdio 可用内网 HTTP 可用需确认 DID 方法

最后说一个我自己的习惯:每次做完协议选型,我会写一个最小验证 Demo,把三个协议各跑通一次调用链,确认端到端没问题再进入正式开发。这个 Demo 不用复杂,MCP 跑通一个工具调用,A2A 跑通一次任务委派,ANP 跑通一次 DID 解析和能力发现就行。花半天时间,能省掉后面两周的返工。从那以后我每次做架构评审都强制走一遍这个验证流程,希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/12 7:29:41

从零搭建轻量代码评审工具:架构设计与核心实现

1. 从零搭建代码评审工具&#xff1a;为什么我要造这个轮子第一次听到“open-code-review”这个说法&#xff0c;是在一次内部技术分享会上。当时团队里有人抱怨&#xff0c;代码评审这件事&#xff0c;工具换了一茬又一茬&#xff0c;流程写了一版又一版&#xff0c;但真正落地…

作者头像 李华
网站建设 2026/10/12 7:29:40

英语祈使句全解:从基础结构到礼貌表达的实用指南

1. 别以为祈使句只是"命令句"——它比你想的复杂得多先说一个可能反直觉的结论&#xff1a;祈使句&#xff08;Imperative Sentences&#xff09;是英语里使用频率最高、但被误解最深的句式之一。我教英语这么多年&#xff0c;几乎每节课都会遇到学生问类似的问题&am…

作者头像 李华
网站建设 2026/10/12 7:27:41

DEAP脑电信号识别实战:CNN-LSTM代码详解与避坑指南

简介&#xff1a;面向DEAP脑电情感识别任务的深度学习代码包&#xff0c;提供结合CNN与LSTM的完整训练、验证与预测流程&#xff0c;适合需要基于脑电信号进行情绪分类的研究者、学生或工程师参考。压缩包共35个文件、约11.86MB&#xff0c;结构涵盖Jupyter Notebook实验脚本&a…

作者头像 李华
网站建设 2026/10/12 7:27:14

Python字典操作全解析:从创建、更新到排序与defaultdict实战

1. 字典基础操作与创建方式全解析字典这个结构&#xff0c;在Python里属于那种“平时不觉得多重要&#xff0c;一旦用顺手了就再也回不去”的工具。我刚开始写代码那会儿&#xff0c;习惯用两个列表分别存键和值&#xff0c;靠下标去对应&#xff0c;结果每次增删改查都要同步维…

作者头像 李华
网站建设 2026/10/12 7:27:14

nginx常见功能部署与配置解析

一.安装部署nginx nginx官网 https://nginx.org/en/download.html 1.安装编译依赖 # centos yum install -y gcc gcc-c make zlib zlib-devel pcre pcre-devel openssl openssl-devel2.下载并解压压缩包 wget http://nginx.org/download/nginx-1.30.5.tar.gz tar -zxvf ng…

作者头像 李华