1. Przegląd
W tym ćwiczeniu dowiesz się, jak wdrożyć aplikację Pet Passport, czyli agenta AI, który korzysta z protokołu Model Context Protocol (MCP) do łączenia analizy danych i usług lokalizacyjnych.
Aplikacja pomaga użytkownikom zaplanować idealny dzień z psem na podstawie popularności rasy w Nowym Jorku. Agent używa łańcucha rozumowania „od makro do mikro”:
- Strategic Discovery (BigQuery): określa kod pocztowy w Nowym Jorku, w którym mieszka najwięcej osób danej rasy.
- Wykonywanie lokalne (Mapy): używa kodu pocztowego jako odchylenia lokalizacji do wyszukiwania „kawiarni przyjaznych zwierzętom” i „wybiegów dla psów”.
- Generowanie planu podróży: łączy dane, aby utworzyć plan podróży „Paszport dla zwierząt” z klikalnymi linkami i obrazami.
Agent został utworzony z użyciem platformy google-adk i korzysta z technologii Gemini.
Uwaga: pełny kod projektu, w tym interfejs użytkownika, jest dostępny na GitHubie. W tym laboratorium skupimy się na podstawowej logice agenta i konfiguracji infrastruktury.
2. Konfiguracja i wymagania
Najpierw upewnijmy się, że środowisko programistyczne jest prawidłowo skonfigurowane.
1. Uwierzytelnianie w Google Cloud
Ustaw aktywny projekt Google Cloud i uwierzytelnij się. Jest to wymagane, aby agent mógł uzyskać dostęp do BigQuery i innych usług.
gcloud config set project [YOUR-PROJECT-ID] gcloud auth application-default login --project [YOUR-PROJECT-ID]
Uwaga: jeśli podczas uwierzytelniania napotkasz błędy dotyczące innego projektu, możesz je pominąć, wyłączając projekt limitu i ustawiając go ręcznie:
gcloud auth application-default login --disable-quota-project gcloud auth application-default set-quota-project [YOUR-PROJECT-ID]
2. Wymagania dotyczące oprogramowania
Na komputerze lokalnym musisz mieć zainstalowane to oprogramowanie:
- Python (wymagana jest wersja 3.13 lub nowsza)
- Git (do pobrania repozytorium)
Pobieranie repozytorium
Kod tego projektu jest dostępny w repozytorium Google MCP. Sklonuj repozytorium i przejdź do folderu projektu:
git clone https://github.com/google/mcp.git cd examples/petpassport
3. Instalacja
Skoro masz już pliki, skonfigurujmy środowisko Pythona.
- Utwórz środowisko wirtualne: dzięki temu zależności będą odseparowane.
python3 -m venv .venv
- Aktywuj środowisko wirtualne:
- W systemie Linux/macOS:
source .venv/bin/activate
- W systemie Windows:
.venv\Scripts\activate
- W systemie Linux/macOS:
- Zainstaluj zależności:
pip install google-adk==1.28.0 python-dotenv google-genai pillow uvicorn
Włączanie interfejsów Cloud API
Włącz w projekcie te interfejsy API:
gcloud services enable \ bigquery.googleapis.com \ aiplatform.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ run.googleapis.com \ storage.googleapis.com
Wybierz region
Ustaw region jako zmienną środowiskową w powłoce:
export REGION=us-central1
4. Uzyskiwanie kluczy interfejsu API
Aby korzystać z usług Mapy i Gemini, musisz uzyskać klucze interfejsu API i zapisać je w pliku .env w katalogu głównym projektu.
1. Klucz interfejsu API Map Google
- Otwórz konsolę Google Cloud.
- Otwórz Interfejsy API i usługi > Dane logowania.
- Kliknij Utwórz dane logowania > Klucz interfejsu API.
- Skopiuj wygenerowany klucz i dodaj go do pliku
.envjakoMAPS_API_KEY=[YOUR_KEY]. - (Zalecane) Ogranicz klucz, aby zezwalał tylko na interfejsy API Map Google używane przez serwer MCP.
2. Klucz interfejsu Gemini API (AI Studio)
- Otwórz Google AI Studio.
- Kliknij Uzyskaj klucz interfejsu API lub otwórz sekcję kluczy interfejsów API.
- Kliknij Utwórz klucz interfejsu API.
- Skopiuj klucz i dodaj go do pliku
.envjakoGEMINI_API_KEY=[YOUR_KEY].
5. Instalowanie zależności
Utwórz plik requirements.txt w folderze petpassport/:
google-adk==1.28.0
python-dotenv
google-genai
pillow
6. Uwierzytelnianie serwerów MCP
Ta aplikacja korzysta z serwerów Model Context Protocol (MCP) do interakcji z Mapami Google i BigQuery. Aby uwierzytelnić te serwery, musisz skonfigurować odpowiednie zmienne środowiskowe i nagłówki.
- Google Maps MCP: wymaga prawidłowego klucza interfejsu API Map Google przekazanego w nagłówku
X-Goog-Api-Key. - BigQuery MCP: wymaga danych logowania OAuth z dostępem do usługi BigQuery. Gdy agent działa w Cloud Run, korzysta z domyślnego konta usługi Compute, a gdy działa lokalnie, korzysta z lokalnych danych logowania.
W repozytorium udostępniamy skrypt konfiguracji setup/setup_env.sh, który pomaga skonfigurować te zmienne w pliku .env.
7. Tworzenie tabeli BigQuery
Zanim agent będzie mógł wysyłać zapytania o dane dotyczące licencji na psy, musimy utworzyć zbiór danych i tabelę w BigQuery oraz wczytać dane.
Udostępniamy skrypt konfiguracjisetup/setup_bigquery.sh, który wykonuje te czynności:
- Tworzy zasobnik Cloud Storage o nazwie
pet-passport-data-[PROJECT_ID]do przechowywania nieprzetworzonych danych. - Pobiera publiczny zbiór danych NYC Dog Licensing (CSV).
- Przesyła plik CSV do zasobnika.
- Tworzy zbiór danych BigQuery o nazwie
nyc_dogs. - Wczytuje dane z zasobnika do tabeli o nazwie
licensesw zbiorze danych.
Aby uruchomić skrypt konfiguracji, wykonaj w terminalu to polecenie:
bash setup/setup_bigquery.sh
8. Łączenie z serwerami MCP
Kluczowym elementem tej aplikacji jest korzystanie z MCP do łączenia się z danymi i usługami. W tej sekcji skonfigurujesz zestawy narzędzi MCP dla BigQuery i Map Google w pliku o nazwie petpassport/tools.py.
Dokończ kod tools.py
Oto pełna implementacja tools.py, w tym zestawy narzędzi MCP i niestandardowe narzędzia do utrwalania obrazów i danych. Zoptymalizowaliśmy ten kod, aby zmniejszyć nadmiarowość, przenosząc rozdzielczość koszyka na poziom modułu:
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
Wyjaśnienie kodu: tools.py
get_maps_mcp_toolsetiget_bigquery_mcp_toolsetkonfigurują klientów MCP z prawidłowymi punktami końcowymi i nagłówkami uwierzytelniania.generate_pet_passport_photoużywa Gemini do utworzenia sceny i przesyła wynik do Google Cloud Storage, zwracając podpisany adres URL do frontendu, aby przetrwać ponowne uruchomienia serwera.
9. Tworzenie agenta
Po skonfigurowaniu narzędzi możesz zacząć budować „mózg” agenta. Za pomocą pakietu Agent Development Kit (ADK) utworzysz agenta w pliku o nazwie petpassport/agent.py.
Dokończ kod agent.py
Oto pełna implementacja agent.py, w której definiujemy agenta i jego instrukcje:
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]
)
Wyjaśnienie kodu: agent.py
- Importujemy
toolsbezpośrednio (spłaszczona struktura), aby obsługiwać środowisko kontenera. - Agent został zainicjowany z wartością
gemini-2.5-pro. - Instrukcje określają ścisły wieloetapowy proces myślowy (najpierw BigQuery, potem Mapy) i surowo zabraniają halucynacji lub renderowania tras pieszych, które prowadzą do bałaganu.
10. Lokalne uruchamianie aplikacji
Przed wdrożeniem aplikacji w Cloud Run warto ją przetestować lokalnie.
- Sprawdź, czy jesteś w katalogu projektu:
cd examples/petpassport
- Uruchom serwer FastAPI: do uruchomienia aplikacji używamy polecenia
uvicorn. Punktem wejścia jest plikmain.pyw folderzepetpassport.uvicorn petpassport.main:app --reload
- Otwórz interfejs: w przeglądarce otwórz stronę
http://127.0.0.1:8000/ui/, aby korzystać z interfejsu paszportu dla zwierząt.
11. Wdrażanie w Cloud Run
Gdy agent będzie gotowy, możesz go wdrożyć w Cloud Run. Używamy standardowego polecenia gcloud, aby zachować ścisłą kontrolę nad środowiskiem kontenera.
W katalogu projektu uruchom to polecenie:
gcloud run deploy petpassport \ --source petpassport \ --region $REGION \ --allow-unauthenticated \ --labels dev-tutorial=google-mcp
Konfigurowanie zmiennych środowiskowych
Po wdrożeniu otwórz usługę Cloud Run w konsoli Google Cloud i na karcie Zmienne i obiekty tajne ustaw te zmienne środowiskowe:
MAPS_API_KEY: klucz interfejsu API Map Google.GOOGLE_CLOUD_PROJECT: identyfikator projektu.PROJECT_ID: identyfikator projektu (w przypadku starszych modułów obsługiwana jest redundancja).
12. Przykładowe prompty
Spróbuj wejść w interakcję z wdrożonym agentem, używając tych promptów:
- Standard: „Chcę iść na spacer z golden retrieverem w Nowym Jorku w pobliżu kodu pocztowego 10021”. Znajdź dla nas trasę, na której jest kawiarnia”.
- Inna rasa: „Mam buldoga francuskiego i mieszkam w Upper West Side (w pobliżu kodu pocztowego 10024). Zaproponuj krótki spacer z przystankiem w popularnym parku dla psów”.
- Z obrazem: (prześlij zdjęcie psa) „Oto zdjęcie mojego corgi. Jesteśmy w pobliżu kodu 10013. Zaplanuj dla nas idealny dzień”.
13. Czyszczenie danych
Aby uniknąć obciążenia konta opłatami za zasoby użyte w tym samouczku:
- Usuń usługę Cloud Run:
gcloud run services delete petpassport --region=$REGION - Usuń zasobnik GCS:
gcloud storage rm -r gs://pet-passport-data-$PROJECT_ID