Cloud Run पर पालतू जानवरों के पासपोर्ट का एजेंट बनाना और उसे डिप्लॉय करना

1. खास जानकारी

इस कोडलैब में, Pet Passport ऐप्लिकेशन को डिप्लॉय करने का तरीका बताया गया है. यह एक एआई एजेंट है, जो डेटा के विश्लेषण और लोकेशन सेवाओं को एक साथ इस्तेमाल करने के लिए, मॉडल कॉन्टेक्स्ट प्रोटोकॉल (एमसीपी) का इस्तेमाल करता है.

यह ऐप्लिकेशन, न्यूयॉर्क शहर में कुत्ते की नस्ल की लोकप्रियता के आधार पर, उपयोगकर्ताओं को अपने कुत्ते के साथ बाहर घूमने की योजना बनाने में मदद करता है. एजेंट, "मैक्रो-टू-माइक्रो" तर्क चेन का इस्तेमाल करता है:

  1. रणनीतिक खोज (BigQuery): यह न्यूयॉर्क शहर के उस ज़िप कोड की पहचान करता है जहां किसी खास नस्ल के कुत्ते सबसे ज़्यादा हैं.
  2. स्थानीय तौर पर लागू करना (Maps): यह ज़िप कोड को लोकेशन के हिसाब से पक्षपात के तौर पर इस्तेमाल करके, "पालतू जानवरों के लिए सही कैफ़े" और "डॉग पार्क" ढूंढता है.
  3. यात्रा कार्यक्रम जनरेट करना: यह डेटा को मिलाकर, "Pet Passport" का यात्रा कार्यक्रम बनाता है. इसमें क्लिक किए जा सकने वाले लिंक और इमेज शामिल होती हैं.

एजेंट को google-adk फ़्रेमवर्क का इस्तेमाल करके बनाया गया है. यह Gemini की मदद से काम करता है.

ध्यान दें: पूरे प्रोजेक्ट का कोड, जिसमें फ़्रंटएंड यूज़र इंटरफ़ेस (यूआई) भी शामिल है, GitHub पर उपलब्ध है. इस कोडलैब में, हम एजेंट की मुख्य लॉजिक और इन्फ़्रास्ट्रक्चर सेटअप पर फ़ोकस करेंगे.

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 एनवायरमेंट सेट अप करते हैं.

  1. वर्चुअल एनवायरमेंट बनाएं: इससे आपकी डिपेंडेंसी अलग-अलग रहेंगी.
    python3 -m venv .venv
    
  2. वर्चुअल एनवायरमेंट चालू करें:
    • Linux/macOS पर:
      source .venv/bin/activate
      
    • Windows पर:
      .venv\Scripts\activate
      
  3. डिपेंडेंसी इंस्टॉल करें:
    pip install google-adk==1.28.0 python-dotenv google-genai pillow uvicorn
    

Cloud API चालू करना

अपने प्रोजेक्ट में ये एपीआई चालू करें:

gcloud services enable \
  bigquery.googleapis.com \
  aiplatform.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  run.googleapis.com \
  storage.googleapis.com

कोई देश/इलाका चुनें

अपने शेल में, देश/इलाके को एनवायरमेंट वैरिएबल के तौर पर सेट करें:

export REGION=us-central1

4. एपीआई पासकोड पाना

Maps और Gemini सेवाओं का इस्तेमाल करने के लिए, आपको एपीआई पासकोड पाने होंगे. इन्हें प्रोजेक्ट के रूट में मौजूद .env फ़ाइल में सेव करना होगा.

1. Google Maps API पासकोड

  1. Google Cloud Console पर जाएं.
  2. एपीआई और सेवाएं > क्रेडेंशियल पर जाएं.
  3. क्रेडेंशियल बनाएं > एपीआई पासकोड पर क्लिक करें.
  4. जनरेट किए गए पासकोड को कॉपी करें और इसे अपनी .env फ़ाइल में MAPS_API_KEY=[YOUR_KEY] के तौर पर जोड़ें.
  5. (सुझाया जाता है) पासकोड को इस तरह से सीमित करें कि इसका इस्तेमाल सिर्फ़ Maps API के लिए किया जा सके. इन एपीआई का इस्तेमाल, एमसीपी सर्वर करता है.

