Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 67 additions & 44 deletions docs/docs/agent/agent-to-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,49 @@ title: A2A Agent
---

## Agent-to-Agent 协议简介

对于复杂度较高的任务,往往无法依赖单个 Agent 独立完成,需要通过协同多个专用 Agent 共同解决。**Agent2Agent (A2A) 协议** 是用于在多个 Agent 之间进行通信的标准。
!!! note 参考链接
- [A2A 协议官方文档](https://a2a-protocol.org/latest/)

## 多 Agent 系统

多 Agent 系统架构通常有两种架构方式: **Local Sub-Agents** 和 **Remote Agents (A2A)**

- **Local Sub-Agents**:这类 Agent 与主 Agent 在同一个应用进程中。它们更像内部模块或库,用于将代码组织为逻辑、可复用的组件。主 Agent 与 Local Sub-Agents 之间的通信直接发生在内存中,无需网络开销,因此速度非常快。
- **Remote Agents (A2A)**:这类 Agent 以独立服务形式运行,通过网络进行通信。A2A 为此类通信定义了标准协议。
### 如何选择合适的 Agent 架构 <!-- 标题序号: 2 -->

### 如何选择合适的 Agent 架构

并不是所有场景都适合使用 A2A,需要您参考以下建议,结合实际使用场景和需求作出合适选择:

#### 适合使用 A2A 的场景
| 场景名称 | 说明 |
| --------------- | ----------------------------------------- |
| **集成第三方服务** | 需要交互的 Agent 是一个独立的、可单独运行的第三方服务(例如需要从外部金融数据服务获取实时交易信息) |
| **微服务架构** | 不同的 Agent 由不同的团队或组织维护, A2A 用于些服务跨网络边界相互通信 |
| **跨语言通信** | 要连接使用不同编程语言或 Agent 框架实现的 Agent, A2A 提供了标准化的通信层 |
| **严格的 API 契约** |为了保证兼容性与稳定性,需要为 Agent 之间的交互制定严格契约 |

<!-- 标题序号: 2.1 -->

#### 不适用 A2A 的场景(更适合 Local Sub-Agents): <!-- 标题序号: 2.2 -->
| 场景名称 | 说明 |
| ----------- | ----------------------------------------- |
| **内部代码组织** | 您在单个 Agent 内将复杂任务拆分为更小、可管理的函数或模块,这类场景出于性能与简洁考虑,更适合作为本地子 |
| **性能关键的内部操作** | 某个 Sub Agent 负责与主 Agent 执行紧密耦合的高频、低延迟操作,这类场景由于需要低延迟响应,更适合作为本地Local Sub-Agents。 |
| **共享内存或上下文** | 当 Sub Agent 需要直接访问主 Agent 的内部状态或共享内存以提高效率时,A2A 的网络开销与序列化/反序列化会适得其反 |
| **简单的辅助函数** |对于无需独立部署或复杂状态管理的小型复用逻辑,直接在同一 Agent 中编写函数或类,通常比拆分为独立的 A2A Agent 更合适 |

## VeADK 中的 A2A 工作流: <!-- 标题序号: 3 -->

| 场景名称 | 说明 |
| - | - |
| **集成第三方服务** | 需要交互的 Agent 是一个独立的、可单独运行的第三方服务(例如需要从外部金融数据服务获取实时交易信息) |
| **微服务架构** | 不同的 Agent 由不同的团队或组织维护, A2A 用于些服务跨网络边界相互通信 |
| **跨语言通信** | 要连接使用不同编程语言或 Agent 框架实现的 Agent, A2A 提供了标准化的通信层 |
| **严格的 API 契约** | 为了保证兼容性与稳定性,需要为 Agent 之间的交互制定严格契约 |

#### 不适用 A2A 的场景(更适合 Local Sub-Agents)

| 场景名称 | 说明 |
| - | - |
| **内部代码组织** | 您在单个 Agent 内将复杂任务拆分为更小、可管理的函数或模块,这类场景出于性能与简洁考虑,更适合作为本地子 |
| **性能关键的内部操作** | 某个 Sub Agent 负责与主 Agent 执行紧密耦合的高频、低延迟操作,这类场景由于需要低延迟响应,更适合作为本地Local Sub-Agents |
| **共享内存或上下文** | 当 Sub Agent 需要直接访问主 Agent 的内部状态或共享内存以提高效率时,A2A 的网络开销与序列化/反序列化会适得其反 |
| **简单的辅助函数** | 对于无需独立部署或复杂状态管理的小型复用逻辑,直接在同一 Agent 中编写函数或类,通常比拆分为独立的 A2A Agent 更合适 |

## VeADK 中的 A2A 工作流

**VeADK** 简化了基于 A2A 协议构建并连接 Agent 的过程。下面是一个直观的工作流概览:

1. **对 Agent 开放访问(Exposing):** 从现有的 VeADK Agent 入手,将其转化为一个 A2AServer, 把它变成能让其他 Agent 可访问的形式。A2AServer 可以视作为 Agent 搭建的一个 Web 服务,其他 Agent 可以通过它向您的 Agent 发送请求。
1. **对 Agent 开放访问(Exposing):** 从现有的 VeADK Agent 入手,将其转化为一个 A2AServer把它变成能让其他 Agent 可访问的形式。A2AServer 可以视作为 Agent 搭建的一个 Web 服务,其他 Agent 可以通过它向您的 Agent 发送请求。
2. **连接到开放访问的 Agent(Consuming):**在另一个 Agent 中(可能运行于同一台机器,也可能运行于不同机器),可使用名为 `RemoteVeAgent` 的 VeADK 组件,作为客户端访问上一步创建的 A2AServer,`RemoteVeAgent` 会在后台处理网络通信、鉴权和数据格式等复杂问题。

**VeADK** 对网络层进行了抽象封装,使分布式多 Agent 系统使用体验接近本地系统, 下图展示了一个完整的 **A2A 系统拓扑**:

```mermaid
flowchart LR
A[Root Agent<br/>(需要访问其它 Agent)<br/>]
Expand All @@ -54,13 +60,16 @@ flowchart LR
```

## 构建一个本地 A2A 项目

下面是一个利用 A2A 搭建的系统示例:

### 创建 A2A 服务器

1. 定义 Agent 工具和功能
2. 使用 to_a2a() 函数将 Agent 转换为 A2AServer
2. 使用 `to_a2a(...)` 函数将 Agent 转换为 A2AServer
3. 配置服务器参数(端口、主机等)
=== "代码"

=== "Python"

```python title="server.py" linenums="1" hl_lines="1 11"
from google.adk.a2a.utils.agent_to_a2a import to_a2a
Expand All @@ -75,13 +84,16 @@ agent = Agent(

app = to_a2a(agent=agent)
```

### 客户端集成
1. 导入 RemoteVeAgent 类

1. 导入 `RemoteVeAgent` 类
2. 配置远程 Agent 连接参数
3. 在 Root Agent 中添加 Remote Agent 作为 Sub Agent
=== "代码"

```python title="client.py" linenums="1"
=== "Python"

```python title="client.py" linenums="1" hl_lines="15 24"
from veadk import Agent, Runner
from veadk.a2a.remote_ve_agent import RemoteVeAgent

Expand Down Expand Up @@ -120,8 +132,11 @@ if __name__ == "__main__":
response = asyncio.run(main("What is the weather like of Beijing?"))
print(response)
```

### 交互流程

下图为示例对应的交互流程图

```mermaid
sequenceDiagram
participant User as 用户
Expand Down Expand Up @@ -149,13 +164,18 @@ sequenceDiagram
Client-->>User: 显示天气信息
```

## A2A Client 鉴权参数
VeADK 的 A2A 鉴权机制提供了灵活的认证选项,支持标准的 Bearer token 认证和查询参数认证两种常见模式,同时也支持无认证的公开服务场景,能够满足不同的安全需求
### Querystring 方式
- 将认证令牌作为 URL 查询参数 token={auth_token} 传递
- 通过设置 auth_method 为 "querystring" 来启用
## 身份认证与鉴权

VeADK 的 A2A 鉴权机制提供了灵活的认证选项,支持标准的 Bearer token 认证和查询参数认证两种常见模式,同时也支持无认证的公开服务场景,能够满足不同的安全需求。

### QueryString 方式

- 将认证令牌作为 URL 查询参数 `?token={auth_token}` 传递
- 通过设置 `auth_method` 为 `querystring` 来启用
- 适用于某些特定的 API 网关或服务配置
=== "代码"

=== "Python"

```python title="client.py" linenums="1" hl_lines="5"
remote_agent = RemoteVeAgent(
name="a2a_agent",
Expand All @@ -166,10 +186,13 @@ VeADK 的 A2A 鉴权机制提供了灵活的认证选项,支持标准的 Beare
```

### Header 方式
- 使用 Authorization: Bearer {auth_token} 格式的 HTTP header 进行鉴权
- 通过设置 auth_method="header" 来启用

- 使用 Authorization: Bearer {auth_token} 格式的 HTTP 请求头进行鉴权
- 通过设置 `auth_method="header"` 来启用
- 适用于需要在 HTTP header 中传递认证信息的场景
=== "代码"

=== "Python"

```python title="client.py" linenums="1" hl_lines="5"
remote_agent = RemoteVeAgent(
name="a2a_agent",
Expand All @@ -179,24 +202,28 @@ VeADK 的 A2A 鉴权机制提供了灵活的认证选项,支持标准的 Beare
)
```

??? note "火山引擎 veFaaS 采用的默认鉴权方式"
??? note "火山引擎 VeFaaS 采用的默认鉴权方式"
- 当您使用火山引擎 veFaaS 作为您的 Agent runtime 时,默认使用 Querystring 方式进行认证鉴权,请参考以下截图中的 “我的应用”中可以查看您创建的资源对应的访问地址信息中携带的 Querystring 认证鉴权信息
![火山 veFaaS 应用中的认证信息](../assets/images/agents/a2a_querystring.png)

### 自定义 HTTP 客户端
在 VeADK中,主要通过 RemoteVeAgent 类来实现自定义 HTTP 客户端的配置,它提供了一个 httpx_client 参数,允许您传入预配置的 httpx.AsyncClient 实例。这使得您可以灵活地控制 HTTP 请求的各种参数,如代理设置、超时控制、连接池管理等,从而更好地适应不同的网络环境和需求。
#### 您可以通过运参考以下示例代码设置创建自定义的 HTTP 客户端,可配置各种 HTTP 客户端参数,如:

在 VeADK中,主要通过 `RemoteVeAgent` 类来实现自定义 HTTP 客户端的配置,它提供了一个 `httpx_client` 参数,允许您传入预配置的 `httpx.AsyncClient` 实例。这使得您可以灵活地控制 HTTP 请求的各种参数,如代理设置、超时控制、连接池管理等,从而更好地适应不同的网络环境和需求。

您可以通过运参考以下示例代码设置创建自定义的 HTTP 客户端,可配置各种 HTTP 客户端参数,如:

- 超时设置
- 代理配置
- 连接池大小
- 重试策略
- 自定义请求头
- SSL 验证选项

=== "代码"
```python title="client.py" linenums="1"
=== "Python"

```python title="client.py" linenums="1" hl_lines="4 43"
# <...code truncated...>

# 创建自定义的 httpx.AsyncClient 实例
custom_client = httpx.AsyncClient(
# 基础 URL 设置
Expand Down Expand Up @@ -242,7 +269,3 @@ VeADK 的 A2A 鉴权机制提供了灵活的认证选项,支持标准的 Beare

# <...code truncated...>
```




117 changes: 60 additions & 57 deletions docs/docs/agent/agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@
}
```


=== "所需环境变量"

环境变量列表:
Expand Down Expand Up @@ -126,17 +125,16 @@

```golang title="agent.go" linenums="1" hl_lines="2-4"
cfg := &veagent.Config{}
cfg.Name = "life_assistant"
cfg.Description = "生活助手"
cfg.Instruction = "你是一个生活助手,你可以回答用户的问题。"

veAgent, err := veagent.New(cfg)
if err != nil {
fmt.Printf("NewVeAgent failed: %v", err)
return
}
```
cfg.Name = "life_assistant"
cfg.Description = "生活助手"
cfg.Instruction = "你是一个生活助手,你可以回答用户的问题。"

veAgent, err := veagent.New(cfg)
if err != nil {
fmt.Printf("NewVeAgent failed: %v", err)
return
}
```

其中,`name` 代表 Agent 的名称,`description` 是对 Agent 功能的简单描述(在Agent Tree中唯一标识某个Agent),`instruction` 是 Agent 的系统提示词,用于定义其行为和响应风格。

Expand All @@ -161,50 +159,56 @@

```golang title="agent.go" linenums="1" hl_lines="2-4"
cfg := &veagent.Config{
ModelName: "...",
ModelAPIBase: "...",
ModelAPIKey: "...",
}
ModelName: "...",
ModelAPIBase: "...",
ModelAPIKey: "...",
}

veAgent, err := veagent.New(cfg)
if err != nil {
fmt.Printf("NewVeAgent failed: %v", err)
return
}
if err != nil {
fmt.Printf("NewVeAgent failed: %v", err)
return
}
```

由于 python VeADK Agent 基于 [LiteLLM]() 实现,因此您可以使用 LiteLLM 支持的所有模型提供商。您可以查看 [LiteLLM 支持的模型提供商列表](https://docs.litellm.ai/docs/providers)来设置 `model_provider` 参数。
VeADK Python 版本中的 Agent 推理模型基于 [LiteLLM](https://github.com/BerriAI/litellm) 实现,因此您可以使用 LiteLLM 支持的所有模型提供商。您可以查看 [LiteLLM 支持的模型提供商列表](https://docs.litellm.ai/docs/providers)来设置 `model_provider` 参数。

基于 LiteLLM 的 [Fallbacks](https://docs.litellm.ai/docs/completion/reliable_completions) 容错机制,VeADK 实现了智能的模型切换能力。当目标模型经多次重试仍调用失败时,系统将自动切换至备选模型继续执行任务:
#### 模型容错

VeADK 为您提供了基于 LiteLLM 的 [Fallbacks](https://docs.litellm.ai/docs/completion/reliable_completions) 模型容错机制,能够在前序模型访问失败时进行模型自动切换。例如,当目标模型经多次重试仍调用失败时,系统将自动切换至备选模型来继续执行任务:

=== "Python"

```python title="agent.py" linenums="1" hl_lines="4"
```python title="agent.py" linenums="1" hl_lines="4-8"
from veadk import Agent

agent = Agent(
model_name=["doubao-seed-1-8-251215", "doubao-seed-1-6-251015", "doubao-seed-1.6-250615"]
model_name=[
"doubao-seed-1-8-251215",
"doubao-seed-1-6-251015",
"doubao-seed-1.6-250615",
]
)
```

在上述配置中,VeADK 默认会首先尝试 doubao-seed-1-8-251215,如果失败再去尝试后续模型,直至成功。

golang 暂不支持 LiteLLM,因此 VeADK 的 Agent 基于 OpenAI 实现,因此您可以使用所有支持OpenAI协议的模型。
在上述配置中,VeADK 默认会首先尝试 `doubao-seed-1-8-251215` 模型,如果失败后会尝试后续模型,直至成功。

#### 设置模型客户端
#### 自定义您的模型客户端

VeADK 支持您直接定义 LiteLLM 的客户端,来实现高度自定义的模型配置:

```python title="agent.py" linenums="1" hl_lines="5 8"
from google.adk.models.lite_llm import LiteLlm
from veadk import Agent
=== "Python"

# 自定义您的模型客户端
llm = LiteLlm()
```python title="agent.py" linenums="1" hl_lines="5 8"
from google.adk.models.lite_llm import LiteLlm
from veadk import Agent

# 直接将模型客户端传递给 Agent
agent = Agent(model=llm)
```
# 自定义您的模型客户端
llm = LiteLlm()

# 直接将模型客户端传递给 Agent
agent = Agent(model=llm)
```

#### 配置模型额外参数

Expand Down Expand Up @@ -236,21 +240,20 @@ agent = Agent(model=llm)
)

veAgent, err := veagent.New(&veagent.Config{
ModelExtraConfig: map[string]any{
"extra_body": map[string]any{
"thinking": map[string]string{
"type": "disabled",
},
},
},
})
if err != nil {
fmt.Printf("NewVeAgent failed: %v", err)
return
}
ModelExtraConfig: map[string]any{
"extra_body": map[string]any{
"thinking": map[string]string{
"type": "disabled",
},
},
},
})
if err != nil {
fmt.Printf("NewVeAgent failed: %v", err)
return
}
```


### 通过配置文件

在您构建 Agent 过程中,往往需要更加简洁的 Agent 定义方式与配置管理。为了方便这种场景,VeADK 提供了 YAML 文件定义方式。该方法以声明式语法描述智能体的全部元信息与行为结构。
Expand All @@ -265,7 +268,7 @@ root_agent:
description: An intelligent_assistant which can provider weather information.
instruction: Help user according to your tools.
model_name: doubao-1-5-pro-32k-250115
model_api_key: xxx # 您的模型API Key
model_api_key: ... # 您的模型API Key
tools:
- name: veadk.tools.demo_tools.get_city_weather # tool 所在的模块及函数名称
```
Expand Down Expand Up @@ -297,14 +300,14 @@ response = asyncio.run(runner.run("今天北京天气如何?"))
print(response)
```

### 构建 Agent 的方法对比
## 构建 Agent 的方法对比

**对比总结**:

| 特性 | 代码方式 | YAML 方式 |
| 特性 | 代码方式 | YAML 方式 |
| ---- | ----- | ------- |
| 灵活性 | 高 | 中 |
| 可读性 | 中 | 高 |
| 可维护性 | 中 | 高 |
| 动态生成 | 支持 | 一般 |
| 适用场景 | 开发、生产 | 实验、配置化、生产 |
| 灵活性 | 高 | 中 |
| 可读性 | 中 | 高 |
| 可维护性 | 中 | 高 |
| 动态生成 | 支持 | 一般 |
| 适用场景 | 开发、生产 | 实验、配置化、生产 |
2 changes: 1 addition & 1 deletion docs/docs/agent/responses-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Responses API 是火山方舟最新推出的 API 接口,原生支持高效的
from veadk import Agent

root_agent = Agent(
enable_responses=True, # 开启 Responses API
enable_responses=True, # 开启 Responses API
)

```
Expand Down
Loading