פריסה, ניהול ומעקב אחרי סוכן ADK ב-Cloud Run

1. מבוא

במדריך הזה נסביר איך פורסים, מנהלים ומנטרים סוכן מתקדם שנבנה באמצעות ערכת פיתוח הסוכנים (ADK) ב-Google Cloud Run. ה-ADK מאפשר לכם ליצור סוכנים שיכולים לבצע תהליכי עבודה מורכבים שכוללים כמה סוכנים. בעזרת Cloud Run, פלטפורמה מנוהלת ללא שרת (serverless), אתם יכולים לפרוס את הסוכן שלכם כאפליקציה בקונטיינר שאפשר להתאים לעומס, בלי לדאוג לתשתית הבסיסית. השילוב הזה מאפשר לכם להתמקד בלוגיקה הבסיסית של הסוכן וליהנות מהסביבה החזקה והניתנת להרחבה של Google Cloud.

במהלך המדריך הזה נסביר על השילוב החלק של ADK עם Cloud Run. תלמדו איך לפרוס את הסוכן, ואז תתעמקו בהיבטים המעשיים של ניהול האפליקציה בסביבה שדומה לסביבת ייצור. נראה לכם איך להשיק בבטחה גרסאות חדשות של הסוכן על ידי ניהול התנועה, כדי שתוכלו לבדוק תכונות חדשות עם קבוצת משנה של משתמשים לפני השקה מלאה.

בנוסף, תקבלו ניסיון מעשי במעקב אחרי הביצועים של הסוכן. נבצע סימולציה של תרחיש מהעולם האמיתי על ידי ביצוע בדיקת עומס, כדי לראות את יכולות ההתאמה האוטומטית של Cloud Run בפעולה. כדי לקבל תובנות מעמיקות יותר לגבי ההתנהגות והביצועים של הסוכן, נפעיל מעקב באמצעות Cloud Trace. כך תוכלו לקבל תצוגה מפורטת מקצה לקצה של הבקשות בזמן שהן עוברות דרך הסוכן, ולזהות ולטפל בצווארי בקבוק בביצועים. בסיום המדריך הזה, תהיה לכם הבנה מקיפה של אופן הפריסה, הניהול והמעקב של סוכנים מבוססי ADK ב-Cloud Run.

במהלך ה-codelab, תשתמשו בגישה שלב אחר שלב באופן הבא:

  1. יצירת מסד נתונים של PostgreSQL ב-CloudSQL לשימוש בשירות סשן מסד הנתונים של סוכן ADK
  2. הגדרה של סוכן ADK בסיסי
  3. הגדרת שירות הפעלות מסד נתונים לשימוש בכלי ADK Runner
  4. פריסה ראשונית של הסוכן ב-Cloud Run
  5. בדיקות עומס ובדיקה של התאמה לעומס (auto-scaling) ב-Cloud Run
  6. פריסת גרסה חדשה של סוכן והגדלה הדרגתית של נפח התנועה לגרסאות חדשות
  7. הגדרת מעקב בענן ובדיקת מעקב של הפעלת סוכן

סקירה כללית של הארכיטקטורה

5e38fc5607fb4543.jpeg

דרישות מוקדמות

  • נוח לעבוד עם Python
  • הבנה של ארכיטקטורת full-stack בסיסית באמצעות שירות HTTP

מה תלמדו

  • המבנה של ADK וכלי עזר מקומיים
  • הגדרת סוכן ADK באמצעות שירות הפעלת מסד נתונים
  • הגדרת PostgreSQL ב-CloudSQL לשימוש בשירות של סשן מסד נתונים
  • פריסת אפליקציה ב-Cloud Run באמצעות Dockerfile והגדרת משתני סביבה ראשוניים
  • הגדרה ובדיקה של התאמה אוטומטית לעומס ב-Cloud Run באמצעות בדיקת עומס
  • אסטרטגיה להפצה הדרגתית באמצעות Cloud Run
  • הגדרה של מעקב אחרי סוכן ADK ב-Cloud Trace

מה צריך

  • דפדפן האינטרנט Chrome
  • חשבון Gmail
  • פרויקט ב-Cloud עם חיוב מופעל

ב-codelab הזה, שמיועד למפתחים בכל הרמות (כולל מתחילים), נעשה שימוש ב-Python באפליקציה לדוגמה. עם זאת, לא נדרש ידע ב-Python כדי להבין את המושגים שמוצגים.

