第 42 章

协议生态全景:MCP vs A2A vs OpenAPI

第42章 协议生态全景:MCP vs A2A vs OpenAPI

导语

2025-2026年,AI Agent 协议领域迎来了一场"寒武纪爆发"。Anthropic 推出 MCP(Model Context Protocol),Google 提出 A2A(Agent-to-Agent Protocol),而 OpenAPI 则以数十年的历史积淀成为 REST 服务的事实标准。三协议并存不是混乱,而是各有其生态位。理解它们的本质差异,是构建可持续 AI 系统的基础能力。

本章将从协议设计哲学出发,梳理三协议的定位差异,给出具体场景的选型指导,并预测 2026 年的协议生态走向。


42.1 三协议的本质定位

一句话定义

协议 一句话定位 设计者 诞生年份
MCP AI 模型访问工具和资源的标准通道 Anthropic 2024
A2A AI Agent 之间协作委托的通信协议 Google DeepMind 2025
OpenAPI 人类开发者和程序调用 REST API 的描述规范 OpenAPI Initiative 2015(前身 Swagger 2011)

协议层次模型

┌─────────────────────────────────────────────────────────────┐
│                     应用层(业务逻辑)                         │
└────────────┬─────────────────┬──────────────────────────────┘
             │                 │
    ┌────────▼───────┐ ┌───────▼────────┐
    │   A2A Protocol │ │  MCP Protocol  │
    │  (Agent ↔ Agent│ │  (Model ↔ Tool)│
    └────────┬───────┘ └───────┬────────┘
             │                 │
    ┌────────▼─────────────────▼────────┐
    │          HTTP / WebSocket          │
    │        (OpenAPI 描述的接口)         │
    └───────────────────────────────────┘
             │
    ┌────────▼───────────────────────────┐
    │    TCP / TLS(传输层)              │
    └────────────────────────────────────┘

关键洞察:OpenAPI 不是 MCP/A2A 的竞争者,而是它们的底层基础设施描述语言。MCP 和 A2A 在语义层面竞争,OpenAPI 在接口描述层面通吃。


42.2 三协议深度对比

全维度对比表

维度 MCP A2A OpenAPI
通信模型 Client-Server(Model 是 Client) Peer-to-Peer(Agent 平等) Client-Server(人/程序 是 Client)
消息格式 JSON-RPC 2.0 JSON-LD + 自定义扩展 RESTful JSON / YAML 描述
传输协议 stdio / HTTP SSE HTTP/2 / WebSocket HTTP 1.1 / 2.0
状态管理 无状态(每次调用独立) 有状态(任务生命周期管理) 无状态(REST 原则)
流式支持 SSE(单向流) WebSocket(双向流) 需自行实现 SSE/WebSocket
认证机制 继承 HTTP 认证 OAuth 2.0 / DID 去中心化身份 API Key / OAuth 2.0 / JWT
工具发现 tools/list 动态发现 Agent Card(JSON-LD 描述) OpenAPI Spec(YAML/JSON)
错误处理 JSON-RPC 标准错误码 任务状态机(pending/running/failed) HTTP 状态码
生态成熟度 快速增长(2024-) 早期(2025-) 极成熟(2011-)
主要客户端 Claude Code / Cursor / Zed Google Agent Space / 自研 任何 HTTP 客户端
Hermes 集成 原生支持(hermes-agent 内置) 实验性支持 需手动封装

设计哲学差异

MCP 的哲学:工具访问的标准化

MCP 的核心假设是:AI 模型需要一个安全、标准化的方式来访问外部工具和数据源。它把"工具调用"这个 AI 特有的需求抽象成了协议层,而不是让每个 AI 厂商各自实现。

MCP 的思维模型是插头与插座:工具(MCP Server)是插座,AI 模型(MCP Client)是插头,协议定义了接口规格。

┌─────────────────────────────────────────────────────┐
│  MCP 思维模型:工具访问标准化                         │
│                                                     │
│  Model ──────── MCP ──────── Tool                   │
│  (智能体)      (协议)      (文件/数据库/API)          │
│                                                     │
│  关注点:工具如何被发现、调用、返回结果                  │
└─────────────────────────────────────────────────────┘

A2A 的哲学:Agent 协作的编排

A2A 的核心假设是:复杂任务需要多个专业 Agent 协作完成。它把"任务委托"这个多 Agent 系统特有的需求抽象成了协议层,引入了任务状态机、Agent 能力描述(Agent Card)等概念。

A2A 的思维模型是企业组织架构:有老板(Orchestrator Agent),有员工(Worker Agent),有工作委托(Task),有汇报(Result)。

┌─────────────────────────────────────────────────────┐
│  A2A 思维模型:Agent 协作编排                         │
│                                                     │
│  Agent A ──── A2A ──── Agent B                      │
│  (编排者)    (协议)    (执行者)                       │
│                                                     │
│  关注点:任务如何被拆分、委托、跟踪、汇总                │
└─────────────────────────────────────────────────────┘

OpenAPI 的哲学:接口契约的文档化

OpenAPI 的核心假设是:服务的使用者和提供者需要一份机器可读的接口契约。它不规定通信行为,只描述接口形态——有哪些端点、参数是什么、返回什么格式。


42.3 何时用哪个协议

决策树

你的场景是什么?
│
├─► AI 模型需要访问工具/数据源(文件、数据库、API)?
│     └─► 使用 MCP
│           • 标准场景:Claude/Hermes 调用 filesystem、database
│           • 优势:生态成熟、Claude Code 原生支持
│           • 示例:hermes-agent + filesystem-mcp + database-mcp
│
├─► 多个 AI Agent 需要协作完成复杂任务?
│     └─► 使用 A2A
│           • 标准场景:研究 Agent 委托写作 Agent 委托校对 Agent
│           • 优势:任务状态追踪、Agent 能力动态发现
│           • 示例:Hermes Orchestrator → 专业领域 Agent × N
│
├─► 需要给人类开发者/非 AI 程序提供 API?
│     └─► 使用 OpenAPI
│           • 标准场景:Hermes 的推理能力封装成 REST API
│           • 优势:工具链极成熟(Swagger UI、Postman、SDK 生成)
│           • 示例:FastAPI + Hermes → 对外 REST 接口
│
└─► 混合场景(最常见)?
      └─► 组合使用(见 42.4 互操作性方案)

场景选型矩阵

场景 推荐协议 理由
Claude Code 调用代码分析工具 MCP 原生支持,零配置
Hermes 读取本地文件系统 MCP filesystem-mcp 成熟稳定
多个 Hermes 实例分工协作 A2A 任务委托和状态追踪需要
研究 Agent 委托翻译 Agent A2A Agent 能力发现和选择
企业内部系统集成 Hermes OpenAPI 现有系统都懂 REST
第三方开发者接入 Hermes OpenAPI 文档化、SDK 生成
Hermes 调用 Slack/GitHub MCP(或 OpenAPI 封装) 已有成熟 MCP Server
跨公司 Agent 协作 A2A + DID 认证 去中心化身份验证

42.4 互操作性方案

方案一:MCP + OpenAPI 桥接

最常见的模式:把现有 OpenAPI 服务自动转换为 MCP Server。

# openapi_to_mcp_bridge.py
"""
自动从 OpenAPI Spec 生成 MCP Server。
无需手写每个工具定义。
"""

import httpx
import yaml
import json
from mcp.server import Server
from mcp import types

async def build_mcp_from_openapi(spec_url: str) -> Server:
    """
    从 OpenAPI Spec URL 动态生成 MCP Server。
    """
    # 获取 OpenAPI Spec
    async with httpx.AsyncClient() as client:
        response = await client.get(spec_url)
        spec = yaml.safe_load(response.text)
    
    app = Server(f"openapi-bridge-{spec['info']['title']}")
    tools = []
    
    # 遍历所有 API 端点,转换为 MCP 工具
    for path, path_item in spec.get("paths", {}).items():
        for method, operation in path_item.items():
            if method not in ["get", "post", "put", "patch", "delete"]:
                continue
            
            tool_name = operation.get("operationId", f"{method}_{path.replace('/', '_')}")
            description = operation.get("summary", "") or operation.get("description", "")
            
            # 构建输入 Schema
            input_schema = _build_input_schema(operation, method)
            
            tools.append({
                "name": tool_name,
                "description": description,
                "inputSchema": input_schema,
                "meta": {
                    "path": path,
                    "method": method,
                    "base_url": spec.get("servers", [{}])[0].get("url", "")
                }
            })
    
    @app.list_tools()
    async def list_tools():
        return [
            types.Tool(name=t["name"], description=t["description"], inputSchema=t["inputSchema"])
            for t in tools
        ]
    
    @app.call_tool()
    async def call_tool(name: str, arguments: dict):
        tool_meta = next((t["meta"] for t in tools if t["name"] == name), None)
        if not tool_meta:
            return [types.TextContent(type="text", text=f"Unknown tool: {name}")]
        
        result = await _call_api(tool_meta, arguments)
        return [types.TextContent(type="text", text=json.dumps(result))]
    
    return app


def _build_input_schema(operation: dict, method: str) -> dict:
    """将 OpenAPI operation 转换为 JSON Schema"""
    properties = {}
    required = []
    
    # 路径参数和查询参数
    for param in operation.get("parameters", []):
        prop_name = param["name"]
        properties[prop_name] = {
            "type": param.get("schema", {}).get("type", "string"),
            "description": param.get("description", "")
        }
        if param.get("required", False):
            required.append(prop_name)
    
    # 请求体(POST/PUT/PATCH)
    if method in ["post", "put", "patch"]:
        request_body = operation.get("requestBody", {})
        content = request_body.get("content", {})
        if "application/json" in content:
            body_schema = content["application/json"].get("schema", {})
            for prop_name, prop_schema in body_schema.get("properties", {}).items():
                properties[prop_name] = prop_schema
            required.extend(body_schema.get("required", []))
    
    return {
        "type": "object",
        "properties": properties,
        "required": list(set(required))
    }


async def _call_api(meta: dict, arguments: dict) -> dict:
    """执行实际的 API 调用"""
    url = meta["base_url"] + meta["path"]
    method = meta["method"]
    
    # 替换路径参数
    for key, value in arguments.items():
        url = url.replace(f"{{{key}}}", str(value))
    
    async with httpx.AsyncClient() as client:
        if method == "get":
            response = await client.get(url, params=arguments)
        elif method == "post":
            response = await client.post(url, json=arguments)
        else:
            response = await client.request(method.upper(), url, json=arguments)
        
        return response.json()

方案二:MCP + A2A 协同架构

用户请求
    │
    ▼
Hermes Orchestrator(通过 MCP 接收指令)
    │
    ├─► A2A → 研究 Agent(专门做信息收集)
    ├─► A2A → 写作 Agent(专门做内容生成)
    └─► A2A → 校对 Agent(专门做质量检查)
         │
         ▼
    各 Agent 通过 MCP 调用各自的工具
    (filesystem / database / web-search)

这个架构的关键是:

方案三:A2A Agent Card 自动注册

# a2a_agent_card.py
"""
为 Hermes Agent 生成 A2A Agent Card,
使其能被 A2A 网络中的其他 Agent 发现。
"""

from dataclasses import dataclass, asdict
import json

@dataclass
class AgentCapability:
    name: str
    description: str
    input_schema: dict
    output_schema: dict

@dataclass  
class HermesAgentCard:
    """
    A2A Agent Card 格式。
    发布到 /.well-known/agent.json 供其他 Agent 发现。
    """
    id: str
    name: str
    description: str
    version: str
    capabilities: list[AgentCapability]
    endpoint: str
    auth_methods: list[str]
    
    def to_json_ld(self) -> dict:
        return {
            "@context": "https://schema.a2aprotocol.org/v1",
            "@type": "Agent",
            "id": self.id,
            "name": self.name,
            "description": self.description,
            "version": self.version,
            "endpoint": self.endpoint,
            "capabilities": [asdict(c) for c in self.capabilities],
            "authMethods": self.auth_methods
        }

# 创建 Hermes Agent Card
hermes_card = HermesAgentCard(
    id="https://ai.mycompany.com/agents/hermes-70b",
    name="Hermes Code Analysis Agent",
    description="Deep code analysis, security review, and refactoring suggestions powered by Hermes 4 70B",
    version="1.0.0",
    capabilities=[
        AgentCapability(
            name="analyze_code",
            description="Analyze code for bugs, security issues, and performance problems",
            input_schema={"type": "object", "properties": {"code": {"type": "string"}, "language": {"type": "string"}}},
            output_schema={"type": "object", "properties": {"issues": {"type": "array"}, "score": {"type": "number"}}}
        )
    ],
    endpoint="https://ai.mycompany.com/a2a/hermes",
    auth_methods=["oauth2", "api_key"]
)

print(json.dumps(hermes_card.to_json_ld(), indent=2, ensure_ascii=False))

42.5 2026 年协议生态趋势预测

预测矩阵

趋势 可信度 影响程度 时间线
MCP 成为"工具访问"的 USB-C 标准 已发生
A2A 进入主流,大型 Agent 系统标配 中高 2026 H1
OpenAPI → MCP 自动桥接工具普及 2025 H2
MCP 与 A2A 合并或深度互操作 极高 2026-2027
去中心化 Agent 身份(DID)标准化 低中 2027+
协议安全标准(Agent 签名/审计) 2026

详细分析

MCP 的护城河正在加深

MCP 的优势来自先发优势和 Anthropic 的生态建设。Claude Code、Cursor、Zed 等主流 AI IDE 已原生支持 MCP,这形成了强大的网络效应:工具开发者优先支持 MCP,MCP 用户越多越多工具支持 MCP。

预测:到 2026 年底,MCP Server 数量将超过 10,000 个,成为 AI 工具生态的基础设施。

A2A 将重塑企业 AI 系统架构

企业级 AI 系统的核心痛点不是"模型能力",而是"系统集成"——如何把多个 AI 服务协调成一个可靠的工作流。A2A 精准击中了这个痛点,它提供了:

预测:2026 年,超过 50% 的新建企业 AI 系统将采用 A2A 作为 Agent 间通信协议

OpenAPI 的韧性与转型

OpenAPI 不会消亡,但会发生角色转变:从"主要接口标准"转变为"AI 协议的底层描述语言"。越来越多的 OpenAPI 服务会自动生成对应的 MCP Server,这让 OpenAPI 焕发新生。

融合趋势:MCP-A2A 互操作

最可能的未来不是三协议中某一个"赢家通吃",而是出现跨协议互操作层:

Unified Agent Protocol Layer(假想)
    ├── MCP 工具访问接口
    ├── A2A 任务委托接口
    └── OpenAPI REST 接口

Anthropic 和 Google 都有动力推动这种融合,因为孤岛式的协议生态对所有人都有害。


42.6 选型决策树(完整版)

开始:你在构建什么?
│
├─► AI 模型的工具访问接口
│   │
│   ├─► 工具需要跨会话状态?
│   │   ├─► 是 → 考虑 A2A(有状态任务)
│   │   └─► 否 → MCP(无状态工具调用)
│   │
│   ├─► 工具的消费者是 Claude Code / Cursor?
│   │   └─► MCP(原生支持,零额外配置)
│   │
│   └─► 工具已有 OpenAPI 文档?
│       └─► OpenAPI → MCP 桥接(自动转换)
│
├─► 多 Agent 协作系统
│   │
│   ├─► 同一组织内部?
│   │   ├─► 小规模(<10 Agents)→ MCP 就够了
│   │   └─► 大规模(>10 Agents)→ A2A
│   │
│   ├─► 跨组织协作?
│   │   └─► A2A + DID 认证(必选)
│   │
│   └─► 需要任务状态追踪、失败重试?
│       └─► A2A(任务状态机)
│
└─► 传统系统/人类开发者集成
    │
    ├─► 消费者是非 AI 程序(移动 App、Web 前端)?
    │   └─► OpenAPI(REST API)
    │
    ├─► 需要生成 SDK / 文档站?
    │   └─► OpenAPI(工具链最成熟)
    │
    └─► 需要与已有 REST API 集成?
        └─► OpenAPI(直接复用已有文档)

本章小结

三协议的本质是三个不同维度的标准化:

协议 标准化的是 核心抽象
MCP AI 模型访问工具的方式 Tool / Resource
A2A AI Agent 之间委托任务的方式 Task / Agent Card
OpenAPI 服务接口的描述方式 Endpoint / Schema

它们不是竞争关系,而是互补的协议栈。成熟的 AI 系统往往三者并用:OpenAPI 描述底层服务,MCP 让 AI 访问这些服务,A2A 协调多个 AI Agent 的协作。

2026 年的预测关键词:MCP 普及化、A2A 企业化、协议融合

思考题

  1. 如果你要把 Hermes Agent 接入一个已有 50 个 REST API 的遗留系统,你会优先选择哪条路径?批量生成 MCP Server,还是部署 OpenAPI-to-MCP 桥接器?各有什么权衡?

  2. A2A 引入了"Agent 身份"(通过 DID),MCP 目前依赖 HTTP 认证。当一个 Hermes Agent 需要向另一个组织的 Agent 证明自己的身份时,应该用哪个协议的认证机制?为什么?

  3. 假设 MCP 和 A2A 最终合并成一个协议,你认为合并后的协议应该保留哪些特性?哪些是可以舍弃的?

本章评分
4.7  / 5  (3 评分)

💬 留言讨论