הפעלה אסינכרונית של אפליקציית AI מבוססת-סוכן באמצעות אירועים

1. מבוא

סקירה כללית

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

הפעולות שתבצעו:

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

איור של שומר גן חיות

תפרסו את אפליקציית ZooKeeper כשירות ב-Cloud Run, פלטפורמת מחשוב מנוהלת ללא שרתים שמריצה קונטיינרים ללא שמירת מצב בתשתית של Google. לאחר מכן תגדירו טריגר Eventarc שיפעיל את נקודת הקצה של השירות כדי לטפל באופן אסינכרוני בהודעות שמתפרסמות בנושא Pub/Sub. תדאגו שהפריסה תתבצע בהתאם לשיטות המומלצות, כולל שימוש בחשבונות שירות ייעודיים של IAM, הענקת גישה עם הרשאות מינימליות וצמצום פוטנציאל ההתקפה על ידי חשיפת נקודת הקצה של אפליקציית ZooKeeper ל-Eventarc בלבד. תעשו את זה בעזרת Cloud Shell ו-Cloud Console. תשתמשו בספריות ADK ו-Cloud SDK ל-Python. כדי לבדוק את ההתנהגות, משתמשים ב-CLI של gcloud.

מה תלמדו

  • פורסים את סוכן ה-ADK ב-Google Cloud Run.
  • משלבים Eventarc trigger עם סוכן ADK שפועל ב-Google Cloud Run.
  • כדי לאבטח את הפריסה והשילוב עם Eventarc, תוכלו להשתמש בעיקרון של הרשאות מינימליות בעזרת Google Cloud IAM.
  • פרסום הודעות ושליפת הודעות אל ומ-Pub/Sub.
  • צריך לצמצם את החשיפה הציבורית של האפליקציה שנפרסה ב-Google Cloud Run.

הדרישות

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

הערה: לחשבון שלכם צריכה להיות גישה ל-IAM בפרויקט, שתאפשר לכם להקצות משאבים ולהגדיר גישה ל-IAM למשאבים האלה.

חוויית המשתמש בדפדפנים אחרים עשויה להיות שונה מהחוויה שמתוארת במעבדה.

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

2. הגדרת הסביבה

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

אם אין לכם חשבון Google, צריך ליצור חשבון Google.

הוראות התקנה

  1. נכנסים למסוף Google Cloud באמצעות חשבון Google.
  2. ‫👉 פותחים את בורר הפרויקטים בסרגל הניווט העליון (יכול להיות שיופיע הכיתוב 'בחירת פרויקט' או שם של פרויקט קיים) או לוחצים על קיצור הדרך במקלדת Ctrl+O ובוחרים פרויקט קיים או יוצרים פרויקט חדש.ייקח כמה שניות ליצור פרויקט חדש. מחכים עד שהפרויקט יהיה מוכן ובוחרים אותו באמצעות בורר הפרויקטים.
  1. ‫👈 לוחצים על סמל Cloud Shell בחלק העליון של מסוף Google Cloud. (מסומן במלבן האדום):הלחצן Cloud Shell
    אם מוצגת בקשה, לוחצים על **Authorize** (אישור) בתיבת הדו-שיח הקופצת כדי לאשר ל-Cloud Shell להשתמש בפרטי הכניסה של החשבון.
    תיבת דו-שיח לאישור
  2. ‫👈💻 מוודאים שה-CLI של gcloud מוגדר לשימוש בפרויקט שבחרתם (או יצרתם). מריצים את הפקודה הבאה כדי לבדוק את מזהה הפרויקט שהוגדר:
    gcloud config get-value project
    
    הפלט אמור להיראות כך:
    Your active configuration is: [cloudshell-19597]
    [PROJECT_ID]
    
    כאשר [PROJECT_ID] הוא מזהה הפרויקט שבחרתם או שיצרתם.👉💻 אם מופיע ערך אחר, מריצים את הפקודה הבאה כדי להגדיר את מזהה הפרויקט כמזהה פרויקט ברירת מחדל לפקודות ב-CLI של gcloud:
    gcloud config set project [YOUR_PROJECT_ID]
    
    לדוגמה, אם מזהה הפרויקט הוא lab-project-id-example-123, הפקודה צריכה להיות:
    gcloud config set project lab-project-id-example-123
    
    🤔💻 אם אתם לא זוכרים את מזהה הפרויקט, אתם יכולים להשתמש בפקודה הבאה כדי להציג רשימה של כל מזהי הפרויקטים שיש לכם גישה אליהם, החל מהפרויקט האחרון:
    gcloud projects list \
        --format='value(projectId)' \
        --sort-by='~createTime'
    
  1. ‫👈💻 מגדירים את המיקום להקצאת משאבים, את המזהה ואת המספר של הפרויקט במשתני הסביבה:
    export LOCATION="us-central1"
    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
    
  2. ‫👈💻 מפעילים את ממשקי Google API שנדרשים למעבדה הזו.
    gcloud services enable \
        aiplatform.googleapis.com \
        eventarc.googleapis.com \
        run.googleapis.com \
        artifactregistry.googleapis.com \
        cloudbuild.googleapis.com \
        pubsub.googleapis.com
    
    חשוב להתאזר בסבלנות, הפקודה הזו יכולה לקחת כמה דקות. אם הפקודה תפעל בהצלחה, תוצג הודעה דומה לזו:
    Operation "operations/ab12345c-6e7f-8ghi-jkl9-m0e1d23456f7" finished successfully.
    

