Build Multi-Agent Systems with ADK

1. מבוא

סקירה כללית

בשיעור Lab הזה נסביר איך לתזמר מערכות מורכבות עם כמה סוכנים באמצעות הערכה לפיתוח סוכנים (ADK) של Google. תעברו מהיררכיות פשוטות של סוכנים ליצירת תהליכי עבודה אוטומטיים ושיתופיים.

מה תפַתחו

תבנו שתי מערכות נפרדות מרובות סוכנים:

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

מה תלמדו

  • איך יוצרים קשרים בין סוכנים ראשיים ומשניים.
  • איך כותבים נתונים לסשן state מכלי.
  • איך קוראים מ-state באמצעות תבניות של מפתחות (לדוגמה, {my_key?}).
  • איך משתמשים ב-SequentialAgent כדי ליצור תהליכי עבודה מפורטים.
  • איך משתמשים ב-LoopAgent כדי ליצור מחזורי שיפור איטרטיביים.
  • איך משתמשים ב-ParallelAgent כדי להריץ משימות עצמאיות במקביל.

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

  • היכרות עם Python וממשקי שורת פקודה (CLI).
  • גישה לפרויקט בענן ב-Google Cloud עם חיוב מופעל.
  • הכלים של CLI שהותקנו: gcloud, uv.

2. מערכות מרובות סוכנים

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

לגישה הזו יש כמה יתרונות בהשוואה לשימוש בפרומפט יחיד ומונוליטי:

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

עץ הסוכנים ההיררכי

מבנה עץ שמציג סוכנים היררכיים

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

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

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

3. הגדרת הפרויקט

חשבון Google

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

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

כניסה למסוף Google Cloud

נכנסים למסוף Google Cloud באמצעות חשבון Google אישי.

הפעלת חיוב

מימוש קרדיטים ב-Google Cloud (אופציונלי)

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

הגדרה של חשבון לחיוב לשימוש אישי

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

כדי להגדיר חשבון לחיוב לשימוש אישי, עוברים לכאן כדי להפעיל את החיוב במסוף Cloud.

הערות:

  • העלות של השלמת ה-Lab הזה צריכה להיות פחות מ-1 דולר ארה"ב במשאבי Cloud.
  • כדי להימנע מחיובים נוספים, אפשר למחוק את המשאבים בסיום ה-Lab.
  • משתמשים חדשים זכאים לתקופת ניסיון בחינם בשווי 300$.

יצירת פרויקט (אופציונלי)

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

4. פתיחת Cloud Shell Editor

  1. כדי לעבור ישירות אל Cloud Shell Editor, לוחצים על הקישור הזה.
  2. אם תתבקשו לאשר בשלב כלשהו היום, לחצו על אישור כדי להמשיך. צריך ללחוץ כדי לתת הרשאה ל-Cloud Shell
  3. אם הטרמינל לא מופיע בתחתית המסך, פותחים אותו:
    • לוחצים על הצגה.
    • לוחצים על Terminal (טרמינל)פתיחת טרמינל חדש ב-Cloud Shell Editor.
  4. בטרמינל, מגדירים את הפרויקט באמצעות הפקודה הבאה:
    gcloud config set project [PROJECT_ID]
    
    • דוגמה:
      gcloud config set project lab-project-id-example
      
    • אם אתם לא זוכרים את מזהה הפרויקט, אתם יכולים להציג את כל מזהי הפרויקטים באמצעות הפקודה:
      gcloud projects list
      
      הגדרת מזהה פרויקט בטרמינל של Cloud Shell Editor
  5. אמורה להופיע ההודעה הבאה:
    Updated property [core/project].
    

5. הפעלת ממשקי ה-API

כדי להשתמש ב-Gemini Enterprise Agent Platform API ולקיים אינטראקציה עם מודל Gemini, צריך להפעיל את ה-API בפרויקט Google Cloud.

  1. בטרמינל, מפעילים את ה-API:
    gcloud services enable aiplatform.googleapis.com
    

מבוא ל-Google GenAI SDK ל-Python

כדי ליצור אינטראקציה עם מודלים שמתארחים בפלטפורמת הסוכנים של Gemini Enterprise מאפליקציית Python, תשתמשו ב-Google GenAI SDK ל-Python. ערכת ה-SDK הזו מפשטת את התהליך של שליחת הנחיות, הגדרת פרמטרים של מודלים וקבלת תשובות, בלי שתצטרכו לטפל ישירות במורכבויות של הקריאות הבסיסיות ל-API.

