第 8 章 Google ADK部署Cloud Run

第 8 章 部署:从本地到云端

第 8 章 部署:从本地到云端

前七章,我们的云销客服一直在本地跑——adk runadk web。但一个真正的产品不能活在开发者的终端里。这一章,我们把云销客服送上生产。你会看到 ADK 的部署哲学:不绑架你选哪朵云,给你自由。

8.1 部署路径总览

8.1.1 四种路径

ADK 的部署有四条主要路径,按"生产就绪程度 vs 自定义灵活性"排列:

路径 说明 适用场景
Agent Runtime Google Cloud 上全托管的自动扩缩服务,专为部署 ADK Agent 设计 生产、托管、治理
Cloud Run 托管自动扩缩计算平台,以容器方式运行 Agent 无服务器、完全控制扩缩
GKE 托管 Kubernetes,需要更多部署控制,或运行开源模型 高控制需求、开源模型
自有服务器 / 任意云 手动打包容器镜像,在任意支持容器的环境运行 离线、非 Google 云、已有基础设施

关键认知:ADK 不强制你上 Google Cloud。Cloud Run 和 GKE 只是"顺手的选项",你完全可以用 Docker 容器打包后部署到自有服务器、AWS、阿里云——只要环境支持容器。

8.1.2 部署负载(Deployment Payload)

部署时,你上传的是 Agent 代码 + 声明的依赖。ADK 部署到 Agent Runtime 时,API server / web UI 由 Agent Runtime 服务提供(Python 部署不包含 ADK API server);Go 部署则会包含专用 API server。

注意:Agent Runtime 是付费服务;Cloud Run/GKE 默认部署不包含 ADK Web UI,除非指定 --with_ui

8.2 用 adk api_server 先跑起来

在部署到任何云之前,先用 API Server 把 Agent 变成 HTTP 接口。这是从"本地运行"到"生产部署"的桥梁。

8.2.1 启动 API Server

adk api_server

默认跑在 http://localhost:8000。它通过 REST API 暴露你的 Agent,供编程测试和集成。

8.2.2 REST API 端点

方法 路径 作用
GET /list-apps 列出所有 agent 应用
POST /apps/{app_name}/users/{user_id}/sessions/{session_id} 创建会话
PATCH /apps/{app_name}/users/{user_id}/sessions/{session_id} 更新会话 state
GET /apps/{app_name}/users/{user_id}/sessions/{session_id} 获取会话
DELETE /apps/{app_name}/users/{user_id}/sessions/{session_id} 删除会话
POST /run 运行 Agent(单次返回全部事件)
POST /run_sse 运行 Agent(SSE 流式)
GET /docs Swagger UI(交互式 API 文档)

创建一个会话:

curl -X POST http://localhost:8000/apps/yunxiao/users/u_123/sessions/s_123 \
  -H "Content-Type: application/json" \
  -d '{"key1": "value1"}'

发送查询:

curl -X POST http://localhost:8000/run_sse \
  -H "Content-Type: application/json" \
  -d '{
    "appName": "yunxiao",
    "userId": "u_123",
    "sessionId": "s_123",
    "newMessage": {
      "role": "user",
      "parts": [{"text": "帮我查一下 ORD-20260901-001"}]
    },
    "streaming": false
  }'

注意请求体字段用 camelCaseappNameuserIdsessionIdnewMessage)。

8.2.3 在代码里嵌入 FastAPI

如果你想在自己的 FastAPI 应用里嵌入 Agent(比如你已经有业务后端),ADK 提供了 get_fast_api_app

import os
import uvicorn
from fastapi import FastAPI
from google.adk.cli.fast_api import get_fast_api_app

AGENT_DIR = os.path.dirname(os.path.abspath(__file__))
SESSION_SERVICE_URI = "sqlite+aiosqlite:///./sessions.db"
SERVE_WEB_INTERFACE = True

app: FastAPI = get_fast_api_app(
    agents_dir=AGENT_DIR,
    session_service_uri=SESSION_SERVICE_URI,
    web=SERVE_WEB_INTERFACE,
)

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

