使用 Go 版 ADK 的 Agent Starter Pack

1. 简介

使用 Go 的 ADK

虽然 Python 在模型训练和研究方面仍然很受欢迎,但 服务编排 AI 智能体的要求与 Go 的优势(低延迟、高并发和类型安全)非常契合。

从原型智能体过渡到生产智能体会带来工程方面的挑战,而 Go 可以出色地应对这些挑战。Go 的静态类型化功能可在解析结构化 LLM 输出时消除运行时错误。与操作系统线程的数兆字节相比,其轻量级 Goroutine 仅需几千字节的堆栈内存,因此代理可以处理数千个并发工具执行,而不会产生繁重的线程管理开销。

Google 的智能体开发套件 (ADK) 弥合了这些架构优势与生成式 AI 之间的差距。在本指南中,您将搭建一个新项目,并将其作为安全的微服务部署到 Google Cloud 上。

您应执行的操作:

  • 使用 Agent Starter Pack 搭建可用于生产用途的智能体项目
  • 利用本地智能体开发套件 Web 界面调试和测试智能体
  • 开发并了解基于 Go 的 ADK 智能体逻辑
  • 运行单元测试和端到端 (E2E) 测试
  • 将代理安全地部署到 Cloud Run

所需条件:

  • 网络浏览器,例如 Chrome
  • 启用了结算功能的 Google Cloud 项目

2. 准备工作

创建 Google Cloud 项目

如果您还没有该停牌,请执行以下操作:

  1. Google Cloud 控制台的项目选择器页面上,选择或创建一个 Google Cloud 项目
  2. 确保您的 Cloud 项目已启用结算功能。

启动 Cloud Shell

Cloud Shell 是在 Google Cloud 中运行的命令行环境,预加载了必要的工具。它将作为本实验的主要开发环境。

  1. 点击 Google Cloud 控制台顶部的激活 Cloud Shell
  2. 连接到 Cloud Shell 后,运行以下命令以验证您在 Cloud Shell 中的身份验证
gcloud auth list
  1. 运行以下命令,确认您的项目已配置为可与 gcloud 搭配使用:
gcloud config get project
  1. 确认项目符合预期,然后运行以下命令以设置项目 ID
export PROJECT_ID=$(gcloud config get project)

3. Agent Starter Pack 使用入门

好消息是,您无需从头开始。Agent Starter Pack 是一款 CLI 工具,可搭建可用于生产用途的文件夹结构,包括 CI/CD 流水线、基础架构配置和样板代码。

如需开始使用,只需运行带有 uvx 的 build 创建命令:

uvx agent-starter-pack create

CLI 将引导您完成交互式设置。对于此项目,请选择以下选项:

  • 项目名称: my-first-go-agent
  • 模板:选项 6(Go ADK,使用 A2A 的 Go 代理)
  • CI/CD:选项 3 (GitHub Actions)
  • 区域: us-central1

Agent Starter Pack 设置

看到绿色的成功!消息后,您就可以继续操作了。

成功消息

4. 在本地直观呈现 Agent

ADK 最便捷的功能之一是能够在部署代理之前直观地调试代理。运行以下命令可启动具有内置界面的本地开发服务器。是的,它有一个聊天窗口,但它不仅限于此,还可以跟踪事件、工具调用等。

切换到项目目录并启动 Playground:

cd my-first-go-agent
make install
make playground

当 Playground 运行后,在 Cloud Shell 中打开网页预览,与您新建的智能体互动。

该代理配置了 ReAct(推理和行动)模式,该框架已成为智能体 AI 的基础。ReAct 模式通过“思考”“行动”和“观察”的持续循环来增强问题解决能力和可解释性,使智能体的决策过程透明化。

例如,如果您询问天气,代理会识别出意图,调用 get_weather 工具,并返回结构化数据。

Playground 界面

5. 了解代码

现在,我们已经了解了代理的实际应用,接下来我们来看看实现此功能的 Go 代码。逻辑位于 agent/agent.go 中。此文件用于处理工具定义、模型配置和初始化。

ADK 使用标准 Go 结构体来定义大语言模型 (LLM) 如何与您的代码互动。为了定义天气工具的输入参数,我们定义了一个带有 jsonjsonschema 标记的结构体:

type GetWeatherArgs struct {
    City string `json:"city" jsonschema:"City name to get weather for"`
}

GetWeatherResult 定义了工具执行后返回给代理的数据的结构:

// GetWeatherResult defines the output for the get_weather tool.
type GetWeatherResult struct {
	Weather string `json:"weather"`
}

GetWeather 是一个标准 Go 函数,它接受 tool.Context 和实参结构体,执行业务逻辑并返回结果结构体:

// GetWeather returns mock weather data for a city.
func GetWeather(_ tool.Context, args GetWeatherArgs) (GetWeatherResult, error) {
	return GetWeatherResult{
		Weather: "It's sunny and 72°F in " + args.City,
	}, nil
}

NewRootAgent 函数负责组装并返回应用启动器所需的 agent.Agent 实例。它首先初始化模型配置,创建一个由 genai.BackendVertexAI 支持的 gemini-2.5-flash 模型实例。

