1. 简介
本教程将指导您在 Google Cloud Run 上部署、管理和监控使用智能体开发套件 (ADK) 构建的强大智能体。借助 ADK,您可以创建能够执行复杂的多智能体工作流的智能体。借助 Cloud Run 这个全托管式无服务器平台,您可以将代理部署为可扩缩的容器化应用,而无需担心底层基础架构。借助这一强大组合,您可以专注于智能体的核心逻辑,同时受益于 Google Cloud 的强大且可伸缩的环境。
在本教程中,我们将探讨 ADK 与 Cloud Run 的无缝集成。您将学习如何部署代理,然后深入了解在类似生产环境的设置中管理应用的实际操作。我们将介绍如何通过管理流量来安全地发布代理的新版本,以便您在全面发布之前先让一部分用户测试新功能。
此外,您还将获得监控代理性能的实践经验。我们将通过进行负载测试来模拟真实场景,以观察 Cloud Run 的自动扩缩功能在实际应用中的表现。为了更深入地了解代理的行为和性能,我们将使用 Cloud Trace 启用跟踪。这样一来,您就可以详细了解请求在代理中的整个流程,从而发现并解决任何性能瓶颈。完成本教程后,您将全面了解如何在 Cloud Run 上有效部署、管理和监控由 ADK 提供支持的代理。
在此 Codelab 中,您将采用以下分步方法:
- 在 CloudSQL 上创建 PostgreSQL 数据库,以用于 ADK 代理数据库会话服务
- 设置基本的 ADK 代理
- 设置供 ADK 运行程序使用的数据库会话服务
- 首次将代理部署到 Cloud Run
- 进行负载测试并检查 Cloud Run 自动扩缩
- 部署新的代理修订版本,并逐渐增加新修订版本的流量
- 设置云跟踪并检查代理运行跟踪
架构概览

前提条件
- 能够熟练使用 Python
- 了解使用 HTTP 服务的全栈基本架构
学习内容
- ADK 结构和本地实用程序
- 使用数据库会话服务设置 ADK 代理
- 在 CloudSQL 中设置 PostgreSQL 以供数据库会话服务使用
- 使用 Dockerfile 将应用部署到 Cloud Run 并设置初始环境变量
- 通过负载测试配置和测试 Cloud Run 自动扩缩
- 使用 Cloud Run 逐步发布策略
- 设置 ADK 代理跟踪到 Cloud Trace
所需条件
- Chrome 网络浏览器
- Gmail 账号
- 启用了结算功能的 Cloud 项目
此 Codelab 专为各种水平的开发者(包括新手)设计,并在示例应用中使用 Python。不过,您无需具备 Python 知识即可理解所介绍的概念。
2. 🚀 准备工作坊设置
现在,我们将在此教程中使用 Cloud Shell IDE,点击以下按钮即可前往该 IDE
进入 Cloud Shell 后,从 GitHub 克隆此 Codelab 的模板工作目录,运行以下命令。它将在 deploy_and_manage_adk 目录中创建工作目录
git clone https://github.com/alphinside/deploy-and-manage-adk-service.git deploy_and_manage_adk
然后,在终端中运行以下命令,将克隆的代码库作为工作目录打开
cloudshell workspace ~/deploy_and_manage_adk && cd ~/deploy_and_manage_adk
之后,您的界面应如下所示

这将是我们的主要界面,顶部是 IDE,底部是终端。现在,我们需要准备终端,以创建并激活我们的 Google Cloud 项目,该项目将与之前声明的试用结算账号相关联。我们为您准备了一个脚本,以确保您的终端会话始终处于就绪状态。运行以下命令(确保您已位于 deploy_and_manage_adk 工作区内)
bash setup_trial_project.sh && source .env
运行此命令时,系统会提示建议的项目 ID 名称,您可以按 Enter 继续

