快速入门:通过 A2A 使用远程智能体¶
本快速入门涵盖了任何开发人员最常见的起点:“有一个远程智能体,我如何让我的 ADK 智能体通过 A2A 使用它?”。这对于构建需要不同智能体协作和交互的复杂多智能体系统至关重要。
概述¶
此示例演示了智能体开发工具包(ADK)中的智能体到智能体(A2A)架构,展示了多个智能体如何协同工作以处理复杂任务。该示例实现了一个可以掷骰子并检查数字是否为质数的智能体。
┌─────────────────┐ ┌──────────────────┐ ┌────────────────────┐
│ 根智能体 │───▶│ 掷骰子智能体 │ │ 远程质数 │
│ (本地) │ │ (本地) │ │ 智能体 │
│ │ │ │ │ (localhost:8001) │
│ │───▶│ │◀───│ │
└─────────────────┘ └──────────────────┘ └────────────────────┘
A2A 基础示例包括:
- 根智能体 (
root_agent):将任务委托给专门子智能体的主要协调器 - 掷骰子智能体 (
roll_agent):处理掷骰子操作的本地子智能体 - 质数智能体 (
prime_agent):检查数字是否为质数的远程 A2A 智能体,此智能体在单独的 A2A 服务器上运行
使用 ADK 服务器暴露你的智能体¶
在 a2a_basic 示例中,你首先需要通过 A2A 服务器暴露 check_prime_agent,以便本地根智能体可以使用它。
1. 获取示例代码¶
首先,请确保你已安装 Go 并设置好环境。
你可以在此处克隆并导航到 a2a_basic 示例:
如你所见,文件夹结构如下:
a2a_basic/
├── remote_a2a/
│ └── check_prime_agent/
│ └── main.go
├── go.mod
├── go.sum
└── main.go # 本地根智能体
主智能体 (a2a_basic/main.go)¶
rollDieTool: 用于掷骰子的函数工具newRollAgent: 专门用于掷骰子的本地智能体newPrimeAgent: 远程 A2A 智能体配置newRootAgent: 具有委托逻辑的主要协调器
远程质数智能体 (a2a_basic/remote_a2a/check_prime_agent/main.go)¶
checkPrimeTool: 质数检查算法main: 质数检查服务和 A2A 服务器的实现。
2. 启动远程质数智能体服务器¶
为了展示你的 ADK 智能体如何通过 A2A 使用远程智能体,你首先需要启动一个远程智能体服务器,该服务器将托管质数智能体(在 check_prime_agent 下)。
执行后,你应该会看到类似以下内容:
2025/11/06 11:00:19 Starting A2A prime checker server on port 8001
2025/11/06 11:00:19 Starting the web server: &{port:8001}
2025/11/06 11:00:19
2025/11/06 11:00:19 Web servers starts on http://localhost:8001
2025/11/06 11:00:19 a2a: you can access A2A using jsonrpc protocol: http://localhost:8001
3. 留意远程智能体所需的智能体卡片¶
A2A 协议要求每个智能体都必须有一个描述其功能的智能体卡片。
在 Go ADK 中,当你使用 A2A 启动器暴露智能体时,智能体卡片是动态生成的。你可以访问 http://localhost:8001/.well-known/agent-card.json 查看生成的卡片。
4. 运行主(消费)智能体¶
工作原理¶
主智能体使用 remoteagent.New 来使用远程智能体(在我们的示例中是 prime_agent)。如下所示,它需要 Name、Description 和 AgentCardSource URL。
func newPrimeAgent() (agent.Agent, error) {
remoteAgent, err := remoteagent.NewA2A(remoteagent.A2AConfig{
Name: "prime_agent",
Description: "Agent that handles checking if numbers are prime.",
AgentCardSource: "http://localhost:8001",
})
if err != nil {
return nil, fmt.Errorf("failed to create remote prime agent: %w", err)
}
return remoteAgent, nil
}
然后,你可以简单地在你的根智能体中使用远程智能体。在这种情况下,primeAgent 在下面的 root_agent 中用作子智能体之一:
func newRootAgent(ctx context.Context, rollAgent, primeAgent agent.Agent) (agent.Agent, error) {
model, err := gemini.NewModel(ctx, "gemini-2.0-flash", &genai.ClientConfig{})
if err != nil {
return nil, err
}
return llmagent.New(llmagent.Config{
Name: "root_agent",
Model: model,
Instruction: `
You are a helpful assistant that can roll dice and check if numbers are prime.
You delegate rolling dice tasks to the roll_agent and prime checking tasks to the prime_agent.
Follow these steps:
1. If the user asks to roll a die, delegate to the roll_agent.
2. If the user asks to check primes, delegate to the prime_agent.
3. If the user asks to roll a die and then check if the result is prime, call roll_agent first, then pass the result to prime_agent.
Always clarify the results before proceeding.
`,
SubAgents: []agent.Agent{rollAgent, primeAgent},
Tools: []tool.Tool{},
})
}
示例交互¶
一旦你的主智能体和远程智能体都运行起来,你就可以与根智能体交互,看看它如何通过 A2A 调用远程智能体:
简单的掷骰子: 此交互使用本地智能体,即掷骰子智能体:
用户:掷一个 6 面骰子
机器人调用工具:transfer_to_agent,参数:map[agent_name:roll_agent]
机器人调用工具:roll_die,参数:map[sides:6]
机器人:我掷了一个 6 面骰子,结果是 6。
质数检查:
此交互通过 A2A 使用远程智能体,即质数智能体:
用户:7 是质数吗?
机器人调用工具:transfer_to_agent,参数:map[agent_name:prime_agent]
机器人调用工具:prime_checking,参数:map[nums:[7]]
机器人:是的,7 是一个质数。
组合操作:
此交互同时使用本地的掷骰子智能体和远程的质数智能体:
用户:掷一个骰子并检查它是否是质数
机器人:好的,我将首先掷一个骰子,然后检查结果是否是质数。
机器人调用工具:transfer_to_agent,参数:map[agent_name:roll_agent]
机器人调用工具:roll_die,参数:map[sides:6]
机器人调用工具:transfer_to_agent,参数:map[agent_name:prime_agent]
机器人调用工具:prime_checking,参数:map[nums:[3]]
机器人:3 是一个质数。
下一步¶
现在你已经创建了一个通过 A2A 服务器使用远程智能体的智能体,下一步是学习如何暴露你自己的智能体。
- A2A 快速入门(暴露):学习如何暴露你现有的智能体,以便其他智能体可以通过 A2A 协议使用它。