3. פריסת אפליקציית הדגמה של ZooKeeper

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

הגדרת משאבי Pub/Sub

תצטרכו ליצור שני נושאים ב-Pub/Sub. אחד מהם ישמש שירות צד שלישי לשליחת אירועים לאפליקציית ה-AI שלכם. אחד נוסף לפרסום תוצאות עיבוד האירועים באפליקציה.

  1. ‫👉💻 יוצרים נושא Pub/Sub שמשמש להפעלת אפליקציית ה-AI עם סוכנים:
    gcloud pubsub topics create invoke_agent
    export INVOKE_TOPIC_ID=$(gcloud pubsub topics describe invoke_agent --format="value(name)")
    
  2. ‫👈💻 יוצרים נושא Pub/Sub שבו האפליקציה יכולה לפרסם את התגובות שלה:
    gcloud pubsub topics create agent_responses
    export RESPONSE_TOPIC_ID=$(gcloud pubsub topics describe agent_responses --format="value(name)")
    gcloud pubsub subscriptions create agent_responses \
        --topic=agent_responses
    
    הפקודות האלה יוצרות גם מינוי לנושא Pub/Sub שנוצר. המינוי ישמש אתכם כשתיכנסו להדגמה כדי לראות את התוצאות.

הגדרה של חשבונות שירות ומדיניות IAM ברמת הפרויקט

תצטרכו ליצור שני חשבונות שירות כדי להגביל את היקף הגישה של שירות Cloud Run ושל טריגר Eventarc למינימום, בהתאם לעיקרון של הרשאות מינימליות. שירות Cloud Run דורש הרשאות לכתיבת יומנים ועקבות, לקריאה ל-Gemini LLM ב-Google Vertex AI ולפרסום תוצאות בנושא Pub/Sub. הגישה המינימלית של הטריגר Eventarc דורשת הרשאות לקריאה של האירועים שפורסמו ב-Pub/Sub ולקריאה של שירות Cloud Run ZooKeeper. ההוראות האלה יעזרו לכם להעניק לחשבון השירות של הטריגר את ההרשאות שנדרשות כדי להתחזות לשירות המערכת Pub/Sub. אחרי שיוצרים את משאב טריגר Eventarc, מריצים את הפקודה שמעניקה את התפקיד roles/run.invoker כדי לאפשר לחשבון השירות של הטריגר לקרוא לשירות Cloud Run.

  1. ‫👈💻 יוצרים חשבון שירות בשביל שירות Cloud Run:
    gcloud iam service-accounts create zookeeper-cloudrun-sa
    export ZOOKEEPER_SA="zookeeper-cloudrun-sa@${PROJECT_ID}.iam.gserviceaccount.com"
    
  2. ‫👈💻 נותנים לחשבון השירות הרשאות לכתוב יומנים ועקבות ולהשתמש במודלים של Gemini ב-Vertex AI:
    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
         --member="serviceAccount:${ZOOKEEPER_SA}" \
         --role="roles/logging.logWriter" \
         --condition=None
    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
        --member="serviceAccount:${ZOOKEEPER_SA}" \
        --role="roles/cloudtrace.agent" \
        --condition=None
    gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
        --member="serviceAccount:${ZOOKEEPER_SA}" \
        --role="roles/aiplatform.user" \
        --condition=None
    
  3. ‫👈💻 נותנים לחשבון השירות הרשאות לפרסום הודעות בנושא agent_responses:
    gcloud pubsub topics add-iam-policy-binding agent_responses \
        --member="serviceAccount:${ZOOKEEPER_SA}" \
        --role="roles/pubsub.publisher"
    
  4. ‫👈💻 יוצרים חשבון שירות לטריגר Eventarc:
    gcloud iam service-accounts create zookeeper-trigger-sa
    export TRIGGER_SA="zookeeper-trigger-sa@${PROJECT_ID}.iam.gserviceaccount.com"
    
  5. ‫👈💻 מעניקים לחשבון השירות של מערכת Pub/Sub הרשאות לשליחת בקשות push מאומתות:
    gcloud iam service-accounts add-iam-policy-binding "${TRIGGER_SA}" \
           --member="serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" \
        --role="roles/iam.serviceAccountTokenCreator"
    
    הפקודה הזו היא אופציונלית אם הפרויקט נוצר אחרי 8 באפריל 2021.