等待一段时间后,如果您在控制台中看到以下输出,则可以继续执行下一步 
这表示您的终端已通过身份验证,并已设置为正确的项目 ID(当前目录路径旁边的黄色文字)。此命令的作用是帮助您创建新项目、查找项目并将其与试用结算账号相关联、准备 .env 文件以进行环境变量配置,并为您在终端中激活正确的项目 ID。
现在,我们已准备好进行下一步
3. 🚀 启用 API
在本教程中,我们将与 CloudSQL 数据库、Gemini 模型和 Cloud Run 进行交互,这些产品需要激活以下 API,请运行以下命令来启用它们
这可能需要一段时间。
gcloud services enable aiplatform.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
cloudresourcemanager.googleapis.com \
sqladmin.googleapis.com \
compute.googleapis.com
成功执行该命令后,您应该会看到类似如下所示的消息:
Operation "operations/..." finished successfully.
4. 🚀 Python 环境设置和环境变量
在此 Codelab 中,我们将使用 Python 3.12,并使用 uv Python 项目管理器来简化创建和管理 Python 版本和虚拟环境的需求。此 uv 软件包已预安装在 Cloud Shell 上。
运行此命令以将所需的依赖项安装到 .venv 目录中的虚拟环境
uv sync --frozen
接下来,我们将检查此项目所需的环境变量文件。之前,此文件是由 setup_trial_project.sh 脚本设置的。运行以下命令,在编辑器中打开 .env 文件
cloudshell open .env
您会看到 .env 文件中已应用以下配置。
# .env # Google Cloud and Vertex AI configuration GOOGLE_CLOUD_PROJECT=your-project-id GOOGLE_CLOUD_LOCATION=global GOOGLE_GENAI_USE_VERTEXAI=True # Database connection for session service # DB_CONNECTION_NAME=your-db-connection-name
在此 Codelab 中,我们将使用 GOOGLE_CLOUD_LOCATION 和 GOOGLE_GENAI_USE_VERTEXAI. 的预配置值
现在,我们可以继续执行下一步,创建数据库以供代理用于状态和会话持久性。
5. 🚀 准备 CloudSQL 数据库
我们需要一个数据库,供 ADK 代理稍后使用。我们来在 Cloud SQL 上创建一个 PostgreSQL 数据库。首先运行以下命令以创建数据库实例。我们将使用默认的 postgres 数据库名称,因此在此处跳过数据库创建步骤。我们还需要配置默认数据库用户名(同样是 postgres),为了方便本教程,我们使用 ADK-deployment123 作为密码
gcloud sql instances create adk-deployment \
--database-version=POSTGRES_17 \
--edition=ENTERPRISE \
--tier=db-g1-small \
--region=us-central1 \
--availability-type=ZONAL \
--project=${GOOGLE_CLOUD_PROJECT} && \
gcloud sql users set-password postgres \
--instance=adk-deployment \
--password=ADK-deployment123
在上述命令中,第一个常见的 gcloud sql instances create adk-deployment 是我们用于创建数据库实例的命令。在本教程中,我们使用的是沙盒最低规格。第二个命令 gcloud sql users set-password postgres 用于更改默认 postgres 用户名密码
请注意,我们使用 adk-deployment 作为数据库实例名称。完成后,您应该会在终端中看到如下所示的输出,其中显示实例已就绪,并且默认用户密码已更新
Created [https://sqladmin.googleapis.com/sql/v1beta4/projects/your-project-id/instances/adk-deployment]. NAME: adk-deployment DATABASE_VERSION: POSTGRES_17 LOCATION: us-central1-a TIER: db-g1-small PRIMARY_ADDRESS: xx.xx.xx.xx PRIVATE_ADDRESS: - STATUS: RUNNABLE Updating Cloud SQL user...done.
部署此数据库需要一些时间,在等待 CloudSQL 数据库部署就绪期间,我们先继续下一部分。
6. 🚀 使用 ADK 和 Gemini 2.5 构建天气智能体
ADK 目录结构简介
我们先来了解一下 ADK 的功能以及如何构建代理。您可以通过此网址访问 ADK 的完整文档。ADK 在其 CLI 命令执行中提供了许多实用程序。其中一些如下所示:
- 设置代理目录结构
- 通过 CLI 输入/输出快速尝试互动
- 快速设置本地开发界面网页界面
现在,我们来检查 weather_agent 目录中的代理结构
weather_agent/ ├── __init__.py ├── agent.py └── tool.py
如果您检查 init.py 和 agent.py,您会看到以下代码
# __init__.py
from weather_agent.agent import root_agent
__all__ = ["root_agent"]
# agent.py
import os
from pathlib import Path
import google.auth
from dotenv import load_dotenv
from google.adk.agents import Agent
from weather_agent.tool import get_weather
# Load environment variables from .env file in root directory
root_dir = Path(__file__).parent.parent
dotenv_path = root_dir / ".env"
load_dotenv(dotenv_path=dotenv_path)
# Use default project from credentials if not in .env
_, project_id = google.auth.default()
os.environ.setdefault("GOOGLE_CLOUD_PROJECT", project_id)
os.environ.setdefault("GOOGLE_CLOUD_LOCATION", "global")
os.environ.setdefault("GOOGLE_GENAI_USE_VERTEXAI", "True")
root_agent = Agent(
name="weather_agent",
model="gemini-2.5-flash",
instruction="""
You are a helpful AI assistant designed to provide accurate and useful information.
""",
tools=[get_weather],
)
ADK 代码说明
此脚本包含我们的代理启动,我们在其中初始化了以下内容:
- 将要使用的模型设置为
gemini-2.5-flash - 提供工具
get_weather以支持作为天气智能体的代理功能
在本地运行 Web 界面
现在,我们可以在本地与智能体互动并检查其行为。借助 ADK,我们可以使用开发 Web 界面来互动和检查互动期间发生的情况。运行以下命令以启动本地开发界面服务器
uv run adk web --port 8080
它将生成类似于以下示例的输出,这意味着我们已经可以访问 Web 界面了
INFO: Started server process [xxxx] INFO: Waiting for application startup. +-----------------------------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://localhost:8080. | +-----------------------------------------------------------------------------+ INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
现在,如需检查,请点击 Cloud Shell 编辑器顶部区域的网页预览按钮,然后选择在端口 8080 上预览

您将看到以下网页,您可以在左上角的下拉按钮中选择可用的代理(在本例中应为 weather_agent),并与机器人互动。您将在左侧窗口中看到有关代理运行时日志详情的许多信息

现在,尝试与之互动。在左侧栏中,我们可以检查每个输入的轨迹,从而了解智能体在形成最终答案之前采取的每项操作所花费的时间。

这是 ADK 中内置的可观测性功能之一,目前我们在本地检查它。稍后,我们将了解如何将此功能集成到 Cloud Trace 中,以便集中跟踪所有请求
7. 🚀 部署到 Cloud Run
现在,我们将此代理服务部署到 Cloud Run。为了便于演示,此服务将作为可供他人访问的公共服务公开。不过,请注意,这不是最佳实践,因为这种做法不安全

此部署方案可让您自定义代理后端服务,我们将使用 Dockerfile 将代理部署到 Cloud Run。至此,我们已经拥有将应用部署到 Cloud Run 所需的所有文件(Dockerfile 和 server.py)。有了这两个项目,您就可以灵活地自定义代理部署(例如,添加自定义后端路由和/或添加额外的边车服务以用于监控)。我们将在稍后详细讨论这一点。
现在,我们先部署服务,然后前往 Cloud Shell 终端,确保当前项目已配置为您的有效项目,再次运行设置脚本,您也可以选择使用命令 gcloud config set project [PROJECT_ID] 来配置有效项目
bash setup_trial_project.sh && source .env
现在,我们需要再次访问 .env 文件,打开该文件后,您会看到我们需要取消注释 DB_CONNECTION_NAME 变量并填写正确的值
# Google Cloud and Vertex AI configuration
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=global
GOOGLE_GENAI_USE_VERTEXAI=True
# Database connection for session service
DB_CONNECTION_NAME=your-db-connection-name
如需获取 DB_CONNECTION_NAME 值,请访问 Cloud SQL 信息中心
然后点击您创建的实例。前往云控制台顶部部分的搜索栏,然后输入“Cloud SQL”。然后点击 Cloud SQL 产品

之后,您会看到之前创建的实例,点击该实例

在实例页面中,向下滚动到“连接到此实例”部分,然后复制连接名称以替换 DB_CONNECTION_NAME 值。

然后,使用以下命令打开 .env 文件
cloudshell edit .env
并修改 .env 文件中的 DB_CONNECTION_NAME 变量。您的 .env 文件应如下例所示
# Google Cloud and Vertex AI configuration
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=global
GOOGLE_GENAI_USE_VERTEXAI=True
# Database connection for session service
DB_CONNECTION_NAME=your-project-id:your-location:your-instance-name
然后运行部署脚本
bash deploy_to_cloudrun.sh
如果系统提示您确认要为 Docker 代码库创建制品注册表,只需回答 Y 即可。
在等待部署过程完成期间,我们来看看 deploy_to_cloudrun.sh
#!/bin/bash
# Load environment variables from .env file
if [ -f .env ]; then
export $(cat .env | grep -v '^#' | xargs)
else
echo "Error: .env file not found"
exit 1
fi
# Validate required variables
required_vars=("GOOGLE_CLOUD_PROJECT" "DB_CONNECTION_NAME")
for var in "${required_vars[@]}"; do
if [ -z "${!var}" ]; then
echo "Error: $var is not set in .env file"
exit 1
fi
done
gcloud run deploy weather-agent \
--source . \
--port 8080 \
--project ${GOOGLE_CLOUD_PROJECT} \
--allow-unauthenticated \
--add-cloudsql-instances ${DB_CONNECTION_NAME} \
--update-env-vars SESSION_SERVICE_URI="postgresql+pg8000://postgres:ADK-deployment123@postgres/?unix_sock=/cloudsql/${DB_CONNECTION_NAME}/.s.PGSQL.5432",GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT} \
--region us-central1 \
--min 1 \
--memory 1G \
--concurrency 10
此脚本将加载您的 .env 变量,然后运行部署命令。
仔细观察一下,您会发现,我们只需要一个 gcloud run deploy 命令即可完成部署服务所需的所有必要操作:构建映像、推送到注册表、部署服务、设置 IAM 政策、创建修订版本,甚至路由流量。在此示例中,我们已提供 Dockerfile,因此此命令将利用它来构建应用
部署完成后,您应该会获得类似于以下内容的链接:
https://weather-agent-*******.us-central1.run.app
获取此网址后,您可以在无痕式窗口或移动设备中使用应用,并访问代理开发者界面。在等待部署期间,我们将在下一部分中检查刚刚部署的详细服务
8. 💡 Dockerfile 和后端服务器脚本
为了使代理可以作为服务访问,我们将代理封装在 FastAPI 应用中,该应用将通过 Dockerfile 命令运行。以下是 Dockerfile 的内容
FROM python:3.12-slim
RUN pip install --no-cache-dir uv==0.7.13
WORKDIR /app
COPY . .
RUN uv sync --frozen
EXPOSE 8080
CMD ["uv", "run", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8080"]
我们可以在此处配置必要服务来支持代理,例如准备用于生产目的的会话、内存或制品服务。以下是将使用的 server.py 的代码
import os
from dotenv import load_dotenv
from fastapi import FastAPI
from google.adk.cli.fast_api import get_fast_api_app
from pydantic import BaseModel
from typing import Literal
from google.cloud import logging as google_cloud_logging
# Load environment variables from .env file
load_dotenv()
logging_client = google_cloud_logging.Client()
logger = logging_client.logger(__name__)
AGENT_DIR = os.path.dirname(os.path.abspath(__file__))
# Get session service URI from environment variables
session_uri = os.getenv("SESSION_SERVICE_URI", None)
# Prepare arguments for get_fast_api_app
app_args = {"agents_dir": AGENT_DIR, "web": True, "trace_to_cloud": True}
# Only include session_service_uri if it's provided
if session_uri:
app_args["session_service_uri"] = session_uri
else:
logger.log_text(
"SESSION_SERVICE_URI not provided. Using in-memory session service instead. "
"All sessions will be lost when the server restarts.",
severity="WARNING",
)
# Create FastAPI app with appropriate arguments
app: FastAPI = get_fast_api_app(**app_args)
app.title = "weather-agent"
app.description = "API for interacting with the Agent weather-agent"
class Feedback(BaseModel):
"""Represents feedback for a conversation."""
score: int | float
text: str | None = ""
invocation_id: str
log_type: Literal["feedback"] = "feedback"
service_name: Literal["weather-agent"] = "weather-agent"
user_id: str = ""
# Example if you want to add your custom endpoint
@app.post("/feedback")
def collect_feedback(feedback: Feedback) -> dict[str, str]:
"""Collect and log feedback.
Args:
feedback: The feedback data to log
Returns:
Success message
"""
logger.log_struct(feedback.model_dump(), severity="INFO")
return {"status": "success"}
# Main execution
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8080)
服务器代码说明
以下是 server.py 脚本中定义的内容:
- 使用
get_fast_api_app方法将我们的代理转换为 FastAPI 应用。这样,我们就可以沿用用于 Web 开发界面的相同路由定义。 - 通过向
get_fast_api_app方法添加关键字实参,配置必要的会话、内存或制品服务。在本教程中,如果我们配置SESSION_SERVICE_URI环境变量,会话服务将使用该变量,否则将使用内存中会话 - 我们可以添加自定义路由来支持其他后端业务逻辑,在脚本中,我们添加了反馈功能路由示例
- 在
get_fast_api_app实参参数中启用 Cloud 跟踪,以将跟踪记录发送到 Google Cloud Trace - 使用 uvicorn 运行 FastAPI 服务
现在,如果您的部署已完成,请尝试通过访问 Cloud Run 网址与网页开发者界面中的智能体互动
9. 🚀 通过负载测试检查 Cloud Run 自动扩缩
现在,我们将检查 Cloud Run 的自动扩缩功能。在此场景中,我们将在启用每个实例的最大并发数的同时部署新修订版本。在上一部分中,我们将最大并发数设置为 10(标志 --concurrency 10)。因此,我们可以预期,当我们进行超出此数量的负载测试时,Cloud Run 将尝试扩缩其实例。
我们来检查一下 load_test.py 文件。我们将使用此脚本通过 locust 框架执行负载测试。此脚本将执行以下操作:
- 随机化的 user_id 和 session_id
- 为 user_id 创建 session_id
- 使用创建的 user_id 和 session_id 命中端点“/run_sse”
如果您错过了,我们需要知道已部署的服务网址。我们可以前往 Cloud Run 控制台
然后,找到 weather-agent 服务并点击它

