11# A2A Simple - Agent-to-Agent 通信协议
22
3- 基于火山引擎 VeADK 和 A2A (Agent-to-Agent) 协议构建的分布式智能体示例,展示如何实现智能体之间的通信和协作 。
3+ 基于火山引擎 VeADK 和 A2A (Agent-to-Agent) 协议构建的智能体示例,展示如何实现标准化的智能体服务 。
44
55## 概述
66
7- 本示例演示 A2A 协议的基础应用,展示如何构建可互操作的分布式智能体系统 。
7+ 本示例演示 A2A 协议的基础应用,展示如何构建符合 A2A 协议标准的智能体服务 。
88
99## 核心功能
1010
1111- A2A 协议:标准化的智能体间通信协议
12- - 远程服务:提供工具能力的远程 Agent
13- - 本地客户端:调用远程 Agent 的客户端
12+ - Agent 服务:提供工具能力的 A2A Agent
13+ - 客户端调用:通过 A2A 协议调用 Agent 服务
1414- 工具能力:投掷骰子和检查质数
1515- 状态管理:跨工具调用的状态持久化
1616
1717## Agent 能力
1818
1919``` text
20- 方式一:直接客户端调用
20+ 客户端调用流程
2121本地客户端 (local_client.py)
2222 ↓
2323A2A 协议 (HTTP/JSONRPC)
2424 ↓
25- 远程 Agent 服务 (remote/ agent.py:8001 )
25+ Agent 服务 (agent.py:8000 )
2626 ├── roll_die 工具 (投掷骰子)
2727 │ └── 状态管理:rolls 历史
2828 │
2929 └── check_prime 工具 (检查质数)
30-
31- 方式二:Agent 级联调用
32- 本地 Agent (agent.py:8000)
33- ├── add 工具 (加法)
34- └── RemoteVeAgent → 远程 Agent 服务 (remote/agent.py:8001)
35- ├── roll_die 工具 (投掷骰子)
36- └── check_prime 工具 (检查质数)
3730```
3831
3932## 目录结构说明
4033
4134``` bash
4235a2a_simple/
43- ├── agent.py # 本地 Agent 服务(端口 8000,可调用远程 Agent )
36+ ├── agent.py # Agent 服务(端口 8000)
4437├── local_client.py # A2A 客户端实现
45- ├── remote/ # 远程 Agent 服务
46- │ ├── agent.py # Agent 定义和 A2A App(端口 8001)
47- │ ├── agentkit.yaml # AgentKit 部署配置
48- │ ├── requirements.txt # Python 依赖
49- │ ├── Dockerfile # Docker 镜像构建
50- │ └── tools/ # 工具实现
51- │ ├── roll_die.py # 投掷骰子工具
52- │ └── check_prime.py # 质数检查工具
53- ├── requirements.txt # 客户端依赖
38+ ├── tools/ # 工具实现
39+ │ ├── roll_die.py # 投掷骰子工具
40+ │ └── check_prime.py # 质数检查工具
41+ ├── agentkit.yaml # AgentKit 部署配置
42+ ├── requirements.txt # Python 依赖
5443├── pyproject.toml # 项目配置
44+ ├── Dockerfile # Docker 镜像构建
5545└── README.md # 项目说明文档
5646```
5747
5848### 核心组件
5949
6050| 组件 | 描述 |
6151| - | - |
62- | ** 远程 Agent** | [ remote/agent.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/remote/agent.py#L14-L40 ) - hello_world_agent,提供工具服务(端口 8001) |
63- | ** 本地 Agent** | [ agent.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/agent.py#L16-L21 ) - a2a_sample_agent,具有 add 工具和 sub_agents(端口 8000) |
64- | ** 本地客户端** | [ local_client.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/local_client.py ) - A2ASimpleClient,调用远程服务 |
65- | ** 工具:roll_die** | [ remote/tools/roll_die.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/remote/tools/roll_die.py ) - 投掷骰子 |
66- | ** 工具:check_prime** | [ remote/tools/check_prime.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/remote/tools/check_prime.py ) - 检查质数 |
52+ | ** Agent 服务** | [ agent.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/agent.py ) - hello_world_agent,提供工具服务(端口 8000) |
53+ | ** 本地客户端** | [ local_client.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/local_client.py ) - A2ASimpleClient,调用 Agent 服务 |
54+ | ** 工具:roll_die** | [ tools/roll_die.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/tools/roll_die.py ) - 投掷骰子 |
55+ | ** 工具:check_prime** | [ tools/check_prime.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/tools/check_prime.py ) - 检查质数 |
6756| ** AgentCard** | Agent 元数据和能力描述 |
68- | ** 项目配置** | [ remote/ agentkit.yaml] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/remote /agentkit.yaml ) - AgentKit 部署配置 |
57+ | ** 项目配置** | [ agentkit.yaml] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/agentkit.yaml ) - AgentKit 部署配置 |
6958
7059### 代码特点
7160
72- ** 本地 Agent 定义** ([ agent.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/agent.py#L16-L21 ) ):
73-
74- ``` python
75- agent = Agent(
76- name = " a2a_sample_agent" ,
77- instruction = " You are a helpful assistant that can add numbers and delegate tasks to a remote agent that can roll dice and check prime numbers." ,
78- tools = [add],
79- sub_agents = [remote_agent],
80- )
81- ```
82-
83- ** 远程 Agent 定义** ([ remote/agent.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/remote/agent.py#L14-L40 ) ):
61+ ** Agent 定义** ([ agent.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/agent.py#L9-L35 ) ):
8462
8563``` python
8664root_agent = Agent(
87- name = ' hello_world_agent' ,
65+ name = " hello_world_agent" ,
8866 description = (
89- ' hello world agent that can roll a dice of 8 sides and check prime numbers.'
67+ " hello world agent that can roll a dice of 8 sides and check prime numbers."
9068 ),
9169 instruction = """
9270 You roll dice and answer questions about the outcome of the dice rolls.
9371 You can roll dice of different sizes.
94- You can use multiple tools in parallel by calling functions in parallel.
95- When you are asked to roll a die, you must call the roll_die tool.
96- When checking prime numbers, call the check_prime tool with a list of integers.
72+ You can use multiple tools in parallel by calling functions in parallel(in one request and in one round).
73+ It is ok to discuss previous dice roles, and comment on the dice rolls.
74+ When you are asked to roll a die, you must call the roll_die tool with the number of sides. Be sure to pass in an integer. Do not pass in a string.
75+ You should never roll a die on your own.
76+ When checking prime numbers, call the check_prime tool with a list of integers. Be sure to pass in a list of integers. You should never pass in a string.
77+ You should not check prime numbers before calling the tool.
78+ When you are asked to roll a die and check prime numbers, you should always make the following two function calls:
79+ 1. You should first call the roll_die tool to get a roll. Wait for the function response before calling the check_prime tool.
80+ 2. After you get the function response from roll_die tool, you should call the check_prime tool with the roll_die result.
81+ 2.1 If user asks you to check primes based on previous rolls, make sure you include the previous rolls in the list.
82+ 3. When you respond, you must include the roll_die result from step 1.
83+ You should always perform the previous 3 steps when asking for a roll and checking prime numbers.
84+ You should not rely on the previous history on prime results.
9785 """ ,
98- tools = [roll_die, check_prime],
86+ tools = [
87+ roll_die,
88+ check_prime,
89+ ],
9990)
10091```
10192
102- ** AgentCard 配置** ([ remote/ agent.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/remote/ agent.py#L48-L58 ) ):
93+ ** AgentCard 配置** ([ agent.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/agent.py#L45-L55 ) ):
10394
10495``` python
10596agent_card = AgentCard(
106- capabilities = AgentCapabilities(streaming = True ),
107- description = root_agent.description,
108- name = root_agent.name,
109- defaultInputModes = [" text" ],
110- defaultOutputModes = [" text" ],
111- provider = AgentProvider(organization = " agentkit" , url = " " ),
112- skills = [AgentSkill(id = " 0" , name = " chat" , description = " Chat" , tags = [" chat" ])],
113- url = " http://localhost:8001 " ,
114- version = " 1.0.0" ,
97+ capabilities = AgentCapabilities(streaming = True ),
98+ description = root_agent.description,
99+ name = root_agent.name,
100+ default_input_modes = [" text" ],
101+ default_output_modes = [" text" ],
102+ provider = AgentProvider(organization = " agentkit" , url = " " ),
103+ skills = [AgentSkill(id = " 0" , name = " chat" , description = " Chat" , tags = [" chat" ])],
104+ url = " http://localhost:8000 " ,
105+ version = " 1.0.0" ,
115106)
116107```
117108
118- ** 本地客户端调用** ([ local_client.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/local_client.py#L32-L97 ) ):
109+ ** 本地客户端调用** ([ local_client.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/local_client.py#L28-L88 ) ):
119110
120111``` python
121112async def create_task (self , agent_url : str , message : str ) -> str :
@@ -134,17 +125,17 @@ async def create_task(self, agent_url: str, message: str) -> str:
134125 responses.append(response)
135126```
136127
137- ** 工具状态管理** ([ remote/ tools/roll_die.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/remote/ tools/roll_die.py#L4-L18 ) ):
128+ ** 工具状态管理** ([ tools/roll_die.py] ( https://github.com/volcengine/agentkit-samples/blob/main/02-use-cases/beginner/a2a_simple/tools/roll_die.py#L6-L21 ) ):
138129
139130``` python
140131def roll_die (sides : int , tool_context : ToolContext) -> int :
141132 result = random.randint(1 , sides)
142133
143134 # 状态持久化
144- if not ' rolls' in tool_context.state:
145- tool_context.state[' rolls' ] = []
135+ if " rolls" not in tool_context.state:
136+ tool_context.state[" rolls" ] = []
146137
147- tool_context.state[' rolls' ] = tool_context.state[' rolls' ] + [result]
138+ tool_context.state[" rolls" ] = tool_context.state[" rolls" ] + [result]
148139 return result
149140```
150141
@@ -186,11 +177,11 @@ cd 02-use-cases/beginner/a2a_simple
186177# 如果没有 `uv` 虚拟环境,可以使用命令先创建一个虚拟环境
187178uv venv --python 3.12
188179
189- # 使用 `pyproject.toml` 管理依赖
190- uv sync --index-url https://pypi.tuna.tsinghua.edu.cn/simple
191-
192180# 激活虚拟环境
193181source .venv/bin/activate
182+
183+ # 使用 `pyproject.toml` 管理依赖
184+ uv sync --index-url https://pypi.tuna.tsinghua.edu.cn/simple
194185```
195186
196187### 环境准备
@@ -215,19 +206,19 @@ veadk web
215206# 在浏览器访问:http://127.0.0.1:8000
216207```
217208
218- Web 界面提供图形化对话测试环境,支持实时查看远程调用过程 。
209+ Web 界面提供图形化对话测试环境,支持实时查看调用过程 。
219210
220211#### 方式二:命令行测试(推荐学习)
221212
222- ** 步骤 1:启动远程 Agent 服务:**
213+ ** 步骤 1:启动 Agent 服务:**
223214
224215``` bash
225216# 在终端窗口 1 中运行
226217cd 02-use-cases/beginner/a2a_simple
227- uv run uvicorn remote. agent:a2a_app --host localhost --port 8001
218+ uv run agent.py
228219
229220# 服务启动后,可访问 Agent Card
230- # http://localhost:8001 /.well-known/agent-card.json
221+ # http://localhost:8000 /.well-known/agent-card.json
231222```
232223
233224** 步骤 2:运行本地客户端:**
@@ -238,22 +229,6 @@ cd 02-use-cases/beginner/a2a_simple
238229python local_client.py
239230```
240231
241- ** 步骤 3(可选):启动本地 Agent 服务:**
242-
243- ``` bash
244- # 在终端窗口 3 中运行(需要先启动远程 Agent)
245- cd 02-use-cases/beginner/a2a_simple
246- python agent.py
247-
248- # 服务启动后,可访问 Agent Card
249- # http://localhost:8000/.well-known/agent-card.json
250- ```
251-
252- 此时您有两个 Agent 服务:
253-
254- - ** 远程 Agent** (端口 8001):提供 roll_die 和 check_prime 工具
255- - ** 本地 Agent** (端口 8000):提供 add 工具,并可调用远程 Agent
256-
257232## AgentKit 部署
258233
259234### 前置准备
@@ -272,7 +247,7 @@ python agent.py
272247### Agentkit 云上部署
273248
274249``` bash
275- cd 02-use-cases/beginner/a2a_simple/remote
250+ cd 02-use-cases/beginner/a2a_simple
276251
277252# 配置部署参数(重要:agent_type 必须为 a2a)
278253agentkit config
@@ -377,10 +352,7 @@ Agent Card 提供以下信息:
377352访问方式:
378353
379354``` bash
380- # 远程 Agent Card
381- http://localhost:8001/.well-known/agent-card.json
382-
383- # 本地 Agent Card(如果启动了 agent.py)
355+ # Agent Card
384356http://localhost:8000/.well-known/agent-card.json
385357```
386358
@@ -393,55 +365,23 @@ http://localhost:8000/.well-known/agent-card.json
393365- 示例:记录投掷历史
394366
395367``` python
396- tool_context.state[' rolls' ] = tool_context.state[' rolls' ] + [result]
368+ tool_context.state[" rolls" ] = tool_context.state[" rolls" ] + [result]
397369```
398370
399- ### 远程调用流程
371+ ### 调用流程
400372
401- ** 方式一:直接客户端调用 (local_client.py):**
373+ ** 客户端调用流程 (local_client.py):**
402374
403- 1 . ** 获取 Agent Card** :了解远程 Agent 的能力
375+ 1 . ** 获取 Agent Card** :了解 Agent 的能力
4043762 . ** 创建客户端** :基于 Agent Card 创建 A2A 客户端
4053773 . ** 发送消息** :通过 A2A 协议发送请求
406- 4 . ** 接收响应** :处理远程 Agent 的响应
407-
408- ** 方式二:Agent 级联调用(agent.py):**
409-
410- 1 . ** 定义 RemoteVeAgent** :配置远程 Agent 的 URL
411- 2 . ** 注册为 sub_agents** :将远程 Agent 注册到本地 Agent
412- 3 . ** 自动路由** :本地 Agent 自动将任务委派给合适的 Agent
413- 4 . ** 统一接口** :对外提供统一的 A2A 接口
414-
415- ### Agent 级联(Sub-Agents)
416-
417- 通过 ` sub_agents ` 参数,可以构建 Agent 级联架构:
418-
419- ``` python
420- from veadk.a2a.remote_ve_agent import RemoteVeAgent
421-
422- remote_agent = RemoteVeAgent(
423- name = " a2a_agent" ,
424- url = " http://localhost:8001/" ,
425- )
426-
427- agent = Agent(
428- name = " a2a_sample_agent" ,
429- tools = [add],
430- sub_agents = [remote_agent], # 级联远程 Agent
431- )
432- ```
433-
434- ** 优势:**
435-
436- - 本地 Agent 可以同时使用本地工具和远程 Agent 的工具
437- - 自动处理工具路由和调用
438- - 支持多个远程 Agent 级联
439- - 对外暴露统一的 A2A 接口
378+ 4 . ** 接收响应** :处理 Agent 的响应
440379
441380### AgentKit A2A App
442381
443382``` python
444383from agentkit.apps import AgentkitA2aApp
384+ from google.adk.a2a.executor.a2a_agent_executor import A2aAgentExecutor
445385
446386a2a_app = AgentkitA2aApp()
447387
@@ -459,7 +399,6 @@ a2a_app.run(agent_card=agent_card, host="0.0.0.0", port=8000)
4593991 . ** [ Multi Agents] ( https://github.com/volcengine/agentkit-samples/tree/main/02-use-cases/beginner/multi_agents/README.md ) ** - 构建多智能体协作系统
4604002 . ** [ Restaurant Ordering] ( https://github.com/volcengine/agentkit-samples/tree/main/02-use-cases/beginner/restaurant_ordering/README.md ) ** - 高级 Agent 特性
4614013 . ** [ Travel Concierge] ( https://github.com/volcengine/agentkit-samples/tree/main/02-use-cases/beginner/travel_concierge/README.md ) ** - 使用 Web 搜索工具
462- 4 . ** 分布式系统** :部署多个 A2A Agent 构建分布式智能体网络
463402
464403## 常见问题
465404
0 commit comments