Appearance
A2A 协议
A2A(Agent-to-Agent)是 Google 在 2025 年发布的开放协议,解决的问题是:当你的系统里有多个 AI Agent 时,它们之间怎么互相发现和协作。
这页和 MCP 协议 是配对的——MCP 处理"Agent 怎么调用工具",A2A 处理"Agent 怎么调用另一个 Agent"。两者面向不同层级的集成需求。
先说清楚 A2A 解决的是什么问题
在单 Agent 系统里,一个 Agent 通过 Tool Calling 调用各种工具(搜索、数据库、API),MCP 提供了标准化的工具接入协议。但在更复杂的系统里,你可能有:
- 一个专门处理客服对话的 Agent
- 一个专门做数据分析的 Agent
- 一个专门处理订单的 Agent
当用户问的问题同时涉及订单状态和数据分析时,一个 Agent 单独处理能力有限。最自然的解法是让 Agent 之间互相协作——但没有标准协议时,每个团队的 Agent 实现都不一样,跨系统集成的成本很高。
A2A 就是为了解决这个互联互通问题:让不同系统、不同团队构建的 Agent,能够通过标准接口互相发现和调用。
五个设计原则
A2A 的设计目标不是替你规定 Agent 内部怎么实现,而是让不同 Agent 能在边界上对齐。官方文档里经常出现的几个关键词,可以这样理解。
Agnostic
A2A 不绑定具体模型、框架或云厂商。远程 Agent 可以用 LangGraph 写,也可以是自研服务;可以调用 Gemini,也可以调用其他模型。调用方只依赖协议暴露出来的 Agent Card、Task、Message 和状态。
这一点对企业集成很关键。跨团队协作时,你通常无法要求对方换成你的 Agent 框架。
Async
Agent 处理的任务经常不是一次 HTTP 请求能马上结束的,比如生成报告、查询多系统数据、等待人工审批。A2A 把 Task 作为核心对象,就是为了支持长任务、状态轮询和流式进度。
同步返回适合简单任务;复杂任务至少要能查询 working、completed、failed 这类状态。
Multimodal
A2A 的 Message 不是只放一段纯文本,而是由多个 parts 组成。一个任务可以同时包含文本、结构化数据、文件或图片引用。对多模态 Agent 来说,这比“所有东西都塞进一段字符串”更容易扩展。
实际落地时,文件和图片通常不会直接塞进 JSON,而是用 URL、文件 ID 或对象存储引用传递。
Interoperability
互操作性是 A2A 最核心的价值。Agent Card 告诉调用方“我能做什么”,Task 和 Message 规定“怎么发任务”,状态和 artifacts 规定“怎么拿结果”。只要这些边界一致,内部实现可以完全不同。
它解决的不是“多 Agent 怎么规划任务”,而是“两个已经存在的 Agent 服务怎么互相理解”。
Security
A2A 默认面向跨服务、跨团队甚至跨组织调用,安全不能靠“大家都在内网”含糊带过。调用方是谁、能调用哪些 skill、能访问哪些用户数据、日志里能不能留下原始输入,都需要在协议边界之外配套实现。
这个原则也提醒你:Agent Card 可以公开能力描述,但不应该暴露内部 prompt、私有 endpoint、数据库字段或敏感业务规则。
A2A 的核心设计
Agent Card
每个支持 A2A 的 Agent 都需要发布一个 Agent Card,相当于 Agent 的"名片",通常放在 /.well-known/agent.json。
json
{
"name": "OrderAgent",
"description": "处理订单查询、退款申请和物流跟踪",
"url": "https://order-service.example.com/agent",
"version": "1.0",
"capabilities": {
"streaming": true,
"pushNotifications": false
},
"skills": [
{
"id": "query_order",
"name": "查询订单",
"description": "根据订单号查询订单状态和物流信息",
"inputModes": ["text"],
"outputModes": ["text", "data"]
},
{
"id": "request_refund",
"name": "申请退款",
"description": "提交退款申请并返回处理进度",
"inputModes": ["text"],
"outputModes": ["text"]
}
]
}客户端 Agent 可以先读取这个 Card,了解目标 Agent 有什么能力,再决定要不要、怎么调用它。
Task 和 Message
A2A 的基本交互单元是 Task。客户端向远程 Agent 发送一个 Task,Agent 处理并返回结果。
json
POST /task
{
"id": "task-123",
"sessionId": "session-456",
"message": {
"role": "user",
"parts": [
{
"type": "text",
"text": "查询订单 ORD-20240315-001 的当前状态"
}
]
}
}响应:
json
{
"id": "task-123",
"status": {
"state": "completed"
},
"artifacts": [
{
"parts": [
{
"type": "text",
"text": "订单 ORD-20240315-001 当前状态:已发货,预计明天到达"
}
]
}
]
}流式响应
对于耗时较长的任务,A2A 支持 SSE 流式返回中间状态,客户端可以实时展示进度,不必等待完整结果。
认证与安全
A2A 本身描述的是 Agent 之间怎么通信,生产系统还要配认证和授权。常见做法有两类:
- API Key:适合内部服务或早期集成,调用方在请求头里带固定密钥,例如
Authorization: Bearer <token> - OAuth2:适合跨组织或需要用户授权的场景,可以区分 client identity、scope、token 过期时间和刷新流程
如果只是系统间调用,API Key 容易落地,但要配合密钥轮换、调用来源限制和审计日志。只靠一个长期有效的 key,很容易在泄露后失控。
OAuth2 更重,但适合回答“这个 Orchestrator 是否有权让订单 Agent 查询某个用户的数据”。这时权限不只是服务级别,还要带上用户身份、租户、scope 等上下文。
在 Agent Card 里,可以公开认证方式和安全 scheme,但不要把真实密钥写进去:
json
{
"name": "OrderAgent",
"url": "https://order-service.example.com/agent",
"securitySchemes": {
"bearer": {
"type": "http",
"scheme": "bearer"
}
}
}服务端还需要做几件事:校验调用方身份、检查 skill 权限、限制输入大小、过滤敏感日志、给长任务设置超时。Agent 间调用一旦能触发真实业务动作,安全边界要按普通生产 API 的标准来做。
一个端到端调用示例
下面的例子展示一个 Orchestrator Agent 如何发现并调用远程订单 Agent。为了让代码短一点,这里没有实现真实模型决策,而是用关键词选择 skill;实际项目里可以把 Agent Card 的能力描述交给模型,让模型决定是否委托远程 Agent。
python
import requests
BASE_URL = "https://order-service.example.com"
API_TOKEN = "replace-with-service-token"
def fetch_agent_card() -> dict:
response = requests.get(f"{BASE_URL}/.well-known/agent.json", timeout=10)
response.raise_for_status()
return response.json()
def call_remote_agent(message: str) -> dict:
headers = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json",
}
payload = {
"id": "task-ord-001",
"sessionId": "session-web-001",
"message": {
"role": "user",
"parts": [{"type": "text", "text": message}],
},
}
response = requests.post(
f"{BASE_URL}/task",
json=payload,
headers=headers,
timeout=30,
)
response.raise_for_status()
return response.json()
card = fetch_agent_card()
skill_names = [skill["name"] for skill in card.get("skills", [])]
print("remote skills:", skill_names)
result = call_remote_agent("查询订单 ORD-20240315-001 的当前状态")
print(result["status"]["state"])
print(result["artifacts"][0]["parts"][0]["text"])这个 demo 的关键点有两个:先读 Agent Card 再调用,不要硬编码对方能力;请求里带认证信息,不要把 Agent 间调用当成普通函数调用。
A2A 和 MCP 的区别
这两个协议经常一起出现,容易混淆:
| 维度 | MCP | A2A |
|---|---|---|
| 解决的问题 | Agent 怎么调用工具 | Agent 怎么调用 Agent |
| 通信对象 | 工具服务(数据库、API、文件系统) | 另一个 AI Agent |
| 典型场景 | Agent 查询数据库、调用搜索 API | Orchestrator Agent 委托专业 Agent 处理子任务 |
| 协议设计者 | Anthropic |
两者可以同时使用:一个 Orchestrator Agent 通过 A2A 调用专业 Agent,专业 Agent 内部通过 MCP 调用工具。
当前的实际状态
A2A 协议发布于 2025 年,目前整体还处于早期阶段:
已经有的:
- Google 发布了官方规范和参考实现
- LangGraph 和部分框架开始支持 A2A
- 有社区实现的 SDK(Python、JS)
还在发展中的:
- 生态系统仍在建立,大多数生产系统还是自定义集成
- 安全和权限控制机制还在完善
- 跨组织的 Agent 发现机制(类似 DNS 的 Agent 目录)还没有标准
对于现在正在做多 Agent 系统的开发者来说,了解 A2A 协议是值得的,但不必急着在所有系统里落地。如果你的多 Agent 协调在单个代码库里,用 LangGraph 或者自定义调用已经够用;A2A 在跨系统、跨团队的 Agent 集成场景里更有价值。
和多 Agent 协调的关系
A2A 是多 Agent 系统的通信层,解决"怎么连接"的问题。但连接之后怎么协调工作——谁是 Orchestrator、任务怎么拆分、结果怎么聚合——这些是系统设计层面的问题,A2A 本身不规定。
这部分的工程设计在 复杂 Agent 系统解析 里有更详细的讨论。
和 LangGraph 怎么集成
LangGraph 负责把一个 Agent 系统内部的流程编排成图,A2A 负责跨服务调用。两者可以放在同一套系统里,但位置不同。
一种常见做法是:
- LangGraph 里的 Orchestrator 节点分析用户任务
- 某个节点读取远程 Agent Card,判断是否有合适 skill
- 如果需要委托,就调用 A2A Task 接口
- 远程 Agent 返回 artifacts 后,写回 LangGraph state
- 后续节点继续汇总、追问或调用其他工具
在代码层面,A2A 调用可以被包成一个 LangChain tool,也可以直接写成 LangGraph 节点。选择取决于你想让模型自由决定调用,还是由图里的条件边明确控制。
如果远程 Agent 调用涉及真实业务动作,我更倾向放在显式节点里。这样可以在调用前加权限检查、人审、幂等键和超时处理。把它包装成一个普通工具虽然方便,但模型可能在不合适的时候重复调用。
一个简化的节点大概是这样:
python
def call_order_agent_node(state: dict) -> dict:
task = call_remote_agent(state["user_message"])
if task["status"]["state"] != "completed":
return {"remote_error": task["status"]}
answer = task["artifacts"][0]["parts"][0]["text"]
return {"order_agent_answer": answer}这个节点不关心远程 Agent 内部是怎么推理的。它只关心协议返回的状态和 artifacts,这正是 A2A 适合放在系统边界的原因。
常见面试考点
A2A 题目数量不多,但容易和 MCP 混在一起。准备时先把层级关系讲清楚:
- 五大设计原则:Agnostic 不绑定模型和框架;Async 支持长任务;Multimodal 支持多类型消息;Interoperability 保证跨系统互通;Security 要求认证、授权和审计。
- A2A vs MCP:MCP 连接工具和数据源,A2A 连接另一个 Agent;前者偏能力接入,后者偏 Agent 间协作。
- Agent Card:它是远程 Agent 的能力说明,调用方要通过它了解名称、地址、技能、输入输出模式、流式能力和认证方式。
- Task / Message 模型:A2A 的基本交互单元是任务,消息和 artifacts 承载输入输出,适合长任务、异步状态和多模态结果。
- 认证机制:内部集成可用 API Key,但要有轮换和审计;跨组织或用户授权场景更适合 OAuth2 和 scope 控制。
- 流式与状态更新:耗时任务不能只等最终结果,SSE 进度返回有助于调用方展示中间状态和处理超时。
- LangGraph 集成:LangGraph 做内部流程编排,A2A 做远程 Agent 通信;A2A 调用可以封装成 tool,也可以作为显式图节点。
- 适用边界:单个系统内部的多 Agent 不一定需要 A2A;跨团队、跨系统、跨组织的 Agent 集成才更能体现价值。
下一章:多 Agent 协调——A2A 解决 Agent 之间怎么通信,协调章节继续讨论任务怎么拆、结果怎么汇总、冲突怎么处理。