בקישור הבא אפשר למצוא תיעוד מקיף של Google GenAI SDK ל-Python: Google GenAI SDK Documentation.

6. הגדרת סביבת הפרויקט

שכפול המאגר

  1. במסוף, משכפלים את המאגר שמכיל את קובצי ההתחלה.
    ‫
    git clone --depth 1 https://github.com/GoogleCloudPlatform/devrel-demos.git devrel-demos-multiagent-lab
    
    הדגל --depth 1 משכפל רק את הגרסה האחרונה, ולכן הוא מהיר יותר.
  2. בטרמינל, מעבירים את התיקייה הספציפית ל-Lab לספריית הבית ומשנים את השם שלה כך שיתאים למבנה הצפוי של ה-Lab.
    mv devrel-demos-multiagent-lab/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems ~
    
  3. בטרמינל, עוברים לספריית העבודה הנכונה של שיעור ה-Lab הזה (adk_multiagent_systems).
    cd ~/adk_multiagent_systems
    

בדיקת מבנה הקבצים

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

  1. בתפריט Cloud Shell Editor, בוחרים באפשרות File (קובץ) > Open Folder... (פתיחת תיקייה...).
    תפריט הקובץ ב-Cloud Shell Editor עם האפשרות 'פתיחת תיקייה' שנבחרה
  2. בתיבה שמופיעה, מוסיפים את פרטי התיקייה הבאים אחרי שם המשתמש: adk_multiagent_systems/. לוחצים על אישור.
    זה אמור להיראות כך:
    פתיחת תיבת הדו-שיח 'פתיחת תיקייה' עם נתיב הפרויקט
  3. חלונית הסייר בצד ימין תעבור רענון. עכשיו אמור להופיע מבנה הפרויקט המלא, עם ספריות המשנה parent_and_subagents ו-workflow_agents, וניתן להמשיך לשלבים הבאים.
    חלונית הסייר שמציגה את התיקייה הפתוחה adk_multiagent_systems

הפעלה של סביבה וירטואלית

  1. בטרמינל, יוצרים ומפעילים סביבה וירטואלית באמצעות uv. כך אפשר לוודא שיחסי התלות של הפרויקט לא יתנגשו עם Python של המערכת או עם פרויקטים אחרים.
    uv venv
    source .venv/bin/activate
    
  2. בטרמינל, מתקינים את google-adk ואת יחסי התלות האחרים מהקובץ requirements.txt:
    uv pip install -r requirements.txt
    

הגדרה של משתני סביבה

  1. אתם כבר בספרייה adk_multiagent_systems. בטרמינל, יוצרים קובץ .env לאחסון משתני הסביבה:
    cloudshell edit .env
    
  2. מדביקים את הקטע הבא בקובץ .env שנפתח בעורך:
    GOOGLE_GENAI_USE_ENTERPRISE=true
    GOOGLE_CLOUD_PROJECT="[YOUR-PROJECT-ID]"
    GOOGLE_CLOUD_LOCATION=global
    MODEL="gemini-3.5-flash"
    
  3. מחליפים את [YOUR-PROJECT-ID] במזהה הפרויקט בפועל ב-Google Cloud. (לדוגמה, PROJECT_ID = "google-cloud-labs")
    אם אתם לא זוכרים את מזהה הפרויקט, מריצים את הפקודה הבאה בטרמינל. תופיע רשימה של כל הפרויקטים והמזהים שלהם.
    gcloud projects list
    
  4. בטרמינל, מעתיקים את הקובץ .env לספריות של הסוכנים המשניים כדי שגם הם יוכלו לגשת למשתנים:
    cp .env parent_and_subagents/.env
    cp .env workflow_agents/.env
    
    מבנה הקובץ אמור להיראות כך:
    חלונית הסייר שמציגה את התיקייה הפתוחה adk_multiagent_systems

7. העברות בין סוכנים ראשיים, סוכני משנה וסוכנים מקבילים

השיחה תמיד מתחילה עם root_agent. כברירת מחדל, סוכן ראשי משתמש בdescription של סוכני המשנה כדי להחליט מתי להעביר את השיחה. אתם יכולים גם להנחות את ההעברות האלה באופן מפורש בחשבון ההורה instruction באמצעות name של סוכני המשנה.