פריסת אפליקציית ZooKeeper ב-Cloud Run

תורידו את הקוד של אפליקציית ההדגמה מ-GitHub. ופורסים את הקוד ב-Cloud Run.

  1. ‫👈💻 הורדת אפליקציית ה-AI לנציגים:
    mkdir zoo-keeper-lab && cd zoo-keeper-lab
    git init
    git remote add origin https://github.com/GoogleCloudPlatform/devrel-demos
    git config set core.sparseCheckout true
    echo "ai-ml/agent-labs/adk_invoke_with_pubsub/" >> .git/info/sparse-checkout
    git pull origin main --depth 1
    cd ai-ml/agent-labs/adk_invoke_with_pubsub/
    
    הפקודות האלה משתמשות ב-Git sparse checkout של התיקייה עם אפליקציית ההדגמה כדי לקצר את זמן ההורדה.
  2. ‫👈💻 פריסת אפליקציית ה-AI עם סוכן ב-Cloud Run:
    gcloud run deploy zookeeper-agent \
        --region="${LOCATION}" \
        --source="." \
        --no-allow-unauthenticated \
        --quiet \
        --service-account="${ZOOKEEPER_SA}" \
        --set-env-vars="REPLY_TOPIC_ID=${RESPONSE_TOPIC_ID}"
    

הגדרת טריגר Eventarc

אחרי שמכינים את כל המשאבים (נושאי Pub/Sub, חשבונות שירות של IAM ושירות Cloud Run), הגיע הזמן להגדיר את משאב הטריגר של Eventarc. תצרו את משאב טריגר Eventarc ותעניקו לחשבון השירות של הטריגר הרשאות לקריאה לשירות Cloud Run.

  1. ‫👉💻 יצירת טריגר Eventarc:
    gcloud eventarc triggers create invoke-agent \
        --location="${LOCATION}" \
        --destination-run-service="zookeeper-agent" \
        --destination-run-path="/zookeeper" \
        --destination-run-region="${LOCATION}" \
        --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
        --transport-topic="${INVOKE_TOPIC_ID}" \
        --service-account="${TRIGGER_SA}"
    
  2. ‫👈💻 נותנים הרשאות לחשבון השירות של הטריגר להפעיל את שירות Cloud Run:
    gcloud run services add-iam-policy-binding zookeeper-agent \
        --region="${LOCATION}" \
        --member="serviceAccount:${TRIGGER_SA}" \
        --role="roles/run.invoker"
    

4. בדיקת אופן הפעולה של הפתרון

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

דיאגרמת פתרון

הפריסה מאובטחת בהתאם לעיקרון של הרשאות מינימליות. שירות Cloud Run אוכף אימות (ראו את הארגומנט --no-allow-unauthenticated בשלב 9 בקטע הקודם). רק זהויות עם ההרשאות roles/run.invoker או הרשאות דומות יכולות לקרוא לשירות. התפקיד הזה מוקצה רק לחשבון השירות של טריגר Eventarc. באופן דומה, הגישה לנושא invoke_agent מצומצמת כדי למנוע פרסום לא מורשה של אירועים. עדיין אפשר להתקשר ישירות לסוכן ZooKeeper בלי לפרסם בנושא Pub/Sub. בקטע 6 מוסבר איך להסתיר את נקודת הקצה של האפליקציה מגישה ציבורית.

הפעלת תהליך העבודה

תדמו אירוע חיצוני על ידי פרסום שאלה בשפה טבעית ב-ZooKeeper.

‫👈💻 משתמשים בפקודה הבאה כדי לפרסם הודעה בנושא Pub/Sub:

gcloud pubsub topics publish invoke_agent \
    --message='{"user_id": "important_app", "prompt": "How many animals are in the zoo?"}'

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

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

‫👈💻 משתמשים בפקודה הבאה כדי לקרוא את התגובה של הנציג מהמינוי ל-Pub/Sub:

gcloud pubsub subscriptions pull agent_responses --auto-ack

