A2A是什么

A2A(Agent2Agent Protocol,Agent间协议) 是由Google于2025年4月推出、同年6月捐赠给Linux基金会的开放协议(现由Linux基金会中立治理,Apache 2.0许可)。
- 解决跨agent框架通讯问题:A2A是AI Agent之间的“通用通讯与协作语言”,解决“不同厂商、不同框架、不同云上的Agent如何像团队一样互相发现、委托任务、交换结果,而不泄露各自内部逻辑”的问题。
从协议视角看 A2A
A2A(Agent2Agent)协议是基于 HTTP + JSON-RPC 2.0 的开放标准,主要用于不同AI Agent(可能来自不同框架、不同厂商)之间的通信与协作。它的通信过程本质上是客户端Agent → 远程Agent的请求-响应模式,核心围绕“任务(Task)”展开,支持多种交互风格。
下面按实际通信流程分步说明(最常见、最核心的路径):
前置:Agent发现(Discovery)
客户端Agent首先要知道要找哪个远程Agent,以及它能做什么。
- 最常见方式:获取 Agent Card(一个JSON文件)
- 通过知名路径:https://remote-agent.example.com/.well-known/agent.json 或 /agent-card
- 或通过注册表、直接配置等方式
- Agent Card 里包含:
- 端点URL
- 支持的能力(streaming? push notification?)
- 技能列表(skills)
- 认证要求(API Key、OAuth等)
- 输入/输出模态(text、json、image等)
客户端拿到Card后,就知道远程Agent的URL和认证方式,接下来才能发起通信。
建立上下文(可选,但多轮对话常用)
很多场景需要保持会话连续性,会使用 contextId / sessionId。
- 第一次通信时可以不传,服务器返回后生成一个 contextId
- 后续请求带上这个 contextId,保持历史、记忆、状态
发起任务(核心通信起点)
客户端通过 JSON-RPC 调用远程Agent的端点(通常是 POST 到同一个URL),最重要两个方法:
| 方法名 | 用途 | 典型场景 | 是否阻塞客户端 |
|---|---|---|---|
| sendTask | 同步请求-响应 | 快速、短任务 | 是(等待完整结果) |
| sendTaskSubscribe | 订阅流式更新(建立SSE长连接) | 需要逐步输出、长思考过程 | 否(异步接收) |
请求体示例
{
"jsonrpc": "2.0",
"id": "req-123", // 客户端自己生成的请求ID
"method": "sendTask", // 或 sendTaskSubscribe
"params": {
"id": "task-abc123", // 任务唯一ID,由客户端生成
"sessionId": "sess-xyz", // 可选,保持会话
"contextId": "ctx-456", // 可选,服务器上次返回的上下文ID
"message": {
"role": "user",
"parts": [
{
"type": "text",
"text": "帮我查一下明天上海的天气"
}
]
},
"acceptedOutputModes": ["text"],
"historyLength": 10 // 希望带多少轮历史
}
}
远程Agent收到请求后,任务会经历几个状态(status):
- submitted → 已接收
- working → 正在处理
- input-required → 需要更多信息(最典型的多轮场景!)
- completed → 完成,有最终结果
- failed / cancelled
同步模式(sendTask)流程
-
客户端发 sendTask
-
远程Agent直接返回完整结果(如果很快)或先返回
{status: "working", taskId: "..."} -
如果很快完成,直接在response里带最终artifact(结果)
{ "jsonrpc": "2.0", "id": "req-123", "result": { "task": { "id": "task-abc123", "status": "completed", "artifact": { "parts": [ {"type": "text", "text": "上海明天多云,最高22℃ ..."} ] } } } }
异步/流式模式(sendTaskSubscribe)流程
-
客户端发 sendTaskSubscribe
-
服务器立即返回 {status: “working”} 并建立 SSE 连接
-
之后服务器通过 SSE 源源不断推送更新:
- 状态变化(working → input-required)
- 中间结果(partial artifact)
- 最终 completed + 完整artifact
-
如果出现 input-required,服务器会推送:客户端再发新的 sendTask(带contextId),补充信息,继续流程。
{ "status": "input-required", "message": { "role": "assistant", "parts": [{"type": "text", "text": "请 уточните是查哪个区的天气?"}] } }
更长时间任务的补充方式
- 轮询:客户端定时调用 getTaskStatus 或 getTask 方法查状态
- Webhook(推送通知):客户端在首次请求时提供 webhook URL,服务器完成后POST通知
5. 典型完整一次多轮对话流程(最常见实际使用场景)
- 客户端发现 → 拿到 Agent Card
- 客户端发送 sendTaskSubscribe(带用户问题)
- 服务器 → SSE 推送 working → 思考中…
- 服务器 → SSE 推送 input-required + “请告诉我具体需求”
- 客户端收到后 → 再次发 sendTask(带contextId + 补充信息)
- 服务器继续 → 最终 SSE 推送 completed + 最终答案
- 客户端展示结果,结束或继续下一轮
总结
“客户端把任务(带消息)扔给远程Agent,远程Agent要么一次给完答案,要么分多次(SSE)给部分答案,甚至中途反问要补充信息,所有通信都通过同一个JSON-RPC接口,靠taskId / contextId串联上下文。”