Skip to content

第14章:协议标准 —— MCP、A2A 与互操作边界

上一章讲了怎么组织多个 Agent 协作。但有一个问题被刻意绕开了:这些 Agent 怎么连接外部工具?不同团队、不同框架构建的 Agent 之间怎么通信?

如果每个 Agent 框架都自己定义工具调用格式、自己搞一套 Agent 间通信协议,结果就是 M 个应用 × N 个工具 = M×N 套集成代码。这不是假设——2024 年之前的现实就是这样。每换一个 LLM 供应商,工具集成要重写;每换一个框架,Agent 间通信要重新对接。

两个开放协议试图终结这种局面:MCP 解决 Agent 与工具/数据的连接,A2A 解决 Agent 与 Agent 的通信。本章的目标不是把规范文档复述一遍,而是讲清楚三件事:它们各自解决什么问题、核心抽象长什么样、在你的系统里该放在哪一层。

本章只固定稳定抽象。版本演进、生态数据、厂商支持矩阵放到附录动态维护,正文不写死某个时间点的快照。

14.1 MCP(Model Context Protocol)—— Agent 连接工具和数据的标准

核心直觉

MCP 就是 AI 应用的 USB-C 接口。以前每个 AI 应用要连数据库、调 API、读文件,都得写一套专用的集成代码。MCP 定义了一个标准插口——任何 AI 应用只要实现 MCP Client,就能连上任何 MCP Server 提供的工具和数据,不用关心对方内部怎么实现。

这个类比不是我编的。社区最早用的类比是 "LSP for LLMs"——就像 Language Server Protocol 让任何编辑器都能获得任何语言的补全和跳转能力,MCP 让任何 AI 应用都能接入任何外部工具和数据源 [1]。

架构:三层模型

MCP 的架构有三个角色,不是两个:

┌─────────────────────────────────┐
│           Host(宿主)            │
│  例:Claude Desktop / IDE 插件    │
│  - 创建和管理多个 Client 实例      │
│  - 拥有 LLM 交互                 │
│  - 执行安全策略                   │
│  ┌──────────┐  ┌──────────┐     │
│  │ Client A │  │ Client B │     │
│  └────┬─────┘  └────┬─────┘     │
└───────┼──────────────┼──────────┘
        │              │
   ┌────▼─────┐  ┌─────▼────┐
   │ Server A │  │ Server B │
   │ (GitHub) │  │ (数据库)  │
   └──────────┘  └──────────┘
  • Host:应用容器。管理所有 Client 实例,控制安全策略,聚合来自多个 Server 的上下文。
  • Client:与单个 Server 保持 1:1 连接。负责协议协商、消息路由、安全隔离。
  • Server:提供具体能力(工具、数据、提示模板)。独立运行,可以是本地子进程也可以是远程服务。

一个关键设计决策:Server 之间互相看不到。Server A 不知道 Server B 的存在,也看不到完整对话。它只接收 Host/Client 显式发给它的内容。这种隔离是刻意的——防止一个被攻破的 Server 影响其他 Server [2]。

三大原语

MCP Server 通过三种原语暴露能力,它们的控制权归属不同:

原语由谁控制作用典型例子
Tools(工具)LLM 决定调用执行操作查数据库、发请求、写文件
Resources(资源)应用/Client 管理提供上下文数据文件内容、git 历史、配置
Prompts(提示模板)用户主动触发预定义交互模板斜杠命令、快捷操作

Tools 是 Agent 场景下最核心的原语。2025 年 3 月的规范更新给 Tools 加了行为注解(annotations),让 Host 可以在执行前判断风险等级 [3]:

json
{
  "name": "delete_record",
  "description": "Delete a record from the database",
  "inputSchema": { ... },
  "annotations": {
    "readOnlyHint": false,
    "destructiveHint": true,
    "idempotentHint": false
  }
}

destructiveHint: true 告诉 Host:这个工具会修改外部状态,调用前最好让用户确认。这不是强制约束——Host 可以忽略这些 hint——但它让分级自主权(第 12 章讲过的 Calibrated Autonomy)有了协议层面的支撑。

