A2A Protocol
A2A MCP 集成

仓库地址:A2A MCP

本仓库演示了如何设置和使用 a2a-python SDK 来创建一个简单的服务器和客户端实现 a2a 协议,其中代理服务器由 mcp 实现。

概述

  • A2A (Agent-to-Agent): 用于构建可互操作 AI 代理的协议和 SDK。
  • 本示例: 展示如何运行基本的 A2A 服务器和客户端,交换消息并查看响应。

前置条件

  • Python 3.13+
  • uv(用于快速依赖管理和运行)
  • OpenRouter 的 API 密钥(设置为 OPENROUTER_API_KEY

安装

  1. 克隆仓库:

    git clone https://github.com/sing1ee/a2a-mcp-openrouter
    cd https://github.com/sing1ee/a2a-mcp-openrouter
    
  2. 安装依赖:

    uv venv
    source .venv/bin/activate
    uv sync
    
  3. 设置环境变量:

    export OPENROUTER_API_KEY=your-openrouter-api-key
    

    或创建一个 .env 文件:

    OPENROUTER_API_KEY=your-openrouter-api-key
    

    注意: 您可以从 https://openrouter.ai/ 获取您的 OpenRouter API 密钥

运行示例

1. 启动服务器

uv run --env-file .env a2a-server
  • 服务器将在端口 9999 上启动。

验证代理卡片:

2. 运行客户端

在新终端中:

uv venv
source .venv/bin/activate

uv run --env-file .env a2a-client --question "What is A2A protocol?"
  • 客户端将连接到服务器并发送请求。

3. 查看响应

  • 客户端的响应将保存到 response.xml。

配置

系统使用以下配置:

  • 模型: 通过 OpenRouter 使用 google/gemini-flash-1.5
  • 基础 URL: https://openrouter.ai/api/v1

文件结构

  • src/a2a_mcp_openrouter/server/:服务器实现。
  • src/a2a_mcp_openrouter/client/:客户端实现。
  • response.xml:客户端的示例响应。

故障排除

  • 缺少依赖: 确保您已安装 uv
  • API 密钥错误: 确保 OPENROUTER_API_KEY 设置正确。
  • 端口冲突: 确保端口 9999 空闲。

A2A vs MCP:协议相似性和统一方法

通过这个实现,我们发现 A2A (Agent-to-Agent)MCP (Model Context Protocol) 具有显著的架构相似性。两个协议都遵循类似的发现、能力交换和执行模式。

统一实现模式

关键发现:A2A 和 MCP 都遵循相同的底层实现模式:

  • 基于 HTTP 的通信:两者都使用 HTTP 进行通信(A2A 使用 REST API,MCP 使用服务器发送事件)
  • 提示驱动设计:两者都依赖 LLM 提示来决定调用什么以及如何调用
  • 发现机制:两者都提供发现可用能力的方法
  • 结构化响应:两者都返回可以程序化处理的结构化数据

查看 mcp.py 实现,我们可以看到:

# 通过 HTTP 进行 MCP 工具发现
async with sse_client(url) as (read, write):
    resources = await session.list_tools()
    
# 为 LLM 决策生成提示
return template.render(tools=resources.tools)

# 通过 HTTP 执行工具调用
return await session.call_tool(tool_name, arguments=arguments)

这在概念上与 A2A 代理调用模式相同 - 发现能力,使用 LLM 决定调用什么,然后执行调用。

A2A 作为通用接口

关键洞察:A2A 可以作为代理间通信和工具调用的统一接口,因为调用模式本质上是相同的:

  1. A2A → 代理客户端 → HTTP → 代理 → LLM 响应
  2. A2A → 工具客户端 → HTTP → 工具包装器 → MCP 工具响应

两种模式都使用:

  • HTTP 通信
  • 能力发现
  • LLM 驱动的决策制定
  • 结构化请求/响应格式

这种统一方法的好处

  • 单一接口:客户端只需要理解一种调用模式
  • 互操作性:在同一工作流中无缝混合代理和工具
  • 一致的架构:不同能力类型使用相同的实现模式
  • LLM 原生设计:两者都利用 LLM 推理进行智能能力选择

这表明 A2A 和 MCP 不是竞争协议,而是可以在单一接口范式下统一的互补模式。

系统架构和流程

下面是详细的序列图,显示了从客户端输入到最终响应的 A2A 协议的完整流程:

sequenceDiagram
    participant User
    participant Client as A2A Client
    participant LLM_Client as OpenRouter LLM (Client)
    participant Server as A2A Server
    participant AgentExecutor as Agent Executor
    participant Agent as Server Agent
    participant LLM_Server as OpenRouter LLM (Server)
    participant MCP as MCP Tool

    User->>Client: 输入问题:"What is A2A protocol?"
    
    Note over Client: 使用 agent_urls 初始化代理
    Client->>Server: GET /agent-card - 发现可用代理
    Server-->>Client: 返回具有能力的 AgentCard
    
    Note over Client: 渲染代理提示模板
    Client->>LLM_Client: 发送包含问题和可用代理的决策提示
    LLM_Client-->>Client: 返回包含选定代理的 JSON
    
    loop 对于每个选定的代理
        Client->>Server: POST /send-message-streaming
        
        Server->>AgentExecutor: execute(context, event_queue)
        AgentExecutor->>Agent: stream(query)
        
        Agent->>MCP: 获取可用工具
        MCP-->>Agent: 返回工具定义
        
        Note over Agent: 渲染工具提示模板
        Agent->>LLM_Server: 发送包含问题和工具的决策提示
        LLM_Server-->>Agent: 返回包含选定工具的 JSON
        
        loop 对于每个选定的工具(最大迭代次数)
            Agent->>MCP: 使用参数调用工具
            MCP-->>Agent: 返回工具结果
            
            Note over Agent: 更新 called_tools 历史
            Agent->>LLM_Server: 发送包含工具结果的更新提示
            LLM_Server-->>Agent: 返回下一个工具或最终答案
            
            alt 需要更多工具
                Note over Agent: 继续下一次迭代
            else 任务完成
                Note over Agent: 任务已完成
            end
        end
        
        Agent-->>AgentExecutor: 产生流式事件
        AgentExecutor-->>Server: 将事件转发到 event_queue
        Server-->>Client: 通过 HTTP 流式传输响应块
        
        Client->>Client: 从响应标签中提取答案
        Note over Client: 添加到 agent_answers 列表
    end
    
    alt 需要最终合成
        Client->>LLM_Client: 发送包含所有答案的合成提示
        LLM_Client-->>Client: 返回最终合成答案
    else 不需要合成
        Note over Client: 使用现有答案
    end
    
    Client-->>User: 流式传输包含代理输出的最终响应

关键特性

  • 代理发现:通过 A2A 协议自动发现可用代理
  • LLM 驱动选择:使用 LLM 推理进行智能代理和工具选择
  • MCP 集成:与 MCP 工具无缝集成以进行知识检索
  • 流式管道:整个管道的实时流式响应
  • 迭代处理:具有维护上下文的多迭代工具调用

流程描述

系统遵循以下主要阶段:

客户端阶段:用户输入问题 → 客户端发现代理 → LLM 选择相关代理

服务器阶段:服务器接收请求 → 代理发现工具 → LLM 选择工具 → 工具迭代执行

响应阶段:结果通过管道流回 → 客户端合成最终答案 → 用户接收响应

这种架构展示了 A2A 协议在创建可互操作的 AI 代理方面的强大功能,这些代理可以相互发现并协作,同时利用 MCP 工具访问外部知识源。