Skip to content

Commit 66612cd

Browse files
optimize a2a simple
1 parent 1084c20 commit 66612cd

File tree

11 files changed

+120
-278
lines changed

11 files changed

+120
-278
lines changed

02-use-cases/beginner/a2a_simple/README.md

Lines changed: 68 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,121 +1,112 @@
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
2323
A2A 协议 (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
4235
a2a_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
8664
root_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
10596
agent_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
121112
async 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
140131
def 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` 虚拟环境,可以使用命令先创建一个虚拟环境
187178
uv venv --python 3.12
188179

189-
# 使用 `pyproject.toml` 管理依赖
190-
uv sync --index-url https://pypi.tuna.tsinghua.edu.cn/simple
191-
192180
# 激活虚拟环境
193181
source .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 中运行
226217
cd 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
238229
python 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)
278253
agentkit 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
384356
http://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 的能力
404376
2. **创建客户端**:基于 Agent Card 创建 A2A 客户端
405377
3. **发送消息**:通过 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
444383
from agentkit.apps import AgentkitA2aApp
384+
from google.adk.a2a.executor.a2a_agent_executor import A2aAgentExecutor
445385

446386
a2a_app = AgentkitA2aApp()
447387

@@ -459,7 +399,6 @@ a2a_app.run(agent_card=agent_card, host="0.0.0.0", port=8000)
459399
1. **[Multi Agents](https://github.com/volcengine/agentkit-samples/tree/main/02-use-cases/beginner/multi_agents/README.md)** - 构建多智能体协作系统
460400
2. **[Restaurant Ordering](https://github.com/volcengine/agentkit-samples/tree/main/02-use-cases/beginner/restaurant_ordering/README.md)** - 高级 Agent 特性
461401
3. **[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

Comments
 (0)