1. Tổng quan
Trong lớp học lập trình này, bạn sẽ tìm hiểu cách triển khai ứng dụng Pet Passport (Hộ chiếu thú cưng), một tác nhân AI sử dụng Giao thức ngữ cảnh mô hình (MCP) để kết hợp dịch vụ phân tích dữ liệu và dịch vụ vị trí.
Ứng dụng này giúp người dùng lên kế hoạch cho một ngày vui chơi hoàn hảo với chú cún của mình dựa trên mức độ phổ biến của giống chó ở Thành phố New York. Tác nhân sử dụng chuỗi suy luận "Từ tổng quan đến chi tiết":
- Khám phá chiến lược (BigQuery): Xác định mã bưu chính ở Thành phố New York có số lượng người thuộc một chủng tộc cụ thể cao nhất.
- Thực thi cục bộ (Maps): Sử dụng mã bưu chính đó làm thông tin thiên vị về vị trí để tìm "quán cà phê cho phép mang theo thú cưng" và "công viên dành cho chó".
- Tạo hành trình: Kết hợp dữ liệu để tạo hành trình "Hộ chiếu thú cưng" có các đường liên kết và hình ảnh có thể nhấp vào.
Tác nhân này được xây dựng bằng khung google-adk và dựa trên nền tảng Gemini.
Lưu ý: Bạn có thể xem toàn bộ mã dự án, bao gồm cả giao diện người dùng, trên GitHub. Trong lớp học lập trình này, chúng ta sẽ tập trung vào logic cốt lõi của tác nhân và thiết lập cơ sở hạ tầng.
2. Thiết lập và yêu cầu
Trước tiên, hãy đảm bảo bạn đã thiết lập môi trường phát triển đúng cách.
1. Xác thực bằng Google Cloud
Đặt dự án trên đám mây của Google Cloud đang hoạt động và xác thực. Đây là yêu cầu bắt buộc để tác nhân truy cập vào BigQuery và các dịch vụ khác.
gcloud config set project [YOUR-PROJECT-ID] gcloud auth application-default login --project [YOUR-PROJECT-ID]
Lưu ý: Nếu gặp lỗi về một dự án khác trong quá trình xác thực, bạn có thể bỏ qua lỗi đó bằng cách tắt dự án hạn mức và đặt dự án theo cách thủ công:
gcloud auth application-default login --disable-quota-project gcloud auth application-default set-quota-project [YOUR-PROJECT-ID]
2. Yêu cầu về phần mềm
Bạn cần cài đặt phần mềm sau trên máy cục bộ:
- Python (bắt buộc phải có phiên bản 3.13 trở lên)
- Git (để tải kho lưu trữ xuống)
Tải kho lưu trữ xuống
Đoạn mã cho dự án này có trong kho lưu trữ MCP của Google. Sao chép kho lưu trữ và chuyển đến thư mục dự án:
git clone https://github.com/google/mcp.git cd examples/petpassport
3. Cài đặt
Giờ đây, khi đã có các tệp, hãy thiết lập môi trường Python.
- Tạo môi trường ảo: Việc này giúp các phần phụ thuộc của bạn được tách biệt.
python3 -m venv .venv
- Kích hoạt môi trường ảo:
- Trên Linux/macOS:
source .venv/bin/activate
- Trên Windows:
.venv\Scripts\activate
- Trên Linux/macOS:
- Cài đặt các phần phụ thuộc:
pip install google-adk==1.28.0 python-dotenv google-genai pillow uvicorn
Bật Cloud API
Bật các API sau trong dự án của bạn:
gcloud services enable \ bigquery.googleapis.com \ aiplatform.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ run.googleapis.com \ storage.googleapis.com
Chọn một khu vực
Đặt khu vực làm biến môi trường trong trình bao:
export REGION=us-central1
4. Lấy khoá API
Để sử dụng các dịch vụ Maps và Gemini, bạn cần lấy khoá API và lưu trữ chúng trong tệp .env ở thư mục gốc của dự án.
1. Khoá API Google Maps
- Chuyển đến Google Cloud Console.
- Chuyển đến phần API và Dịch vụ > Thông tin xác thực.
- Nhấp vào Tạo thông tin xác thực > Khoá API.
- Sao chép khoá đã tạo rồi thêm khoá đó vào tệp
.envdưới dạngMAPS_API_KEY=[YOUR_KEY]. - (Nên dùng) Hạn chế khoá để chỉ cho phép các Maps API mà máy chủ MCP sử dụng.
2. Khoá Gemini API (AI Studio)
- Truy cập vào Google AI Studio.
- Nhấp vào Lấy khoá API hoặc chuyển đến phần khoá API.
- Nhấp vào Tạo khoá API.
- Sao chép khoá này rồi thêm vào tệp
.envdưới dạngGEMINI_API_KEY=[YOUR_KEY].
5. Cài đặt các phần phụ thuộc
Tạo tệp requirements.txt trong thư mục petpassport/:
google-adk==1.28.0
python-dotenv
google-genai
pillow
6. Xác thực máy chủ MCP
Ứng dụng này dựa vào các máy chủ Giao thức ngữ cảnh mô hình (MCP) để tương tác với Google Maps và BigQuery. Để xác thực các máy chủ này, bạn cần định cấu hình các biến môi trường và tiêu đề thích hợp.
- MCP Google Maps: Yêu cầu phải có khoá Maps API hợp lệ được truyền trong tiêu đề
X-Goog-Api-Key. - BigQuery MCP: Yêu cầu thông tin đăng nhập OAuth có quyền truy cập vào dịch vụ BigQuery. Tác nhân sử dụng tài khoản dịch vụ điện toán mặc định khi chạy trên Cloud Run hoặc thông tin xác thực cục bộ của bạn khi chạy cục bộ.
Chúng tôi cung cấp một tập lệnh thiết lập setup/setup_env.sh trong kho lưu trữ để giúp định cấu hình các biến này trong tệp .env.
7. Tạo bảng BigQuery
Trước khi tác nhân có thể truy vấn dữ liệu giấy phép nuôi chó, chúng ta cần tạo tập dữ liệu và bảng trong BigQuery, sau đó tải dữ liệu lên.
Chúng tôi cung cấp một tập lệnh thiết lập setup/setup_bigquery.sh thực hiện các bước sau:
- Tạo một bộ chứa Cloud Storage có tên là
pet-passport-data-[PROJECT_ID]để lưu trữ dữ liệu thô. - Tải tập dữ liệu công khai về việc cấp phép cho chó ở Thành phố New York (CSV) xuống.
- Tải tệp CSV lên bộ chứa.
- Tạo một tập dữ liệu BigQuery có tên là
nyc_dogs. - Tải dữ liệu từ bộ chứa vào một bảng có tên là
licensestrong tập dữ liệu.
Để chạy tập lệnh thiết lập, hãy thực thi lệnh sau trong thiết bị đầu cuối:
bash setup/setup_bigquery.sh
8. Kết nối với máy chủ MCP
Một phần quan trọng của ứng dụng này là sử dụng MCP để kết nối với dữ liệu và dịch vụ. Trong phần này, bạn sẽ định cấu hình các bộ công cụ MCP cho BigQuery và Google Maps trong một tệp có tên là petpassport/tools.py.
Hoàn tất mã tools.py
Dưới đây là quy trình triển khai đầy đủ cho tools.py, bao gồm cả bộ công cụ MCP và các công cụ tuỳ chỉnh để duy trì hình ảnh và dữ liệu. Chúng tôi đã tối ưu hoá mã này để giảm sự dư thừa bằng cách chuyển độ phân giải nhóm sang cấp độ mô-đun:
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
Giải thích mã: tools.py
get_maps_mcp_toolsetvàget_bigquery_mcp_toolsetđịnh cấu hình các ứng dụng MCP bằng các điểm cuối và tiêu đề xác thực chính xác.generate_pet_passport_photosử dụng Gemini để tạo một cảnh và tải kết quả lên Google Cloud Storage, trả về một URL đã ký cho giao diện người dùng để duy trì hoạt động sau khi máy chủ khởi động lại.
9. Tạo tác nhân
Sau khi định cấu hình các công cụ, bạn cần xây dựng "bộ não" cho tác nhân. Bạn sẽ dùng Bộ công cụ phát triển tác nhân (ADK) để tạo một tác nhân trong một tệp có tên là petpassport/agent.py.
Hoàn tất mã agent.py
Sau đây là quá trình triển khai đầy đủ cho agent.py, trong đó chúng ta xác định tác nhân và hướng dẫn của tác nhân:
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]
)
Giải thích mã: agent.py
- Chúng tôi nhập
toolstrực tiếp (cấu trúc được đơn giản hoá) để hỗ trợ môi trường vùng chứa. - Nhân viên hỗ trợ được khởi chạy bằng
gemini-2.5-pro. - Các chỉ dẫn này xác định một chuỗi suy luận nhiều bước chặt chẽ (trước tiên là BigQuery, sau đó là Maps) và nghiêm cấm việc tạo thông tin sai lệch hoặc hiển thị các tuyến đường đi bộ dẫn đến tình trạng lộn xộn.
10. Chạy ứng dụng cục bộ
Trước khi triển khai đến Cloud Run, bạn nên kiểm thử ứng dụng cục bộ.
- Đảm bảo bạn đang ở trong thư mục dự án:
cd examples/petpassport
- Khởi động máy chủ FastAPI: Chúng ta sẽ dùng
uvicornđể chạy ứng dụng. Điểm truy cập làmain.pybên trong thư mụcpetpassport.uvicorn petpassport.main:app --reload
- Mở giao diện người dùng: Chuyển đến
http://127.0.0.1:8000/ui/trong trình duyệt để tương tác với giao diện Hộ chiếu cho thú cưng.
11. Triển khai lên Cloud Run
Khi nhân viên hỗ trợ đã sẵn sàng, bạn có thể triển khai nhân viên hỗ trợ đó lên Cloud Run. Chúng ta sử dụng trực tiếp lệnh gcloud tiêu chuẩn để duy trì quyền kiểm soát chặt chẽ đối với môi trường vùng chứa.
Trong thư mục dự án, hãy chạy lệnh sau:
gcloud run deploy petpassport \ --source petpassport \ --region $REGION \ --allow-unauthenticated \ --labels dev-tutorial=google-mcp
Định cấu hình các biến môi trường
Sau khi triển khai, hãy chuyển đến dịch vụ Cloud Run trong Google Cloud Console và đặt các biến môi trường sau đây trong thẻ Variables & Secrets (Biến và bí mật):
MAPS_API_KEY: Khoá API Google Maps của bạn.GOOGLE_CLOUD_PROJECT: Mã dự án của bạn.PROJECT_ID: Mã dự án của bạn (hỗ trợ dự phòng cho các mô-đun cũ).
12. Câu lệnh mẫu
Hãy thử tương tác với tác nhân đã triển khai bằng các câu lệnh sau:
- Tiêu chuẩn: "Tôi muốn đi dạo với chú chó Golden Retriever của mình ở Thành phố New York gần mã bưu chính 10021. Tìm cho chúng tôi một tuyến đường có quán cà phê."
- Giống khác: "Tôi có một chú chó Bull Pháp và chúng tôi ở Upper West Side (gần mã bưu chính 10024). Đề xuất một chuyến đi bộ ngắn có dừng chân tại một công viên nổi tiếng dành cho chó."
- Có hình ảnh: (Tải ảnh chú chó của bạn lên) "Đây là ảnh chú Corgi của tôi! Chúng tôi ở gần mã bưu chính 10013. Lên kế hoạch cho một ngày vui chơi hoàn hảo cho chúng tôi."
13. Dọn dẹp
Để tránh bị tính phí cho các tài nguyên được dùng trong hướng dẫn này, hãy làm như sau:
- Xoá dịch vụ Cloud Run:
gcloud run services delete petpassport --region=$REGION - Xoá bộ chứa GCS:
gcloud storage rm -r gs://pet-passport-data-$PROJECT_ID