服务网址将显示在区域信息旁边。例如,

为了简化操作,我们运行以下脚本来获取您最近部署的服务网址,并将其存储在 SERVICE_URL 环境变量中
export SERVICE_URL=$(gcloud run services describe weather-agent \
--platform managed \
--region us-central1 \
--format 'value(status.url)')
然后运行以下命令,对我们的代理应用进行负载测试
uv run locust -f load_test.py \
-H $SERVICE_URL \
-u 60 \
-r 5 \
-t 120 \
--headless
运行此命令后,您将看到如下所示的指标。(在此示例中,所有请求均成功)
Type Name # reqs # fails | Avg Min Max Med | req/s failures/s
--------|------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
POST /run_sse end 813 0(0.00%) | 5817 2217 26421 5000 | 6.79 0.00
POST /run_sse message 813 0(0.00%) | 2678 1107 17195 2200 | 6.79 0.00
--------|------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
Aggregated 1626 0(0.00%) | 4247 1107 26421 3500 | 13.59 0.00
接下来,我们来看看 Cloud Run 中发生了什么,再次前往已部署的服务,然后查看信息中心。这会显示 Cloud Run 如何自动扩缩实例以处理传入请求。由于我们将每个实例的最大并发数限制为 10,因此 Cloud Run 实例会尝试自动调整容器数量以满足此条件。

