A2A协议的应用
明确如下几个问题
- Agent是什么呢?
- 为什么需要引入多个agent呢?单个agent不能解决问题吗?
- 为什么需要引入A2A协议?A2A协议的作用是什么?
- Agent的分类
1. 什么是 Agent?
简单来说,Agent = 大模型**(如豆包、DeepSeek) + 工具 + 交互协议**。大模型擅长文本理解与决策,但无法直接执行具体操作(比如查天气、查机票、创建文件);为了让大模型 "长出手",就需要搭配工具(如天气查询接口、机票预订系统),而 MCP 协议则负责解决 "大模型如何调用工具" 的问题 ------ 三者结合,就是能独立完成特定任务的智能体(Agent)。
2. 为什么需要多个 Agent?单个 Agent 不行吗?
核心原因是 "单一职责原则"+"避免上下文过载":
- 实际场景(如 "查天气选机票")需要多种不同能力,若让一个 Agent 包揽所有任务,会导致其逻辑复杂、响应变慢;
- 大模型存在 "上下文长度限制":上下文过长时,结果准确性会下降。把 Agent 按职责拆分(如天气 Agent 只负责查天气、机票 Agent 只负责查机票),每个 Agent 专注于单一领域,既能提升专业度和响应速度,也能避免单个 Agent 上下文过载。
3. 为什么需要 A2A 协议?它的作用是什么?
A2A(Agent to Agent)协议是 多个 Agent 之间的 "通信标准"。当系统中有多个分工不同的 Agent 时,它们需要协同工作(如调度 Agent 要给天气 Agent 发查询指令、接收返回结果),而不同 Agent 可能由不同团队开发、基于不同技术实现 ------A2A 协议的核心作用就是:
- 统一 Agent 间的交互格式(如请求参数、返回结果的规范);
- 让 Agent 之间无需人工适配就能 "互相理解",实现自动化协同;
- 降低 Agent 接入和扩展的成本(新 Agent 只要遵循 A2A 协议,就能快速融入系统)。
4. Agent 的分类
Agent 按角色可分为两类,类似 "组长与组内成员" 的关系:
- 调度 Agent(消费者 Agent):相当于 "组长",不负责具体任务执行,核心职责是:接收用户需求(如 "查天气选机票")→ 拆解任务(拆成 "查天气""查机票" 两个子任务)→ 调度对应 Agent 执行 → 整合所有结果反馈给用户;
- 功能 Agent(提供者 Agent):相当于 "组内成员",负责执行具体任务(如天气 Agent 查天气、机票 Agent 查机票),只能响应调度 Agent 的指令,不直接对接用户。
名词解释
| 名词 | 描述 | 示例 |
|---|---|---|
| Agent Card | Agent 的「身份 + 能力说明书」 | json<br/>{<br/> "capabilities": {<br/> "streaming": false<br/> },<br/> "defaultInputModes": [<br/> "text"<br/> ],<br/> "defaultOutputModes": [<br/> "text"<br/> ],<br/> "description": "提供天气相关的查询功能",<br/> "name": "天气 Agent",<br/> "preferredTransport": "JSONRPC",<br/> "protocolVersion": "0.3.0",<br/> "skills": [<br/> {<br/> "description": "给出某地的天气预告",<br/> "examples": [<br/> "给我纽约未来 7 天的天气预告"<br/> ],<br/> "id": "天气预告",<br/> "name": "天气预告",<br/> "tags": [<br/> "天气",<br/> "预告"<br/> ]<br/> },<br/> {<br/> "description": "给出某地当前时间的空气质量报告,不做预告",<br/> "examples": [<br/> "给我纽约当前的空气质量报告"<br/> ],<br/> "id": "空气质量报告",<br/> "name": "空气质量报告",<br/> "tags": [<br/> "空气",<br/> "质量"<br/> ]<br/> }<br/> ],<br/> "url": "http://127.0.0.1:10000",<br/> "version": "1.0.0"<br/>}<br/> |
| Client Agent (A2A Client) | A2A 调用方(消费者) | 调度Agent |
| Remote Agent (A2A Server) | A2A 服务提供方(提供者) | 天气Agent |
示例
整体的流程分为
- 注册阶段
- 用户问答阶段
注册阶段
天气Agent 调度Agent 平台 用户 天气Agent 调度Agent 平台 用户 调度Agent的职责: 任务拆解 + 下发 Agent列表: [天气Agent] 可用工具: send_message 提交天气Agent的URL 请求 /.well-known/agent.json 返回 Agent Card 创建
通过Wireshark抓包工具抓包获取结果如下