בוא נבדוק את זה.

  1. ב-Cloud Shell Editor, פותחים את adk_multiagent_systems/parent_and_subagents/agent.py. שימו לב לשלושת הסוכנים בקובץ agent.py:
    • ‫root_agent (בשם steering): שואל את המשתמש שאלה כדי להחליט לאיזה סוכן משנה להעביר אותו. בתחילה, הוא מסתמך רק על description של סוכני המשנה שלו.
    • ‫travel_brainstormer: עוזר למשתמש לערוך סיעור מוחות לגבי יעדים.
    • ‫attractions_planner: עוזר למשתמש ליצור רשימה של דברים שאפשר לעשות במדינה מסוימת.
  2. כדי להגדיר את travel_brainstormer ואת attractions_planner כסוכני משנה של root_agent, מוסיפים את השורה הבאה ליצירה של root_agent:
        sub_agents=[travel_brainstormer, attractions_planner]
    
  3. במסוף, מתכתבים בצ'אט עם הסוכן:
    cd ~/adk_multiagent_systems
    adk run parent_and_subagents
    
  4. בשורת הפקודה [user]: בטרמינל, מקלידים:
    hello
    
    פלט לדוגמה (יכול להיות שהפלט שלכם יהיה קצת שונה):
    [steering]: Hi there! Do you already have a country in mind for your trip, or would you like some help deciding where to go?
    
  5. עכשיו, אומרים לסוכן בטרמינל:
    I could use some help deciding.
    
    פלט לדוגמה (יכול להיות שהפלט שלכם יהיה קצת שונה):
    [travel_brainstormer]: Okay! To give you the best recommendations, I need to understand what you're looking for in a trip.
    ...
    
    שימו לב לתג [travel_brainstormer]. root_agent העביר את השליטה על סמך רק description של סוכן המשנה.
  6. בהנחיה user: בטרמינל, מקלידים exit ומקישים על Enter כדי לסיים את השיחה.
  7. עכשיו נסביר את זה בצורה ברורה יותר. ב-agent.py, מוסיפים את הערכים הבאים ל-root_agent של instruction:
            If they need help deciding, send them to 'travel_brainstormer'.
            If they know what country they'd like to visit, send them to the 'attractions_planner'.
    
  8. במסוף, מריצים שוב את הסוכן:
    adk run parent_and_subagents
    
  9. בשורת הפקודה [user]: בטרמינל, מקלידים:
    hello
    
  10. תשובה עם:
    I would like to go to Japan.
    
    פלט לדוגמה (יכול להיות שהפלט שלכם יהיה קצת שונה):
    [attractions_planner]: Okay, I can help you with that! Here are some popular attractions in Japan:
    ...
    
    שימו לב להעברה אל attractions_planner, בהתאם להוראות החדשות.
  11. עכשיו תשיב עם:
    Actually I don't know what country to visit.
    
    פלט לדוגמה (יכול להיות שהפלט שלכם יהיה קצת שונה):
    [travel_brainstormer]: Okay! I can help you brainstorm some countries for travel...
    
    לידיעתך, הועברת אל travel_brainstormer, שהוא עמית של attractions_planner. האפשרות הזו מופעלת כברירת מחדל.
  12. בהנחיית המשתמש, מקלידים exit כדי לסיים את הסשן.

Recap

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

  • השיחה תמיד מתחילה עם root_agent.
  • סוכן הורה יכול להעביר באופן אוטומטי לסוכן משנה על סמך description.
  • אתם יכולים לשלוט בתהליך הזה באופן מפורש על ידי מתן האפשרות להורה instruction להעברה לסוכן משנה באמצעות name.
  • כברירת מחדל, סוכנים יכולים להעביר לסוכנים שלהם (אחים בהיררכיה) peer.

8. שימוש במצב הסשן כדי לאחסן ולאחזר מידע

לכל שיחה ב-ADK יש Session, שכולל מילון של מצב הסשן. כל הסוכנים יכולים לגשת למצב הזה, ולכן הוא מתאים להעברת מידע ביניהם או לשמירת נתונים (כמו רשימה) לאורך השיחה.