‫2. לפני שמתחילים

בחירת פרויקט פעיל ב-Cloud Console

ב-codelab הזה אנחנו יוצאים מנקודת הנחה שכבר יש לכם פרויקט ב-Google Cloud עם חיוב מופעל. אם עדיין אין לכם חשבון, אתם יכולים לפעול לפי ההוראות שבהמשך כדי להתחיל.

  1. ב-Google Cloud Console, בדף לבחירת הפרויקט, בוחרים או יוצרים פרויקט ב-Google Cloud.
  2. מוודאים שהחיוב מופעל בפרויקט ב-Cloud. כך בודקים אם החיוב מופעל בפרויקט

c714d4741fc97644.png

הכנת מסד נתונים ב-Cloud SQL

בהמשך נצטרך מסד נתונים שישמש את סוכן ה-ADK. ניצור מסד נתונים של PostgreSQL ב-Cloud SQL. קודם, עוברים לסרגל החיפוש בחלק העליון של מסוף Cloud ומקלידים 'cloud sql'. לאחר מכן לוחצים על המוצר Cloud SQL.

1005cb65520eb3fc.png

לאחר מכן, צריך ליצור מכונה חדשה למסד נתונים. לוחצים על Create Instance (יצירת מכונה) ובוחרים באפשרות PostgreSQL.

7f2ad19bc246895d.png

ead4a98e7a8d8a39.png

יכול להיות שתצטרכו גם להפעיל את Compute Engine API אם אתם מתחילים עם פרויקט חדש. אם ההנחיה הזו מופיעה, פשוט לוחצים על Enable API.

724cf67681535679.png

לאחר מכן, בוחרים את המפרטים של מסד הנתונים, בוחרים במהדורת Enterprise עם הגדרות קבועות מראש של מהדורת Sandbox.

24aa9defed93a3ef.png

אחרי זה, מגדירים כאן את שם המופע ואת סיסמת ברירת המחדל למשתמש postgres. אתם יכולים להגדיר את זה עם כל פרטי כניסה שתרצו, אבל לצורך המדריך הזה נשתמש ב-adk-deployment גם לשם המופע וגם לסיסמה.

573719a4582f541c.png

במדריך הזה נשתמש באזור us-central1 עם אזור יחיד. כדי לסיים את יצירת מסד הנתונים ולהשלים את כל ההגדרות הנדרשות, לוחצים על הלחצן יצירת מופע.

773e2ea11d97369d.png

בזמן ההמתנה לסיום הפעולה, אפשר להמשיך לקטע הבא

הגדרת פרויקט בענן בטרמינל Cloud Shell

  1. תשתמשו ב-Cloud Shell, סביבת שורת פקודה שפועלת ב-Google Cloud. לוחצים על 'הפעלת Cloud Shell' בחלק העליון של מסוף Google Cloud.

1829c3759227c19b.png

  1. אחרי שמתחברים ל-Cloud Shell, בודקים שכבר בוצע אימות ושהפרויקט מוגדר למזהה הפרויקט באמצעות הפקודה הבאה:
gcloud auth list
  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שפקודת gcloud מכירה את הפרויקט.
gcloud config list project
  1. אם הפרויקט לא מוגדר, משתמשים בפקודה הבאה כדי להגדיר אותו:
gcloud config set project <YOUR_PROJECT_ID>

אפשר גם לראות את המזהה במסוף:PROJECT_ID

4032c45803813f30.jpeg

לוחצים עליו וכל הפרויקטים ומזהה הפרויקט יופיעו בצד שמאל.

8dc17eb4271de6b5.jpeg

  1. מפעילים את ממשקי ה-API הנדרשים באמצעות הפקודה שמוצגת למטה. זה יימשך כמה דקות, אז כדאי לחכות בסבלנות.
gcloud services enable aiplatform.googleapis.com \
                       run.googleapis.com \
                       cloudbuild.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       sqladmin.googleapis.com

אם הפקודה תפעל בהצלחה, תוצג הודעה שדומה לזו שמופיעה בהמשך:

Operation "operations/..." finished successfully.

אפשר גם לחפש כל מוצר במסוף או להשתמש בקישור הזה במקום בפקודת gcloud.

אם פספסתם API כלשהו, תמיד תוכלו להפעיל אותו במהלך ההטמעה.

