1. 简介
概览
学习内容
- 如何使用 vLLM 在 Cloud Run RTX 6000 Pro GPU 上部署 Gemma 4 模型
- 如何使用 智能体开发套件 (ADK) 创建 AI 智能体并使用 Gemma 4
- 如何使用 BigQuery MCP 服务器 向 AI 智能体授予对 BigQuery 中结构化数据的访问权限。
Gemma 4 是 Google DeepMind 推出的一系列采用 Apache 2 许可的开放权重模型。这些模型是多模态、多语言的,提供推理和高效架构。
Cloud Run 是一种支持 GPU 的容器无服务器环境。
智能体开发套件 (ADK) 是一种开源智能体开发框架,可让您以企业级规模构建、调试和部署可靠的 AI 智能体。
BigQuery 是一种全代管式无服务器企业数据仓库,可让您存储、查询和分析大量数据集。
Model Context Protocol (MCP) 标准化了大语言模型 (LLM) 和 AI 应用或智能体连接到外部数据源的方式。借助 MCP 服务器,您可以使用其工具、资源和提示来执行操作,并从其后端服务获取更新后的数据。借助 BigQuery MCP 服务器 ,您的 AI 智能体可以直接安全地分析 BigQuery 中的数据。这一全托管式 MCP 服务器不会带来额外的管理开销,让您可以专注于智能体的开发。
2. 设置和要求
首先设置默认项目和 Cloud Run 区域:
# set the project
gcloud config set project YOUR_PROJECT_ID
将 YOUR_PROJECT_ID 替换为您的 Google Cloud 项目 ID。
# set Cloud Run region
REGION="CLOUD-RUN-REGION"; gcloud config set run/region $REGION && echo $REGION > lab2rgn.txt
将 CLOUD-RUN-REGION 替换为以下 Cloud 区域之一:
us-central1asia-southeast1
以下是此 Codelab 中将使用的环境变量。您可以将这些变量保存在环境文件中并“获取”该文件。请务必正确设置项目 ID 的值,并可选择设置区域。
# Model name on HuggingFace Hub
export MODEL_NAME="google/gemma-4-31B-it"
# Cloud Run Service name
export SERVICE_NAME="gemma4-rtx-vllm-codelab"
# Cloud Project and Region for Cloud Run
export GOOGLE_CLOUD_PROJECT=$(gcloud config get project -q)
export GOOGLE_CLOUD_REGION=$(cat lab2rgn.txt 2> /dev/null || gcloud config get run/region -q)
# Service account for Cloud Run service
export SERVICE_ACCOUNT="vllm-service-sa"
export SERVICE_ACCOUNT_EMAIL="${SERVICE_ACCOUNT}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com"
# GCS Bucket for the model cache.
export MODEL_CACHE_BUCKET="${GOOGLE_CLOUD_PROJECT}-${GOOGLE_CLOUD_REGION}-hf-model-cache"
# Model cache location in GSC bucket
export GCS_MODEL_LOCATION="gs://${MODEL_CACHE_BUCKET}/model-cache/${MODEL_NAME}"
# Uncomment next line if loading gemma-4-31B-it directly from the public cache bucket
# export GCS_MODEL_LOCATION="gs://vertex-model-garden-public-us/gemma4/gemma-4-31B-it"
# VPC Network for Direct VPC Egress
export VPC_NETWORK="vllm-${GOOGLE_CLOUD_REGION}-net"
export VPC_SUBNET="vllm-${GOOGLE_CLOUD_REGION}-subnet"
export SUBNET_RANGE="10.8.0.0/26"
启用此 Codelab 所需的 API。API 更改可能需要 2-3 分钟才能生效。
gcloud services enable --project "${GOOGLE_CLOUD_PROJECT}" \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
iam.googleapis.com \
compute.googleapis.com \
vpcaccess.googleapis.com \
storage.googleapis.com \
bigquery.googleapis.com \
aiplatform.googleapis.com
3. 创建服务账号
如果您在创建 Cloud Run 服务或作业时未指定服务账号,则 Cloud Run 会使用 Compute Engine 默认服务账号。建议为 Cloud Run 服务使用单独的服务账号,以避免使用过多的权限运行服务。
为 Cloud Run 服务创建服务账号
gcloud iam service-accounts create ${SERVICE_ACCOUNT} \
--project "${GOOGLE_CLOUD_PROJECT}" \
--display-name "vLLM Service Account"
4. 设置 Cloud Storage
创建 Cloud Storage 存储分区以存储模型权重。这样,每次 Cloud Run 启动服务实例时,都可以使用直接 VPC 出站流量更快地下载模型权重。
结合 vLLM 中的 Run:ai Model Streamer 功能,可显著缩短模型加载时间。
创建存储分区
确保它是与 Cloud Run 服务位于同一位置的单区域存储分区。
gcloud storage buckets create "gs://${MODEL_CACHE_BUCKET}" \
--uniform-bucket-level-access --public-access-prevention \
--project "${GOOGLE_CLOUD_PROJECT}" --location "${GOOGLE_CLOUD_REGION}"
5. 检索和缓存模型权重
接下来,将 Gemma 4 模型下载到 Cloud Storage 存储分区。模型权重有数十 GB,因此先将其下载到本地机器或 Cloud Shell 可能不可行。请改用 Cloud Build,并确保有足够的存储空间来存储模型权重。
从共享 Cloud Storage 存储分区复制模型权重
Google Cloud 托管着一个可公开访问的 Cloud Storage 存储分区,其中包含 Gemma 4 模型权重。
如需将其复制到存储分区,请运行以下命令:
gcloud builds submit --project="${GOOGLE_CLOUD_PROJECT}" --region="${GOOGLE_CLOUD_REGION}" --no-source \
--substitutions="_MODEL_NAME=${MODEL_NAME},_GCS_MODEL_LOCATION=${GCS_MODEL_LOCATION}" \
--config=/dev/stdin <<'EOF'
steps:
- name: 'gcr.io/google.com/cloudsdktool/google-cloud-cli:slim'
entrypoint: 'bash'
args:
- '-c'
- |
if [[ "$_GCS_MODEL_LOCATION" == *"vertex-model-garden-public-us"* ]]; then
echo "Using the public cache bucket."
exit 0
fi
gcloud config set storage/parallel_composite_upload_enabled True
gcloud config set storage/parallel_composite_upload_threshold 150M
gcloud config set storage/sliced_object_download_threshold 150M
MODEL_NAME="$_MODEL_NAME"
SHORT_NAME="$${MODEL_NAME#*/}"
gcloud storage cp -r -D "gs://vertex-model-garden-public-us/gemma4/$${SHORT_NAME}" "$_GCS_MODEL_LOCATION"
EOF
6. 为直接 VPC 出站流量配置网络
直接 VPC 出站流量配置需要创建启用了专用 Google 访问通道的网络和子网。
这样,Cloud Run 服务就可以连接到 Google API 和服务(包括 Cloud Storage)使用的一组外部 IP 地址。
创建网络
gcloud compute networks create "$VPC_NETWORK" \
--subnet-mode=custom \
--bgp-routing-mode=regional \
--project "$GOOGLE_CLOUD_PROJECT"
创建子网
gcloud compute networks subnets create "$VPC_SUBNET" \
--network="$VPC_NETWORK" \
--region="$GOOGLE_CLOUD_REGION" \
--range="$SUBNET_RANGE" \
--enable-private-ip-google-access \
--project "$GOOGLE_CLOUD_PROJECT"
7. 配置服务账号访问政策
Cloud Run 服务账号需要有权访问您创建的存储分区中的模型权重。
gcloud storage buckets add-iam-policy-binding "gs://${MODEL_CACHE_BUCKET}" \
--member "serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--role "roles/storage.admin" \
--project "${GOOGLE_CLOUD_PROJECT}"
8. 初始化配置变量
为 vLLM 推理引擎和 Cloud Run 服务定义变量。
# vLLM variables
export MAX_MODEL_LEN="32767" # 32767 to improve concurrency. Keep it empty to use model's maximim context length (256K)
export QUANTIZATION_TYPE="fp8" # Model quantization for faster performance and lower memory usage.
export KV_CACHE_DTYPE="fp8" # KV-cache quantization to save GPU memory.
export GPU_MEM_UTIL="0.95" # Fraction of GPU memory to be used by the vLLM engine.
export TENSOR_PARALLEL_SIZE="1" # Partitioning model across GPUs (1 here as we have only 1 GPU).
export MAX_NUM_SEQS="16" # Max concurrent requests vLLM processes in one batch.
# Cloud Run variables
export CLOUD_RUN_CPU_NUM=20
export CLOUD_RUN_MEMORY_GB=80
export CLOUD_RUN_MAX_INSTANCES=1
export CLOUD_RUN_CONCURRENCY=16
9. 部署到 Cloud Run
准备 vLLM 容器命令行
vLLM 需要大量参数才能快速高效地运行大型模型。这些参数将作为实参传递给部署到 Cloud Run 的容器。
CONTAINER_ARGS=(
"vllm"
"serve"
"${GCS_MODEL_LOCATION}"
"--served-model-name" "${MODEL_NAME}"
"--enable-log-requests"
"--enable-chunked-prefill"
"--enable-prefix-caching"
"--generation-config" "auto"
"--enable-auto-tool-choice"
"--tool-call-parser" "gemma4"
"--reasoning-parser" "gemma4"
"--dtype" "bfloat16"
"--quantization" "${QUANTIZATION_TYPE}"
"--kv-cache-dtype" "${KV_CACHE_DTYPE}"
"--max-num-seqs" "${MAX_NUM_SEQS}"
"--gpu-memory-utilization" "${GPU_MEM_UTIL}"
"--tensor-parallel-size" "${TENSOR_PARALLEL_SIZE}"
"--load-format" "runai_streamer"
"--port" "8080"
"--host" "0.0.0.0"
)
if [[ "${MAX_MODEL_LEN}" != "" ]]; then
CONTAINER_ARGS+=("--max-model-len" "${MAX_MODEL_LEN}")
fi
export CONTAINER_ARGS_STR="${CONTAINER_ARGS[*]}"
部署 Cloud Run 服务
运行以下命令以部署 Cloud Run 服务。请注意 GPU 类型 (RTX 6000 Pro)、基础映像 (pytorch-vllm-serve:gemma4),以及调用服务时需要进行身份验证 (--no-allow-unauthenticated)。
gcloud beta run deploy "${SERVICE_NAME}" \
--image="us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:gemma4" \
--project "${GOOGLE_CLOUD_PROJECT}" \
--region "${GOOGLE_CLOUD_REGION}" \
--service-account "${SERVICE_ACCOUNT_EMAIL}" \
--execution-environment gen2 \
--no-allow-unauthenticated \
--cpu="${CLOUD_RUN_CPU_NUM}" \
--memory="${CLOUD_RUN_MEMORY_GB}Gi" \
--gpu=1 \
--gpu-type=nvidia-rtx-pro-6000 \
--no-gpu-zonal-redundancy \
--no-cpu-throttling \
--max-instances ${CLOUD_RUN_MAX_INSTANCES} \
--concurrency ${CLOUD_RUN_CONCURRENCY} \
--network ${VPC_NETWORK} \
--subnet ${VPC_SUBNET} \
--vpc-egress all-traffic \
--set-env-vars "MODEL_NAME=${MODEL_NAME}" \
--set-env-vars "GOOGLE_CLOUD_PROJECT=${GOOGLE_CLOUD_PROJECT}" \
--set-env-vars "GOOGLE_CLOUD_REGION=${GOOGLE_CLOUD_REGION}" \
--port=8080 \
--timeout=3600 \
--cpu-boost \
--startup-probe tcpSocket.port=8080,initialDelaySeconds=240,failureThreshold=40,timeoutSeconds=10,periodSeconds=15 \
--command "bash" \
--args="^;^-c;${CONTAINER_ARGS_STR}"
部署需要几分钟时间。完成后,您将拥有一个由 GPU 提供支持的环境,该环境使用无服务器基础架构(包括缩容至零的自动扩缩功能,即无流量、无费用)来提供 Gemma 4。
10. 测试服务
部署完成后,您可以使用 vLLM OpenAI 兼容型 API 与 Gemma 4 模型进行交互。
获取服务网址
检索已部署的 Cloud Run 服务的网址。
SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --project "${GOOGLE_CLOUD_PROJECT}" --region "${GOOGLE_CLOUD_REGION}" --format 'value(status.url)')
echo "Service URL: $SERVICE_URL"
运行推断
使用 curl 向模型发送提示。
curl -s "$SERVICE_URL/v1/chat/completions" \
-H "Authorization: Bearer $(gcloud auth print-identity-token)" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${MODEL_NAME}"'",
"messages": [
{"role": "user", "content": "Why is the sky blue?"}
],
"chat_template_kwargs": {
"enable_thinking": true
},
"skip_special_tokens": false
}' | jq -r '.choices[0].message.content'
11. 使用智能体开发套件创建数据智能体
编写智能体的代码
在 Cloud Shell 终端或本地终端中,为智能体应用创建一个根目录:
mkdir data_agent
打开 Cloud Shell Editor 或其他文本编辑器,然后在 data_agent 目录中创建 agent.py:
data_agent/
agent.py
agent.py
import os
import subprocess
from google.adk.agents import LlmAgent
from google.adk.models.lite_llm import LiteLlm
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
import google.auth
from google.auth.transport.requests import Request
from google.oauth2 import id_token
# Fetch Application Default Credentials (ADC)
application_default_credentials, project_id = google.auth.default()
application_default_credentials.refresh(Request())
# Retrieve Google Cloud project to use.
project_id = os.getenv("GOOGLE_CLOUD_PROJECT", project_id)
if not project_id:
raise ValueError("GOOGLE_CLOUD_PROJECT environment variable is not set.")
if os.getenv("GOOGLE_GENAI_USE_ENTERPRISE", "").lower() not in ["true", "1"]:
# Using Cloud Run for hosting LLM with LiteLLM wrapper
api_base = os.getenv(
"API_BASE",
os.environ.get("OPENAI_API_BASE", "")
).rstrip("/")
if not api_base:
raise ValueError("API_BASE environment variable is not set")
if not api_base.endswith("/v1"):
api_base += "/v1"
model_name = os.getenv("MODEL_NAME")
if not model_name:
raise ValueError("MODEL_NAME environment variable is not set")
# Format required by LiteLLM for OpenAI-compatible APIs
model_name=f"openai/{model_name}"
# To access the model's Cloud Run service,
# we need an identity token.
try:
model_service_token_string = id_token.fetch_id_token(Request(), api_base)
except Exception as e:
# Fallback with using gcloud CLI to get the identity token
model_service_token_string = subprocess.check_output(
f"gcloud auth print-identity-token -q",
shell=True
).decode().strip()
# Gemma 4 in vLLM requires additional parameters in the request body.
extra_body={
"chat_template_kwargs": {
"enable_thinking": True
},
"skip_special_tokens": False
}
# Configure the model with LiteLLM and an OpenAI-compatible endpoint
custom_model = LiteLlm(
model=model_name,
base_url=api_base,
api_key=model_service_token_string,
extra_body=extra_body
)
model = custom_model
else:
# Gemini API in Agent Platform fallback
model = "gemini-3.5-flash-lite"
# Initialize the MCP Toolset with the connection parameters
bigquery_toolset = MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url="https://bigquery.googleapis.com/mcp",
headers={
"Authorization": f"Bearer {application_default_credentials.token}",
"x-goog-user-project": project_id, # This is used for billing
},
tool_filter=[
'get_dataset_info',
'list_table_ids',
'get_table_info',
# Using readonly is a security measure to prevent accidental data modification.
'execute_sql_readonly',
]
)
)
# Configure the agent
system_instruction = f"""
You are a helpful assistant that can answer questions about data in BigQuery.
To answer the user's question, use data you have access to by using tools `list_table_ids` and `get_table_info`.
Your data is in `bigquery-public-data.new_york_citibike` dataset
(Citi Bike trips and stations in the NYC area.
It includes trip records starting from September 2013 and is updated daily.)
Plan of action:
0. ALWAYS start by analyzing dataset.
1. Analyze your data, investigate schema and dimensions by querying distrinct values of columns using `execute_sql_readonly`.
Output information about tables, columns, their data types and sets of values (for dimensions).
Note which columns can be joined or used in aggregations/filters, and what type conversion may be needed for joining or aggregating.
DO NOT MAKE ASSUMPTIONS ABOUT DATA (structure, type, values, relationships) BASED ON YOUR PRIOR KNOWLEDGE. ALWAYS VERIFY YOUR ASSUMPTIONS.
2. Understand and interpret the user's question.
3. Formulate a plan to answer the user's question.
4. Write a SQL query to retrieve relevant data in necessary form.
This is where you must pay extra attention to column types and dimensions' sets of values.
5. Retrieve data by generating BigQuery SQL and using `execute_sql_readonly`.
Always use Dry Run to verify SQL correctness.
Use `{project_id}` to run BigQuery queries (`project_id` parameter of `execute_sql_readonly`).
Do not use LaTeX in your responses. When giving a final answer, use Markdown.
"""
root_agent = LlmAgent(
model=model,
name="data_agent",
instruction=system_instruction,
description="A helpful assistant that can answer questions using NYC Citibike data.",
tools=[bigquery_toolset]
)
ADK 还要求部署时使用 __init__.py 和 requirements.txt:
__init__.py必须包含智能体的导入。requirements.txt列出了 Python 依赖项:用于智能体开发套件的google-adk、用于 ADK 利用 LiteLLM 库来使用非 Gemini 模型的litellm,以及用于 Model Context Protocol 客户端的mcp。
这些命令可帮助您创建 __init__.py 和 requirements.txt:
echo "from . import agent" > data_agent/__init__.py
echo -e "google-adk==2.4.*\nlitellm\nmcp==1.29.*" > data_agent/requirements.txt
最终文件夹结构应如下所示:
data_agent/
__init__.py
agent.py
requirements.txt
在本地试用智能体
智能体开发套件附带 adk CLI 工具,这是一个用于测试智能体的交互式终端界面。这对于快速测试、脚本化交互和 CI/CD 流水线非常有用。它提供的一项功能是 adk web(ADK 网页界面),这是一种以交互方式开发和调试智能体的简单方法。ADK Web 不适用于生产部署,但可以非常简单地试用智能体。
此命令会启动 adk web,后者会在端口 8080 上启动本地 Web 服务器。
export API_BASE=$(gcloud run services describe $SERVICE_NAME \
--project $GOOGLE_CLOUD_PROJECT \
--region $GOOGLE_CLOUD_REGION \
--format 'value(status.url)')
# If Gemma 4 deployment failed, use Gemini fallback
if [[ "${API_BASE}" == "" ]]; then
export GOOGLE_GENAI_USE_ENTERPRISE=true
else
export GOOGLE_GENAI_USE_ENTERPRISE=false
fi
uv tool run --with litellm,"mcp==1.29.*" --from "google-adk[mcp]==2.4.*" adk web --allow_origins="*" --port 8080 .
服务启动后,打开本地 ADK 网页:http://localhost:8080/。
如果您使用的是 Google Cloud Shell,请点击“网页预览”图标。
在 ADK 网页界面中,询问智能体它有权访问的数据:
What data do you have?
智能体代码将使用部署到 Cloud Run 的 Gemma 4 模型。该模型将使用 BigQuery MCP 工具来探索 citibike 数据集。它将为您提供 Citibike 数据集中可用表和字段的概览。
12. 将智能体部署到 Cloud Run
此命令将使用 ADK CLI 将智能体部署到 Cloud Run。
export API_BASE=$(gcloud run services describe $SERVICE_NAME \
--project $GOOGLE_CLOUD_PROJECT \
--region $GOOGLE_CLOUD_REGION \
--format 'value(status.url)')
# If Gemma 4 deployment failed, use Gemini fallback
if [[ "${API_BASE}" == "" ]]; then
export GOOGLE_GENAI_USE_ENTERPRISE=true
else
export GOOGLE_GENAI_USE_ENTERPRISE=false
fi
uv tool run --from google-adk==2.4.0 \
adk deploy cloud_run \
--with_ui \
--project $GOOGLE_CLOUD_PROJECT \
--region $GOOGLE_CLOUD_REGION \
--service_name gemma4-data-agent \
--app_name data_agent \
data_agent \
-- \
--allow-unauthenticated \
--max-instances 1 \
--set-env-vars GOOGLE_GENAI_USE_ENTERPRISE=${GOOGLE_GENAI_USE_ENTERPRISE},MODEL_NAME="${MODEL_NAME}",API_BASE="${API_BASE}",GOOGLE_CLOUD_PROJECT="${GOOGLE_CLOUD_PROJECT}"
试用智能体
我们为智能体部署使用了 --with_ui 选项。它使用 ADK 网页界面 部署了智能体。
- 在网络浏览器中打开智能体网址。
adk deploy命令返回了该网址,您还可以通过运行gcloud run services命令来检索该网址:
gcloud run services describe gemma4-data-agent \
--project $GOOGLE_CLOUD_PROJECT \
--region $GOOGLE_CLOUD_REGION \
--format 'value(status.url)'
- 要求智能体对可用的 Citibike 数据进行推理:
We have budget for 3 coffee trucks.
We want to find the best city bike stations to place our coffee trucks.
智能体应使用 BigQuery MCP 服务器探索 Citibike 数据集,运行一些 SQL 查询,并返回 3 个 citibike 站点的列表。
13. 恭喜!
恭喜您完成此 Codelab!
我们建议您查看 Cloud Run 文档。
所学内容
- 如何在 Cloud Run RTX 6000 Pro GPU 上部署 Gemma 4 模型
- 如何使用 Cloud Storage 配置直接 VPC 出站流量和 vLLM 模型流式传输,以加快服务启动速度。
- 如何使用智能体开发套件创建和部署 AI 智能体,该智能体使用 Gemma 4 LLM 和 BigQuery MCP 服务器。
14. 清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,您可以删除项目或删除各个资源。
选项 1:删除资源
删除 Cloud Run 服务
gcloud run services delete gemma4-data-agent \
--project "${GOOGLE_CLOUD_PROJECT}" \
--region "${GOOGLE_CLOUD_REGION}" \
--quiet
gcloud run services delete $SERVICE_NAME \
--project "${GOOGLE_CLOUD_PROJECT}" \
--region "${GOOGLE_CLOUD_REGION}" \
--quiet
删除服务账号
gcloud iam service-accounts delete \
${SERVICE_ACCOUNT_EMAIL} \
--project "${GOOGLE_CLOUD_PROJECT}" \
--quiet
删除 Cloud Storage 存储分区
gcloud storage rm --recursive gs://$MODEL_CACHE_BUCKET
删除 VPC 网络和子网
gcloud compute networks subnets delete $VPC_SUBNET \
--region "${GOOGLE_CLOUD_REGION}" \
--project "${GOOGLE_CLOUD_PROJECT}" \
--quiet
gcloud compute networks delete $VPC_NETWORK \
--project "${GOOGLE_CLOUD_PROJECT}" \
--quiet
选项 2:删除项目
如需删除整个项目,请前往“管理资源”,选择您在第 2 步中创建的项目,然后选择“删除”。如果您删除了项目,则需要在 Cloud SDK 中更改项目。您可以通过运行 gcloud projects list 查看所有可用项目的列表。如果您想坚持使用命令行,也可以使用此命令:
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}