10. 🚀 逐步发布新版本
现在,我们假设有以下场景。我们想更新代理的提示。使用以下命令打开 weather_agent/agent.py
cloudshell edit weather_agent/agent.py
并使用以下代码覆盖它:
# weather_agent/agent.py
import os
from pathlib import Path
import google.auth
from dotenv import load_dotenv
from google.adk.agents import Agent
from weather_agent.tool import get_weather
# Load environment variables from .env file in root directory
root_dir = Path(__file__).parent.parent
dotenv_path = root_dir / ".env"
load_dotenv(dotenv_path=dotenv_path)
# Use default project from credentials if not in .env
_, project_id = google.auth.default()
os.environ.setdefault("GOOGLE_CLOUD_PROJECT", project_id)
os.environ.setdefault("GOOGLE_CLOUD_LOCATION", "global")
os.environ.setdefault("GOOGLE_GENAI_USE_VERTEXAI", "True")
root_agent = Agent(
name="weather_agent",
model="gemini-2.5-flash",
instruction="""
You are a helpful AI assistant designed to provide accurate and useful information.
You only answer inquiries about the weather. Refuse all other user query
""",
tools=[get_weather],
)
然后,您想要发布新修订版本,但不希望所有请求流量都直接转到新版本。我们可以使用 Cloud Run 进行逐步发布。首先,我们需要部署一个新修订版本,但要使用 –no-traffic 标志。保存之前的代理脚本,然后运行以下命令
gcloud run deploy weather-agent \
--source . \
--port 8080 \
--project $GOOGLE_CLOUD_PROJECT \
--allow-unauthenticated \
--region us-central1 \
--no-traffic
完成后,您将收到与之前部署过程类似的日志,不同之处在于所服务的流量数量。系统将显示投放的流量为 0%。
Service [weather-agent] revision [weather-agent-xxxx-xxx] has been deployed and is serving 0 percent of traffic.
接下来,我们前往 Cloud Run 信息中心
然后,找到 weather-agent 服务并点击它