אפשר לעיין במאמרי העזרה בנושא פקודות gcloud ושימוש בהן.

כניסה אל Cloud Shell Editor והגדרת ספריית העבודה של האפליקציה

עכשיו אפשר להגדיר את עורך הקוד כדי לבצע פעולות שקשורות לקוד. נשתמש ב-Cloud Shell Editor לצורך הזה

  1. לוחצים על הלחצן Open Editor (פתיחת העורך) כדי לפתוח את Cloud Shell Editor. כאן אפשר לכתוב את הקוד b16d56e4979ec951.png
  2. מוודאים שהפרויקט ב-Cloud Code מוגדר בפינה הימנית התחתונה (סרגל הסטטוס) של העורך ב-Cloud Shell, כפי שמודגש בתמונה שלמטה, ושהוא מוגדר לפרויקט הפעיל ב-Google Cloud שבו החיוב מופעל. אם מתבקשים, לוחצים על Authorize (אישור). אם כבר ביצעתם את הפקודה הקודמת, יכול להיות שהלחצן יפנה ישירות לפרויקט שהפעלתם במקום ללחצן הכניסה.

f5003b9c38b43262.png

  1. בשלב הבא, משכפלים את ספריית העבודה של התבנית בשביל ה-codelab הזה מ-GitHub, ומריצים את הפקודה הבאה. ספריית העבודה תיצור בספרייה deploy_and_manage_adk
git clone https://github.com/alphinside/deploy-and-manage-adk-service.git deploy_and_manage_adk
  1. אחרי כן, עוברים לחלק העליון של Cloud Shell Editor ולוחצים על File->Open Folder (קובץ > פתיחת תיקייה), מאתרים את ספריית username (שם המשתמש) ואת הספרייה deploy_and_manage_adk (פריסה וניהול של ADK), ואז לוחצים על הלחצן OK. הפעולה הזו תגדיר את הספרייה שנבחרה כספריית העבודה הראשית. בדוגמה הזו, שם המשתמש הוא alvinprayuda, ולכן נתיב הספרייה מוצג למטה

2c53696f81d805cc.png

a51615f22ba1690f.png

עכשיו Cloud Shell Editor אמור להיראות כך

228d4c1844790573.png

בשלב הבא, אפשר להגדיר את סביבת Python

הגדרת הסביבה

הכנת סביבה וירטואלית של Python

השלב הבא הוא הכנת סביבת הפיתוח. ספריית העבודה הפעילה הנוכחית של הטרמינל צריכה להיות בתוך ספריית העבודה deploy_and_manage_adk. ב-codelab הזה נשתמש ב-Python 3.12 וב-uv python project manager כדי לפשט את הצורך ביצירה ובניהול של גרסת Python וסביבה וירטואלית.

  1. אם עדיין לא פתחתם את הטרמינל, פותחים אותו על ידי לחיצה על Terminal (טרמינל) -> New Terminal (טרמינל חדש), או באמצעות Ctrl + Shift + C. חלון הטרמינל ייפתח בחלק התחתון של הדפדפן.

f8457daf0bed059e.jpeg

  1. מורידים את uv ומתקינים את Python 3.12 באמצעות הפקודה הבאה
curl -LsSf https://astral.sh/uv/0.6.16/install.sh | sh && \
source $HOME/.local/bin/env && \
uv python install 3.12
  1. עכשיו מאתחלים את הסביבה הווירטואלית באמצעות uv. מריצים את הפקודה הזו
uv sync --frozen

תיקיית .venv תיצור ותתקין את יחסי התלות. תצוגה מקדימה מהירה של pyproject.toml תיתן לכם מידע על התלות שמוצגת כך

dependencies = [
    "google-adk==1.3.0",
    "locust==2.37.10",
    "pg8000==1.31.2",
    "python-dotenv==1.1.0",
]
  1. כדי לבדוק את הסביבה הווירטואלית, יוצרים קובץ חדש בשם main.py ומעתיקים את הקוד הבא
def main():
   print("Hello from deploy_and_manage_adk!")

if __name__ == "__main__":
   main()
  1. לאחר מכן, מריצים את הפקודה הבאה
uv run main.py

יוצג פלט כמו זה שמופיע למטה

Using CPython 3.12
Creating virtual environment at: .venv
Hello from deploy_and_manage_adk!

ההודעה הזו מציינת שהגדרת פרויקט Python מתבצעת בצורה תקינה.

