Skip to content

快速入门:通过 A2A 暴露远程智能体

Supported in ADKGo实验性

本快速入门涵盖了任何开发人员最常见的起点:“我有一个智能体。我如何暴露它以便其他智能体可以通过 A2A 使用我的智能体?”。这对于构建需要不同智能体协作和交互的复杂多智能体系统至关重要。

概述

此示例演示了如何轻松暴露一个 ADK 智能体,以便另一个智能体可以使用 A2A 协议来消费它。

在 Go 中,你可以通过使用 A2A 启动器来暴露一个智能体,它会为你动态生成一个智能体卡片。

┌─────────────────┐                             ┌───────────────────────────────┐
│   根智能体       │       A2A 协议               │ A2A 暴露的检查质数智能体         │
│                 │────────────────────────────▶│      (localhost: 8001)        │
└─────────────────┘                             └───────────────────────────────┘

该示例包括:

  • 远程质数智能体 (remote_a2a/check_prime_agent/main.go):这是你想要暴露以便其他智能体可以通过 A2A 使用的智能体。它是一个处理质数检查的智能体。它通过 A2A 启动器被暴露。
  • 根智能体 (main.go):一个仅调用远程质数智能体的简单智能体。

使用 A2A 启动器暴露远程智能体

你可以将使用 Go ADK 构建的现有智能体通过 A2A 启动器使其与 A2A 兼容。

1. 获取示例代码

首先,请确保你已安装 Go 并设置好环境。

你可以在此处克隆并导航到 a2a_basic 示例

cd examples/go/a2a_basic

如你所见,文件夹结构如下:

a2a_basic/
├── remote_a2a/
│   └── check_prime_agent/
│       └── main.go    # 远程质数智能体
├── go.mod
├── go.sum
└── main.go            # 根智能体

根智能体 (a2a_basic/main.go)

  • newRootAgent: 连接到远程 A2A 服务的本地智能体。

远程质数智能体 (a2a_basic/remote_a2a/check_prime_agent/main.go)

  • checkPrimeTool: 用于质数检查的函数。
  • main: 创建智能体并启动 A2A 服务器的主函数。

2. 启动远程 A2A 智能体服务器

你现在可以启动远程智能体服务器,它将托管 check_prime_agent

# 启动远程智能体
go run remote_a2a/check_prime_agent/main.go

执行后,你应该会看到类似以下内容:

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 启动器自动生成的智能体卡片来检查你的智能体是否已启动并正在运行:

http://localhost:8001/.well-known/agent-card.json

你应该会看到智能体卡片的内容。

4. 运行主(消费)智能体

现在你的远程智能体正在运行,你可以运行主智能体。

# 在单独的终端中,运行主智能体
go run main.go

工作原理

远程智能体在 main 函数中使用 A2A 启动器进行暴露。启动器负责启动服务器并生成智能体卡片。

remote_a2a/check_prime_agent/main.go
func main() {
    ctx := context.Background()
    primeTool, err := functiontool.New(functiontool.Config{
        Name:        "prime_checking",
        Description: "Check if numbers in a list are prime using efficient mathematical algorithms",
    }, checkPrimeTool)
    if err != nil {
        log.Fatalf("Failed to create prime_checking tool: %v", err)
    }

    model, err := gemini.NewModel(ctx, "gemini-2.0-flash", &genai.ClientConfig{})
    if err != nil {
        log.Fatalf("Failed to create model: %v", err)
    }

    primeAgent, err := llmagent.New(llmagent.Config{
        Name:        "check_prime_agent",
        Description: "check prime agent that can check whether numbers are prime.",
        Instruction: `
            You check whether numbers are prime.
            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.
            You should not rely on the previous history on prime results.
    `,
        Model: model,
        Tools: []tool.Tool{primeTool},
    })
    if err != nil {
        log.Fatalf("Failed to create agent: %v", err)
    }

    // Create launcher. The a2a.NewLauncher() will dynamically generate the agent card.
    port := 8001
    webLauncher := web.NewLauncher(a2a.NewLauncher())
    _, err = webLauncher.Parse([]string{
        "--port", strconv.Itoa(port),
        "a2a", "--a2a_agent_url", "http://localhost:" + strconv.Itoa(port),
    })
    if err != nil {
        log.Fatalf("launcher.Parse() error = %v", err)
    }

    // Create ADK config
    config := &launcher.Config{
        AgentLoader:    agent.NewSingleLoader(primeAgent),
        SessionService: session.InMemoryService(),
    }

    log.Printf("Starting A2A prime checker server on port %d\n", port)
    // Run launcher
    if err := webLauncher.Run(context.Background(), config); err != nil {
        log.Fatalf("webLauncher.Run() error = %v", err)
    }
}

示例交互

一旦两个服务都运行起来,你就可以与根智能体交互,看看它如何通过 A2A 调用远程智能体:

质数检查:

此交互通过 A2A 使用远程智能体,即质数智能体:

用户:掷一个骰子并检查它是否是质数
机器人:好的,我将首先掷一个骰子,然后检查结果是否是质数。

机器人调用工具: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 服务器暴露远程智能体的智能体,下一步是学习如何从另一个智能体消费它。