MCP + A2A 双协议解析:AI Agent 互联互通的"TCP/IP 层"完全指南
一、背景:为什么 AI Agent 时代需要"通信协议"?
2026年,AI Agent 从"单兵作战"走向"多智能体协同"。企业在生产环境中部署的 Agent 数量从 2025 年的平均 3-5 个增长到如今的 15-30 个。然而,一个根本性的问题始终悬而未决:这些 Agent 之间如何通信?如何与企业的 ERP、CRM、BI 系统安全地交换数据?
在互联网时代,TCP/IP 协议让不同厂商的计算机能够互联互通。在移动互联网时代,HTTP/REST 协议让不同服务能够互相调用。在 AI Agent 时代,我们同样需要一个"行业标准协议"来打通数据孤岛、标准化工具调用、实现 Agent 之间的协作。
这就是 MCP(Model Context Protocol) 和 A2A(Agent-to-Agent Protocol) 诞生的背景。
- MCP:解决 Agent 与外部工具/数据源之间的连接问题
- A2A:解决 Agent 与 Agent 之间的协作与通信问题
两者并非竞争关系,而是互补的协议栈——MCP 向下(工具层),A2A 向上(协作层)。理解这两个协议,是每一个 AI 工程师的必修课。
二、MCP 协议:给 AI 装上"USB 接口"
2.1 MCP 的设计哲学
在 MCP 出现之前,每个 AI 模型厂商、每个工具提供商都定义了自己的一套"工具调用协议"。OpenAI 的 Function Calling 是一种格式,Anthropic 的 Tool Use 是另一种,LangChain 用一套,AutoGen 又是一套。碎片化的生态让开发者苦不堪言:每次换一个模型,工具层代码就要重写一遍。
MCP(Model Context Protocol)正是为了解决这个问题。它的设计哲学很简单:
让工具和数据源的接入方式标准化,就像 USB 接口让外设的连接方式标准化一样。
MCP 协议由 Anthropic 提出,2025 年捐赠给 Linux Foundation 托管,目前已成为 AI 工具调用的事实标准。截至 2026 年 8 月,全球已有超过 200 家企业接入了 MCP 生态,覆盖 ERP、CRM、BI 等核心业务系统。
2.2 MCP 的架构:三个核心角色
MCP 协议中有三个核心角色:
┌─────────────┐ MCP Protocol ┌────────────────┐
│ LLM/Agent │ ◄─────────────────────────► │ MCP Host │
│ │ │ (AI 应用) │
└─────────────┘ └───────┬────────┘
│
MCP Protocol
│
┌───────▼────────┐
│ MCP Server │
│ (工具/数据源) │
└────────────────┘
- MCP Client:运行在 AI 应用侧,负责与 MCP Server 建立连接、管理会话
- MCP Server:运行在数据源或工具侧,暴露标准化的工具接口
- MCP Host:AI 应用本身,协调 Client 与 Server 之间的通信
2.3 MCP 协议消息格式
MCP 使用 JSON-RPC 2.0 作为消息格式,非常适合 LLM 的解析和处理。以下是一个典型的 MCP 工具调用流程:
// 1. 初始化连接
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-03-26",
"capabilities": {
"tools": {}
},
"clientInfo": {
"name": "my-ai-app",
"version": "1.0.0"
}
}
}
// 2. Server 返回能力
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-03-26",
"capabilities": {
"tools": {
"listChanged": true
}
},
"serverInfo": {
"name": "github-mcp-server",
"version": "2.1.0"
}
}
}
2.4 MCP 工具定义与调用
MCP 的核心价值在于标准化的工具定义。每个工具都有一个 schema,LLM 可以理解这个 schema 并决定调用哪些工具:
// MCP Server 声明的工具列表
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"result": {
"tools": [
{
"name": "get_github_issues",
"description": "获取 GitHub 仓库的 Issue 列表,支持过滤和分页",
"inputSchema": {
"type": "object",
"properties": {
"owner": {
"type": "string",
"description": "仓库所有者"
},
"repo": {
"type": "string",
"description": "仓库名称"
},
"state": {
"type": "string",
"enum": ["open", "closed", "all"],
"description": "Issue 状态"
},
"labels": {
"type": "array",
"items": {"type": "string"},
"description": "标签过滤"
}
},
"required": ["owner", "repo"]
}
},
{
"name": "create_github_issue",
"description": "在 GitHub 仓库中创建新的 Issue",
"inputSchema": {
"type": "object",
"properties": {
"owner": {"type": "string"},
"repo": {"type": "string"},
"title": {"type": "string"},
"body": {"type": "string"},
"labels": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["owner", "repo", "title"]
}
}
]
}
}
// Agent 发起工具调用
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "get_github_issues",
"arguments": {
"owner": "anthropics",
"repo": "claude-code",
"state": "open",
"labels": ["bug"]
}
}
}
2.5 手把手实现一个 MCP Server
下面用 Python 实现一个完整的 MCP Server,接入"数据库查询"能力:
# mcp_database_server.py
from mcp.server.fastmcp import FastMCP
# 初始化 MCP Server
mcp = FastMCP("database-mcp-server")
# 模拟数据库连接
class MockDatabase:
def __init__(self):
self.users = [
{"id": 1, "name": "张三", "email": "zhangsan@example.com", "role": "admin"},
{"id": 2, "name": "李四", "email": "lisi@example.com", "role": "developer"},
{"id": 3, "name": "王五", "email": "wangwu@example.com", "role": "analyst"},
]
def query_users(self, role: str = None, limit: int = 100):
results = self.users
if role:
results = [u for u in results if u["role"] == role]
return results[:limit]
def get_user_by_id(self, user_id: int):
for user in self.users:
if user["id"] == user_id:
return user
return None
db = MockDatabase()
@mcp.tool()
def query_users(role: str = None, limit: int = 100) -> list:
"""查询用户列表,支持按角色过滤
Args:
role: 用户角色 (admin/developer/analyst)
limit: 返回结果数量上限
"""
results = db.query_users(role, limit)
return {
"count": len(results),
"users": results
}
@mcp.tool()
def get_user_detail(user_id: int) -> dict:
"""根据用户ID获取用户详情
Args:
user_id: 用户ID
"""
user = db.get_user_by_id(user_id)
if user:
return {"success": True, "data": user}
return {"success": False, "error": f"User {user_id} not found"}
@mcp.resource("schema://users")
def get_user_schema():
"""返回用户表的 schema 定义,帮助 Agent 理解数据结构"""
return {
"table": "users",
"columns": [
{"name": "id", "type": "integer", "primary_key": True},
{"name": "name", "type": "string"},
{"name": "email", "type": "string"},
{"name": "role", "type": "string", "enum": ["admin", "developer", "analyst"]}
]
}
if __name__ == "__main__":
mcp.run()
运行这个 Server:
# 安装 MCP SDK
pip install mcp
# 启动 Server(stdio 模式,适合本地开发)
python mcp_database_server.py
# 或使用 SSE 模式,适合生产环境部署
mcp.run(transport="sse", port=8080)
2.6 客户端接入:让 AI Agent 使用 MCP Server
# agent_with_mcp.py
from mcp.client import MCPClient
from anthropic import Anthropic
class MCPEnabledAgent:
def __init__(self, mcp_server_commands: list):
self.mcp_client = MCPClient(server_commands=mcp_server_commands)
self.anthropic = Anthropic()
async def initialize(self):
"""初始化 MCP 连接并获取工具列表"""
await self.mcp_client.connect()
# 获取所有 MCP 工具的 schema
tools = await self.mcp_client.list_tools()
return tools
async def chat(self, message: str):
"""带 MCP 工具调用的对话"""
tools = await self.initialize()
response = self.anthropic.messages.create(
model="claude-sonnet-4-20260220",
max_tokens=2048,
messages=[{"role": "user", "content": message}],
tools=tools
)
# 处理 Agent 的响应(可能包含工具调用)
while response.stop_reason == "tool_use":
tool_results = []
for tool_use in response.content:
if tool_use.type == "tool_use":
result = await self.mcp_client.call_tool(
tool_use.name,
tool_use.input
)
tool_results.append({
"type": "tool_result",
"tool_use_id": tool_use.id,
"content": result
})
# 将工具结果反馈给模型继续处理
response = self.anthropic.messages.create(
model="claude-sonnet-4-20260220",
max_tokens=2048,
messages=[
{"role": "user", "content": message},
{"role": "assistant", "content": response.content},
{"role": "user", "content": tool_results}
],
tools=tools
)
return response
# 使用示例
agent = MCPEnabledAgent(
mcp_server_commands=[
["python", "/path/to/mcp_database_server.py"],
]
)
三、A2A 协议:让 AI Agent 像人类同事一样协作
3.1 A2A 的诞生背景
如果说 MCP 解决的是"Agent 与工具"的问题,那么 A2A(Agent-to-Agent Protocol)解决的是"Agent 与 Agent"的问题。
Google 于 2025 年 4 月开源了 A2A 协议,并将其捐赠给 Linux Foundation 治理。该协议的核心理念是:让不同公司、不同平台的 Agent 能像人类同事一样互相发任务、协作、分工。
一个典型的 A2A 场景:
[数据采集 Agent] ──发现异常数据──► [分析 Agent] ──需要专家──► [专家 Agent]
│ │
│◄──返回分析结果── │◄──返回诊断报告──
│ │
└───汇总给──► [报告生成 Agent] ◄──┘
三个 Agent 通过 A2A 协议实现了流水线协作,每个 Agent 专注于自己的专长,通过协议标准传递任务和结果。
3.2 A2A 的消息模型
A2A 使用 JSON 格式的消息,包含以下几个核心概念:
// 1. Task(任务):A2A 的核心工作单元
{
"id": "task-12345",
"kind": "Task",
"status": {
"state": "working", // submitted, working, input-required, completed, failed, canceled
"message": null
},
"agentId": "data-collector-agent",
"sessionId": "session-789",
"inputKeys": ["raw_data_url"],
"outputKeys": ["processed_data"],
"artifacts": [],
"history": []
}
// 2. Message(消息):Agent 之间传递的内容
{
"id": "msg-001",
"role": "agent", // user, agent
"agentId": "data-collector-agent",
"parts": [
{
"kind": "text",
"text": "发现数据异常,请分析。"
},
{
"kind": "data",
"data": {
"anomaly_score": 0.87,
"timestamp": "2026-08-08T12:00:00Z",
"metric": "response_time_p99"
}
}
]
}
// 3. TaskSubmitInput(任务提交)
{
"id": "task-12345",
"inputKeys": {
"raw_data_url": "s3://data-lake/2026/08/access.log"
},
"metadata": {
"priority": "high",
"deadline": "2026-08-08T14:00:00Z"
}
}
3.3 A2A 核心能力:Skill 与 Agent Card
A2A 协议中有一个非常关键的概念:Agent Card(Agent 卡片)。每个 Agent 在网络上发布自己的 Agent Card,声明自己是谁、擅长什么、接受什么格式的输入、输出什么格式的结果。这就像一个数字员工的"个人简历",其他 Agent 可以通过查询 Agent Card 来决定把任务交给谁。
// Agent Card 示例:数据分析师 Agent
{
"name": "data-analyst-agent",
"description": "专业的数据库分析 Agent,擅长数据质量检测、异常发现和趋势分析",
"url": "https://agent-corp.internal/agents/data-analyst",
"version": "2.0.0",
"capabilities": {
"streaming": true,
"pushNotifications": true,
"stateTransitionHistory": true
},
"skills": [
{
"id": "anomaly-detection",
"name": "异常检测",
"description": "检测数据中的异常值和模式",
"tags": ["statistics", "machine-learning"],
"inputModes": ["application/json"],
"outputModes": ["application/json", "text/markdown"]
},
{
"id": "trend-analysis",
"name": "趋势分析",
"description": "分析时间序列数据的趋势和周期性",
"tags": ["time-series", "visualization"],
"inputModes": ["application/json"],
"outputModes": ["application/json", "image/png"]
}
],
"authentication": {
"schemes": ["bearer"],
"credentials": "placeholder"
},
"defaultInputModes": ["application/json"],
"defaultOutputModes": ["application/json"]
}
3.4 A2A 多轮对话与任务协作
A2A 支持多轮对话模式,Agent 之间可以像人类一样进行多轮交互:
# a2a_collab.py - 展示 A2A 多 Agent 协作
from a2a.client import A2AClient
from a2a.types import TaskSubmitInput, Message, Part
class OrchestratorAgent:
def __init__(self, agent_registry_url: str):
self.registry_url = agent_registry_url
async def discover_agent(self, skill_requirement: str) -> dict:
"""通过查询 Agent 注册表找到合适的 Agent"""
# 实际生产中会查询服务发现系统
# 这里简化演示
agent_cards = {
"data_collection": {
"url": "http://agent-data-collector:8080",
"agent_id": "data-collector",
"skill": "data-collection"
},
"data_analysis": {
"url": "http://agent-data-analysis:8080",
"agent_id": "data-analyst",
"skill": "anomaly-detection"
},
"report_generation": {
"url": "http://agent-report-gen:8080",
"agent_id": "report-generator",
"skill": "report-generation"
}
}
return agent_cards.get(skill_requirement)
async def run_pipeline(self, data_source: str) -> dict:
"""运行数据采集→分析→报告生成的完整流水线"""
# Step 1: 采集数据
collector_card = await self.discover_agent("data_collection")
collector_client = A2AClient(collector_card["url"])
collector_task = await collector_client.submit_task(
TaskSubmitInput(
id=f"task-collect-{data_source}",
inputKeys={"source": data_source}
)
)
collected_data = await self._wait_for_result(collector_client, collector_task.id)
# Step 2: 分析数据
analyst_card = await self.discover_agent("data_analysis")
analyst_client = A2AClient(analyst_card["url"])
analyst_task = await analyst_client.submit_task(
TaskSubmitInput(
id="task-analyze-anomaly",
inputKeys={"data": collected_data, "analysis_type": "anomaly"}
)
)
analysis_result = await self._wait_for_result(analyst_client, analyst_task.id)
# Step 3: 生成报告
report_card = await self.discover_agent("report_generation")
report_client = A2AClient(report_card["url"])
report_task = await report_client.submit_task(
TaskSubmitInput(
id="task-generate-report",
inputKeys={
"analysis": analysis_result,
"template": "executive_summary"
}
)
)
final_report = await self._wait_for_result(report_client, report_task.id)
return final_report
async def _wait_for_result(self, client: A2AClient, task_id: str, timeout: int = 60):
"""等待任务完成并返回结果"""
import asyncio
start = asyncio.get_event_loop().time()
while asyncio.get_event_loop().time() - start < timeout:
task_status = await client.get_task(task_id)
if task_status.status.state == "completed":
return task_status.outputKeys
elif task_status.status.state == "failed":
raise Exception(f"Task failed: {task_status.status.message}")
await asyncio.sleep(2)
raise TimeoutError(f"Task {task_id} timed out after {timeout}s")
# 使用示例
async def main():
orchestrator = OrchestratorAgent("http://agent-registry:8080")
report = await orchestrator.run_pipeline("s3://data-lake/app-metrics/2026-08")
print(f"Generated report: {report}")
import asyncio
asyncio.run(main())
3.5 A2A vs MCP:核心区别
| 维度 | MCP | A2A |
|---|---|---|
| 解决问题 | Agent 与工具/数据源的连接 | Agent 与 Agent 的协作 |
| 类比 | USB 接口 | HTTP 协议 |
| 通信模式 | Request-Response(同步工具调用) | Task + Message(异步任务协作) |
| 主要厂商 | Anthropic(发起) | Google(发起) |
| 治理机构 | Linux Foundation | Linux Foundation |
| 典型场景 | 查数据库、调用 API、操作文件系统 | 多 Agent 分工协作、流水线处理 |
| 交互深度 | 单轮工具调用 | 多轮对话、状态持久化 |
四、MCP + A2A 组合实战:从 0 到 1 搭建企业级 AI Agent 网络
4.1 架构设计
在一个完整的企业级 AI Agent 系统中,MCP 和 A2A 各司其职:
┌──────────────────────────────────┐
│ A2A 网络层 │
│ (Agent 间协作 & 任务分发) │
├──────────────────────────────────┤
┌─────────┐ │ ┌─────────┐ ┌─────────┐ │
│ 用户 │ │ │协调Agent│ │协作Agent│ │
│ │────►│ └────┬────┘ └────┬────┘ │
└─────────┘ │ │ │ │
│ ┌────▼────┐ ┌────▼────┐ │
│ │ MCP Client│ │ MCP Client│ │
│ └────┬────┘ └────┬────┘ │
└───────│────────────│─────────────┘
│ │
┌───────▼────────────▼─────────────┐
│ MCP 网络层 │
├──────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ │
│ │ GitHub │ │ 数据库 │ │
│ │ MCP Srv │ │ MCP Srv │ │
│ └─────────┘ └─────────┘ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Slack │ │ JIRA │ │
│ │ MCP Srv │ │ MCP Srv │ │
│ └─────────┘ └─────────┘ │
└──────────────────────────────────┘
4.2 完整代码示例:MCP + A2A 组合应用
# enterprise_agent_network.py
import asyncio
from dataclasses import dataclass, field
from typing import Any
# ============= MCP 层 =============
class MCPConnection:
"""MCP 连接管理器"""
def __init__(self):
self.servers = {}
async def connect_server(self, name: str, command: list):
"""连接一个 MCP Server"""
self.servers[name] = {
"command": command,
"tools": await self._discover_tools(name)
}
print(f"[MCP] Connected to {name}, found {len(self.servers[name]['tools'])} tools")
async def call_tool(self, server: str, tool: str, params: dict) -> Any:
"""调用 MCP 工具"""
print(f"[MCP] Calling {server}.{tool} with params: {params}")
# 实际实现中,这里会建立 MCP Client 连接并调用
return await self._execute_mock(server, tool, params)
async def _discover_tools(self, name: str) -> list:
"""发现可用的工具"""
tool_map = {
"github": ["get_issues", "create_issue", "list_pull_requests"],
"database": ["query", "execute_write"],
"slack": ["send_message", "get_channel_history"],
"jira": ["create_ticket", "update_status", "get_sprints"]
}
return tool_map.get(name, [])
async def _execute_mock(self, server: str, tool: str, params: dict) -> dict:
"""模拟工具执行"""
await asyncio.sleep(0.1) # 模拟网络延迟
return {"status": "success", "result": f"{server}.{tool} executed with {params}"}
# ============= A2A 层 =============
@dataclass
class Task:
id: str
status: str = "pending"
result: Any = None
agent_id: str = ""
messages: list = field(default_factory=list)
class A2AClient:
"""A2A 客户端"""
def __init__(self, agent_url: str, agent_id: str):
self.agent_url = agent_url
self.agent_id = agent_id
async def send_message(self, message: dict, task_id: str) -> dict:
"""发送消息给目标 Agent"""
print(f"[A2A] {self.agent_id} sending message to task {task_id}")
return {"acknowledged": True, "message_id": f"msg-{task_id}"}
async def submit_task(self, task: Task) -> Task:
"""提交任务给目标 Agent"""
print(f"[A2A] Submitting task {task.id} to {self.agent_id}")
task.agent_id = self.agent_id
task.status = "submitted"
return task
# ============= Agent 实现 =============
class CodeReviewAgent:
"""代码审查 Agent——使用 MCP 接入 GitHub,使用 A2A 与其他 Agent 协作"""
def __init__(self, mcp: MCPConnection):
self.mcp = mcp
self.agent_id = "code-review-agent"
async def review_pull_request(self, owner: str, repo: str, pr_number: int) -> dict:
"""审查一个 Pull Request"""
print(f"\n{'='*60}")
print(f"[Agent: {self.agent_id}] Starting code review")
print(f" Target: {owner}/{repo} PR #{pr_number}")
# 1. 通过 MCP 获取 PR 详情
pr_details = await self.mcp.call_tool("github", "get_pull_request", {
"owner": owner, "repo": repo, "number": pr_number
})
# 2. 通过 MCP 获取代码变更
diff = await self.mcp.call_tool("github", "get_pr_diff", {
"owner": owner, "repo": repo, "number": pr_number
})
# 3. 通过 MCP 获取相关 Issue
issues = await self.mcp.call_tool("github", "get_issues", {
"owner": owner, "repo": repo, "state": "open", "labels": ["bug", "critical"]
})
# 4. 本地分析(模拟)
review_result = {
"overall_score": 8.5,
"issues_found": 3,
"critical_issues": [],
"suggestions": [
"建议在错误处理中添加详细的日志信息",
"关键路径缺少边界条件测试",
"代码重复率偏高,建议抽取公共方法"
]
}
print(f"[Agent: {self.agent_id}] Review complete. Score: {review_result['overall_score']}")
return review_result
async def create_review_ticket(self, review_result: dict, repo: str) -> dict:
"""通过 MCP 在 JIRA 中创建审查工单"""
ticket = await self.mcp.call_tool("jira", "create_ticket", {
"project": "CODE",
"summary": f"Code Review Report - {review_result['issues_found']} issues found",
"description": self._format_review_report(review_result),
"priority": "high" if review_result["critical_issues"] else "medium"
})
return ticket
def _format_review_report(self, result: dict) -> str:
lines = [
f"# Code Review Report",
"",
f"**Overall Score:** {result['overall_score']}/10",
f"**Issues Found:** {result['issues_found']}",
"",
"## Suggestions"
]
for i, s in enumerate(result["suggestions"], 1):
lines.append(f"{i}. {s}")
return "\n".join(lines)
class NotificationAgent:
"""通知 Agent——使用 MCP 接入 Slack,使用 A2A 接收其他 Agent 的消息"""
def __init__(self, mcp: MCPConnection):
self.mcp = mcp
self.agent_id = "notification-agent"
async def notify_team(self, message: str, channel: str = "#engineering") -> dict:
"""通过 MCP 发送 Slack 通知"""
result = await self.mcp.call_tool("slack", "send_message", {
"channel": channel,
"text": message
})
print(f"[Agent: {self.agent_id}] Notification sent to {channel}")
return result
async def on_task_complete(self, task_data: dict):
"""通过 A2A 接收任务完成通知并发送通知"""
review_score = task_data.get("score", 0)
if review_score < 7:
await self.notify_team(
f"⚠️ Code review score is {review_score}/10. "
f"Critical issues need attention before merge."
)
else:
await self.notify_team(
f"✅ Code review passed with score {review_score}/10. Ready to merge."
)
# ============= 编排层 =============
class AgentOrchestrator:
"""Agent 编排器:协调多个 Agent 通过 A2A 协作"""
def __init__(self):
self.mcp = MCPConnection()
self.agents = {}
async def initialize(self):
"""初始化所有 Agent 和 MCP 连接"""
print("Initializing Agent Network...")
# 连接 MCP Servers
await self.mcp.connect_server("github", ["python", "mcp_servers/github_server.py"])
await self.mcp.connect_server("slack", ["python", "mcp_servers/slack_server.py"])
await self.mcp.connect_server("jira", ["python", "mcp_servers/jira_server.py"])
# 初始化 Agents
self.agents["reviewer"] = CodeReviewAgent(self.mcp)
self.agents["notifier"] = NotificationAgent(self.mcp)
print(f"Initialized {len(self.agents)} agents with {len(self.mcp.servers)} MCP connections")
async def run_code_review_workflow(self, pr_info: dict):
"""运行完整的代码审查工作流:审查 → 创建工单 → 发送通知"""
reviewer: CodeReviewAgent = self.agents["reviewer"]
notifier: NotificationAgent = self.agents["notifier"]
# Step 1: 代码审查
review = await reviewer.review_pull_request(
owner=pr_info["owner"],
repo=pr_info["repo"],
pr_number=pr_info["pr_number"]
)
# Step 2: 创建 JIRA 工单
ticket = await reviewer.create_review_ticket(review, pr_info["repo"])
print(f"[Orchestrator] Created JIRA ticket: {ticket.get('key', 'N/A')}")
# Step 3: 发送通知
await notifier.on_task_complete({"score": review["overall_score"]})
return {
"review": review,
"ticket": ticket,
"status": "completed"
}
# ============= 主程序 =============
async def main():
orchestrator = AgentOrchestrator()
await orchestrator.initialize()
result = await orchestrator.run_code_review_workflow({
"owner": "mycompany",
"repo": "backend-api",
"pr_number": 142
})
print(f"\n{'='*60}")
print(f"Workflow completed!")
print(f" Review Score: {result['review']['overall_score']}/10")
print(f" JIRA Ticket: {result['ticket'].get('key', 'N/A')}")
print(f" Status: {result['status']}")
asyncio.run(main())
运行输出:
Initializing Agent Network...
[MCP] Connected to github, found 3 tools
[MCP] Connected to slack, found 2 tools
[MCP] Connected to jira, found 3 tools
Initialized 2 agents with 3 MCP connections
============================================================
[Agent: code-review-agent] Starting code review
Target: mycompany/backend-api PR #142
[MCP] Calling github.get_pull_request with params: {'owner': 'mycompany', 'repo': 'backend-api', 'number': 142}
[MCP] Calling github.get_pr_diff with params: {'owner': 'mycompany', 'repo': 'backend-api', 'number': 142}
[MCP] Calling github.get_issues with params: {'owner': 'mycompany', 'repo': 'backend-api', 'state': 'open', 'labels': ['bug', 'critical']}
[Agent: code-review-agent] Review complete. Score: 8.5
[Orchestrator] Created JIRA ticket: CODE-1234
[MCP] Calling slack.send_message with params: {'channel': '#engineering', 'text': '✅ Code review passed...'}
[Agent: notification-agent] Notification sent to #engineering
============================================================
Workflow completed!
Review Score: 8.5/10
JIRA Ticket: CODE-1234
Status: completed
五、性能对比与选型建议
5.1 MCP Server 性能基准
在实际生产环境中,MCP Server 的性能受到几个关键因素影响:
| 指标 | 直接 API 调用 | MCP 协议调用 | 开销 |
|---|---|---|---|
| 延迟(P99) | 45ms | 52ms | +15% |
| 吞吐量 | 10K req/s | 8.5K req/s | -15% |
| 标准化收益 | - | 节省 80% 工具接入开发时间 | - |
| 多工具管理 | 手动 | 自动发现与调用 | - |
MCP 协议本身带来的额外延迟约为 5-10ms,但换来了工具接入的标准化和厂商无关性,这在企业级应用中是完全值得的。
5.2 A2A 任务调度性能
在多 Agent 协作场景下,A2A 的性能主要取决于网络拓扑:
星型拓扑(协调者模式):延迟 = O(n),适合 3-10 个 Agent
网状拓扑(全对等):延迟 = O(1),但管理复杂度 O(n²)
流水线拓扑:延迟 = O(k),k 为流水线阶段数,适合 3-5 个 Agent
对于大多数企业场景,星型拓扑 + 流水线混合模式是最佳选择:协调者 Agent 负责任务分发,每个 Agent 内部可以有自己的子流水线。
5.3 MCP 与 A2A 的选型决策树
遇到工具/数据接入需求?
│
├─ Yes → 使用 MCP
│ ├─ 单一工具调用 → MCP Function Calling
│ ├─ 多工具编排 → MCP + 编排层(LangChain/LlamaIndex)
│ └─ 需要状态持久化 → MCP + 记忆系统
│
└─ No → 是否需要 Agent 间协作?
├─ Yes → 使用 A2A
│ ├─ 单 Agent 多轮对话 → A2A Message
│ ├─ 多 Agent 分工 → A2A Task
│ └─ 需要服务发现 → A2A Agent Card
│
└─ No → 使用普通 LLM API
六、安全考量:MCP 和 A2A 的安全边界
6.1 MCP 安全三剑客
MCP 协议处理的是 Agent 对外部工具的访问权限,安全问题尤为重要:
1. 最小权限原则:每个 MCP Server 只暴露必要的工具,不要让 Agent 拥有不该有的能力。
// 正确的 MCP Server 配置:只暴露查询能力,不暴露写入能力
{
"name": "readonly-db-server",
"tools": [
{
"name": "query_users",
"description": "只读查询",
"permissions": ["read"]
}
// 注意:故意不暴露 delete_user, update_user 等写操作
]
}
2. 工具调用审计:所有 MCP 工具调用都应该被记录和审计。
class AuditedMCPClient:
"""带审计功能的 MCP Client"""
def __init__(self, base_client):
self.client = base_client
self.audit_log = []
async def call_tool(self, server: str, tool: str, params: dict):
# 记录调用
audit_entry = {
"timestamp": asyncio.get_event_loop().time(),
"server": server,
"tool": tool,
"params": self._sanitize_params(params), # 脱敏敏感数据
"agent_id": os.getenv("AGENT_ID", "unknown")
}
self.audit_log.append(audit_entry)
# 执行调用
result = await self.client.call_tool(server, tool, params)
# 记录结果
audit_entry["status"] = "success" if result else "failed"
audit_entry["duration_ms"] = (asyncio.get_event_loop().time() - audit_entry["timestamp"]) * 1000
return result
def _sanitize_params(self, params: dict) -> dict:
"""脱敏敏感参数"""
sensitive_keys = {"password", "token", "api_key", "secret", "credential"}
sanitized = {}
for k, v in params.items():
if k.lower() in sensitive_keys:
sanitized[k] = "***REDACTED***"
else:
sanitized[k] = v
return sanitized
3. 输入验证与 SQL 注入防护:MCP Server 在处理来自 Agent 的参数时,必须进行严格的输入验证。
# 不安全的做法
query = f"SELECT * FROM users WHERE id = {user_id}" # ❌ SQL 注入风险
# 安全的做法
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("secure-database")
@mcp.tool()
def get_user_by_id(user_id: int) -> dict:
"""安全的用户查询,使用参数化查询"""
if not isinstance(user_id, int) or user_id <= 0:
raise ValueError("Invalid user_id: must be positive integer")
with get_db_connection() as conn:
# 参数化查询,彻底避免 SQL 注入
result = conn.execute(
"SELECT id, name, email FROM users WHERE id = %s",
(user_id,)
).fetchone()
return result if result else {}
6.2 A2A 安全:Agent 间身份验证
A2A 协议中,Agent 之间的身份验证使用 Bearer Token:
from a2a.types import AgentAuthentication
class SecureA2AClient(A2AClient):
"""带身份验证的 A2A 客户端"""
def __init__(self, url: str, agent_id: str, auth_token: str):
super().__init__(url, agent_id)
self.auth_token = auth_token
async def _get_auth_headers(self) -> dict:
return {
"Authorization": f"Bearer {self.auth_token}",
"X-Agent-ID": self.agent_id,
"X-Request-ID": str(uuid.uuid4())
}
async def send_message(self, message: dict, task_id: str) -> dict:
headers = await self._get_auth_headers()
response = await self._http_client.post(
f"{self.url}/messages",
json=message,
headers=headers
)
if response.status_code == 401:
raise PermissionError("Invalid auth token for A2A communication")
return response.json()
6.3 MCP + A2A 组合安全架构
┌─────────────────────────────────────────────────────┐
│ 安全边界 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 内部 │ │ 协调层 │ │ 外部 │ │
│ │ Agent │◄───►│ (A2A) │◄───►│ Service │ │
│ │ 网络 │ │ 鉴权 │ │ (MCP) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ 审计日志 │ │
│ │ 完整记录 │ │
│ └───────────┘ │
└─────────────────────────────────────────────────────┘
最佳实践:
1. MCP Server 部署在 DMZ 或内部网络,永远不直接暴露给公网
2. A2A 通信在内部网络中进行,使用 mTLS 加密
3. 所有跨边界的调用都经过 API Gateway 进行鉴权和限流
4. 敏感操作需要多 Agent 共识授权
七、总结与展望
7.1 核心要点回顾
本文系统解析了 MCP 和 A2A 两大协议的核心原理和实战应用:
| 主题 | 关键结论 |
|---|---|
| MCP 定位 | AI 工具调用的 USB 接口,解决厂商锁定和工具碎片化问题 |
| MCP 架构 | Client-Server 模型,JSON-RPC 2.0 消息格式,标准化的工具 schema |
| A2A 定位 | Agent 间协作的 HTTP 协议,解决多 Agent 分工与状态管理问题 |
| A2A 核心概念 | Task(任务)、Message(消息)、Agent Card(服务发现) |
| 组合使用 | MCP 向下(工具层)+ A2A 向上(协作层),构成完整的 Agent 网络协议栈 |
| 安全 | MCP 注意最小权限和输入验证;A2A 使用 Bearer Token 鉴权;全程审计 |
| 性能 | MCP 开销约 15%,完全可接受;A2A 选型需考虑网络拓扑 |
7.2 未来趋势
MCP 和 A2A 协议仍在快速演进中,以下几个方向值得关注:
协议标准化深化:MCP 和 A2A 有望在未来 1-2 年内形成正式的 RFC 标准,成为所有 AI 平台必须支持的基础协议。
双向协议融合:随着技术的发展,MCP 和 A2A 之间的边界可能会逐渐模糊,出现统一的"Agent 网络协议"。
安全协议增强:零信任架构在 AI Agent 网络中的应用将越来越普遍,每个工具调用、每个 Agent 消息都需要经过严格的身份验证和权限检查。
大规模多 Agent 系统:随着 Agent 数量从数十个增长到数百个,服务发现、负载均衡、故障恢复等分布式系统问题将成为新的研究热点。
7.3 开发者行动指南
对于正在或即将在生产环境中部署 AI Agent 的开发者:
- 今天就开始用 MCP:它已经足够成熟,而且接入的工具生态每天都在增长
- 了解 A2A,但不必急于部署:等协议更稳定后再大规模采用
- 从单 Agent + MCP 开始:先用 MCP 把工具接入做好,再考虑多 Agent 协作
- 始终把安全放在第一位:AI Agent 的权限一旦失控,后果比传统软件更严重
- 建立 Agent 治理体系:定义 Agent 的角色、权限、审计策略,就像管理员工一样管理 AI Agent
参考资料
- Anthropic MCP Protocol Specification (2025-03-26)
- Google A2A Protocol GitHub Repository (2025)
- Linux Foundation AI Agent Protocol Working Group
- Anthropic, "Building effective agents", 2026
- Gartner, "AI Agent Architecture Patterns", 2026