הגדרת קובצי תצורה

עכשיו צריך להגדיר קובצי הגדרה לפרויקט הזה.

משנים את שם הקובץ .env.example ל-.env והערך שמופיע למטה יוצג. מעדכנים את הערך של GOOGLE_CLOUD_PROJECT למזהה הפרויקט.

# Google Cloud and Vertex AI configuration
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=global
GOOGLE_GENAI_USE_VERTEXAI=True

# Database connection for session service
# SESSION_SERVICE_URI=postgresql+pg8000://<username>:<password>@/<database>?unix_sock=/cloudsql/<instance_connection_name>/.s.PGSQL.5432

בשיעור הזה נשתמש בערכים שהוגדרו מראש עבור GOOGLE_CLOUD_LOCATION ו-GOOGLE_GENAI_USE_VERTEXAI.. בשלב הזה, נשאיר את SESSION_SERVICE_URI כהערה.

עכשיו אפשר לעבור לשלב הבא, לבדוק את הלוגיקה של הסוכן ולפרוס אותו

3. Build the Weather Agent with ADK and Gemini 2.5

מבוא למבנה הספריות של ADK

נתחיל בהסבר על האפשרויות של ADK ואיך ליצור את הסוכן. אפשר לגשת לתיעוד המלא של ADK בכתובת ה-URL הזו . חבילת ה-ADK מציעה לנו הרבה כלי עזר בביצוע פקודות ה-CLI שלה. לדוגמה :

  • הגדרת מבנה ספריית הסוכנים
  • ניסיון מהיר של אינטראקציה באמצעות קלט ופלט של CLI
  • הגדרה מהירה של ממשק משתמש מקומי לפיתוח

עכשיו נבדוק את מבנה הסוכן בספרייה weather_agent

weather_agent/
├── __init__.py
├── agent.py

אם בודקים את הקבצים init.py ו-agent.py, אפשר לראות את הקוד הזה

# __init__.py

from weather_agent.agent import root_agent

__all__ = ["root_agent"]
# agent.py

import os
from pathlib import Path

import google.auth
from dotenv import load_dotenv
from google.adk.agents import Agent
from google.cloud import logging as google_cloud_logging

# Load environment variables from .env file in root directory
root_dir = Path(__file__).parent.parent
dotenv_path = root_dir / ".env"
load_dotenv(dotenv_path=dotenv_path)

# Use default project from credentials if not in .env
_, project_id = google.auth.default()
os.environ.setdefault("GOOGLE_CLOUD_PROJECT", project_id)
os.environ.setdefault("GOOGLE_CLOUD_LOCATION", "global")
os.environ.setdefault("GOOGLE_GENAI_USE_VERTEXAI", "True")

logging_client = google_cloud_logging.Client()
logger = logging_client.logger("weather-agent")


def get_weather(city: str) -> dict:
    """Retrieves the current weather report for a specified city.

    Args:
        city (str): The name of the city (e.g., "New York", "London", "Tokyo").

    Returns:
        dict: A dictionary containing the weather information.
              Includes a 'status' key ('success' or 'error').
              If 'success', includes a 'report' key with weather details.
              If 'error', includes an 'error_message' key.
    """
    logger.log_text(
        f"--- Tool: get_weather called for city: {city} ---", severity="INFO"
    )  # Log tool execution
    city_normalized = city.lower().replace(" ", "")  # Basic normalization

    # Mock weather data
    mock_weather_db = {
        "newyork": {
            "status": "success",
            "report": "The weather in New York is sunny with a temperature of 25°C.",
        },
        "london": {
            "status": "success",
            "report": "It's cloudy in London with a temperature of 15°C.",
        },
        "tokyo": {
            "status": "success",
            "report": "Tokyo is experiencing light rain and a temperature of 18°C.",
        },
    }

    if city_normalized in mock_weather_db:
        return mock_weather_db[city_normalized]
    else:
        return {
            "status": "error",
            "error_message": f"Sorry, I don't have weather information for '{city}'.",
        }


root_agent = Agent(
    name="weather_agent",
    model="gemini-2.5-flash",
    instruction="You are a helpful AI assistant designed to provide accurate and useful information.",
    tools=[get_weather],
)

הסבר על הקוד ב-ADK