这里用了 SQLite 做会话持久化(sqlite+aiosqlite:///./sessions.db)——不配置的话,会话数据会丢在内存里,实例回收就没了。

8.3 Docker 容器化:不依赖 Google 的部署

8.3.1 为什么 Docker 是底座

所有部署路径(Cloud Run、GKE、自有服务器)本质上都是"跑容器"。理解了 Docker 打包,你就理解了 ADK 部署的通用逻辑——而且这个逻辑不依赖任何云厂商

requirements.txt

google-adk
# 其他依赖

Dockerfile

FROM python:3.13-slim
WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

RUN adduser --disabled-password --gecos "" myuser && \
    chown -R myuser:myuser /app

COPY . .

USER myuser

ENV PATH="/home/myuser/.local/bin:$PATH"

CMD ["sh", "-c", "uvicorn main:app --host 0.0.0.0 --port $PORT"]

main.py 用上一节的 get_fast_api_app。然后本地构建并运行:

docker build -t yunxiao-agent .
docker run -p 8080:8080 -e PORT=8080 yunxiao-agent

这就是"部署中立"的证明:这个镜像可以在任何支持容器的环境跑——自有服务器、AWS ECS、阿里云 ACK、或者下面的 Cloud Run。

8.3.2 多 Agent 的容器组织

一个容器里可以有多个 Agent:每个 agent 文件夹放在根目录下,各自含 root_agent 定义和 __init__.py。API server 通过 /list-apps 列出它们。

8.4 Cloud Run:无服务器部署

Cloud Run 是 Google Cloud 的托管容器平台,自动扩缩、按用量计费。

8.4.1 用 adk deploy 一键部署

export GOOGLE_CLOUD_PROJECT=your-project-id
export GOOGLE_CLOUD_LOCATION=us-central1
export GOOGLE_GENAI_USE_ENTERPRISE=True

adk deploy cloud_run \
  --project=$GOOGLE_CLOUD_PROJECT \
  --region=$GOOGLE_CLOUD_LOCATION \
  --with_ui \
  $AGENT_PATH

AGENT_PATH 是含 __init__.pyagent.py 的目录。可选参数包括:

  • --service_name:服务名
  • --app_name:应用名
  • --session_service_uri:会话存储(sqlite://<path>memory:// 等)
  • --artifact_service_uri:工件存储(gs://<bucket>file://memory://
  • --with_ui:附带 Web UI

重要:如果不设置 --session_service_uri / --artifact_service_uri,容器回退到内存服务,实例回收后会话/工件丢失。生产环境一定要配置持久化存储。

8.4.2 手动部署(gcloud run deploy)

如果你想要更多控制,用标准 gcloud run deploy

gcloud run deploy yunxiao-service \
  --source . \
  --region $GOOGLE_CLOUD_LOCATION \
  --project $GOOGLE_CLOUD_PROJECT \
  --allow-unauthenticated \
  --set-env-vars="GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT,GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION,GOOGLE_GENAI_USE_ENTERPRISE=$GOOGLE_GENAI_USE_ENTERPRISE"

8.4.3 测试部署的 Agent

export APP_URL="YOUR_CLOUD_RUN_SERVICE_URL"

# 列出所有 agent
curl -X GET $APP_URL/list-apps

# 发消息
curl -X POST $APP_URL/run_sse \
  -H "Content-Type: application/json" \
  -d '{
    "app_name": "yunxiao",
    "user_id": "u_123",
    "session_id": "s_123",
    "new_message": {
      "role": "user",
      "parts": [{"text": "What is the capital of Canada?"}]
    },
    "streaming": false
  }'

8.5 GKE:需要更多控制时

GKE(Google Kubernetes Engine)适合需要精细控制部署、或运行开源模型的场景。两种方式:手动(gcloud + kubectl)或自动(adk deploy gke)。

8.5.1 自动部署

adk deploy gke \
  --project myproject \
  --cluster_name adk-cluster \
  --region us-central1 \
  --with_ui \
  ~/agents/yunxiao/

自动化流程:容器化 → 推送 Artifact Registry → 动态生成 Kubernetes manifests(Deployment + Service)→ 应用到集群。默认 ClusterIP 只在集群内可访问,暴露公网需 --service_type=LoadBalancer

8.5.2 手动部署

先创建集群:

gcloud container clusters create-auto adk-cluster \
  --location=$GOOGLE_CLOUD_LOCATION \
  --project=$GOOGLE_CLOUD_PROJECT

gcloud container clusters get-credentials adk-cluster \
  --location=$GOOGLE_CLOUD_LOCATION \
  --project=$GOOGLE_CLOUD_PROJECT

构建并推送镜像:

gcloud builds submit \
  --tag $GOOGLE_CLOUD_LOCATION-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/adk-repo/adk-agent:latest \
  --project=$GOOGLE_CLOUD_PROJECT \
  .

然后写 Kubernetes manifests(Deployment + Service),kubectl apply -f deployment.yaml

GKE 常见故障

  • 403 PERMISSION_DENIED:K8s 服务账号缺权限,需绑定 Workload Identity
  • SQLite read-only:构建前 rm -f sessions.db 或加 .dockerignore 排除

8.6 部署到非 Google 环境:自由选择

这一节专门回答一个问题:如果我不想用 Google Cloud 呢?

完全没问题。云销客服的 Docker 镜像可以部署到任何地方:

  1. 自有服务器docker run -p 8080:8080 yunxiao-agent,配一个 Nginx 反代 + HTTPS
  2. AWS:ECS / EKS 跑同一个镜像
  3. 阿里云:ACK / ECS 跑同一个镜像
  4. 边缘/离线:任何支持 Docker 的环境,甚至完全断网(模型用本地 Ollama)

模型侧也一样:云销客服的模型可以是 ollama_chat/gemma3(本地)、openai/gpt-4oanthropic/claude——模型和部署都是你的选择,不是 ADK 的强制

这就是本书反复强调的"部署中立":ADK 给你最顺手的默认(Cloud Run),但绝不设围墙。

8.7 部署到 Agent Runtime:全托管选项

如果你的团队不想管基础设施,Agent Runtime 是全托管的选择。两种方式:

标准部署

adk deploy agent_engine \
  --project=$PROJECT_ID \
  --region=$LOCATION_ID \
  --display_name="Yunxiao Agent" \
  yunxiao_agent

Agents CLI 加速部署(自动配置云资源 + CI/CD + Terraform):

uvx google-agents-cli setup
agents-cli scaffold enhance --deployment-target agent_engine
agents-cli deploy

「为什么 ADK 这样设计」:部署自由是框架的隐形竞争力

这一章的内容可以用一句话概括:ADK 让部署成为"你的选择",而不是"它的决定"。

很多框架的部署是绑定式的——用某框架,就要用它配套的云服务。ADK 反其道而行:

  • 本地到云端一条线adk api_server → Docker → Cloud Run/GKE/自有服务器,每一步都是平滑过渡,不换框架
  • 容器是通用底座:不发明专有的部署格式,就用标准 Docker 镜像
  • Google Cloud 是选项不是强制:Cloud Run/GKE/Agent Runtime 只是"顺手的默认",你完全可以在别处跑

这个设计的深层逻辑是:Agent 框架的竞争,不止是代码体验,更是"你能否掌控自己的部署"。开发者害怕被框架绑架——绑在模型上、绑在云上。ADK 用"处处可选"消除了这种恐惧。这也是为什么我们说 ADK 是"生产优先"的框架:它从第一天就考虑了你把代码放到哪里、怎么长期运行。

本章小结

  • 四条部署路径:Agent Runtime(全托管)、Cloud Run(无服务器)、GKE(高控制)、自有服务器(自由)
  • API Server 是桥梁adk api_server 把 Agent 变成 REST API,端点齐全(/run、/run_sse、/list-apps)
  • Docker 是通用底座get_fast_api_app + Dockerfile 打包,不依赖任何云
  • 部署中立:同一个镜像可以部署到自有服务器、AWS、阿里云,模型也可以自由切换
  • Cloud Run 一键部署adk deploy cloud_run,记得配置持久化存储(session_service_uri)
  • GKE 高控制adk deploy gke 或手动 kubectl,适合开源模型和精细控制
  • Agent Runtime 全托管:标准部署或 Agents CLI 加速,适合不想管基础设施的团队
  • 生产三件套:容器化 + 持久化存储 + 环境变量配置,缺一不可

练习

  1. 本地起 API Server:用 adk api_server 跑起云销客服,用 curl 创建会话、发消息,走一遍 REST API 全流程。
  2. Docker 打包:给云销客服写 Dockerfile,本地 docker run 跑起来,验证镜像可以在任意环境运行。
  3. 配置持久化:在 FastAPI 嵌入里用 sqlite+aiosqlite:///./sessions.db 配置会话持久化,重启容器后验证会话还在。
  4. 对比部署路径:如果方便,分别评估 Cloud Run 和自有服务器两条路径对你的场景的成本和运维负担。

下一章预告:第 9 章,Agent 上线后,最大的难题来了——怎么知道它没在犯错?可观测性,是生产 Agent 的最后一层保障。