כדי ללמוד איך להוסיף לסטייט ולקרוא ממנו:

  1. חזרה לקובץ adk_multiagent_systems/parent_and_subagents/agent.py
  2. מדביקים את הגדרת הפונקציה הבאה אחרי הכותרת # Tools:
    def save_attractions_to_state(
    tool_context: ToolContext,
    attractions: List[str]
    ) -> dict[str, str]:
        """Saves the list of attractions to state["attractions"].
    
        Args:
            attractions [str]: a list of strings to add to the list of attractions
    
        Returns:
            None
        """
        # Load existing attractions from state. If none exist, start an empty list
        existing_attractions = tool_context.state.get("attractions", [])
    
        # Update the 'attractions' key with a combo of old and new lists.
        # When the tool is run, ADK will create an event and make
        # corresponding updates in the session's state.
        tool_context.state["attractions"] = existing_attractions + attractions
    
        # A best practice for tools is to return a status message in a return dict
        return {"status": "success"}
    
    בקטע הקוד הזה, שימו לב לפרטים הבאים:
    • הפונקציה מקבלת את הערך tool_context: ToolContext. האובייקט הזה הוא השער שלכם לסשן.
    • השורה tool_context.state["attractions"] = ... קוראת ישירות ממילון המצב של הסשן וכותבת אליו. ה-ADK מטפל בכל השאר.
  3. מוסיפים את הכלי לסוכן attractions_planner על ידי הוספת הפרמטר tools:
        tools=[save_attractions_to_state]
    
  4. מוסיפים את נקודות התבליט הבאות לattractions_planner הקיים של הסוכן instruction:
            - When they reply, use your tool to save their selected attraction and then provide more possible attractions.
            - If they ask to view the list, provide a bulleted list of { attractions? } and then suggest some more.
    
  5. מפעילים את ממשק האינטרנט של ערכת פיתוח הסוכנים (ADK) באמצעות הפקודה הבאה בטרמינל:
    adk web
    
    פלט
    INFO:     Started server process [2434]
    INFO:     Waiting for application startup.
    +-------------------------------------------------------+
    | ADK Web Server started                                |
    |                                                       |
    | For local testing, access at http://localhost:8000.   |
    +-------------------------------------------------------+
    
    INFO:     Application startup complete.
    INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
    
  6. במסוף Cloud Shell, לוחצים על הלחצן תצוגה מקדימה של האינטרנט ובוחרים באפשרות שינוי יציאה כדי להציג את ממשק האינטרנט בכרטיסייה חדשה.
    תפריט תצוגה מקדימה של אתר
  7. מזינים את מספר הפורט 8000 ולוחצים על שינוי ותצוגה מקדימה. תיפתח כרטיסייה חדשה בדפדפן עם ממשק המשתמש של ADK Dev.
    שינוי תיבת החלון הקופץ של היציאה עם הערך 8000 שהוזן בתיבת הטקסט
  8. בתפריט הנפתח Select an agent (בחירת סוכן) בצד ימין, בוחרים באפשרות parent_and_subagents.
  9. מתחילים את השיחה עם: hello
  10. אחרי שהנציג יברך אתכם, תשיבו לו:
    I'd like to go to Egypt.
    
    תועברו אל attractions_planner ותוצג לכם רשימה של אטרקציות.
  11. בוחרים אטרקציה, למשל:
    I'll go to the Sphinx
    
  12. אמורה להתקבל תגובה כמו: בסדר, שמרתי את The Sphinx ברשימה שלך...
  13. לוחצים על תיבת הכלים של התגובה (מסומנת בסימן וי) כדי לראות את האירוע שנוצר מהתגובה של הכלי.
    שימו לב שהוא כולל שדה actions שכולל stateDelta שמתאר את השינויים במצב.
  14. תגיב עם אטרקציה אחרת מרשימת האטרקציות של הסוכן.
  15. בתפריט הניווט הימני, לוחצים על X כדי לצאת מההתמקדות באירוע שנבדק קודם.
  16. בסרגל הצד שמימין, לוחצים על הכרטיסייה מצב. עכשיו אפשר לראות את המערך attractions במצב של הסשן, שאמור להכיל את שני הפריטים שבחרתם.תצוגה מקדימה של מצב הסשן בממשק המשתמש באינטרנט
  17. שולחים את ההודעה הבאה לסוכן:
    What is on my list?
    
    הסוכן אמור לקרוא עכשיו מהמצב ולהחזיר את הרשימה.
  18. בסיום הניסוי עם הסוכן, סוגרים את הכרטיסייה בדפדפן האינטרנט ומקישים על CTRL + C במסוף Cloud Shell כדי לעצור את השרת.

סיכום הקטע

בקטע הזה למדתם איך להשתמש במצב Session כדי לשתף נתונים:

  • כדי לכתוב למצב: כותבים למילון המצב מתוך כלי, באמצעות אובייקט tool_context.state (למשל, tool_context.state["my_list"] = [...]).
  • כדי לקרוא את הסטטוס: מזריקים נתוני סטטוס ישירות ל-instruction של הסוכן באמצעות תבניות מפתח (למשל, Here is your list: {my_list?}).
  • כדי לבדוק את הסטטוס: אפשר לעקוב אחרי סטטוס הסשן בזמן אמת בממשק המשתמש של ADK Dev באמצעות הכרטיסייה State.