הסקריפט הזה מכיל את ההפעלה של הנציג, שבה אנחנו מאתחלים את הדברים הבאים:

  • הגדרת המודל לשימוש בתור gemini-2.5-flash
  • מספק כלי get_weather לתמיכה בפונקציונליות של הסוכן כסוכן מזג אוויר

הפעלת ממשק המשתמש באינטרנט

עכשיו אפשר לקיים אינטראקציה עם הסוכן ולבדוק את ההתנהגות שלו באופן מקומי. ה-ADK מאפשר לנו להשתמש בממשק משתמש אינטרנטי לפיתוח כדי לקיים אינטראקציה עם המערכת ולבדוק מה קורה במהלך האינטראקציה. מריצים את הפקודה הבאה כדי להפעיל את שרת ממשק המשתמש של סביבת הפיתוח המקומית

uv run adk web --port 8080

יוצג פלט כמו בדוגמה הבאה, כלומר כבר יש לנו גישה לממשק האינטרנט

INFO:     Started server process [xxxx]
INFO:     Waiting for application startup.

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://localhost:8080.                         |
+-----------------------------------------------------------------------------+

INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)

כדי לבדוק את זה, לוחצים על הלחצן Web Preview (תצוגה מקדימה של אתר) באזור העליון של Cloud Shell Editor ובוחרים באפשרות Preview on port 8080 (תצוגה מקדימה ביציאה 8080).

e7c9f56c2463164.png

יוצג דף אינטרנט שבו תוכלו לבחור סוכנים זמינים באמצעות הלחצן הנפתח בפינה הימנית העליונה ( במקרה שלנו, weather_agent) ולנהל אינטראקציה עם הבוט. בחלון הימני יוצגו פרטים רבים על יומן הרישום במהלך זמן הריצה של הסוכן

d95b1e057315fee2.png

עכשיו, נסו ליצור איתו אינטראקציה. בסרגל הימני, אפשר לבדוק את המעקב של כל קלט, כדי להבין כמה זמן לוקח לכל פעולה שהסוכן מבצע לפני שהוא יוצר את התשובה הסופית.

39c0a06ace937683.png

זו אחת מתכונות הניטור שמוטמעות ב-ADK. בשלב הזה אנחנו בודקים אותה באופן מקומי. בהמשך נראה איך השילוב הזה מתבצע ב-Cloud Tracing, כדי שיהיה לנו מעקב מרכזי של כל הבקשות

4. הסקריפט של השרת העורפי

כדי להפוך את הסוכן לזמין כשירות, נשתמש באפליקציית FastAPI כדי לעטוף את הסוכן. כאן נוכל להגדיר את השירותים הנדרשים לתמיכה בסוכן, כמו הכנת שירותי Session, ‏ Memory או Artifact למטרות ייצור. זה הקוד של server.py שבו נשתמש

import os

from dotenv import load_dotenv
from fastapi import FastAPI
from google.adk.cli.fast_api import get_fast_api_app
from pydantic import BaseModel
from typing import Literal
from google.cloud import logging as google_cloud_logging
from tracing import CloudTraceLoggingSpanExporter
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider, export


# Load environment variables from .env file
load_dotenv()

logging_client = google_cloud_logging.Client()
logger = logging_client.logger(__name__)

AGENT_DIR = os.path.dirname(os.path.abspath(__file__))

# Get session service URI from environment variables
session_uri = os.getenv("SESSION_SERVICE_URI", None)

# Prepare arguments for get_fast_api_app
app_args = {"agents_dir": AGENT_DIR, "web": True}

# Only include session_service_uri if it's provided
if session_uri:
    app_args["session_service_uri"] = session_uri
else:
    logger.log_text(
        "SESSION_SERVICE_URI not provided. Using in-memory session service instead. "
        "All sessions will be lost when the server restarts.",
        severity="WARNING",
    )

provider = TracerProvider()
processor = export.BatchSpanProcessor(CloudTraceLoggingSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)

# Create FastAPI app with appropriate arguments
app: FastAPI = get_fast_api_app(**app_args)

app.title = "weather-agent"
app.description = "API for interacting with the Agent weather-agent"


class Feedback(BaseModel):
    """Represents feedback for a conversation."""

    score: int | float
    text: str | None = ""
    invocation_id: str
    log_type: Literal["feedback"] = "feedback"
    service_name: Literal["weather-agent"] = "weather-agent"
    user_id: str = ""