2. Gemini API पासकोड (AI Studio)

  1. Google AI Studio पर जाएं.
  2. एपीआई पासकोड पाएं पर क्लिक करें या एपीआई पासकोड सेक्शन पर जाएं.
  3. एपीआई पासकोड बनाएं पर क्लिक करें.
  4. पासकोड को कॉपी करें और इसे अपनी .env फ़ाइल में GEMINI_API_KEY=[YOUR_KEY] के तौर पर जोड़ें.

5. डिपेंडेंसी इंस्टॉल करना

petpassport/ फ़ोल्डर में, requirements.txt फ़ाइल बनाएं:

google-adk==1.28.0
python-dotenv
google-genai
pillow

6. एमसीपी सर्वर की पुष्टि करना

यह ऐप्लिकेशन, Google Maps और BigQuery के साथ इंटरैक्ट करने के लिए, मॉडल कॉन्टेक्स्ट प्रोटोकॉल (एमसीपी) सर्वर पर निर्भर करता है. इन सर्वर की पुष्टि करने के लिए, आपको सही एनवायरमेंट वैरिएबल और हेडर कॉन्फ़िगर करने होंगे.

  1. Google Maps MCP: इसके लिए, X-Goog-Api-Key हेडर में पास किया गया, मान्य Maps API पासकोड ज़रूरी है.
  2. BigQuery MCP: इसके लिए, OAuth क्रेडेंशियल ज़रूरी हैं. साथ ही, BigQuery सेवा का ऐक्सेस भी ज़रूरी है. Cloud Run पर चलने के दौरान, एजेंट डिफ़ॉल्ट कंप्यूट सेवा खाते का इस्तेमाल करता है. वहीं, स्थानीय तौर पर चलने के दौरान, यह आपके स्थानीय क्रेडेंशियल का इस्तेमाल करता है.

हमने डेटा स्टोर करने की जगह में, setup/setup_env.sh नाम की एक सेटअप स्क्रिप्ट दी है. इससे आपकी .env फ़ाइल में इन वैरिएबल को कॉन्फ़िगर करने में मदद मिलती है.

7. BigQuery टेबल बनाना

एजेंट, कुत्ते के लाइसेंस के डेटा के बारे में क्वेरी कर सके, इसके लिए हमें BigQuery में डेटासेट और टेबल बनानी होगी. साथ ही, डेटा लोड करना होगा.

हमने setup/setup_bigquery.sh नाम की एक सेटअप स्क्रिप्ट दी है. यह स्क्रिप्ट, ये चरण पूरे करती है:

  1. कच्चे डेटा को सेव करने के लिए, pet-passport-data-[PROJECT_ID] नाम की Cloud Storage बकेट बनाती है.
  2. न्यूयॉर्क शहर के सार्वजनिक तौर पर उपलब्ध, कुत्ते के लाइसेंसिंग डेटासेट (सीएसवी) को डाउनलोड करती है.
  3. सीएसवी को बकेट में अपलोड करती है.
  4. nyc_dogs नाम का BigQuery डेटासेट बनाती है.
  5. डेटासेट में, licenses नाम की टेबल में बकेट से डेटा लोड करती है.

सेटअप स्क्रिप्ट चलाने के लिए, अपने टर्मिनल में यह कमांड डालें:

bash setup/setup_bigquery.sh

8. एमसीपी सर्वर से कनेक्ट करना

इस ऐप्लिकेशन का एक अहम हिस्सा, डेटा और सेवाओं से कनेक्ट करने के लिए, एमसीपी का इस्तेमाल करना है. इस सेक्शन में, petpassport/tools.py नाम की फ़ाइल में, BigQuery और Google Maps के लिए, एमसीपी टूलसेट कॉन्फ़िगर किए जाएंगे.

tools.py का पूरा कोड

tools.py के लिए यहां पूरा कोड दिया गया है. इसमें एमसीपी टूलसेट के साथ-साथ, इमेज और डेटा को सेव करने के लिए, कस्टम टूल भी शामिल हैं. हमने इस कोड को ऑप्टिमाइज़ किया है, ताकि बकेट रिज़ॉल्यूशन को मॉड्यूल लेवल पर ले जाकर, डुप्लीकेट कोड को कम किया जा सके:

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, एमसीपी क्लाइंट को सही एंडपॉइंट और अनुमति वाले हेडर के साथ कॉन्फ़िगर करते हैं.
  • generate_pet_passport_photo, Gemini का इस्तेमाल करके एक सीन बनाता है और नतीजे को Google Cloud Storage पर अपलोड करता है. साथ ही, सर्वर रीस्टार्ट होने के बाद भी, फ़्रंटएंड पर दिखने के लिए, Signed URL दिखाता है.