接下来,它通过将本地 GetWeather 函数封装到 functiontool 中,弥合了 Go 代码与 LLM 之间的差距。此步骤会注册名称为 get_weather 的工具,并为模型的上下文提供必要的说明。最后,它使用 llmagent.New 构建智能体,该函数会将初始化的 Gemini 模型、定义智能体行为的系统指令和可用工具切片组合成一个单元。

// NewRootAgent creates and returns the root agent with all configured tools.
func NewRootAgent(ctx context.Context) (agent.Agent, error) {
	model, err := gemini.NewModel(ctx, "gemini-2.5-flash", &genai.ClientConfig{
		Backend: genai.BackendVertexAI,
	})

	weatherTool, err := functiontool.New(functiontool.Config{
		Name:        "get_weather",
		Description: "Get the current weather for a city.",
	}, GetWeather)

	rootAgent, err := llmagent.New(llmagent.Config{
		Name:        "my-first-go-agent",
		Model:       model,
		Description: "A helpful AI assistant.",
		Instruction: "You are a helpful AI assistant designed to provide accurate and useful information.",
		Tools:       []tool.Tool{weatherTool},
	})
	// ... (additional logic omitted for brevity)
	return rootAgent, nil
}

6. 测试

该项目包含内部逻辑的单元测试和服务器集成的端到端测试。

agent/agent_test.go 中,系统会使用一组测试用例调用 GetWeather 函数,以验证输出字符串是否符合预期。

func TestGetWeather(t *testing.T) {
	// tests struct initialized with "San Francisco" and "New York"

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Pass nil for tool.Context since GetWeather doesn't use it
			result, err := GetWeather(nil, GetWeatherArgs{City: tt.city})
			if err != nil {
				t.Fatalf("GetWeather() error = %v", err)
			}
			if !strings.Contains(result.Weather, tt.wantCity) {
				t.Errorf("GetWeather() = %v, want city %v in response", result.Weather, tt.wantCity)
			}
		})
	}
}

端到端测试用于验证代理在作为服务器运行时是否正常工作,具体来说,就是检查 A2A 或代理到代理协议支持是否正常工作。E2E 测试会启动服务器的实际实例,向其发送 HTTP 请求,并检查响应。

以下是 e2e/integration/server_e2e_test.go 中的一段代码:

func TestA2AMessageSend(t *testing.T) {
    if testing.Short() { t.Skip("Skipping E2E test in short mode") }

    // Start server (local variable to avoid race conditions)
    t.Log("Starting server process")
    serverProcess := startServer(t)
    defer stopServer(t, serverProcess)

    if !waitForServer(t, 90*time.Second) {
	    t.Fatal("Server failed to start")
    }
    t.Log("Server process started")
    // ...
}

您可以使用 Makefile 在本地运行所有测试:

make test

7. 部署

当您准备好与全世界分享您的代理或将其连接到生产生态系统时,请运行随附的部署命令:

make deploy

此命令使用 Google Cloud Buildpack 从源代码自动构建应用,由 --source . 标志触发。它使用多个经过生产环境优化的标志将此映像部署到 Cloud Run:--memory "4Gi" 为 LLM 操作提供充足的 RAM,以及 --no-cpu-throttling 确保 CPU 全天候保持分配状态,这可以防止冷启动并确保在代理互动中快速响应。

为确保代理安全运行,系统在部署时会采用严格的配置,使用 --no-allow-unauthenticated 默认阻止所有公开访问,并要求对所有请求进行 Identity and Access Management (IAM) 身份验证。它还会注入包括 GOOGLE_GENAI_USE_VERTEXAI=True 在内的环境变量。

部署服务网址

启用 IAP

启用 IAP 并将您的电子邮件地址添加为主账号后,您可以前往部署后提供的服务网址。查看基本服务网址可让您看到已部署的代理卡片。此 JSON 结构充当智能体的标准接口,使其他智能体、编排器或面向用户的界面能够动态发现和使用该智能体。

代理卡片

8. 清理

为避免系统向您的 Google Cloud 账号持续收取费用,请删除在此 Codelab 中创建的资源。

您可以删除 Cloud 项目,这样系统会停止对该项目中使用的所有资源计费:

gcloud projects delete $PROJECT_ID

您可能还需要从 Cloud Shell 磁盘中删除 Codelab 项目目录:

rm -rf ~/my-first-go-agent

9. 恭喜!

🎊 任务完成!您已使用智能体开发套件成功搭建、测试并部署了 Go 中的 AI 智能体。

您的学习成果

  • 使用 Agent Starter Pack 搭建了初始结构化基准
  • 在本地验证并测试了代理界面和代码
  • 深入研究了将 LLM 行为映射到 Go 对象的类型化架构和函数
  • 已将 Go 服务部署到 Cloud Run

后续操作

  • ADK 文档:有关高级模式、多智能体编排和记忆系统的完整指南
  • 智能体入门指南:探索模板,包括多智能体系统和复杂架构
  • Cloud Run 文档:深入探讨性能优化、扩缩策略和安全性方面的最佳实践
  • Go 并发模式:了解 goroutine 和渠道有助于您构建更高效的代理工具
  • Vertex AI Agent Engine:用于构建具有内置编排和工具的全托管式代理基础设施