9. סוכני תהליכי עבודה

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

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

  • SequentialAgent
  • LoopAgent
  • ParallelAgent

בהמשך ה-Lab הזה נתמקד ביצירת מערכת מרובת סוכנים באמצעות שלושת הסוכנים לתהליכי עבודה האלה.

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

בסופו של דבר, המערכת שלכם תיראה כך:

דיאגרמה של מערכת מרובת סוכנים של צוות film_concept_team

תבנו את המערכת הזו שלב אחרי שלב, ותתחילו בתהליך העבודה הפשוט ביותר.

10. יצירת מערכת מרובת סוכנים באמצעות SequentialAgent

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

הגרסה הראשונה תהיה במבנה הבא:

Film_concept_team multi-agent system step 1

  • root_agent (greeter) יקבל את המשתמש בברכה וישאל אותו על איזה סרט הוא רוצה לקבל מידע.
  • השיחה תועבר אל SequentialAgent בשם film_concept_team, שיבצע את הפעולות הבאות:
    1. מריצים סוכן researcher כדי לקבל עובדות מתוך ויקיפדיה.
    2. מריצים סוכן screenwriter כדי להשתמש בעובדות האלה לכתיבת עלילה.
    3. מריצים סוכן file_writer כדי לשמור את העלילה הסופית בקובץ.

בוא נריץ אותו.

  1. ב-Cloud Shell Editor, פותחים את הקובץ adk_multiagent_systems/workflow_agents/agent.py.
    קוראים את קובץ ההגדרה של הסוכן. כדי לקרוא את הקובץ לפי סדר זרימת השיחה, אפשר לקרוא את הסוכנים מלמטה למעלה, כי צריך להגדיר את הסוכנים המשניים לפני שאפשר להקצות אותם לסוכן הראשי.
  2. שימו לב לכלי append_to_state. פונקציית העזר הזו מאפשרת לסוכנים לצרף נתונים לרשימה במצב הסשן, וכך הפונקציות researcher ו-screenwriter יעבירו את העבודה שלהן.
  3. כדאי לנסות את הסוכן. במסוף, מפעילים את ממשק האינטרנט עם טעינה מחדש בזמן אמת:
    cd ~/adk_multiagent_systems
    adk web --reload_agents
    
  4. במסוף Cloud Shell, לוחצים על הלחצן תצוגה מקדימה של האינטרנט ובוחרים באפשרות שינוי יציאה כדי להציג את ממשק האינטרנט בכרטיסייה חדשה.
    תפריט תצוגה מקדימה של אתר
  5. מזינים את מספר הפורט 8000 ולוחצים על שינוי ותצוגה מקדימה. תיפתח כרטיסייה חדשה בדפדפן עם ממשק המשתמש של ADK Dev.
    שינוי תיבת החלון הקופץ של היציאה עם הערך 8000 שהוזן בתיבת הטקסט
  6. בתפריט הנפתח Select an agent, בוחרים באפשרות workflow_agents.
  7. מתחילים את השיחה עם: hello. סוכן greeter יגיב.
  8. כשמופיעה בקשה, מזינים דמות היסטורית. אפשר להשתמש באחת מהאפשרויות הבאות או באפשרות משלכם:
    • ג'אנג ג'ונגג'ינג
    • עדה לוי
    • מרקוס אורליוס
  9. השליטה תעבור עכשיו אל SequentialAgent. לא תראו הודעות ביניים. הפעולות researcher,‏ screenwriter ו-file_writer יפעלו אחת אחרי השנייה. הסוכן יגיב רק אחרי שהרצף כולו יושלם.
    אם הפעולה נכשלת, אפשר ללחוץ על + סשן חדש בפינה השמאלית העליונה ולנסות שוב.
  10. אחרי שהסוכן מאשר שהקובץ נכתב, מאתרים ופותחים את הקובץ החדש .txt בספרייה movie_pitches ב-Cloud Shell Editor כדי לראות את הפלט.
  11. בממשק המשתמש של ADK Dev, לוחצים על סמל הסוכן האחרון בהיסטוריית הצ'אט כדי לפתוח את תצוגת האירועים.
  12. בתצוגת האירועים מוצג גרף ויזואלי של עץ הסוכנים. אפשר לראות איך greeter התקשר אל film_concept_team, ואז התקשר לכל אחד מסוכני המשנה שלו לפי הסדר.תרשים אינטרנט של ADK
  13. אפשר ללחוץ על הכרטיסיות בקשה ותגובה של כל סוכן בתרשים כדי לבדוק את הנתונים המדויקים שהועברו, כולל מצב הסשן.