9. एजेंट बनाना

टूल कॉन्फ़िगर करने के बाद, अब एजेंट का "दिमाग" बनाने का समय है. एजेंट डेवलपमेंट किट (एडीके) का इस्तेमाल करके, 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 पर डिप्लॉय करने से पहले, ऐप्लिकेशन को स्थानीय तौर पर टेस्ट करना अच्छा होता है.

  1. पक्का करें कि आप प्रोजेक्ट डायरेक्ट्री में हों:
    cd examples/petpassport
    
  2. FastAPI सर्वर शुरू करें: हम ऐप्लिकेशन चलाने के लिए, uvicorn का इस्तेमाल करते हैं. एंट्री पॉइंट, petpassport फ़ोल्डर में मौजूद main.py है.
    uvicorn petpassport.main:app --reload
    
  3. यूज़र इंटरफ़ेस (यूआई) खोलें: Pet Passport इंटरफ़ेस के साथ इंटरैक्ट करने के लिए, अपने ब्राउज़र में http://127.0.0.1:8000/ui/ पर जाएं.

11. Cloud Run पर डिप्लॉय किया जा रहा है

आपका एजेंट तैयार है, तो अब इसे Cloud Run पर डिप्लॉय करने का समय है. कंटेनर एनवायरमेंट पर सख्त कंट्रोल बनाए रखने के लिए, हम सीधे तौर पर स्टैंडर्ड gcloud कमांड का इस्तेमाल करते हैं.

प्रोजेक्ट डायरेक्ट्री से, यह कमांड चलाएं:

gcloud run deploy petpassport \
  --source petpassport \
  --region $REGION \
  --allow-unauthenticated \
  --labels dev-tutorial=google-mcp

एनवायरमेंट वैरिएबल कॉन्फ़िगर करना

डिप्लॉय करने के बाद, Google Cloud Console में Cloud Run सेवा पर जाएं और वैरिएबल और सीक्रेट टैब में जाकर, ये एनवायरमेंट वैरिएबल सेट करें:

  • MAPS_API_KEY: आपका Google Maps API पासकोड.
  • GOOGLE_CLOUD_PROJECT: आपका प्रोजेक्ट आईडी.
  • PROJECT_ID: आपका प्रोजेक्ट आईडी (लेगसी मॉड्यूल के लिए, डुप्लीकेट आईडी इस्तेमाल किया जा सकता है).

12. प्रॉम्प्ट के सैंपल

इन प्रॉम्प्ट का इस्तेमाल करके, डिप्लॉय किए गए एजेंट के साथ इंटरैक्ट करें:

  1. स्टैंडर्ड: "मुझे न्यूयॉर्क शहर में, 10021 के आस-पास, अपने गोल्डन रिट्रीवर के साथ टहलने जाना है. हमारे लिए ऐसा रास्ता ढूंढें जहां एक कैफ़े हो."
  2. अलग नस्ल: "मेरे पास एक फ़्रेंच बुलडॉग है और हम अपर वेस्ट साइड (10024 के आस-पास) में हैं. हमारे लिए, पैदल चलने का एक छोटा रास्ता सुझाएं, जो किसी लोकप्रिय डॉग पार्क पर खत्म होता हो."
  3. इमेज के साथ: (अपने कुत्ते की फ़ोटो अपलोड करें) "यह मेरे Corgi की फ़ोटो है! हम 10013 के आस-पास हैं. हमारे लिए, बाहर घूमने की एक शानदार योजना बनाएं."

13. व्यवस्थित करें

इस ट्यूटोरियल में इस्तेमाल किए गए संसाधनों के लिए शुल्क लगने से बचने के लिए:

  • Cloud Run सेवा मिटाएं: gcloud run services delete petpassport --region=$REGION
  • GCS बकेट मिटाएं: gcloud storage rm -r gs://pet-passport-data-$PROJECT_ID