用户问答阶段
天气Agent 调度Agent 平台 用户 天气Agent 调度Agent 平台 用户 西雅图明天的天气怎么样? 西雅图明天的天气怎么样? 西雅图明天的天气怎么样? 未来三天的天气如下:... 西雅图明天晴天 西雅图明天晴天
注:蓝色表示使用A2A协议的部分
进阶
多个Agent提供服务
机票Agent 调度Agent 机票Agent(提供者) 天气Agent(提供者) 调度Agent(消费者) 平台 用户 机票Agent 调度Agent 机票Agent(提供者) 天气Agent(提供者) 调度Agent(消费者) 平台 用户 前置:所有Agent遵循A2A协议,已完成注册 任务拆解: 1. 查5.1-5.3天气 2. 查对应日期机票 3. 整合推荐 按天气适配机票: 筛选晴朗日期的低价机票 我要查5.1-5.3天气,选合适的机票 转发用户复合需求 A2A请求:查询5.1-5.3天气(统一格式) A2A响应:返回天气数据(统一格式) A2A请求:查询5.1-5.3机票(统一格式) A2A响应:返回机票数据(统一格式) 返回整合后的推荐结果 展示最终结果:天气+适配机票推荐
流式响应
提问-回答如下

调度Agent发送给天气Agent的请求

可以发现调度Agent发送给天气Agent的请求,过滤掉了订机票的提问prompt。
由于5月1日是晴天,后续调度Agent发给机票Agent的请求就只需要关注5月1日的机票信息了,"请帮我查询2025年5月1日从西雅图飞往纽约的航班有哪些?"
上述过程体现了调度Agent的任务分配
请求-响应示例
发往机票Agent的请求
JSON
{
"id": "0a96020b-5876-4011-94d4-b8fc4743b911",
"jsonrpc": "2.0",
"method": "message/stream",
"params": {
"configuration": {
"acceptedOutputModes": [
"text",
"text/plain",
"image/png"
]
},
"message": {
"contextId": "b5cdbc7f-504e-4174-a543-ba8aef6e85a9",
"kind": "message",
"messageId": "9a022c61-4948-4731-b0b0-2671c66b0b43",
"parts": [
{
"kind": "text",
"text": "请帮我查询2025年5月1日从西雅图飞往纽约的航班有哪些?"
}
],
"role": "user"
}
}
}
注:"method": "message/stream" 流式返回
机票Agent的返回
JSON
data: {
"id": "0a96020b-5876-4011-94d4-b8fc4743b911",
"jsonrpc": "2.0",
"result": {
"contextId": "b5cdbc7f-504e-4174-a543-ba8aef6e85a9",
"history": [
{
"contextId": "b5cdbc7f-504e-4174-a543-ba8aef6e85a9",
"kind": "message",
"messageId": "9a022c61-4948-4731-b0b0-2671c66b0b43",
"parts": [
{
"kind": "text",
"text": "请帮我查询2025年5月1日从西雅图飞往纽约的航班有哪些?"
}
],
"role": "user",
"taskId": "41469774-41a2-4b33-b0fb-1f12f6bbef6e"
}
],
"id": "41469774-41a2-4b33-b0fb-1f12f6bbef6e",
"kind": "task",
"status": {
"state": "submitted"
}
}
}
data: {
"id": "0a96020b-5876-4011-94d4-b8fc4743b911",
"jsonrpc": "2.0",
"result": {
"append": false,
"artifact": {
"artifactId": "6b457be7-8c24-4ca2-879d-cd03fe3528a1",
"parts": [
{
"kind": "text",
"text": "你要查询的机票"
}
]
},
"contextId": "b5cdbc7f-504e-4174-a543-ba8aef6e85a9",
"kind": "artifact-update",
"lastChunk": false,
"taskId": "41469774-41a2-4b33-b0fb-1f12f6bbef6e"
}
}
data: {
"id": "0a96020b-5876-4011-94d4-b8fc4743b911",
"jsonrpc": "2.0",
"result": {
"append": true,
"artifact": {
"artifactId": "6b457be7-8c24-4ca2-879d-cd03fe3528a1",
"parts": [
{
"kind": "text",
"text": "如下:"
}
]
},
"contextId": "b5cdbc7f-504e-4174-a543-ba8aef6e85a9",
"kind": "artifact-update",
"lastChunk": false,
"taskId": "41469774-41a2-4b33-b0fb-1f12f6bbef6e"
}
}
data: {
"id": "0a96020b-5876-4011-94d4-b8fc4743b911",
"jsonrpc": "2.0",
"result": {
"append": true,
"artifact": {
"artifactId": "6b457be7-8c24-4ca2-879d-cd03fe3528a1",
"parts": [
{
"kind": "text",
"text": "1. 航班号 FAKE-001,起飞时间 20:00,余票 30 张;2. 航班号 FAKE-002,起飞时间 23:00,余票 50 张"
}
]
},
"contextId": "b5cdbc7f-504e-4174-a543-ba8aef6e85a9",
"kind": "artifact-update",
"lastChunk": true,
"taskId": "41469774-41a2-4b33-b0fb-1f12f6bbef6e"
}
}
data: {
"id": "0a96020b-5876-4011-94d4-b8fc4743b911",
"jsonrpc": "2.0",
"result": {
"contextId": "b5cdbc7f-504e-4174-a543-ba8aef6e85a9",
"final": true,
"kind": "status-update",
"status": {
"state": "completed"
},
"taskId": "41469774-41a2-4b33-b0fb-1f12f6bbef6e"
}
}