Resources 和 Prompts 相对简单。Resources 通过 URI 寻址(如 file:///path/to/docpostgres://db/schema),支持订阅变更通知。Prompts 是给用户用的预定义模板,不是 LLM 自己触发的——想象成 Slack 里的斜杠命令。

MCP 与 Function Calling 的区别

这是最容易混淆的地方。

Function Calling 是 LLM API 提供的结构化工具调用接口。你在请求里定义一组 JSON Schema 描述的函数,模型决定调用哪个、传什么参数,你的应用负责执行。OpenAI、Anthropic、Google 各有自己的格式,但本质一样:模型产出结构化意图,应用执行。

MCP 解决的是 Function Calling 下面一层的问题:这些函数从哪来?怎么发现?怎么安全地跨应用复用?

打个比方:Function Calling 是"嘴巴能说出要吃什么",MCP 是"把菜单标准化,让任何餐厅的菜单都能被任何点餐系统读懂"。

它们是互补关系:LLM 通过 Function Calling 表达"我要调用工具 X",应用通过 MCP 协议去 Server 上执行工具 X。

什么时候只用 Function Calling 就够?工具少(2-3 个)、单应用、不需要跨团队复用。什么时候 MCP 有价值?多工具、多 LLM 供应商、工具需要在不同应用间共享、需要标准化的认证和发现机制。

传输层:stdio 和 Streamable HTTP

MCP 支持两种传输方式(截至 2025-11-25 规范)[4]:

stdio:Client 把 Server 作为子进程启动,通过 stdin/stdout 传递 JSON-RPC 消息。零网络开销,零认证配置。适合本地开发工具集成。限制也很明显——只能本地运行,单用户,单进程。

Streamable HTTP(2025 年 3 月取代了旧的 HTTP+SSE 方案):单个 HTTP 端点同时支持 POST(发消息)和 GET(接收服务端推送)。通过 MCP-Session-Id 头管理会话状态,支持 SSE 断线重连。

两种传输之间的鸿沟比看起来大。有开发者在实践中总结:"从 stdio 切换到 HTTP 的那一刻,你突然要处理 OAuth、token 管理、CORS、TLS、重定向验证、SSRF 防护、速率限制和审计日志" [5]。这不是 MCP 的设计缺陷——任何协议从本地到远程都会遇到这个复杂度跳跃——但它意味着 "写一个 MCP Server" 和 "在生产环境运行一个 MCP Server" 是两件截然不同的事。

OAuth 2.1 授权流

远程 MCP Server 的认证采用 OAuth 2.1(截至 2025-06-18 规范引入)。角色映射很直觉:

  • MCP Server = OAuth Resource Server(持有受保护资源)
  • MCP Client = OAuth Client(代表用户请求访问)
  • Authorization Server = 独立实体(可以跟 Server 共部署,也可以是第三方)

发现流程:Client 发送未认证请求 → Server 返回 401WWW-Authenticate 头 → Client 从中获取 Protected Resource Metadata URL → 解析得到 Authorization Server 地址 → 走标准 OAuth 授权码流程(PKCE 必须用 S256) [6]。

一个值得注意的设计:规范要求 Client 在授权请求和 token 请求中都带上 resource 参数(RFC 8707),绑定到具体的 MCP Server。这意味着 token 是对特定 Server 签发的,不能拿一个 Server 的 token 去访问另一个——防止 token 被透传到上游 API。

生产环境的难点不在于协议本身,而在于:

  • 动态客户端注册:规范支持三种方式(预注册、Client ID Metadata Documents、RFC 7591 动态注册),不同 Server 支持不同方式
  • Token 生命周期管理:短 token、刷新、scope 升级(Server 返回 403 insufficient_scope 时 Client 要发起 re-authorization)
  • 跨组织场景:你的 Agent 要访问另一个组织的 MCP Server,谁来做身份联邦?

动手实战:一个最小 MCP Server

下面用 Python 实现一个查询 SQLite 数据库的 MCP Server。选 stdio 传输——先跑通核心逻辑,不引入 HTTP 的复杂度。

python
# db_server.py
# 依赖:pip install mcp[cli] aiosqlite
import sqlite3
import json
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent

server = Server("sqlite-query")

DB_PATH = "example.db"

def init_db():
    """创建示例数据库"""
    conn = sqlite3.connect(DB_PATH)
    conn.execute("""
        CREATE TABLE IF NOT EXISTS products (
            id INTEGER PRIMARY KEY,
            name TEXT NOT NULL,
            price REAL NOT NULL,
            stock INTEGER NOT NULL
        )
    """)
    conn.execute("DELETE FROM products")
    conn.executemany(
        "INSERT INTO products (name, price, stock) VALUES (?, ?, ?)",
        [("Widget A", 29.99, 150), ("Widget B", 49.99, 80), ("Widget C", 9.99, 500)],
    )
    conn.commit()
    conn.close()

@server.list_tools()
async def list_tools():
    return [
        Tool(
            name="query_products",
            description="Query the products table with fixed, read-only filters. "
                        "Returns matching rows as JSON.",
            inputSchema={
                "type": "object",
                "properties": {
                    "max_stock": {
                        "type": "integer",
                        "description": "Return products whose stock is less than or equal to this value.",
                    },
                    "limit": {
                        "type": "integer",
                        "description": "Maximum number of rows to return. Default 20, max 100.",
                        "default": 20,
                    }
                },
                "required": ["max_stock"],
            },
        )
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict):
    if name != "query_products":
        raise ValueError(f"Unknown tool: {name}")

    max_stock = int(arguments["max_stock"])
    limit = min(int(arguments.get("limit", 20)), 100)

    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    try:
        rows = conn.execute(
            """
            SELECT id, name, price, stock
            FROM products
            WHERE stock <= ?
            ORDER BY stock ASC, id ASC
            LIMIT ?
            """,
            (max_stock, limit),
        ).fetchall()
        result = [dict(row) for row in rows]
        return [TextContent(type="text", text=json.dumps(result, indent=2))]
    except sqlite3.Error as e:
        return [TextContent(type="text", text=f"SQL Error: {e}")]
    finally:
        conn.close()

async def main():
    init_db()
    async with stdio_server() as (read, write):
        await server.run(read, write, server.create_initialization_options())

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

在 Claude Desktop 的配置文件(claude_desktop_config.json)中注册:

json
{
  "mcpServers": {
    "sqlite-query": {
      "command": "python",
      "args": ["db_server.py"],
      "cwd": "/path/to/your/project"
    }
  }
}

重启 Claude Desktop 后,你可以直接对话:"帮我查一下库存低于 100 的产品"。Claude 会调用 query_products(max_stock=100),Server 在内部执行固定的参数化查询,拿到结果后自然语言回答。

这个例子刻意做了简化:只暴露 products 表、查询模板写死、没有连接池。这样做的目的,是示范一个更安全的 MCP Server 基线:让模型填写结构化参数,而不是让模型直接写 SQL。生产环境要加的东西还有很多,但核心交互模式就是这样:Server 暴露受限工具 → Client 连接 → LLM 决定调用 → 结果返回上下文。

社区真实反馈

MCP 在社区的评价呈现两极分化。

看好的声音:开发者普遍认可 "LSP for LLMs" 的定位。OpenAI 在 2025 年 3 月宣布支持 MCP——在此之前它有自己的方案——被社区视为协议获得实质性认可的信号。截至 2026 年 3 月,MCP SDK 的月下载量约 9,700 万次,相比 2024 年 11 月发布时的约 10 万次/月,增长了近三个数量级 [7]。

批评的声音也很具体:

HN 上有开发者在读了一小时文档后说:"I still don't understand how and why I'd use this"——协议早期的文档确实对 "context" 这个核心概念缺乏清晰定义 [1]。

也有人质疑 MCP 是否比 OpenAPI 多提供了什么。社区的基本共识是:MCP 的价值不在协议机制本身(JSON-RPC 谁都能写),而在那个 "opinionated contract"——类似 LSP,不是因为协议本身有多精妙,而是因为大家都同意用它 [1]。

安全问题是最集中的批评方向。Astrix Research 在 2025 年分析了 5,200 多个开源 MCP Server,发现 88% 需要凭证但 53% 使用不安全的长期静态密钥,只有 8.5% 使用 OAuth [8]。学术研究发现 43% 的被测 MCP 实现存在命令注入漏洞 [9]。甚至 Anthropic 自己的 MCP Inspector 工具也被发现有未认证远程代码执行漏洞。

生产部署现实:Clutch Security 的调研显示,86% 的 MCP Server 跑在开发者本地机器上,只有 5% 在真正的生产环境中 [10]。这不代表 MCP 不能用于生产——而是说协议还很年轻,大部分使用场景还停留在开发阶段。

MCP 的边界

什么是 MCP 的稳定主干?三大原语(Tools、Resources、Prompts)、Client-Server 交互模型、capability 协商机制。这些在过去四个版本中保持了结构稳定。

什么是易变部分?传输层细节(HTTP+SSE → Streamable HTTP 的切换发生在协议发布仅 5 个月后)、授权机制(从 "TODO" 到 OAuth 2.1 经历了两个版本)、Tasks 原语(2025-11-25 引入,仍标记为实验性)。

如果你现在开始集成 MCP,建议:稳定主干可以放心依赖,易变部分在每次升级时回规范文档核验。

14.2 A2A(Agent-to-Agent Protocol)—— Agent 间通信的标准

核心直觉

如果 MCP 是 USB-C(连接设备和外设),A2A 就是互联网协议(让设备之间对话)。

MCP 解决 "Agent 怎么用工具",A2A 解决 "Agent 怎么跟另一个 Agent 协作"。这两个问题看起来可以用同一个协议解决("把 Agent 包装成工具不就行了?"),但实际场景中它们有本质区别:工具调用是透明的——调用方知道工具的完整 schema;Agent 协作是不透明的——你只知道对方能做什么任务,不需要也不应该知道对方内部用了什么模型、什么工具、什么 prompt。

A2A 由 Google 在 2025 年 4 月发起,2025 年 6 月捐赠给 Linux Foundation,2026 年 3 月发布 v1.0.0 稳定版 [11]。

核心抽象

A2A 的设计围绕三个核心概念:

Agent Card:能力声明

每个 A2A Server 在 /.well-known/agent-card.json 发布一个 JSON 文档,描述自己是谁、能做什么、怎么认证。早期草案里这个路径曾写作 agent.json,但当前稳定规范已经统一到 agent-card.json

json
{
  "name": "Supplier Order Agent",
  "description": "Handles purchase orders for office supplies",
  "url": "https://supplier.example.com/a2a",
  "skills": [
    {
      "id": "create-po",
      "name": "Create Purchase Order",
      "description": "Creates a new purchase order given item list and quantities"
    }
  ],
  "securitySchemes": {
    "oauth2": {
      "type": "oauth2",
      "flows": {
        "clientCredentials": {
          "tokenUrl": "https://auth.supplier.example.com/token",
          "scopes": { "orders:write": "Create purchase orders" }
        }
      }
    }
  },
  "security": [{ "oauth2": ["orders:write"] }]
}

Agent Card 的作用类似于 API 的 OpenAPI 文档,但粒度更粗——它描述的是"技能"(skills),不是具体的函数签名。调用方只知道"这个 Agent 能创建采购订单",不知道它内部查了几个数据库、调了几个 MCP 工具。

v1.0 新增了签名 Agent Card——用密码学签名防止 Agent Card 被伪造或篡改 [12]。

任务生命周期

A2A 的通信单元是 Task(任务),有明确的状态机:

任务可以产出 Artifacts(产物)——这是任务的可交付结果。一个研究任务的 Artifact 可能是一份报告;一个代码生成任务的 Artifact 可能是一个 patch 文件。

两种通信方式

  • SendMessage:JSON-RPC binding 下的同步方法。发消息,等任务完成(或进入中断状态)后返回。也支持 return_immediately: true 模式——发完立即返回任务 ID,后续通过 GetTask 轮询。
  • SendStreamingMessage:JSON-RPC binding 下的流式方法。建立 SSE 流,实时接收任务状态更新和 Artifact 产出。

底层传输是 JSON-RPC 2.0 over HTTP(S)。如果你看的是 HTTP+JSON/REST 或 gRPC binding,会看到不同的路径或方法名;这里为了避免混淆,统一按当前 JSON-RPC binding 的命名来讲。

A2A 与 MCP 的关系

官方定位:互补,不竞争

MCPA2A
连接对象Agent ↔ 工具/数据Agent ↔ Agent
透明度调用方看到工具的完整 schema调用方只看到对方的技能描述
通信模式工具调用(请求-响应)任务委托(可能多轮、长时间运行)
状态模型无状态(每次调用独立)有状态(任务有生命周期)

一个典型的协作场景:

库存 Agent 用 MCP 查自己的数据库,用 A2A 委托供应商 Agent 下单。供应商 Agent 内部又用 MCP 连接 ERP 系统。两个 Agent 不需要知道彼此的内部实现。

有开发者在 HN 上问:"为什么不能把 Agent 包装成 MCP Tool?" Google A2A 团队的回应是:MCP 要求暴露工具的完整 schema 和内部能力,而 Agent 间协作的核心前提恰好是不暴露——"Customers are building individual agents in different frameworks OR purchasing agents from multiple vendors. Those agents are isolated and do not share tools, or memory, or context" [13]。

这个区别在跨组织场景下尤其重要。你不会把自己公司的内部数据库 schema 暴露给合作伙伴的 Agent——你只告诉它"我能处理采购订单",具体怎么处理是我的事。

认证与安全

A2A 的认证声明在 Agent Card 中,执行在 HTTP 传输层。支持的认证方式与 OpenAPI 对齐:API Key、HTTP Bearer、OAuth 2.0、OpenID Connect、Mutual TLS [12]。

但安全工程师 Semgrep 团队的分析指出了几个结构性问题 [14]:

  • Agent Card 签名在 v1.0 中是支持但不强制的——实现可以选择不验证签名
  • OAuth 没有强制短 token 生命周期、细粒度 scope 或用户同意机制
  • 多个并发流之间没有强制终止机制——存在 session 劫持风险
  • 最根本的问题:Agent 的"用户"是另一个 LLM,攻击者可以针对 A2A 端点构造 prompt injection

Simon Willison(SQLite/Datasette 作者)对此有一个广被引用的观点:这类协议的设计模式鼓励给 LLM 访问特权工具的同时暴露它们于不可信的外部内容——这从结构上制造了 prompt injection 的攻击面 [14]。

社区真实反馈

A2A 在社区的接受度比 MCP 更分化。

质疑的声音比较集中。HN 上的主讨论帖(217 条评论)里,一位开发者说:"It's frustratingly difficult to see what these protocols actually look like. All I want is a simple example conversation..." [13]。Simon Willison 更直接:"I still don't see much value in LLMs calling other LLMs"——LLM 本身已经不够可靠,让它们之间互相调用是在叠加不可靠性 [13]。

也有人看到协议发布时背书的企业名单(KPMG、Accenture、BCG)后说:这些"legit the last people I would trust with software development" [13]。

还有一种常见批评:这不就是 SOA 和 WSDL 的 LLM 版?

但也有务实的声音。Google A2A 团队成员在 HN 上解释了核心场景:企业在不同框架中构建了独立的 Agent,或者从多个供应商购买了 Agent,这些 Agent 天然是隔离的——A2A 让它们在不暴露内部的前提下协作 [13]。

2025 年 9 月的低谷与后续反弹。有分析文章在 2025 年 9 月写道:"A2A had quietly faded into the background while MCP became the de facto standard" [15]。但这个判断是在 v1.0 发布(2026 年 3 月)和 150+ 组织采纳公告(2026 年 4 月)之前做出的。截至写作时(2026.04),A2A GitHub 仓库有 23,400+ star,5 种语言的官方 SDK,LangGraph、CrewAI、Google ADK 等主流框架已原生支持 [11]。

OpenAI 的态度是一个有意思的信号。2025 年 10 月,一位社区贡献者提交了一个 1,200 行代码、30 个测试、完整文档的 A2A 支持 PR,被 OpenAI 拒绝了。社区普遍将此解读为竞争策略——OpenAI 已经采纳了 MCP,而 A2A 由 Google 发起 [16]。截至写作时,OpenAI Agents SDK 仍未原生支持 A2A。

14.3 相关协议与历史脉络

MCP 和 A2A 不是凭空出现的。理解它们的定位,需要知道这个领域还有哪些尝试。

ACP(Agent Communication Protocol)

IBM 在 2025 年 3 月发布的协议,属于 BeeAI 开源项目。设计哲学是本地优先、开发者友好——纯 REST/HTTP,不需要 JSON-RPC,用 cURL 就能调。

ACP 的特点是简单到极致:没有 SDK 也能用。但它缺乏 A2A 的企业级支持和生态广度。2025 年 8 月,IBM 决定将 ACP 合并进 A2A,在 Linux Foundation AI & Data 下统一发展。ACP 团队的声明说:"When A2A came on the scene a month later, the teams immediately saw alignment and began exploring how to bring the efforts together" [17]。

ANP、AGORA 等

社区还有 ANP(Agent Network Protocol)、AGORA 等协议提案,但截至写作时都没有达到 MCP 或 A2A 的采纳规模。这里不展开——不是因为它们不好,而是在协议标准化中,技术方案和生态支持同等重要,只有技术方案是不够的。

治理汇聚:Agentic AI Foundation

2025 年 12 月,一件重要的事情发生了:Anthropic(MCP 发起者)、Google(A2A 发起者)、OpenAI、Microsoft、AWS、Block 共同成立了 Agentic AI Foundation(AAIF),作为 Linux Foundation 下的专项基金。MCP 和 A2A 都被纳入 AAIF 治理 [18]。

这意味着两件事:一,这两个协议不再是单一公司的项目——它们有了中立的治理主体;二,竞争对手们至少在协议层面达成了合作意愿。当然,"坐在同一张桌子上"和"真正互操作"之间还有很长的路要走。

14.4 协议设计的现实问题

协议规范是理想化的。一旦进入生产环境,下面这些问题会逐个冒出来:

身份与信任

本地 stdio 模式下不需要认证——Server 就是你自己启动的进程。但跨网络、跨组织场景下,你要回答:

  • 谁来颁发和验证 Agent 的身份?
  • 一个 Agent 声称自己"能处理采购订单",你凭什么信它?
  • Agent Card 的签名验证是可选的(A2A v1.0),那不验证的实现怎么防伪造?

MCP 的 OAuth 2.1 方案解决了"用户通过 Agent 访问 Server"的认证,但没有解决"Agent 自己的身份认证"。A2A 的 Agent Card 签名机制是一个方向,但目前是可选的。

长任务与异步

Agent 任务可能跑几分钟甚至几小时。A2A 的 Task 状态机和 SendStreamingMessage 原生支持这种场景。MCP 在 2025-11-25 版本引入了实验性的 Tasks 原语,但还不成熟——重试语义和结果过期策略仍在讨论中 [19]。

生产中最常见的问题是:连接断了怎么办?Streamable HTTP 支持带 Last-Event-ID 的 SSE 重连,但前提是 Server 实现了事件持久化。很多早期 Server 没有实现这一点。

权限边界

MCP Server 的工具可能有不同的权限等级。规范提供了 annotations(如 destructiveHint)来声明,但执行权限的判断和授权留给了 Host。这意味着:

  • 不同 Host 对同一个 destructiveHint: true 的工具可能有完全不同的处理策略
  • 没有协议级别的"这个工具需要 admin 权限"声明
  • 审计日志格式也没有标准化

这些问题不是协议应该解决的(协议定义最小公约数,不规定所有实现细节),但工程上你必须自己补齐。第 20 章会展开讨论权限治理和审计体系。

跨组织互联

当你的 Agent 要通过 A2A 调用另一个组织的 Agent,信任链变得复杂:

  • 身份联邦:你们用不同的 IdP,怎么互认?
  • 数据隔离:任务执行中产生的中间数据谁能看、谁负责清理?
  • 责任归属:Agent B 执行了 Agent A 委托的任务,出了事谁负责?
  • 合规:跨境数据传输、GDPR 数据处理协议

这些问题超出了协议规范的范围,但如果你在做企业级 Agent 系统,它们会比协议选型更早成为瓶颈。

14.5 协议选型:什么时候用什么

不要把协议选型搞复杂。大多数场景下的决策很简单:

几个具体的判断:

只用 MCP 的场景(最常见):你的 Agent 需要连数据库、调 API、读文件系统。所有工具都在你的控制范围内。一个 Agent,多个工具。

MCP + A2A 的场景:你的系统涉及多个独立 Agent,它们由不同团队甚至不同组织维护。每个 Agent 内部用 MCP 连自己的工具,Agent 之间用 A2A 通信。

都不需要的场景:你的 Agent 只用 2-3 个工具,单应用,不需要跨团队复用。直接用 Function Calling + 手写执行逻辑,比引入协议层更简单。

一个务实的建议:如果你在犹豫要不要引入 MCP,先问自己一个问题——"这些工具会被其他应用复用吗?" 如果答案是 "不会" 或 "不确定",先用 Function Calling 手写,等确实需要复用时再迁移到 MCP。协议的价值在规模效应,单点使用时它只增加复杂度。

14.6 不要把生态动态误写成协议事实

这一节是给自己(和所有写 Agent 技术内容的人)的提醒。

在读 MCP 和 A2A 相关材料时,四种内容经常被混为一谈:

类别例子怎么区分
协议事实"MCP 用 JSON-RPC 通信"在规范文档里能找到
SDK 事实"Python SDK 支持自动重连"在 SDK 代码/文档里能找到,但不是协议要求
产品能力"Claude Desktop 支持 MCP"是某个产品的功能,不是协议本身
社区约定"大家都把 Agent Card 放在 /.well-known/ 下"社区惯例,可能但不一定写进了规范

一个常见的错误:"MCP 支持自动发现 Server"——实际上协议本身到 2025-11-25 版本都没有标准化 Server 发现机制,这是 2026 年路线图中的 .well-known metadata 方案,还在推进中。目前的"发现"靠的是 Host 配置文件(如 Claude Desktop 的 claude_desktop_config.json)。

另一个常见错误:把某个框架实现的 Guardrails 绑定方式当成协议定义。比如 OpenAI Agents SDK 把 Input Guardrails 绑到入口 Agent——这是框架的实现选择,不是 MCP 或 A2A 协议的要求。


面试高频题

问:MCP 和 A2A 分别解决什么问题?在一个完整的 Multi-Agent 系统中它们如何协作?

参考答案框架:

  1. 分层回答:MCP 解决 Agent ↔ 工具/数据的连接(垂直集成),A2A 解决 Agent ↔ Agent 的通信(水平协作)。它们工作在不同层次,互补而非替代。

  2. 协作场景:举一个具体例子。比如电商系统——订单 Agent 用 MCP 连接订单数据库和支付 API,当需要物流追踪时通过 A2A 委托物流 Agent(由第三方物流公司维护)。物流 Agent 内部用 MCP 连接自己的追踪系统,但订单 Agent 看不到这些内部细节。

  3. 关键区别:MCP 是透明的(调用方看到完整工具 schema),A2A 是不透明的(只看到技能描述)。这种不透明性在跨组织场景下是必要的——你不会把内部系统的 API schema 暴露给合作伙伴。

加分点:

  • 提到不是所有场景都需要协议——工具少、单应用时 Function Calling 就够了
  • 提到 AAIF 治理结构:两个协议现在由同一个 Linux Foundation 基金管理,背后有 Anthropic、Google、OpenAI、Microsoft 等联合支持
  • 提到 A2A 的 Task 状态机对长任务的原生支持,对比 MCP 的 Tasks 原语还在实验阶段
  • 指出协议事实 vs SDK 实现 vs 产品能力的区分——面试时展现这种分辨力比背诵协议细节更有价值

问:为什么说"协议边界"比"生态口号"更值得理解?

参考答案思路:

协议定义的是最小公约数——所有实现必须遵守的规则。生态口号("一个协议连接所有工具"、"Agent 互操作的未来")描述的是愿景,不是现实。

理解协议边界意味着知道:

  • MCP 规范里没有 Server 发现机制(截至写作时),所以别指望"自动发现所有可用工具"
  • A2A Agent Card 签名是可选的,所以跨组织场景下你需要自己验证对方身份
  • OAuth 2.1 授权解决了用户委托访问,但没有解决 Agent 自身的身份认证
  • Tool annotations 是 hint 不是约束,Host 可以忽略它们

知道这些边界,你才能在系统设计中补上缺失的部分(认证、审计、权限),而不是假设协议已经帮你搞定了。


参考资料

[1] HN 上 MCP 发布讨论 - Hacker News (https://news.ycombinator.com/item?id=42237424)

[2] MCP Architecture - Model Context Protocol Specification (https://modelcontextprotocol.io/specification/2025-11-25/architecture)

[3] MCP Specification Changelog - 2025-03-26 版本 Tool Annotations (https://modelcontextprotocol.io/specification/2025-11-25/changelog)

[4] MCP Transports Specification (https://modelcontextprotocol.io/specification/2025-11-25/basic/transports)

[5] MCP Server Production Security Challenges - Lenses.io (https://lenses.io/blog/mcp-server-production-security-challenges)

[6] MCP Authorization Specification (https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization)

[7] MCP Adoption Statistics 2026 - MCP Manager (https://mcpmanager.ai/blog/mcp-adoption-statistics/)

[8] State of MCP Server Security 2025 - Astrix Research (https://astrix.security/learn/blog/state-of-mcp-server-security-2025/)

[9] MCP 实现安全分析 - arXiv (https://arxiv.org/html/2506.13538v1)

[10] MCP 部署分布数据 - Clutch Security(转引自 Scalifiai: https://www.scalifiai.com/blog/model-context-protocol-flaws-2025)

[11] A2A Protocol Surpasses 150 Organizations - PR Newswire (https://www.prnewswire.com/news-releases/a2a-protocol-surpasses-150-organizations-lands-in-major-cloud-platforms-and-sees-enterprise-production-use-in-first-year-302737641.html)

[12] A2A Protocol Specification v1.0 (https://a2a-protocol.org/latest/specification/)

[13] HN 上 A2A 发布讨论 - Hacker News (https://news.ycombinator.com/item?id=43631381)

[14] A Security Engineer's Guide to the A2A Protocol - Semgrep (https://semgrep.dev/blog/2025/a-security-engineers-guide-to-the-a2a-protocol/)

[15] What Happened to Google's A2A? - fka.dev (https://blog.fka.dev/blog/2025-09-11-what-happened-to-googles-a2a/)

[16] OpenAI Rejects A2A PR - Hacker News (https://news.ycombinator.com/item?id=45766384)

[17] ACP Joins Forces with A2A - LF AI & Data Foundation (https://lfaidata.foundation/communityblog/2025/08/29/acp-joins-forces-with-a2a-under-the-linux-foundations-lf-ai-data/)

[18] Agentic AI Foundation 成立 - Blocks and Files (https://blocksandfiles.com/2025/12/11/a2a-aaif-ai-agents/)

[19] 2026 MCP Roadmap - MCP Blog (https://blog.modelcontextprotocol.io/posts/2026-mcp-roadmap/)