@app.post("/feedback")
def collect_feedback(feedback: Feedback) -> dict[str, str]:
    """Collect and log feedback.

    Args:
        feedback: The feedback data to log

    Returns:
        Success message
    """
    logger.log_struct(feedback.model_dump(), severity="INFO")
    return {"status": "success"}


# Main execution
if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8080)

הסבר על קוד השרת

אלה הדברים שמוגדרים בסקריפט server.py:

  1. להמיר את הסוכן לאפליקציית FastAPI באמצעות השיטה get_fast_api_app. כך נשתמש באותה הגדרת נתיב שמשמשת את ממשק המשתמש של פיתוח האתר.
  2. מגדירים את השירותים הנדרשים של Session,‏ Memory או Artifact על ידי הוספת ארגומנטים של מילות מפתח לשיטה get_fast_api_app. במדריך הזה, אם נגדיר את משתנה הסביבה SESSION_SERVICE_URI, שירות הסשן ישתמש בו, אחרת הוא ישתמש בסשן בזיכרון
  3. אנחנו יכולים להוסיף מסלול מותאם אישית כדי לתמוך בלוגיקה עסקית אחרת של ה-Backend. בסקריפט אנחנו מוסיפים דוגמה למסלול של פונקציונליות משוב
  4. הפעלת מעקב בענן כדי לשלוח את המעקב אל Google Cloud Trace

5. פריסה ב-Cloud Run

עכשיו נראה איך פורסים את שירות הסוכן הזה ב-Cloud Run. לצורך ההדגמה הזו, השירות הזה יהיה שירות ציבורי שאנשים אחרים יוכלו לגשת אליו. עם זאת, חשוב לזכור שזו לא שיטה מומלצת כי היא לא מאובטחת

5e38fc5607fb4543.jpeg

בשיעור הזה נשתמש ב-Dockerfile כדי לפרוס את הסוכן שלנו ב-Cloud Run. בהמשך מופיע התוכן של Dockerfile שבו ייעשה שימוש

FROM python:3.12-slim

RUN pip install --no-cache-dir uv==0.7.13

WORKDIR /app

COPY . .

RUN uv sync --frozen

EXPOSE 8080