前往修订版本标签页,您会看到已部署的修订版本列表

您会看到,新部署的修订版本正在提供 0% 的流量,您可以在此处点击 Kebab 按钮 (⋮),然后选择管理流量

在新弹出的窗口中,您可以修改流向各个修订版本的流量百分比。

等待一段时间后,系统会根据百分比配置按比例分配流量。这样,如果新版本出现问题,我们就可以轻松回滚到之前的修订版本
11. 🚀 ADK 跟踪
使用 ADK 构建的代理已支持使用嵌入其中的开放遥测技术进行跟踪。我们有 Cloud Trace 来捕获这些跟踪记录并直观呈现。让我们检查一下 server.py,看看如何在之前部署的服务中启用它
# server.py
...
app_args = {"agents_dir": AGENT_DIR, "web": True, "trace_to_cloud": True}
...
app: FastAPI = get_fast_api_app(**app_args)
...
在此示例中,我们将 trace_to_cloud 实参传递给 True。如果您使用其他选项进行部署,可以查看此文档,详细了解如何通过各种部署选项启用从 Cloud Trace 到 Cloud Trace 的跟踪
尝试访问服务 Web 开发者界面,并与代理对话。之后,前往“Trace 探索器”页面
在 Trace 探索器页面上,您会看到与代理的对话跟踪记录已提交。从 Span name 部分可以看出,您可以过滤掉与代理相关的 span(名为 agent_run [weather_agent])

如果已过滤 span,您还可以直接检查每个轨迹。它会显示代理采取的每项操作的详细时长。例如,请参阅下图

在每个部分中,您都可以检查属性中的详细信息,如下所示

这样一来,我们就能够很好地观测到智能体与用户的每次互动,并获取相关信息,从而帮助我们调试问题。欢迎尝试各种工具或工作流!
12. 🎯 挑战
尝试多智能体或智能体工作流,看看它们在负载下的表现如何,以及轨迹是什么样的
13. 🧹 清理
为避免系统因本 Codelab 中使用的资源向您的 Google Cloud 账号收取费用,请按照以下步骤操作: