1. 概览
在此 Codelab 中,您将学习如何部署 Pet Passport 应用,这是一款使用 Model Context Protocol (MCP) 将数据分析和位置服务相结合的 AI 智能体。
该应用可根据纽约市的犬种受欢迎程度,帮助用户规划与爱犬共度的完美一天。该智能体使用“宏观到微观”推理链:
- 战略发现 (BigQuery): 确定特定犬种在纽约市人口最多的邮政编码。
- 本地执行 (Maps): 使用该邮政编码作为位置偏差,查找“宠物友好型咖啡馆”和“遛狗公园”。
- 行程生成: 将数据组合在一起,创建包含可点击链接和图片的“宠物护照”行程。
该智能体使用 google-adk 框架构建,并由 Gemini 提供支持。
注意:GitHub 上提供了完整的项目代码,包括前端界面。在此 Codelab 中,我们将重点介绍核心智能体逻辑和基础架构设置。
2. 设置和要求
首先,请确保您的开发环境设置正确。
1. 向 Google Cloud 进行身份验证
设置您的有效 Google Cloud 项目并进行身份验证。智能体需要此操作才能访问 BigQuery 和其他服务。
gcloud config set project [YOUR-PROJECT-ID] gcloud auth application-default login --project [YOUR-PROJECT-ID]
注意:如果您在身份验证期间遇到有关其他项目的错误,可以通过停用配额项目并手动进行设置来绕过该错误:
gcloud auth application-default login --disable-quota-project gcloud auth application-default set-quota-project [YOUR-PROJECT-ID]
2. 软件要求
您需要在本地计算机上安装以下软件:
- Python (需要 3.13 或更高版本)
- Git (用于下载代码库)
下载代码库
此项目的代码位于 Google MCP 代码库中。克隆代码库并前往项目文件夹:
git clone https://github.com/google/mcp.git cd examples/petpassport
3. 安装
现在您已拥有这些文件,接下来我们来设置 Python 环境。
- 创建虚拟环境: 这可确保您的依赖项处于隔离状态。
python3 -m venv .venv
- 激活虚拟环境:
- 在 Linux/macOS 上:
source .venv/bin/activate
- 在 Windows 上:
.venv\Scripts\activate
- 在 Linux/macOS 上:
- 安装依赖项:
pip install google-adk==1.28.0 python-dotenv google-genai pillow uvicorn
启用 Cloud API
在项目中启用以下 API:
gcloud services enable \ bigquery.googleapis.com \ aiplatform.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ run.googleapis.com \ storage.googleapis.com
选择区域
在 Shell 中将区域设置为环境变量:
export REGION=us-central1
4. 获取 API 密钥
如需使用 Maps 和 Gemini 服务,您需要获取 API 密钥并将其存储在项目根目录中的 .env 文件中。
1. Google 地图 API 密钥
- 前往 Google Cloud 控制台。
- 前往 API 和服务 > 凭据 。
- 依次点击创建凭据 > API 密钥 。
- 复制生成的密钥,并将其添加到
.env文件中,格式为MAPS_API_KEY=[YOUR_KEY]。 - (推荐)限制该密钥,使其仅允许访问 MCP 服务器使用的 Maps API。
2. Gemini API 密钥 (AI Studio)
- 前往 Google AI Studio。
- 点击获取 API 密钥 或前往 API 密钥部分。
- 点击创建 API 密钥 。
- 复制该密钥,并将其添加到
.env文件中,格式为GEMINI_API_KEY=[YOUR_KEY]。
5. 安装依赖项
在 petpassport/ 文件夹中创建一个 requirements.txt 文件:
google-adk==1.28.0
python-dotenv
google-genai
pillow
6. 对 MCP 服务器进行身份验证
此应用依赖于 Model Context Protocol (MCP) 服务器与 Google 地图和 BigQuery 进行交互。如需对这些服务器进行身份验证,您需要配置相应的环境变量和标头。
- Google 地图 MCP: 需要在
X-Goog-Api-Key标头中传递有效的地图 API 密钥。 - BigQuery MCP: 需要具有 BigQuery 服务访问权限的 OAuth 凭据。该智能体在 Cloud Run 上运行时使用默认的计算服务账号,在本地运行时使用本地凭据。
我们在代码库中提供了一个设置脚本 setup/setup_env.sh,可帮助您在 .env 文件中配置这些变量。
7. 创建 BigQuery 表
在智能体查询犬只许可证数据之前,我们需要在 BigQuery 中创建数据集和表,并加载数据。
我们提供了一个设置脚本 setup/setup_bigquery.sh,用于执行以下步骤:
- 创建一个名为
pet-passport-data-[PROJECT_ID]的 Cloud Storage 存储分区,用于存储原始数据。 - 下载公开的纽约市犬只许可数据集 (CSV)。
- 将 CSV 文件上传到存储分区。
- 创建一个名为
nyc_dogs的 BigQuery 数据集。 - 将数据从存储分区加载到数据集中的名为
licenses的表中。
如需运行设置脚本,请在终端中执行以下命令:
bash setup/setup_bigquery.sh
8. 连接到 MCP 服务器
此应用的一个关键部分是使用 MCP 连接到数据和服务。在本部分中,您将在名为 petpassport/tools.py 的文件中为 BigQuery 和 Google 地图配置 MCP 工具集。
完整的 tools.py 代码
以下是 tools.py 的完整实现,包括 MCP 工具集以及用于图片和数据持久性的自定义工具。我们对这段代码进行了优化,通过将存储分区解析移至模块级来减少冗余:
import os
import dotenv
import google.auth
import time
import datetime
from google.cloud import storage
from PIL import Image
from google import genai
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
MAPS_MCP_URL = "https://mapstools.googleapis.com/mcp"
BIGQUERY_MCP_URL = "https://bigquery.googleapis.com/mcp"
PROJECT_ID = os.getenv('GOOGLE_CLOUD_PROJECT', 'project_not_set')
BUCKET_NAME = f"pet-passport-data-{PROJECT_ID}"
def get_maps_mcp_toolset():
dotenv.load_dotenv()
maps_api_key = os.getenv('MAPS_API_KEY', 'no_api_found')
tools = MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url=MAPS_MCP_URL,
headers={
"X-Goog-Api-Key": maps_api_key
},
timeout=30.0,
sse_read_timeout=300.0
)
)
print("Maps MCP Toolset configured.")
return tools
def get_bigquery_mcp_toolset():
credentials, project_id = google.auth.default(
scopes=["https://www.googleapis.com/auth/bigquery"]
)
credentials.refresh(google.auth.transport.requests.Request())
oauth_token = credentials.token
HEADERS_WITH_OAUTH = {
"Authorization": f"Bearer {oauth_token}",
"x-goog-user-project": project_id
}
tools = MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url=BIGQUERY_MCP_URL,
headers=HEADERS_WITH_OAUTH,
timeout=30.0,
sse_read_timeout=300.0
)
)
print("BigQuery MCP Toolset configured.")
return tools
def generate_pet_passport_photo(prompt: str, image_path: str = None) -> str:
"""Generates an image using gemini-3.1-flash-image-preview based on a prompt and a reference image."""
client = genai.Client()
output_path = f"/tmp/pet_passport_{int(time.time())}.png"
try:
image = Image.open(image_path)
response = client.models.generate_content(
model="gemini-3.1-flash-image-preview",
contents=[prompt, image],
)
for part in response.parts:
if part.inline_data is not None:
generated_image = part.as_image()
generated_image.save(output_path)
# Upload to GCS and generate signed URL
try:
storage_client = storage.Client()
bucket = storage_client.bucket(BUCKET_NAME)
blob_name = os.path.basename(output_path)
blob = bucket.blob(blob_name)
blob.upload_from_filename(output_path)
url = blob.generate_signed_url(
version="v4",
expiration=datetime.timedelta(hours=24),
method="GET",
)
return url
except Exception as e:
print(f"Error uploading image to GCS: {e}")
return output_path
raise ValueError("No image was returned by the model.")
except Exception as e:
print(f"Error generating image: {e}")
raise
def save_pet_passport(user_id: str, breed: str, postal_code: str, route_details: str, image_paths: list[str] = None) -> str:
"""Appends the generated itinerary to the user's history in GCS."""
try:
storage_client = storage.Client()
bucket = storage_client.bucket(BUCKET_NAME)
blob = bucket.blob(f"user-{user_id}.json")
# Download existing or start fresh
# ... (Implementation details hidden for brevity) ...
return "Success"
except Exception as e:
print(f"Error saving path: {e}")
raise
代码说明:tools.py
get_maps_mcp_toolset和get_bigquery_mcp_toolset使用正确的端点和身份验证标头配置 MCP 客户端。generate_pet_passport_photo使用 Gemini 创建场景,并将结果上传到 Google Cloud Storage,然后向前端返回签名网址,以便在服务器重启后继续使用。
9. 创建智能体
配置完工具后,接下来就可以构建智能体的“大脑”了。您将使用智能体开发套件 (ADK) 在名为 petpassport/agent.py 的文件中创建智能体。
完整的 agent.py 代码
以下是 agent.py 的完整实现,我们在此处定义了智能体及其说明:
import os
import dotenv
import tools
from google.adk.agents import LlmAgent
dotenv.load_dotenv()
PROJECT_ID = os.getenv('GOOGLE_CLOUD_PROJECT', 'project_not_set')
maps_toolset = tools.get_maps_mcp_toolset()
bigquery_toolset = tools.get_bigquery_mcp_toolset()
root_agent = LlmAgent(
model='gemini-2.5-pro',
name='root_agent',
instruction=f"""
You are the Pet Passport Agent. Your goal is to help users find a fun walking route for their dog in NYC.
When given a breed and a postal code, follow this flow:
1. **Strategic Discovery:** Use BigQuery to find the most popular neighborhood for that breed in NYC.
2. **Local Execution:** Use Maps to build a walking route with specific places (parks, cafes) in that area.
**NO DIRECTIONS LINKS:** You must NOT include a Google Maps directions link (e.g., `https://www.google.com/maps/dir/...`) in your final response. Only provide links to individual places.
After generating the itinerary, you MUST call the `save_pet_passport` tool to save this path to the user's profile. Pass a clean summary of the itinerary as `route_details`. The summary should include details (like rating, description from maps).
""",
tools=[maps_toolset, bigquery_toolset, tools.generate_pet_passport_photo, tools.save_pet_passport]
)
代码说明:agent.py
- 我们直接导入
tools(扁平化结构)以支持容器环境。 - 智能体使用
gemini-2.5-pro进行初始化。 - 这些说明定义了严格的多步思维链(先 BigQuery,然后 Maps),并严格禁止产生幻觉或渲染导致杂乱的步行路线。
10. 在本地运行应用
在部署到 Cloud Run 之前,最好先在本地测试应用。
- 确保您位于项目目录中:
cd examples/petpassport
- 启动 FastAPI 服务器: 我们使用
uvicorn运行应用。入口点是petpassport文件夹内的main.py。uvicorn petpassport.main:app --reload
- 打开界面: 在浏览器中前往
http://127.0.0.1:8000/ui/,与 Pet Passport 界面互动。
11. 部署至 Cloud Run
智能体准备就绪后,接下来就可以将其部署到 Cloud Run 了。我们直接使用标准 gcloud 命令,以便严格控制容器环境。
在项目目录中,运行以下命令:
gcloud run deploy petpassport \ --source petpassport \ --region $REGION \ --allow-unauthenticated \ --labels dev-tutorial=google-mcp
配置环境变量
部署后,在 Google Cloud 控制台中前往 Cloud Run 服务,然后在变量和 Secret 标签页下设置以下环境变量:
MAPS_API_KEY:您的 Google 地图 API 密钥。GOOGLE_CLOUD_PROJECT:您的项目 ID。PROJECT_ID:您的项目 ID(支持旧版模块的冗余)。
12. 示例提示
尝试使用以下提示与已部署的智能体互动:
- 标准:“我想在纽约市 10021 附近与我的金毛寻回犬一起散步。为我们找到一条有咖啡馆的路线。”
- 不同犬种:“我有一只法国斗牛犬,我们位于上西区(10024 附近)。建议我们进行一次短途散步,并在一个受欢迎的遛狗公园停留。”
- 带图片:(上传爱犬的照片)“这是我的柯基犬的照片!我们位于 10013 附近。为我们规划完美的一天。”
13. 清理
为避免因本教程中使用的资源而产生费用,请执行以下操作:
- 删除 Cloud Run 服务:
gcloud run services delete petpassport --region=$REGION - 删除 GCS 存储分区:
gcloud storage rm -r gs://pet-passport-data-$PROJECT_ID