CMD ["uv", "run", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8080"]

בשלב הזה, יש לנו כבר את כל הקבצים שנדרשים לפריסת האפליקציות ב-Cloud Run, אז נבצע את הפריסה. עוברים לטרמינל Cloud Shell ומוודאים שהפרויקט הנוכחי מוגדר לפרויקט הפעיל שלכם. אם לא, צריך להשתמש בפקודה gcloud configure כדי להגדיר את מזהה הפרויקט:

gcloud config set project [PROJECT_ID]

לאחר מכן, מריצים את הפקודה הבאה כדי לפרוס אותו ב-Cloud Run.

gcloud run deploy weather-agent \
                  --source . \
                  --port 8080 \
                  --project {YOUR_PROJECT_ID} \
                  --allow-unauthenticated \
                  --add-cloudsql-instances {YOUR_DB_CONNECTION_NAME} \
                  --update-env-vars SESSION_SERVICE_URI="postgresql+pg8000://postgres:{YOUR_DEFAULT_USER_PASS}@postgres/?unix_sock=/cloudsql/{YOUR_DB_CONNECTION_NAME}/.s.PGSQL.5432",GOOGLE_CLOUD_PROJECT={YOUR_PROJECT_ID} \
                  --region us-central1

כדי לקבל את הערך {YOUR_DB_CONNECTION_NAME}, אפשר להיכנס שוב ל-Cloud SQL וללחוץ על המופע שיצרתם. בדף של המופע, גוללים למטה לקטע Connect to this instance (התחברות למופע הזה) ומעתיקים את שם החיבור כדי להחליף את הערך {YOUR_DB_CONNECTION_NAME}. לדוגמה, התמונה שמוצגת למטה

5d7d6c6f17e559c1.png

אם מוצגת בקשה לאישור יצירה של מאגר Docker ב-Artifact Registry, פשוט משיבים Y. שימו לב שאנחנו מאפשרים כאן גישה לא מאומתת כי זו אפליקציית הדגמה. מומלץ להשתמש באימות מתאים לאפליקציות שלכם בארגון ובסביבת הייצור.

אחרי שהפריסה תושלם, תקבלו קישור שדומה לזה שבהמשך:

https://weather-agent-*******.us-central1.run.app

אפשר להשתמש באפליקציה מהחלון במצב אנונימי או מהנייד. הוא כבר אמור להיות פעיל.

6. בדיקת התאמה אוטומטית לעומס (auto-scaling) ב-Cloud Run באמצעות בדיקת עומס

עכשיו נבדוק את יכולות ההתאמה האוטומטית של Cloud Run. בתרחיש הזה, נפרס גרסה חדשה תוך הפעלת מספר מקסימלי של פעולות בו-זמניות לכל מופע. מריצים את הפקודה הבאה

gcloud run deploy weather-agent \
                  --source . \
                  --port 8080 \
                  --project {YOUR_PROJECT_ID} \
                  --allow-unauthenticated \
                  --region us-central1 \
                  --concurrency 10

לאחר מכן, נבדוק את הקובץ load_test.py. זה יהיה הסקריפט שבו נשתמש כדי לבצע את בדיקת העומס באמצעות מסגרת locust. הסקריפט הזה יבצע את הפעולות הבאות :

  1. מזהה משתמש (user_id) ומזהה סשן (session_id) רנדומליים
  2. יצירת session_id עבור user_id
  3. הפעלת נקודת הקצה (endpoint) '/run_sse' עם הערכים של user_id ו-session_id שנוצרו

אם פספסתם את כתובת ה-URL של השירות שפרסתם, נצטרך לדעת אותה. נכנסים למסוף Cloud Run ולוחצים על השירות weather-agent.

f5cc953cc422de6d.png

אחר כך, מחפשים את שירות weather-agent ולוחצים עליו.

ddd0df8544aa2bfb.png

כתובת ה-URL של השירות תוצג לצד פרטי האזור. לדוגמה

41b1276616379ee8.png

לאחר מכן מריצים את הפקודה הבאה כדי לבצע את בדיקת העומס

uv run locust -f load_test.py \
              -H {YOUR_SERVICE_URL} \
              -u 60 \
              -r 5 \
              -t 120 \
              --headless

כשמריצים את הפקודה הזו, מוצגים מדדים כמו אלה. ( בדוגמה הזו, כל הבקשות הצליחו )

Type     Name                                  # reqs      # fails |    Avg     Min     Max    Med |   req/s  failures/s
--------|------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
POST     /run_sse end                             813     0(0.00%) |   5817    2217   26421   5000 |    6.79        0.00
POST     /run_sse message                         813     0(0.00%) |   2678    1107   17195   2200 |    6.79        0.00
--------|------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
         Aggregated                              1626     0(0.00%) |   4247    1107   26421   3500 |   13.59        0.00  

עכשיו נבדוק מה קרה ב-Cloud Run. נחזור לשירות שפרסתם ונראה את לוח הבקרה. כך תוכלו לראות איך Cloud Run משנה את גודל המכונה באופן אוטומטי כדי לטפל בבקשות נכנסות. מכיוון שאנחנו מגבילים את מספר הבקשות המקסימלי ל-10 לכל מופע, מופע Cloud Run ינסה להתאים את מספר הקונטיינרים כדי לעמוד בתנאי הזה באופן אוטומטי.

1ad41143eb9d95df.png

7. הפצה הדרגתית של תיקונים חדשים

עכשיו נבחן את התרחיש הבא. אנחנו רוצים לעדכן את ההנחיה של הסוכן להנחיה הבאה :

# agent.py

...

root_agent = Agent(
    name="weather_agent",
    model="gemini-2.5-flash-preview-05-20",
    instruction="You are a helpful AI assistant designed to provide accurate and useful information. You only answer inquiries about the weather. Refuse all other user query",
    tools=[get_weather],
)

לאחר מכן, אתם רוצים לפרסם גרסאות חדשות, אבל לא רוצים שכל התנועה של הבקשות תעבור ישירות לגרסה החדשה. אפשר לבצע השקה הדרגתית באמצעות Cloud Run. קודם צריך לפרוס גרסה חדשה, אבל עם הדגל ‎–no-traffic. שומרים את סקריפט הסוכן הקודם ומריצים את הפקודה הבאה:

gcloud run deploy weather-agent \
                  --source . \
                  --port 8080 \
                  --project {YOUR_PROJECT_ID} \
                  --allow-unauthenticated \
                  --region us-central1 \
                  --no-traffic

בסיום, תקבלו יומן דומה לזה שקיבלתם בתהליך הפריסה הקודם, אבל עם מספר שונה של תנועה. יוצג ערך התנועה שהוצגה 0 אחוזים.

עכשיו נעבור לדף המוצר של Cloud Run ונחפש את המופע שפרסתם. מקלידים cloud run בסרגל החיפוש ולוחצים על המוצר Cloud Run.

f5cc953cc422de6d.png

אחר כך, מחפשים את שירות weather-agent ולוחצים עליו.

ddd0df8544aa2bfb.png

עוברים לכרטיסייה Revisions (גרסאות) ורואים את רשימת הגרסאות שנפרסו.

8519c5a59bc7efa6.png

אפשר לראות שהגרסאות החדשות שפרסמתם מציגות 0% מהתנועה. מכאן אפשר ללחוץ על לחצן האפשרויות הנוספות (⋮) ולבחור באפשרות ניהול תנועה.

d4d224e20813c303.png

בחלון הקופץ החדש, אפשר לערוך את אחוז התנועה שמופנה לכל אחת מהגרסאות.

6df497c3d5847f14.png

אחרי המתנה של זמן מה, התנועה תופנה באופן יחסי על סמך הגדרות האחוזים. כך נוכל לחזור בקלות לגרסאות הקודמות אם יקרה משהו בגרסה החדשה

8. מעקב ADK

סוכנים שנוצרו באמצעות ADK כבר תומכים במעקב באמצעות הטמעה של טלמטריה פתוחה. יש לנו את Cloud Trace כדי לתעד את המעקב הזה ולהציג אותו באופן חזותי. בואו נבדוק את הקובץ server.py כדי לראות איך מפעילים אותו בשירות שפרסנו קודם

# server.py

from tracing import CloudTraceLoggingSpanExporter
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider, export

...

provider = TracerProvider()
processor = export.BatchSpanProcessor(CloudTraceLoggingSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)

...

כאן מאתחלים את הכלי למעקב ואת כלי הייצוא. אפשר לבדוק את פרטי הייצוא ב-tracing.py . במקרה הזה אנחנו יוצרים כלי ייצוא בהתאמה אישית כי יש מגבלה על נתוני המעקב שאפשר לייצא ל-Cloud Trace. אנחנו משתמשים בהטמעה מ- https://googlecloudplatform.github.io/agent-starter-pack/guide/observability.html כדי להפעיל את יכולת המעקב הזו.

אפשר לנסות לגשת לממשק המשתמש של מפתח האתרים של השירות ולשוחח עם הסוכן. אחרי זה עוברים לסרגל החיפוש ב-Cloud Console, מקלידים 'Trace Explorer' ובוחרים במוצר Trace Explorer.

4353c0f8982361ab.png

בדף של כלי המעקב אחר נתונים, תראו שהשיחה שלנו עם הסוכן נשלחה למעקב. אפשר לראות את זה בקטע Span name ולסנן את ה-span שספציפי לסוכן שלנו ( השם שלו הוא agent_run [weather_agent])

c4336d117a3d2f6a.png

אם הטווחים כבר מסוננים, אפשר גם לבדוק כל מעקב ישירות. יוצג משך זמן מפורט של כל פעולה שהסוכן ביצע. לדוגמה, התמונות הבאות

76a56dff77979037.png

1a3ce0a803d6061a.png

בכל קטע, אפשר לבדוק את הפרטים במאפיינים כמו שמוצג בהמשך

2c87b6d67b0164a8.png

עכשיו יש לנו יכולת תצפית טובה ומידע על כל אינטראקציה של הסוכן עם המשתמש, שיעזרו לנו לנפות באגים בבעיות. אתם מוזמנים לנסות כלים או תהליכי עבודה שונים.

9. האתגר

כדאי לנסות תהליכי עבודה מרובי-סוכנים או תהליכי עבודה שמבוססים על סוכנים כדי לראות איך הם פועלים בעומסים גבוהים ואיך נראה המעקב

10. הסרת המשאבים

כדי לא לצבור חיובים לחשבון Google Cloud על המשאבים שבהם השתמשתם ב-Code Lab הזה:

  1. במסוף Google Cloud, עוברים לדף Manage resources.
  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
  4. לחלופין, אפשר לעבור אל Cloud Run במסוף, לבחור את השירות שפרסתם ולמחוק אותו.