סיכום הקטע

בקטע הזה למדתם איך להשתמש בסוכן של תהליך עבודה:

  • סוכן SequentialAgent מפעיל את סוכני המשנה שלו אחד אחרי השני, לפי הסדר, בלי לחכות לקלט של משתמשים בין השלבים.
  • זהו 'תהליך עבודה' כי המשתמש מדבר עם root_agent, שמעביר את העבודה ל-SequentialAgent כדי להשלים אותה.
  • סוכני משנה ברצף משתמשים במצב הסשן (למשל, { PLOT_OUTLINE? }) כדי לגשת לעבודה של סוכנים קודמים.
  • אפשר להשתמש בתרשים האירועים בממשק המשתמש למפתחים כדי להמחיש ולנפות באגים בכל תהליך העבודה של סוכן לסוכן.

11. הוספת סוכן Loop לעבודה איטרטיבית

‫LoopAgent הוא סוכן של תהליך עבודה שמריץ את הסוכנים המשניים שלו ברצף ואז חוזר על הפעולה, החל מההתחלה. הלולאה הזו נמשכת עד שמתקיים תנאי מסוים, כמו הגעה לספירה של max_iterations או סוכן משנה שמתקשר לכלי המובנה exit_loop.

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

Film_concept_team multi-agent system step 2

כדי לבצע את השינויים האלה:

  1. ב-adk_multiagent_systems/workflow_agents/agent.py, מוסיפים את הייבוא של exit_loop (ליד הייבוא האחר של google.adk):
    from google.adk.tools import exit_loop
    
  2. מוסיפים את הסוכן החדש critic. הסוכן הזה יבדוק את העלילה. אם הוא טוב, הוא קורא ל-exit_loop. אם לא, הוא מוסיף משוב למצב של הלולאה הבאה.
    מדביקים את הגדרת הסוכן הבאה בקטע # Agents:
    critic = Agent(
        name="critic",
        model=model_name,
        description="Reviews the outline so that it can be improved.",
        instruction="""
        INSTRUCTIONS:
        Consider these questions about the PLOT_OUTLINE:
        - Does it meet a satisfying three-act cinematic structure?
        - Do the characters' struggles seem engaging?
        - Does it feel grounded in a real time period in history?
        - Does it sufficiently incorporate historical details from the RESEARCH?
    
        If the PLOT_OUTLINE does a good job with these questions, exit the writing loop with your 'exit_loop' tool.
        If significant improvements can be made, use the 'append_to_state' tool to add your feedback to the field 'CRITICAL_FEEDBACK'.
        Explain your decision and briefly summarize the feedback you have provided.
    
        PLOT_OUTLINE:
        { PLOT_OUTLINE? }
    
        RESEARCH:
        { research? }
        """,
        before_model_callback=log_query_to_model,
        after_model_callback=log_model_response,
        tools=[append_to_state, exit_loop]
    )
    
  3. יוצרים את writers_room LoopAgent. הוא יכיל את שלושת הסוכנים שיעבדו בלולאה.
    מדביקים את הקוד הבא מעל הגדרת הסוכן film_concept_team:
    writers_room = LoopAgent(
        name="writers_room",
        description="Iterates through research and writing to improve a movie plot outline.",
        sub_agents=[
            researcher,
            screenwriter,
            critic
        ],
        max_iterations=5,
    )
    
  4. מעדכנים את film_concept_team SequentialAgent כדי להשתמש בלולאה החדשה writers_room. מחליפים את researcher ואת screenwriter בסוכן היחיד writers_room.מחליפים את ההגדרה הקיימת של film_concept_team בהגדרה הבאה:
    film_concept_team = SequentialAgent(
        name="film_concept_team",
        description="Write a film plot outline and save it as a text file.",
        sub_agents=[
            writers_room,
            file_writer
        ],
    )
    
  5. חוזרים לכרטיסייה ADK Dev UI (ממשק משתמש לפיתוח ADK) ולוחצים על + New Session (הפעלה חדשה) בפינה השמאלית העליונה.
  6. מתחילים שיחה חדשה עם: hello
  7. כשמוצגת בקשה, נותנים לסוכן נושא רחב יותר. הנה כמה רעיונות:
    • מעצב תעשייתי שיצר מוצרים לקהל הרחב
    • קרטוגרף (יוצר מפות)
    • הבחור הזה שגרם ליבולים להניב יותר מזון
    הסוכן יפעל עכשיו בלולאה. בממשק המשתמש של ADK Dev, היומנים יופיעו כשהסוכנים יפעלו מספר פעמים (לדוגמה, [חוקר], [תסריטאי], [מבקר], [חוקר], [תסריטאי], [מבקר]...).
  8. כשהלולאה מסתיימת, הסוכן כותב את הקובץ. בודקים את הקובץ שנוצר בספרייה adk_multiagent_systems/movie_pitches.
  9. כדי לראות את מבנה הלולאה, בודקים את גרף האירועים בממשק המשתמש למפתחים.