הפלט יהיה טבלה עם המטא-נתונים של ההודעה והמטען הייעודי (Payload) שמכיל את התשובה שיש בגן החיות 33 מינים. הדגל --auto-ack מאשר אוטומטית את קבלת ההודעה אחרי שהיא נמשכת, כך שהיא לא תימסר שוב.

איך זה עובד

כדי לראות את קוד המקור של אפליקציית ה-AI עם סוכנים, פותחים את Cloud Shell Editor ומציגים את הקבצים בתיקייה ~/zoo-keeper-lab. אפשר גם לראות את קוד המקור ב-GitHub.

  • main.py מטמיע אפליקציית אינטרנט בסיסית של FastAPI עם handler יחיד שמטפל באירועי Eventarc.
  • הסקריפט processor.py מנתח את ההודעה של האירוע כדי לאחזר את מזהה המשתמש ואת הבקשה. לאחר מכן נוצרת סשן חדש ב-ADK runner והסוכן Zookeeper נקרא כדי לעבד את הבקשה. התשובה מהנציג מתפרסמת בנושא Pub/Sub ‏agent_responses.
  • תיקיית המשנה zookeeper_agent מכילה את קוד המקור של סוכן ADK. אפשר להריץ את הפקודה adk run zookeeper_agent מתיקיית הבסיס של האפליקציה כדי ליצור אינטראקציה עם הסוכן באמצעות adk CLI.

איך פותרים בעיות

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

  • אם הפלט של הפקודה 'gcloud run deploy...‎' מדווח שהבנייה נכשלה, צריך לעיין בכתובת ה-URL של יומני הבנייה בפלט ולפתוח אותה בחלון נפרד.
  • אם בפלט מופיעה הודעה כמו 'השירות לא הופעל' או הודעה דומה, המשמעות היא שהשירות נפרס אבל הביצוע נכשל בבדיקת התקינות. במקרה כזה, פותחים את Logs Explorer או מעיינים בפסקה הבאה כדי לראות את הפקודה ב-CLI של gcloud. קוראים את היומנים כדי למצוא את שורש הבעיה של הכשל.

מה קורה אם פרסמתם הודעה ב-Pub/Sub אבל הסוכן לא מגיב או שהתגובה נראית מוזרה?

‫👈💻 משתמשים בפקודה הבאה כדי לקרוא את יומני האפליקציה שפורסמו מההרצה האחרונה:

gcloud logging read \
    'resource.type = "cloud_run_revision" AND \
     resource.labels.service_name = "zookeeper-agent" AND \
     resource.labels.location = "us-central1"'

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

5. חיזוק האבטחה של הפריסה

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

‫👈💻 כדי לסגור את וקטור התקיפה הזה, צריך להגביל את הקריאות לשירות כך שיתבצעו רק מאוסף המקורות המוגבל, כולל טריגרים של Eventarc:

gcloud run services update zookeeper-agent --region=${LOCATION} --ingress=internal

עכשיו, אם תנסו להתקשר לכתובת ה-URL של השירות מהמחשב המקומי, תקבלו את השגיאה '404 הדף לא נמצא'.

‫👈💻 משתמשים ב-curl כדי לשלוח בקשה לנקודת הקצה של השירות:

URL=$(gcloud run services describe zookeeper-agent --region=${LOCATION} --format='value(status.url)')
curl -X POST -d '{}' "${URL}/zookeeper"

הפלט אמור להיראות כך:

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>404 Page not found</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Page not found</h1>
<h2>The requested URL was not found on this server.</h2>
<h2></h2>
</body></html>

אחרי השינוי הזה, אי אפשר יותר להפעיל את ZooKeeper ישירות על ידי קריאה לנקודת הקצה של שירות Cloud Run, אלא אם הקריאה מתבצעת מ-VPC באותו פרויקט, מרשת VPC משותפת שהגרסה מוגדרת לשלוח אליה תנועה או ממארח שמהווה חלק מהיקף VPC Service Controls.

6. סיכום

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

הסרת המשאבים

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

יש שתי שיטות לעשות זאת:

שיטה 1: השבתת הפרויקט

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

gcloud projects delete $(gcloud config get-value project) --quiet

שיטה 2: מחיקת משאבים בפרויקט

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

gcloud run services delete zookeeper-agent --region=${LOCATION}

הגדרת הטריגר ב-Eventarc והנושאים ב-Pub/Sub לא כרוכים בעלויות ניהול (לפרטים נוספים אפשר לעיין במאמרים בנושא תמחור ב-Eventarc ותמחור ב-Pub/Sub).

מידע נוסף על סגירת הפרויקט

המאמרים הבאים