使用说明
A2A+MCP协议演示
两个开放协议成为可互操作AI代理系统标准的最小、可运行的示例:
- A2A(代理2代理) --代理人如何相互交谈
- MCP(模型上下文协议) --代理如何与工具对话
三种不同的框架(Google ADK、LangGraph、BeeAI)都通过A2A进行通信——这就是重点。
两个协议
A2A——代理人对代理人
A2A是一个开放的HTTP协议,允许AI代理使用 不同的框架 无需自定义集成代码即可相互发现和调用。由Google Cloud于2025年4月推出,捐赠给Linux基金会。
A2A代理只是一个HTTP服务器。任何其他说A2A的代理都可以呼叫它。
三个核心概念:
| 概念 | 它是什么 | 你在哪里看到它 |
|---|---|---|
| 代理卡 | JSON文档位于 GET /.well-known/agent.json --代理的名称、URL、版本和技能。客户如何 发现 代理人。 |
a2a_policy_agent.py → LlmAgent(name=..., description=...) |
| AgentSkill 的 | AgentCard中声明的功能。路由器和协调器通过阅读技能来决定呼叫哪个代理。 | a2a_provider_agent.py → AgentSkill(...) |
| 代理执行器 | 传入A2A请求和业务逻辑之间的桥梁。要么实施 execute() 手动或让像ADK这样的框架通过 to_a2a(). |
a2a_provider_agent.py → 由...处理 langgraph-a2a-server |
MCP——代理到工具
MCP是一个开放协议,标准化了LLM代理如何连接到外部工具和数据源。MCP服务器公开任何MCP客户端都可以调用的类型化函数,而不管框架如何。
三个核心概念:
| 概念 | 它是什么 | 你在哪里看到它 |
|---|---|---|
| MCP服务器 | 显示一个或多个工具。框架无关。 | mcpserver.py |
| MCP客户端 | 发现并调用MCP工具的代理端适配器。 | a2a_provider_agent.py → MultiServerMCPClient |
| 工具 | 一个带有docstring的类型化Python函数。LLM读取它并决定何时调用它 | mcpserver.py → list_doctors() |
它们如何相互补充
A2A=代理人与代理人交谈。MCP=代理与工具对话。
代理可以同时是 A2A服务器 (接受任务)和 MCP客户端 (调用工具来实现它们)。提供商代理正是这样做的。
完整架构
┌─────────────────────────────────────────────────┐
│ Option A: client.py (GPT-4o router) │
│ Option B: a2a_orchestrator_client.py (BeeAI) │
└────────────────┬────────────────────────────────┘
│ A2A
│
┌────────────────▼────────────────────────────────┐
│ a2a_orchestrator.py :9996 │
│ BeeAI RequirementAgent │
│ │
│ Fetches AgentCards at startup → creates │
│ HandoffTools → routes via LLM reasoning │
└──────────────┬──────────────┬───────────────────┘
│ A2A │ A2A
┌───────────────▼──┐ ┌───▼──────────────────────┐
│ Policy Agent │ │ Provider Agent │
│ :9999 │ │ :9997 │
│ Google ADK │ │ LangGraph + MCP │
│ │ │ │
│ LlmAgent │ │ ReAct agent loop │
│ + to_a2a() │ │ │ MCP (stdio) │
│ │ │ │ ▼ │
│ │ LiteLLM │ │ mcpserver.py │
│ ▼ │ │ │ │
│ Gemini + PDF │ │ ▼ │
└──────────────────┘ │ doctors.json │
└──────────────────────────┘
特工Deep Dives
策略代理——谷歌ADK
文件夹: policy_agent.py + a2a_policy_agent.py | 端口: 9999
回答有关保险计划覆盖范围的问题。
User question (via A2A)
│
▼
Google ADK LlmAgent receives request
│
├── Decides to call answer_policy_question() tool
│
▼
policy_agent.py → LiteLLM → Gemini API + PDF (base64)
│
▼
to_a2a() sends response back over A2A
按键图案-- to_a2a() 与手动A2A SDK相比:
| A2A SDK手册 | 谷歌ADK |
|---|---|
定义 AgentCard 您自己 |
生成自 LlmAgent(name=..., description=...) |
实施 AgentExecutor.execute() |
ADK内部处理 |
电线 DefaultRequestHandler + A2AStarletteApplication |
to_a2a(agent) 做这一切 |
| 约80行 | 约20行 |
权衡:ADK隐藏了协议细节。手动方法更具教育性。
提供者代理--LangGraph+MCP
文件夹: a2a_provider_agent.py + mcpserver.py | 端口: 9997
按地点查找医疗保健提供者,并告诉你他们接受什么保险。
User question (via A2A)
│
▼
LangGraph ReAct agent loop
├── LLM thinks: "I need to search for doctors"
├── Calls list_doctors() via MCP ──► mcpserver.py subprocess (stdio)
│ └── filters doctors.json
├── LLM receives results
└── LLM formats readable answer
│
▼
A2A response (result in task.artifacts)
关键模式: 一个代理中有三个协议:
- A2A --外层,接受任务并提供响应(
langgraph-a2a-server) - LangGraph --中间层,运行ReAct推理循环
- 主控程序 --内层,将LangGraph连接到
list_doctors通过stdio工具
mcpserver.py 作为子进程自动启动 MultiServerMCPClient --切勿手动启动。
BeeAI编排器
文件: a2a_orchestrator.py | 端口: 9996
协调两个子代理来回答跨越两个领域的复杂问题。
User question (via A2A)
│
▼
BeeAI RequirementAgent
│
├── ThinkTool: reasons about what's needed
│
├── HandoffTool → Policy Agent (A2A :9999)
│ "What does the plan cover for mental health?"
│
├── ThinkTool: reasons about next step
│
├── HandoffTool → Provider Agent (A2A :9997)
│ "Find psychiatrists in Boston, MA"
│
└── Synthesizes both answers into one response
│
▼
A2A response
关键图案——BeeAI的优雅:
- 在启动时,
check_agent_exists()获取每个子代理的代理卡 HandoffTool将每个A2A代理包装为可调用工具——描述直接来自AgentCardConditionalRequirement防止无限循环(每个代理每个请求调用一次max)- 零硬编码路由——LLM根据AgentCard描述决定调用哪些工具
client.py——原始A2A SDK+GPT-4o路由器
文件: client.py
直接调用两个子代理的交互式客户端(绕过编排器)。使用GPT-4o读取AgentCard并智能路由。
Startup: fetch AgentCards from both agents → show discovery output
Loop:
User types question
→ GPT-4o reads AgentCards, reasons about which agent fits
→ Routes to chosen agent via A2A
→ Prints response
使用此功能: 演示A2A发现,并展示任何LLM如何纯粹从AgentCard元数据充当路由器。
项目结构
a2a/
│
├── policy_agent.py # Plain Python class — no A2A, no framework
│ # Reads PDF at startup, answers via Gemini/LiteLLM
│
├── a2a_policy_agent.py # Google ADK: LlmAgent + to_a2a() (port 9999)
│
├── a2a_provider_agent.py # LangGraph + MCP as A2A server (port 9997)
│
├── mcpserver.py # MCP server — exposes list_doctors() tool (stdio)
│
├── a2a_orchestrator.py # BeeAI RequirementAgent orchestrator (port 9996)
│ # Reads AgentCards, coordinates sub-agents
│
├── a2a_orchestrator_client.py # Interactive client for the BeeAI orchestrator
│ # Keeps conversation memory across follow-ups
│
├── client.py # Interactive client with GPT-4o router
│ # Calls sub-agents directly (no orchestrator)
│
├── helpers.py # setup_env() — loads .env, suppresses warnings
│
├── data/
│ ├── 2026AnthemgHIPSBC.pdf # Insurance policy PDF (Policy Agent)
│ └── doctors.json # Doctor dataset (MCP server)
│
├── example.env # Environment variable template
└── pyproject.toml # Project dependencies
设置
1.API密钥
| 密钥 | 使用人 | 获取 |
|---|---|---|
GEMINI_API_KEY |
策略代理、提供者代理、编排器 | 谷歌AI工作室 |
OPENAI_API_KEY |
路由器在 client.py (GPT-4o) |
OpenAI平台 |
2.配置环境
cp example.env .env
# Edit .env and fill in both API keys
3.安装依赖项
uv sync
4.VS代码解释器
Cmd+Shift+P → Python:选择解释器 → 选择 .venv 在这个文件夹中。
跑步
选项A——两个代理+GPT-4o路由器(3个终端)
# Terminal 1
uv run a2a_policy_agent.py # Google ADK, port 9999
# Terminal 2
uv run a2a_provider_agent.py # LangGraph + MCP, port 9997
# Terminal 3
uv run client.py # GPT-4o router, interactive
选项B——全栈BeeAI编排器(4个终端)
# Terminal 1
uv run a2a_policy_agent.py # Google ADK, port 9999
# Terminal 2
uv run a2a_provider_agent.py # LangGraph + MCP, port 9997
# Terminal 3 — start AFTER 1 & 2 are running
uv run a2a_orchestrator.py # BeeAI orchestrator, port 9996
# Terminal 4
uv run a2a_orchestrator_client.py # Interactive, with memory
重要提示: 仅在子代理运行后启动编排器(终端3)——它调用
check_agent_exists()在启动时获取两个AgentCard。
要尝试的示例问题
| 问题 | 最佳客户 |
|---|---|
| “我的计划包括心理健康吗?” | client.py → 策略代理 |
| “我的免赔额是多少?” | client.py → 策略代理 |
| “在波士顿找心理医生” | client.py → 提供商代理 |
| “阿曼达·福斯特医生接受什么保险?” | client.py → 提供商代理 |
| “我在波士顿。我有什么心理健康保险,并在我附近找一位精神病医生?” | a2a_orchestrator_client.py (同时调用两者) |
关键依赖
| 包 | 角色 |
|---|---|
a2a-sdk |
A2A协议-- AgentCard, AgentExecutor, ClientFactory |
google-adk |
谷歌代理开发工具包-- LlmAgent, to_a2a() |
mcp |
MCP协议-- FastMCP 服务器工具包 |
langchain-mcp-adapters |
MultiServerMCPClient --LangGraph↔ MCP电桥 |
langgraph |
在提供者代理中重新执行代理循环 |
langgraph-a2a-server |
将LangGraph图包装为A2A HTTP服务器 |
beeai-framework |
RequirementAgent, HandoffTool, A2AServer |
litellm |
统一LLM API-Gemini+OpenAI,带有一个接口 |
langchain-litellm |
LiteLLM的LangChain适配器 |