סיכום הקטע

בקטע הזה למדתם איך להשתמש ב-LoopAgent:

  • LoopAgent הוא סוכן לתהליכי עבודה שחוזר על רצף סוכני המשנה שלו, ויוצר 'לולאה פנימית' למשימות איטרטיביות.
  • סוכנים בתוך הלולאה משתמשים במצב הסשן כדי להעביר עבודה (לדוגמה, PLOT_OUTLINE) ומשוב (לדוגמה, CRITICAL_FEEDBACK) אחד לשני במעברים הבאים.
  • אפשר לעצור את הלולאה אם מגיעים למגבלת max_iterations או אם נציג מתקשר לכלי exit_loop.

12. שימוש ב-ParallelAgent לביצוע פעולות מקבילות ואיסוף התוצאות

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

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

Film_concept_team multi-agent system step 3

סוכן ה-Flow הסופי ייראה כך:

  1. ‫greeter (הבסיס) מתחיל את הצ'אט.
  2. הוא מועבר אל film_concept_team (SequentialAgent), שפועל:
    • ‫writers_room (LoopAgent) כדי ליצור את העלילה.
    • התכונה החדשה preproduction_team (ParallelAgent) מאפשרת לחקור את נתוני הקופות ואת צוות השחקנים בו-זמנית.
    • ‫file_writer כדי לאסוף את כל התוצאות ולשמור את הקובץ.

כדי לבצע את השינויים האלה:

  1. ב-adk_multiagent_systems/workflow_agents/agent.py, מדביקים את ParallelAgent החדש ואת סוכני המשנה שלו מתחת לכותרת # Agents.
    box_office_researcher = Agent(
        name="box_office_researcher",
        model=model_name,
        description="Considers the box office potential of this film",
        instruction="""
        PLOT_OUTLINE:
        { PLOT_OUTLINE? }
    
        INSTRUCTIONS:
        Write a report on the box office potential of a movie like that described in PLOT_OUTLINE based on the reported box office performance of other recent films.
        """,
        output_key="box_office_report"
    )
    
    casting_agent = Agent(
        name="casting_agent",
        model=model_name,
        description="Generates casting ideas for this film",
        instruction="""
        PLOT_OUTLINE:
        { PLOT_OUTLINE? }
    
        INSTRUCTIONS:
        Generate ideas for casting for the characters described in PLOT_OUTLINE
        by suggesting actors who have received positive feedback from critics and/or
        fans when they have played similar roles.
        """,
        output_key="casting_report"
    )
    
    preproduction_team = ParallelAgent(
        name="preproduction_team",
        sub_agents=[
            box_office_researcher,
            casting_agent
        ]
    )
    
  2. מעדכנים את רשימת film_concept_team של SequentialAgentsub_agents כדי לכלול את preproduction_team החדש (בין writers_room לבין file_writer).מחליפים את ההגדרה הקיימת של film_concept_team בהגדרה הבאה:
    film_concept_team = SequentialAgent(
        name="film_concept_team",
        description="Write a film plot outline and save it as a text file.",
        sub_agents=[
            writers_room,
            preproduction_team,
            file_writer
        ],
    )
    
  3. מעדכנים את file_writer instruction של הסוכן כדי שהוא "יאסוף" את הדוחות החדשים מהמדינה ויוסיף אותם לקובץ.
    מחליפים את המחרוזת instruction של file_writer במחרוזת הבאה:
        instruction="""
        INSTRUCTIONS:
        - Create a marketable, contemporary movie title suggestion for the movie described in the PLOT_OUTLINE.
        If a title has been suggested in PLOT_OUTLINE, you can use it, or replace it with a better one.
        - Use your 'write_file' tool to create a new txt file with the following arguments:
        - for a filename, use the movie title
        - Write to the 'movie_pitches' directory.
        - For the 'content' to write, include:
        - The PLOT_OUTLINE
        - The BOX_OFFICE_REPORT
        - The CASTING_REPORT
    
        PLOT_OUTLINE:
        { PLOT_OUTLINE? }
    
        BOX_OFFICE_REPORT:
        { box_office_report? }
    
        CASTING_REPORT:
        { casting_report? }
        """,
    
  4. חוזרים לכרטיסייה של ממשק המשתמש למפתחים של ADK ולוחצים על + סשן חדש.
  5. מקישים על hello כדי להתחיל את השיחה.
  6. כשמופיעה בקשה, מזינים רעיון לדמות חדשה. הנה כמה רעיונות:
    • השחקנית שהמציאה את הטכנולוגיה של Wi-Fi
    • שף מרגש
    • שחקנים מרכזיים בתערוכות של היריד העולמי
  7. כשהסוכן מסיים את העבודה, בודקים את הקובץ הסופי בספרייה adk_multiagent_systems/movie_pitches. המסמך צריך לכלול עכשיו את תקציר העלילה, את דוח ההכנסות ממכירת כרטיסים ואת דוח צוות השחקנים – הכול במסמך אחד.

סיכום הקטע

בקטע הזה למדתם איך להשתמש ב-ParallelAgent:

  • עבודת ParallelAgent מתבצעת בשיטת 'פיצול', כלומר כל הסוכנים המשניים פועלים בו-זמנית ולא ברצף.
  • השיטה הזו יעילה מאוד למשימות שלא תלויות זו בזו (כמו מחקר על שני נושאים שונים).
  • התוצאות של סוכנים מקבילים 'נאספות' על ידי סוכן מאוחר יותר. כדי לעשות את זה, הסוכנים המקבילים שומרים את העבודה שלהם במצב הסשן (באמצעות output_key), וסוכן סופי (כמו file_writer) קורא את המפתחות האלה.

13. סוכני תהליכי עבודה בהתאמה אישית

אם סוכני העבודה המוגדרים מראש של SequentialAgent,‏ LoopAgent ו-ParallelAgent לא מספיקים לצרכים שלכם, CustomAgent מאפשרת לכם להטמיע לוגיקה חדשה של תהליך עבודה.

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

יצירת CustomAgent לא נכללת בשיעור ה-Lab הזה, אבל כדאי לדעת שהיא אפשרית אם תצטרכו אותה.

14. מעולה!

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

Recap

בשיעור ה-Lab הזה:

  • סוכנים מאורגנים בעץ היררכי עם קשרים של סוכן הורה וסוכני משנה.
  • העברות מבוקרות מסוכן לסוכן, באופן אוטומטי (באמצעות description) ובאופן מפורש (באמצעות instruction).
  • השתמשתם בכלי כדי לכתוב נתונים למילון tool_context.state.
  • השתמשו בתבניות של מפתחות (למשל, { PLOT_OUTLINE? }) כדי לקרוא ממצב הסשן ולהנחות את ההנחיה של הנציג.
  • הטמענו SequentialAgent כדי ליצור תהליך עבודה פשוט ומפורט (מחקר -> כתיבה -> שמירה).
  • השתמשתם ב-LoopAgent עם סוכן critic והכלי exit_loop כדי ליצור מחזור של שיפורים חוזרים.
  • השתמשו ב-ParallelAgent כדי להפעיל משימות עצמאיות (כמו ליהוק ומחקר על הכנסות ממכירת כרטיסים) במקביל.

המשך הניסויים

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

  • הוספת עוד סוכנים: נסו להוסיף סוכן חדש ל-preproduction_team ParallelAgent. לדוגמה, אפשר ליצור marketing_agent שכותב סלוגן לסרט על סמך PLOT_OUTLINE.
  • הוספת עוד כלים: נותנים לסוכן researcher עוד כלים. אפשר ליצור כלי שמשתמש ב-Google Search API כדי למצוא מידע שלא מופיע בוויקיפדיה.
  • כלי הניתוחים CustomAgent: ב-Lab מוזכר CustomAgent לתהליכי עבודה שלא מתאימים לתבניות הרגילות. אפשר לנסות ליצור סוכן שפועל באופן מותנה רק אם קיים מפתח ספציפי במצב הסשן.