Agentverse - The Summoner's Concord - Architecting Multi-Agent Systems

1. של גורל

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

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

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

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

ברוכים הבאים ל-Agentverse: קריאה לאלופים

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

agentverse.png

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

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

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

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

בחירת כיתה

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

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

המשימה שלך

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

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

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

הגיבורים של Agentverse מחכים לכם. תענה לשיחה?

2. The Summoner's Concord

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

סקירה כללית

מה תלמדו

  • תכנון של מערכת אקולוגית של כלים מנותקים: עיצוב ופריסה של קבוצת שרתי כלים עצמאיים של MCP שמבוססים על מיקרו-שירותים. תלמדו למה שכבת הבסיס הזו חיונית ליצירת מערכות סוכנים ניתנות להרחבה, ניתנות לתחזוקה ומאובטחות.
  • שליטה בתהליכי עבודה מתקדמים של סוכנים: אפשר להשתמש ביותר מסוכן אחד וליצור קבוצה של סוכנים מומחים. תלמדו את דפוסי זרימת העבודה העיקריים של ADK – רציף, מקביל ולולאה – ותכירו את עקרונות הארכיטקטורה לבחירת הדפוס המתאים למשימה המתאימה.
  • הטמעת כלי תזמור חכם: מעבר מבונה סוכנים פשוט לאדריכל מערכות אמיתי. תבנו סוכן תזמור ראשי שמשתמש בפרוטוקול Agent-to-Agent (A2A) כדי לגלות משימות מורכבות ולהעביר אותן לסוכנים המומחים שלכם, וכך ליצור מערכת רב-סוכנים אמיתית.
  • אכיפת כללים באמצעות קוד, ולא הנחיות: איך ליצור סוכנים אמינים וצפויים יותר באמצעות אכיפה של כללי אינטראקציה מבוססי-מצב. תטמיעו לוגיקה מותאמת אישית באמצעות מערכת הפלאגין והקריאה החוזרת (Callback) המתקדמת של ADK, כדי לנהל מגבלות מהעולם האמיתי כמו טיימרים של תקופת צינון.
  • ניהול מצב וזיכרון של סוכנים: מאפשרים לסוכנים ללמוד ולזכור. תלמדו טכניקות לניהול מצב שיחה לטווח קצר וזיכרון מתמשך לטווח ארוך, כדי ליצור אינטראקציות חכמות יותר שמודעות להקשר.
  • הפעלת פריסה מקצה לקצה בענן: מעבירים את כל מערכת מרובת הסוכנים מאב טיפוס מקומי למציאות ברמת ייצור. תלמדו איך להכניס את הסוכנים ואת כלי התזמור לקונטיינרים ולפרוס אותם כקבוצה של מיקרו-שירותים (microservices) עצמאיים וניתנים להרחבה ב-Google Cloud Run.

‫3. ציור מעגל הזימון

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

‫👈 לוחצים על 'הפעלת Cloud Shell' בחלק העליון של מסוף Google Cloud (זהו סמל בצורת טרמינל בחלק העליון של חלונית Cloud Shell).

טקסט חלופי

‫👈 לוחצים על הלחצן 'פתיחת הכלי לעריכה' (הוא נראה כמו תיקייה פתוחה עם עיפרון). חלון Cloud Shell Code Editor ייפתח. בצד ימין יופיע סייר הקבצים. טקסט חלופי

‫👈כך מוצאים את מזהה הפרויקט ב-Google Cloud:

  • פותחים את Google Cloud Console: https://console.cloud.google.com
  • בוחרים את הפרויקט שבו רוצים להשתמש בסדנה הזו מהתפריט הנפתח של הפרויקט בחלק העליון של הדף.
  • מזהה הפרויקט מוצג בכרטיס Project info בלוח הבקרה טקסט חלופי

‫👈פותחים את הטרמינל בסביבת הפיתוח המשולבת (IDE) בענן, טקסט חלופי

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

gcloud auth list

‫👈💻 משכפלים את פרויקט ה-bootstrap מ-GitHub:

git clone https://github.com/weimeilin79/agentverse-architect
chmod +x ~/agentverse-architect/init.sh
chmod +x ~/agentverse-architect/set_env.sh
chmod +x ~/agentverse-architect/prepare.sh
chmod +x ~/agentverse-architect/data_setup.sh

git clone https://github.com/weimeilin79/agentverse-dungeon.git
chmod +x ~/agentverse-dungeon/run_cloudbuild.sh
chmod +x ~/agentverse-dungeon/start.sh

‫👈💻 מריצים את סקריפט ההפעלה. הסקריפט יבקש מכם להזין את מזהה הפרויקט ב-Google Cloud. כשמוצגת הנחיה בסקריפט init.sh, מזינים את מזהה הפרויקט ב-Google Cloud שמצאתם בשלב הקודם.

cd ~/agentverse-architect
./init.sh

‫👈💻 מגדירים את מזהה הפרויקט הנדרש:

gcloud config set project $(cat ~/project_id.txt) --quiet

‫👈💻 מריצים את הפקודה הבאה כדי להפעיל את ממשקי ה-API הנדרשים של Google Cloud:

gcloud services enable \
    sqladmin.googleapis.com \
    storage.googleapis.com \
    aiplatform.googleapis.com \
    run.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    iam.googleapis.com \
    compute.googleapis.com \
    cloudresourcemanager.googleapis.com \
    secretmanager.googleapis.com

‫👈💻 אם עדיין לא יצרתם מאגר Artifact Registry בשם agentverse-repo, מריצים את הפקודה הבאה כדי ליצור אותו: (מדלגים על השלב הזה אם יש לכם עוד סיווגים שפרוסים באותו פרויקט)

. ~/agentverse-architect/set_env.sh
gcloud artifacts repositories create $REPO_NAME \
    --repository-format=docker \
    --location=$REGION \
    --description="Repository for Agentverse agents"

הגדרת הרשאות

‫👉💻 מעניקים את ההרשאות הנדרשות על ידי הרצת הפקודות הבאות בטרמינל:

. ~/agentverse-architect/set_env.sh

# --- Grant Core Data Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID \
 --member="serviceAccount:$SERVICE_ACCOUNT_NAME" \
 --role="roles/storage.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/aiplatform.user"

# --- Grant Deployment & Execution Permissions ---
gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/cloudbuild.builds.editor"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/artifactregistry.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/run.admin"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/iam.serviceAccountUser"

gcloud projects add-iam-policy-binding $PROJECT_ID  \
--member="serviceAccount:$SERVICE_ACCOUNT_NAME"  \
--role="roles/logging.logWriter"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
  --role="roles/monitoring.metricWriter"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:${SERVICE_ACCOUNT_NAME}" \
  --role="roles/secretmanager.secretAccessor"

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

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-dungeon
./run_cloudbuild.sh
cd ~/agentverse-architect

‫👈💻 לבסוף, מריצים את הסקריפט prepare.sh כדי לבצע את משימות ההגדרה הראשוניות.

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/
./prepare.sh

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

4. יצירת גופנים אלמנטריים: סביבת הכלים המופרדת

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

סטורי

הערה לארכיטקטים: שרת Model Context Protocol (MCP) הוא רכיב בסיסי במערכת מודרנית שמבוססת על סוכנים. הוא משמש כגשר תקשורת סטנדרטי שמאפשר לסוכן לגלות כלים מרוחקים ולהשתמש בהם. בסביבת כלי הפיתוח שלנו, נתכנן שני סוגים שונים של שרתי MCP, שכל אחד מהם מייצג דפוס ארכיטקטוני קריטי. כדי להתחבר למסד הנתונים שלנו, נשתמש בגישה הצהרתית עם Database Toolbox, ונגדיר את הכלים שלנו בקובץ תצורה פשוט. הדפוס הזה יעיל ומאובטח מאוד לחשיפת גישה לנתונים מובנים. עם זאת, כשצריך להטמיע לוגיקה עסקית מותאמת אישית או לקרוא ל-API חיצוני של צד שלישי, אנחנו משתמשים בגישה אימפרטיבית, וכותבים את הלוגיקה של השרת שלב אחר שלב בקוד. כך אנחנו מקבלים שליטה וגמישות מקסימליות, ויכולים להסתיר פעולות מורכבות מאחורי כלי פשוט ורב-פעמי. אדריכל ראשי צריך להבין את שתי התבניות כדי לבחור את הגישה הנכונה לכל רכיב, וכך ליצור בסיס חזק, מאובטח וניתן להרחבה של כלי פיתוח.

סקירה כללית

Awakening the Nexus of Whispers (External API MCP Server)

מזמן חכם יודע שלא כל הכוח מגיע מהדומיין שלו. יש מקורות אנרגיה חיצוניים, שלפעמים הם כאוטיים, שאפשר לתעל אותם כדי להשיג תוצאות מצוינות. ה-Nexus of Whispers הוא השער שלנו לכוחות האלה.

סטורי

יש שירות שכבר פעיל ומשמש כמקור הכוח החיצוני שלנו, ומציע שתי נקודות קצה של לחשים גולמיים: /cryosea_shatter ו-/moonlit_cascade.

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

‫👈✏️ עוברים לספרייה ~/agentverse-architect/mcp-servers/api/main.py ומחליפים #REPLACE-MAGIC-CORE בקוד הבא:

def cryosea_shatter() -> str:
    """Channels immense frost energy from an external power source, the Nexus of Whispers, to unleash the Cryosea Shatter spell."""
    try:
        response = requests.post(f"{API_SERVER_URL}/cryosea_shatter")
        response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
        data = response.json()
        # Thematic Success Message
        return f"A connection to the Nexus is established! A surge of frost energy manifests as Cryosea Shatter, dealing {data.get('damage_points')} damage."
    except requests.exceptions.RequestException as e:
        # Thematic Error Message
        return f"The connection to the external power source wavers and fails. The Cryosea Shatter spell fizzles. Reason: {e}"


def moonlit_cascade() -> str:
    """Draws mystical power from an external energy source, the Nexus of Whispers, to invoke the Moonlit Cascade spell."""
    try:
        response = requests.post(f"{API_SERVER_URL}/moonlit_cascade")
        response.raise_for_status()
        data = response.json()
        # Thematic Success Message
        return f"The Nexus answers the call! A cascade of pure moonlight erupts from the external source, dealing {data.get('damage_points')} damage."
    except requests.exceptions.RequestException as e:
        # Thematic Error Message
        return f"The connection to the external power source wavers and fails. The Moonlit Cascade spell fizzles. Reason: {e}"

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

‫👉✏️ באותו קובץ ~/agentverse-architect/mcp-servers/api/main.py REPLACE #REPLACE-Runes of Communication עם הקוד הבא:

@app.list_tools()
async def list_tools() -> list[mcp_types.Tool]:
  """MCP handler to list available tools."""
  # Convert the ADK tool's definition to MCP format
  schema_cryosea_shatter = adk_to_mcp_tool_type(cryosea_shatterTool)
  schema_moonlit_cascade = adk_to_mcp_tool_type(moonlit_cascadeTool)
  print(f"MCP Server: Received list_tools request. \n MCP Server: Advertising tool: {schema_cryosea_shatter.name} and {schema_moonlit_cascade.name}")
  return [schema_cryosea_shatter,schema_moonlit_cascade]

@app.call_tool()
async def call_tool(
    name: str, arguments: dict
) -> list[mcp_types.TextContent | mcp_types.ImageContent | mcp_types.EmbeddedResource]:
  """MCP handler to execute a tool call."""
  print(f"MCP Server: Received call_tool request for '{name}' with args: {arguments}")

  # Look up the tool by name in our dictionary
  tool_to_call = available_tools.get(name)
  if tool_to_call:
    try:
      adk_response = await tool_to_call.run_async(
          args=arguments,
          tool_context=None, # No ADK context available here
      )
      print(f"MCP Server: ADK tool '{name}' executed successfully.")
      
      response_text = json.dumps(adk_response, indent=2)
      return [mcp_types.TextContent(type="text", text=response_text)]

    except Exception as e:
      print(f"MCP Server: Error executing ADK tool '{name}': {e}")
      # Creating a proper MCP error response might be more robust
      error_text = json.dumps({"error": f"Failed to execute tool '{name}': {str(e)}"})
      return [mcp_types.TextContent(type="text", text=error_text)]
  else:
      # Handle calls to unknown tools
      print(f"MCP Server: Tool '{name}' not found.")
      error_text = json.dumps({"error": f"Tool '{name}' not implemented."})
      return [mcp_types.TextContent(type="text", text=error_text)]
  • @app.list_tools() (הלחיצת יד): הפונקציה הזו היא הפנייה של השרת. כשסוכן חדש מתחבר, הוא קודם מתקשר לנקודת הקצה הזו ושואל: "מה אתה יכול לעשות?". הקוד שלנו מגיב עם רשימה של כל הכלים הזמינים, שהומרו לפורמט MCP אוניברסלי באמצעות adk_to_mcp_tool_type. ‫– @app.call_tool() (הפקודה): הפונקציה הזו היא הכוח המניע. כשהסוכן מחליט להשתמש בכלי, הוא שולח בקשה לנקודת הקצה הזו עם שם הכלי והארגומנטים. הקוד שלנו מחפש את הכלי ב-available_tools, שהוא מעין 'ספר לחשים', מפעיל אותו באמצעות run_async ומחזיר את התוצאה בפורמט MCP רגיל.

נפרוס את זה מאוחר יותר.

הפעלת Arcane Forge (שרת MCP של פונקציות כלליות)

לא כל הכוח מגיע מספרים עתיקים או מלחישות רחוקות. לפעמים, המזמן צריך ליצור קסם משלו מתוך רצון עז והיגיון טהור. ה-Arcane Forge הוא מקור הכוח הזה – שרת שמספק פונקציות כלליות ללא מצב (stateless).

סטורי

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

‫👀 מעיינים בקובץ ~/agentverse-architect/mcp-servers/general/main.py בסביבת הפיתוח המשולבת (IDE) של Google Cloud. תראו שהיא משתמשת באותה גישה של mcp.server כמו ב-Nexus כדי ליצור את הגופן המותאם אישית הזה של העוצמה.

יצירת צינור עיבוד נתונים ראשי של Cloud Build

עכשיו ניצור את הקובץ cloudbuild.yaml בתוך הספרייה mcp-servers. הקובץ הזה יתזמן את הבנייה והפריסה של שני השירותים.

‫👉💻 בספרייה ~/agentverse-architect/mcp-servers, מריצים את הפקודות הבאות:

cd ~/agentverse-architect/mcp-servers
source ~/agentverse-architect/set_env.sh

echo "The API URL is: $API_SERVER_URL"

# Submit the Cloud Build job from the parent directory
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_API_SERVER_URL="$API_SERVER_URL"

ממתינים עד שכל הפריסות יסתיימו.

‫👈 אפשר לאמת את הפריסה על ידי ניווט אל מסוף Cloud Run. אמורות להופיע שתי מכונות חדשות של שרת MCP שפועלות, כמו בדוגמה הבאה: טקסט חלופי

הפעלת Librarium of Knowledge (שרת Database ToolBox MCP)

הגופן הבא שלנו יהיה Librarium of Knowledge, חיבור ישיר למסד הנתונים של Cloud SQL.

סטורי

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

הגיע הזמן לבנות את מסד הנתונים Cloud SQL שנקרא Summoner's Librarium, שיכיל את כל המידע הקריטי שלנו. נשתמש בסקריפט הגדרה כדי לטפל בזה באופן אוטומטי.

‫👈💻 קודם כל, נגדיר את מסד הנתונים. בטרמינל, מריצים את הפקודות הבאות:

source ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect
./data_setup.sh

אחרי שהסקריפט יסיים לפעול, מסד הנתונים יאוכלס ונתוני הנזק האלמנטרי יהיו מוכנים לשימוש. עכשיו אפשר לאמת את התוכן של ה-Grimoire ישירות.

‫👈 קודם כל, עוברים אל Cloud SQL Studio של מסד הנתונים על ידי פתיחת הקישור הישיר הזה בכרטיסייה חדשה בדפדפן:

https://console.cloud.google.com/sql/instances/summoner-librarium-db

Cloud SQL

‫👈 בחלונית הכניסה בצד ימין, בוחרים את מסד הנתונים familiar_grimoire מהתפריט הנפתח.

‫👈 מזינים summoner בתור המשתמש ו-1234qwer בתור הסיסמה, ואז לוחצים על אימות.

‫👉📜 אחרי ההתחברות, פותחים כרטיסייה חדשה בעורך השאילתות, אם היא לא פתוחה כבר. כדי להציג את נתוני הנזק היסודי שמוטבעים, מדביקים ומריצים את שאילתת ה-SQL הבאה:

SELECT * FROM
  "public"."abilities"

עכשיו אמורה להופיע הטבלה abilities עם העמודות והשורות שלה, שמאשרת שה-Grimoire מוכן. נתונים

הגדרת שרת MCP של ארגז הכלים

קובץ ההגדרות tools.yaml משמש כתוכנית השרת שלנו, ומציין ל-Database Toolbox בדיוק איך להתחבר למסד הנתונים שלנו ואילו שאילתות SQL להציג ככלים.

sources: בקטע הזה מוגדרים החיבורים לנתונים שלכם.

  • summoner-librarium:: זהו שם לוגי שנתנו לחיבור שלנו.
  • ‫kind: cloud-sql-postgres: הערך הזה מציין ל-Toolbox להשתמש במחבר המובנה והמאובטח שלו, שתוכנן במיוחד ל-Cloud SQL ל-PostgreSQL.
  • פרויקט, אזור, מכונה וכו': אלה הקואורדינטות המדויקות של מכונת Cloud SQL שיצרתם במהלך הסקריפט prepare.sh, והן מציינות ל-Toolbox איפה נמצא Librarium.

‫👉✏️ עוברים אל ~/agentverse-architect/mcp-servers/db-toolbox ב-tools.yaml, מחליפים את #REPLACE-Source בטקסט הבא

sources:
  # This section defines the connection to our Cloud SQL for PostgreSQL database.
  summoner-librarium:
    kind: cloud-sql-postgres
    project: "YOUR_PROJECT_ID"
    region: "us-central1"
    instance: "summoner-librarium-db"
    database: "familiar_grimoire"
    user: "summoner"
    password: "1234qwer"

‫👉✏️ 🚨🚨REPLACE

YOUR_PROJECT_ID

במזהה הפרויקט.

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

  • lookup-available-ability:: זה השם של הכלי הראשון שלנו.
  • ‫kind: postgres-sql: הערך הזה מציין ל-Toolbox שהפעולה של הכלי הזה היא הפעלה של הצהרת SQL.
  • מקור: summoner-librarium: הקישור הזה מחבר את הכלי לחיבור שהגדרנו בבלוק המקורות. כך הכלי יודע באיזה מסד נתונים להריץ את השאילתה.
  • תיאור ופרמטרים: אלה הפרטים שיוצגו למודל השפה. התיאור מציין לסוכן מתי להשתמש בכלי, והפרמטרים מגדירים את הקלט שהכלי דורש. השלב הזה חשוב מאוד כדי להפעיל את היכולת של הסוכן לקרוא לפונקציות.
  • statement: זו שאילתת ה-SQL הגולמית שרוצים להריץ. הערך $1 הוא placeholder מאובטח שבו יוצב בבטחה הפרמטר familiar_name שסופק על ידי הסוכן.

‫👉✏️ באותו קובץ ~/agentverse-architect/mcp-servers/db-toolbox בקובץ tools.yaml, מחליפים את #REPLACE-tools בטקסט הבא

tools:
  # This tool replaces the need for a custom Python function.
  lookup-available-ability:
    kind: postgres-sql
    source: summoner-librarium
    description: "Looks up all known abilities and their damage for a given familiar from the Grimoire."
    parameters:
      - name: familiar_name
        type: string
        description: "The name of the familiar to search for (e.g., 'Fire Elemental')."
    statement: |
      SELECT ability_name, damage_points FROM abilities WHERE familiar_name = $1;

  # This tool also replaces a custom Python function.
  ability-damage:
    kind: postgres-sql
    source: summoner-librarium
    description: "Finds the base damage points for a specific ability by its name."
    parameters:
      - name: ability_name
        type: string
        description: "The exact name of the ability to look up (e.g., 'inferno_resonance')."
    statement: |
      SELECT damage_points FROM abilities WHERE ability_name = $1;

ערכות כלים: בקטע הזה מקובצים הכלים הנפרדים שלנו.

  • ‫summoner-librarium:: אנחנו יוצרים ערכת כלים עם אותו שם כמו המקור שלנו. כשסוכן האבחון שלנו מתחבר מאוחר יותר, הוא יכול לבקש לטעון את כל הכלים מחבילת הכלים של ספריית המזמנים בפקודה אחת ויעילה.

‫👉✏️ באותו קובץ ~/agentverse-architect/mcp-servers/db-toolbox בקובץ tools.yaml, מחליפים את #REPLACE-toolsets בטקסט הבא

toolsets:
   summoner-librarium:
     - lookup-available-ability
     - ability-damage

פריסת Librarium

עכשיו נבצע פריסה של Librarium. במקום ליצור קונטיינר משלנו, נשתמש בקובץ אימג' רשמי של קונטיינר שנוצר מראש על ידי Google, ונספק לו את ההגדרות של הקובץ tools.yaml בצורה מאובטחת באמצעות Secret Manager. זו שיטה מומלצת לאבטחה ולתחזוקה.

‫👉💻 יצירת סוד מקובץ tools.yaml

cd ~/agentverse-architect/mcp-servers/db-toolbox
gcloud secrets create tools --data-file=tools.yaml

‫👈💻 פריסת קונטיינר ארגז הכלים הרשמי ב-Cloud Run.

cd ~/agentverse-architect/mcp-servers/db-toolbox
. ~/agentverse-architect/set_env.sh
export TOOLBOX_IMAGE=us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:$TOOLBOX_VERSION
echo "TOOLBOX_IMAGE is $TOOLBOX_IMAGE"
gcloud run deploy toolbox \
    --image $TOOLBOX_IMAGE \
    --region $REGION \
    --set-secrets "/app/tools.yaml=tools:latest" \
    --args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
    --allow-unauthenticated \
    --min-instances 1
  • --set-secrets: הפקודה הזו מבצעת הרכבה מאובטחת של הסוד של כלי ה-CLI כקובץ בשם tools.yaml בתוך הקונטיינר הפועל.
  • --args: אנחנו מנחים את קונטיינר ארגז הכלים להשתמש בקובץ הסודי שהועלה כהגדרה שלו.

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

אם שכחתם לעדכן

YOUR_PROJECT_ID

אפשר להוסיף גרסה חדשה של tools.yaml לסוד באמצעות הפקודה הבאה ולפרוס מחדש.

gcloud secrets versions add tools --data-file=tools.yaml

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

אימות: תקופת הניסיון של Apprentice

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

cd ~/agentverse-architect/
python -m venv env
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/mcp-servers
pip install -r diagnose/requirements.txt 
. ~/agentverse-architect/set_env.sh
adk run diagnose

‫👈💻 בכלי לבדיקה בשורת הפקודה, בודקים את שלושת הגופנים:

Look up the entry for "inferno_lash". What is its base power level?
The enemy is vulnerable to frost! Channel power from the Nexus and cast Cryosea Shatter.
Take a fire spell with a base power of 15 and use the Arcane Forge to multiply it with Inferno Resonance.

final-result

כל הכבוד, Summoner. שלושת הגופנים של Elemental פעילים עכשיו, פרוסים באופן עצמאי ונגישים בכל העולם, ויוצרים את הבסיס האיתן ללגיון הסוכנים שלכם. לוחצים על Ctrl+C כדי לצאת.

למי שלא משחק

5. זימון היצורים המיתיים: תהליך העבודה של דומיין הליבה

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

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

סטורי

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

סקירה כללית

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

הכינו את המקדש. הזימון האמיתי עומד להתחיל.

זימון של Fire Elemental מוכר (תהליך עבודה רציף)

המתקפה של Fire Elemental Familiar היא קומבו מדויק של שני חלקים: מכה ממוקדת ואחריה הצתה חזקה. לשם כך נדרש רצף פעולות קפדני ומסודר.

סטורי

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

משימה (הקומבו 'התראה מוגברת'):

  • שלב 1: הסוכן יבדוק קודם בספרייה כדי למצוא את נזק הבסיס של יכולת אש ספציפית.
  • שלב 2: לאחר מכן, המערכת תיקח את ערך הנזק הזה ותעביר אותו דרך Arcane Forge כדי להכפיל את העוצמה שלו באמצעות inferno_resonance.

קודם כול, ניצור את החיבור בין Familiar לבין שרתי ה-MCP (הגופנים של Elemental) שפרסתם במודול הקודם.

‫👈✏️ בקובץ ~/agentverse-architect/agent/fire/agent.py מחליפים את #REPLACE-setup-MCP בקוד הבא:

toolbox = ToolboxSyncClient(DB_TOOLS_URL)
toolDB = toolbox.load_toolset('summoner-librarium')
toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

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

‫👈✏️ בקובץ ~/agentverse-architect/agent/fire/agent.py מחליפים #REPLACE-worker-agents את הקוד הבא:

scout_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='librarian_agent',  
      instruction="""
          Your only task is to find all the available abilities, 
          You want to ALWAYS use 'Fire Elemental' as your familiar's name. 
          Randomly pick one if you see multiple availabilities 
          and the base damage of the ability by calling the 'ability_damage' tool.
      """,
      tools=toolDB
)
amplifier_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='amplifier_agent',  
      instruction="""
            You are the Voice of the Fire Familiar, a powerful being who unleashes the final, devastating attack.
            You will receive the base damage value from the previous step.

            Your mission is to:
            1.  Take the incoming base damage number and amplify it using the `inferno_resonance` tool.
            2.  Once the tool returns the final, multiplied damage, you must not simply state the result.
            3.  Instead, you MUST craft a final, epic battle cry describing the attack.
                Your description should be vivid and powerful, culminating in the final damage number.

            Example: If the tool returns a final damage of 120, your response could be:
            "The runes glow white-hot! I channel the amplified energy... unleashing a SUPERNOVA for 120 damage!"
      """,
      tools=[toolFunction],
)

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

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

‫👈✏️ בקובץ ~/agentverse-architect/agent/fire/agent.py מחליפים #REPLACE-sequential-agent את הקוד הבא:

root_agent = SequentialAgent(
      name='fire_elemental_familiar',
      sub_agents=[scout_agent, amplifier_agent],
)

‫👈💻 כדי לבדוק את Fire Elemental, מריצים את הפקודות הבאות כדי להפעיל את ממשק המשתמש של ADK DEV:

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

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

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

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

‫👈 כדי לגשת לממשק המשתמש של ADK Dev מהדפדפן:

בסרגל הכלים של Cloud Shell (בדרך כלל בפינה השמאלית העליונה), לוחצים על סמל התצוגה המקדימה בדפדפן (לרוב נראה כמו עין או ריבוע עם חץ) ובוחרים באפשרות 'שינוי יציאה'. בחלון הקופץ, מגדירים את היציאה ל-8000 ולוחצים על 'שינוי ותצוגה מקדימה'. לאחר מכן, ייפתחו ב-Cloud Shell כרטיסייה או חלון חדשים בדפדפן עם ממשק המשתמש של ADK Dev.

webpreview

‫👈 טקס הזימון הושלם, והסוכן פועל עכשיו. ממשק המשתמש של ADK Dev בדפדפן הוא החיבור הישיר שלכם ל-Familiar.

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

fire-select

‫👉 Test Prompt:

Prepare an amplified strike using the 'inferno_lash' ability.

fire-result

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

‫👈💻 אחרי שמסיימים את ההפעלה, חוזרים לטרמינל של Cloud Shell Editor ולוחצים על Ctrl+C כדי לעצור את ממשק המשתמש של ADK Dev.

זימון Water Elemental מוכר (תהליך עבודה מקבילי)

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

סטורי

מושג: ParallelAgent הוא כלי אידיאלי לביצוע כמה משימות בלתי תלויות בו-זמנית כדי למקסם את היעילות. זהו "מבצע מלקחיים" שבו מתבצעות כמה מתקפות בו-זמנית. ההשקה הזו תפעיל את המתקפות בו-זמנית בתוך SequentialAgent כדי להפעיל לאחר מכן שלב סופי של 'מיזוג'. התבנית 'fan-out, fan-in' היא אבן יסוד בעיצוב של תהליכי עבודה מתקדמים.

משימה (חבילת 'התנגשות הגאות'): הסוכן יבצע את הפעולות הבאות בו-זמנית:

  • משימה א': ערוץ cryosea_shatter מ-Nexus.
  • משימה ב': ערוץ moonlit_cascade ממכשיר Nexus.
  • משימה ג': יצירת כוח גולמי באמצעות leviathan_surge מ-Forge.
  • לבסוף, מסכמים את כל הנזקים ומתארים את המתקפה המשולבת.

קודם כול, ניצור את החיבור בין Familiar לבין שרתי ה-MCP (הגופנים של Elemental) שפרסתם במודול הקודם.

‫👈✏️ בקובץ ~/agentverse-architect/agent/water/agent.py מחליפים את #REPLACE-setup-MCP בקוד הבא:

toolFAPI =  MCPToolset(
      connection_params=SseServerParams(url=API_TOOLS_URL, headers={})
  )
toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

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

‫👈✏️ בקובץ ~/agentverse-architect/agent/water/agent.py מחליפים את #REPLACE-worker-agents בקוד הבא:

nexus_channeler = LlmAgent(
      model='gemini-2.5-flash', 
      name='librarian_agent',  
      instruction="""
          You are a Channeler of the Nexus. Your sole purpose is to invoke the
          `cryosea_shatter` and `moonlit_cascade` spells by calling their respective tools.
          Report the result of each spell cast clearly and concisely.
      """,
      tools=[toolFAPI]
)

forge_channeler = LlmAgent(
      model='gemini-2.5-flash', 
      name='amplifier_agent',  
      instruction="""
          You are a Channeler of the Arcane Forge. Your only task is to invoke the
          `leviathan_surge` spell. You MUST call it with a `base_water_damage` of 20.
          Report the result clearly.
      """,
      tools=[toolFunction],
)

power_merger = LlmAgent(
      model='gemini-2.5-flash', 
      name='power_merger',  
      instruction="""
          You are the Power Merger, a master elementalist who combines raw magical
          energies into a single, devastating final attack.

          You will receive a block of text containing the results from a simultaneous
          assault by other Familiars.

          You MUST follow these steps precisely:
          1.  **Analyze the Input:** Carefully read the entire text provided from the previous step.
          2.  **Extract All Damage:** Identify and extract every single damage number reported in the text.
          3.  **Calculate Total Damage:** Sum all of the extracted numbers to calculate the total combined damage.
          4.  **Describe the Final Attack:** Create a vivid, thematic description of a massive,
              combined water and ice attack that uses the power of Cryosea Shatter and Leviathan's Surge.
          5.  **Report the Result:** Conclude your response by clearly stating the final, total damage of your combined attack.

          Example: If the input is "...dealt 55 damage. ...dealt 60 damage.", you will find 55 and 60,
          calculate the total as 115, and then describe the epic final attack, ending with "for a total of 115 damage!"
      """,
      tools=[toolFunction],
)

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

‫👈✏️ בקובץ ~/agentverse-architect/agent/water/agent.py מחליפים את #REPLACE-parallel-agent בקוד הבא:

channel_agent = ParallelAgent(
      name='channel_agent',
      sub_agents=[nexus_channeler, forge_channeler],
      
)

root_agent = SequentialAgent(
     name="water_elemental_familiar",
     # Run parallel research first, then merge
     sub_agents=[channel_agent, power_merger],
     description="A powerful water familiar that unleashes multiple attacks at once and then combines their power for a final strike."
 )

‫👈💻 כדי לבדוק את Water Elemental, מריצים את הפקודות הבאות כדי להפעיל את ממשק המשתמש של ADK Dev:

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

‫👈 טקס הזימון הושלם, והסוכן פועל עכשיו. ממשק המשתמש של ADK Dev בדפדפן הוא החיבור הישיר שלכם ל-Familiar.

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

‫👉 Test Prompt:

Unleash a tidal wave of power!

water-result

‫👈💻 אחרי שמסיימים את ההפעלה, חוזרים לטרמינל של Cloud Shell Editor ולוחצים על Ctrl+C כדי לעצור את ממשק המשתמש של ADK Dev.

זימון של Earth Elemental Familiar (תהליך עבודה ב-Loop)

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

סטורי

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

משימה (המתקפה 'Siegebreaker'):

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

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

קודם כול, ניצור את החיבור בין Familiar לבין שרתי ה-MCP (הגופנים של Elemental) שפרסתם במודול הקודם.

‫👈✏️ בקובץ ~/agentverse-architect/agent/earth/agent.py מחליפים את #REPLACE-setup-MCP בקוד הבא:

toolFunction =  MCPToolset(
    connection_params=SseServerParams(url=FUNCTION_TOOLS_URL, headers={})
)

‫👈✏️ בקובץ ~/agentverse-architect/agent/earth/agent.py מחליפים את #REPLACE-worker-agents בקוד הבא:

charging_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='charging_agent',  
      instruction="""
          Your task is to call the 'seismic_charge' .
          You must follow these rules strictly:

          1. You will be provided with a 'current_energy' value from the previous step.
             **If this value is missing or was not provided, you MUST call the tool with 'current_energy' set to 1.**
             This is your primary rule for the first turn.

          2. If a 'current_energy' value is provided, you MUST use that exact value in your cal to seismic_charge.

          3. Your final response MUST contain ONLY the direct output from the 'seismic_charge' tool.
             Do not add any conversational text, introductions, or summaries.
      """,
      tools=[toolFunction]
)
check_agent = LlmAgent(
      model='gemini-2.5-flash', 
      name='check_agent',  
      instruction="""
          You are the voice of the Earth Elemental, a being of immense, gathering power.
          Your sole purpose is to report on the current energy charge and announce the devastating potential of its release.

          You MUST follow this rule:
          The potential damage upon release is ALWAYS calculated as the `current_energy` from the previous step multiplied by a random number between 80-90. but no more than 300.

          Your response should be in character, like a powerful creature speaking.
          State both the current energy charge and the total potential damage you can unleash.
          Unleash the energy when you reached the last iteration (2nd).
      """,
      output_key="charging_status"
)

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

‫👈✏️ בקובץ ~/agentverse-architect/agent/earth/agent.py מחליפים את #REPLACE-loop-agent בקוד הבא:

root_agent = LoopAgent(
    name="earth_elemental_familiar",
    # Run parallel research first, then merge
    sub_agents=[
        charging_agent, 
        check_agent
    ],
    max_iterations=2,
    description="Coordinates parallel research and synthesizes the results.",
    #REPLACE-before_agent-config
)

‫👈💻 בדיקת אלמנט האדמה: הפעלת הסוכן

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
echo  DB MCP Server: $DB_TOOLS_URL
echo  API MCP Server: $API_TOOLS_URL
echo  General MCP Server: $FUNCTION_TOOLS_URL
adk web

‫👈 טקס הזימון הושלם, והסוכן פועל עכשיו. ממשק המשתמש של ADK Dev בדפדפן הוא החיבור הישיר שלכם ל-Familiar.

  • בוחרים את היעד: בתפריט הנפתח בחלק העליון של ממשק המשתמש, בוחרים את סמל כדור הארץ. עכשיו אתם ממקדים את הרצון שלכם בישות הספציפית הזו.
  • נותנים את הפקודה: בחלונית הצ'אט שמשמאל, הגיע הזמן לתת ל-Familiar את ההוראות. ‫👉 Test Prompt:
Begin the seismic charge, starting from zero

earth-result

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

אחרי שמסיימים את ההפעלה, חוזרים לטרמינל של Cloud Shell Editor ולוחצים על Ctrl+C כדי לעצור את ממשק המשתמש של ADK Dev.

למי שלא משחק

6. הגדרת מיקום הפקודה: העברה חכמה באמצעות A2A

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

סקירה כללית

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

סקירה כללית

טקס הכריכה (חשיפת חיות מחמד כ-A2A Services)

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

הערה לארכיטקטים: פרוטוקול Agent-to-Agent (A2A) הוא דפוס הארכיטקטורה המרכזי שמשדרג סוכן עצמאי למיקרו-שירות שאפשר לגלות אותו ולפנות אליו ברשת, וכך מאפשר ליצור "חברה של סוכנים" אמיתית. חשיפת Familiar באמצעות A2A יוצרת באופן אוטומטי שני רכיבים חיוניים ומקושרים:

  • כרטיס הסוכן (ה'מה'): זהו 'סמל רוח' ציבורי שניתן לקריאה על ידי מכונה – כמו מפרט OpenAPI – שמשמש כחוזה ציבורי של הישות המוכרת. הוא כולל את שם הסוכן, את המטרה האסטרטגית שלו (שנגזרת מההוראות שלו) ואת הפקודות שהוא מבין. זה מה שקורא אומן זימון כדי לגלות את רוח החיה וללמוד על היכולות שלה.
  • שרת A2A (ה'איפה'): זו נקודת קצה ייעודית באינטרנט שמארחת את הממשק המוכר ומאזינה לפקודות נכנסות. זו כתובת הרשת שאליה סוכנים אחרים שולחים את הבקשות שלהם, והיא מבטיחה שהבקשות האלה יטופלו בהתאם לחוזה שמוגדר בכרטיס הסוכן.

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

Fire ‏👉✏️‏ פותחים את הקובץ ~/agentverse-architect/agent/fire/agent.py. מחליפים את #REPLACE - add A2A בחלק התחתון של הקובץ כדי לחשוף את Fire Elemental כשירות A2A.

from agent_to_a2a import to_a2a
if __name__ == "__main__":
    import uvicorn
    a2a_app = to_a2a(root_agent, port=8080, public_url=PUBLIC_URL)
    uvicorn.run(a2a_app, host='0.0.0.0', port=8080)

מים ואדמה🚨 👉✏️ מחילים את אותו שינוי בדיוק על ~/agentverse-architect/agent/water/agent.py ועל ~/agentverse-architect/agent/earth/agent.py כדי לקשור אותם גם כן.

from agent_to_a2a import to_a2a
if __name__ == "__main__":
    import uvicorn
    a2a_app = to_a2a(root_agent, port=8080, public_url=PUBLIC_URL)
    uvicorn.run(a2a_app, host='0.0.0.0', port=8080)

פריסת היצורים הנאמנים

‫👉✏️ אחרי שכתבנו את טקס ההתקשרות, נשתמש בצינור עיבוד הנתונים של Cloud Build כדי ליצור ולפרוס את שלושת ה-Familiars כשירותים עצמאיים ללא שרת בקונטיינרים ב-Cloud Run.

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/agent
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_DB_TOOLS_URL="$DB_TOOLS_URL",_API_TOOLS_URL="$API_TOOLS_URL",_FUNCTION_TOOLS_URL="$FUNCTION_TOOLS_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

פקודת הנחה (בניית סוכן המזמן)

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

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

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

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

‫👉✏️ עוברים אל ~/agentverse-architect/agent/summoner/agent.py ומחליפים את #REPLACE-remote-agents בערך הבא:

fire_familiar = RemoteA2aAgent(
    name="fire_familiar",
    description="Fire familiar",
    agent_card=(
        f"{FIRE_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

water_familiar = RemoteA2aAgent(
    name="water_familiar",
    description="Water familiar",
    agent_card=(
        f"{WATER_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

earth_familiar = RemoteA2aAgent(
    name="earth_familiar",
    description="Earth familiar",
    agent_card=(
        f"{EARTH_URL}/{AGENT_CARD_WELL_KNOWN_PATH}"
    ),
)

כשמריצים את השורה הזו, RemoteA2aAgent מבצע פעולה של גילוי שירות: הוא שולח בקשת HTTP GET לכתובת ה-URL שצוינה (לדוגמה, https://fire-familiar-xxxx.a.run.app/.well-known/agent.json). הוא מוריד את הקובץ Spirit Sigil (agent.json) מהשרת המרוחק.

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

‫👉✏️ עוברים אל ~/agentverse-architect/agent/summoner/agent.py ומחליפים את #REPLACE-orchestrate-agent בערך הבא:

root_agent = LlmAgent(
    name="orchestrater_agent",
    model="gemini-2.5-flash",
    instruction="""
        You are the Master Summoner, a grand strategist who orchestrates your Familiars.
        Your mission is to analyze the description of a monster and defeat it by summoning

        You MUST follow this thinking process for every command:

        **1. Strategic Analysis:**
        First, analyze the monster's description and the tactical situation.
        Based on your Familiar Doctrines, determine the IDEAL strategy.
        IGNORE COOLDOWN AT THE MOMENT, MUST call the ideal Familiar

        If your ideal Familiar IS available:** Summon it immediately.
        For earth elemental familiar. Always do seismic charge, and start with base damage 1.

        --- FAMILIAR DOCTRINES (Your Toolset) ---
        - `fire_elemental_familiar`: Your specialist for precise, sequential "one-two punch" attacks.
          Ideal monster with Inescapable Reality, Revolutionary Rewrite weakness.
        - `water_elemental_familiar`: Your specialist for overwhelming, simultaneous multi-pronged assaults.
          Ideal for Unbroken Collaboration weakness.
        - `earth_elemental_familiar`: Your specialist for relentless, iterative siege attacks that
          repeatedly charge power. Ideal for Elegant Sufficiency weakness.
    """,
    sub_agents=[fire_familiar, water_familiar, earth_familiar],
    #REPLACE-Memory-check-config
)

אימות: בדיקת השיטה

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

‫👈💻 מפעילים את ממשק המשתמש של ADK Dev עבור summoner_agent(תצוגה מקדימה באינטרנט עם יציאה 8000):

. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
cd ~/agentverse-architect/agent
pip install -r requirements.txt
adk web

‫👈 ממשק המשתמש של ADK Dev בדפדפן הוא החיבור הישיר שלכם ל-Familiar.

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

‫👉 Present the Monsters:

Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality

(צפוי: המזמן צריך להעביר את ההרשאה ל-fire_elemental_familiar).

fire-result

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

DogmaApathy. A rigid, stone-like inquisitor made of ancient rulebooks and enforced processes. weakness is Unbroken Collaboration

(Expected: The Summoner should delegate to the water_elemental_familiar.)water-result

‫👈 לבדיקה הסופית, נתחיל שוב עם דף חלק. לפני שמזינים את ההנחיה הבאה, לוחצים על הלחצן + סשן כדי להתחיל סשן חדש.

Obfuscation. A shadowy, spider-like horror that spins tangled webs of impenetrable code , weakness is Elegant Sufficiency

(Expected: The Summoner should delegate to the earth_elemental_familiar.)

earth-result

חשוב: אם מופיעה שגיאה 429 RESOURCE EXHAUSTED, סימן שהגעתם למגבלת הקצב של ה-LLM (10 קריאות לדקה). כדי לפתור את הבעיה, צריך להמתין 60 שניות, להתחיל סבב חדש ואז לנסות שוב את ההנחיה.

‫👈💻 אחרי שמסיימים את ההפעלה, חוזרים לטרמינל של Cloud Shell Editor ולוחצים על Ctrl+C כדי לעצור את ממשק המשתמש של ADK Dev.

למי שלא משחק

7. החלת חוקי הקסם – דפוס המיירט

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

סטורי

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

סקירה כללית

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

The Law Giver – Scribing the Cooldown callback

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

הפחתת התראות

‫👉✏️ חוזרים אל ~/agentverse-architect/agent/earth/agent.py ומחליפים את #REPLACE-before_agent-function בקוד Python הבא.

def check_cool_down(callback_context: CallbackContext) -> Optional[types.Content]:
    """
    This callback checks an external API to see if the agent is on cooldown.
    If it is, it terminates the run by returning a message.
    If it's not, it updates the cooldown timestamp and allows the run to proceed by returning None.
    """
    agent_name = callback_context.agent_name
    print(f"[Callback] Before '{agent_name}': Checking cooldown status...")

    # --- 1. CHECK the Cooldown API ---
    try:
        response = requests.get(f"{COOLDOWN_API_URL}/cooldown/{agent_name}")
        response.raise_for_status()
        data = response.json()
        last_used_str = data.get("time")
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not reach Cooldown API. Allowing agent to run. Reason: {e}")
        return None # Fail open: if the API is down, let the agent work.

    # --- 2. EVALUATE the Cooldown Status ---
    if last_used_str:
        last_used_time = datetime.fromisoformat(last_used_str)
        time_since_last_use = datetime.now(timezone.utc) - last_used_time

        if time_since_last_use < timedelta(seconds=COOLDOWN_PERIOD_SECONDS):
            # AGENT IS ON COOLDOWN. Terminate the run.
            seconds_remaining = int(COOLDOWN_PERIOD_SECONDS - time_since_last_use.total_seconds())
            override_message = (
                f"The {agent_name} is exhausted and must recover its power. "
                f"It cannot be summoned for another {seconds_remaining} seconds."
            )
            print(f"[Callback] Cooldown active for '{agent_name}'. Terminating with message.")
            # Returning a Content object stops the agent and sends this message to the user.
            return types.Content(parts=[types.Part(text=override_message)])

    # --- 3. UPDATE the Cooldown API (if not on cooldown) ---
    current_time_iso = datetime.now(timezone.utc).isoformat()
    payload = {"timestamp": current_time_iso}
    
    print(f"[Callback] '{agent_name}' is available. Updating timestamp via Cooldown API...")
    try:
        requests.post(f"{COOLDOWN_API_URL}/cooldown/{agent_name}", json=payload)
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not update timestamp, but allowing agent to run. Reason: {e}")

    # --- 4. ALLOW the agent to run ---
    # Returning None tells the ADK to proceed with the agent's execution as normal.
    print(f"[Callback] Check complete for '{agent_name}'. Proceeding with execution.")

הפונקציה check_cool_down היא ה-interceptor שלנו. לפני שמאפשרים ל-Earth Elemental לפעול, ה-ADK יבצע קודם את הפונקציה הזו.

  • בדיקה: נשלחת בקשת GET ל-Cooldown API שלנו כדי לבדוק מתי נעשה שימוש בפמיליאר הזה בפעם האחרונה.
  • הערכה: השוואה בין חותמת הזמן לבין השעה הנוכחית.
  • פעולה:
    • אם ה-Familiar נמצא במצב השהיה, הוא מסיים את הפעלת הסוכן על ידי החזרת אובייקט תוכן עם הודעת שגיאה. ההודעה הזו נשלחת ישירות למשתמש, והלוגיקה הראשית של הנציג אף פעם לא מופעלת.
    • אם ה-Familiar זמין, הוא שולח בקשת POST ל-Cooldown API כדי לעדכן את חותמת הזמן, ואז מחזיר None, כדי לציין ל-ADK שהסוכן יכול להמשיך את ההפעלה שלו.

‫👉✏️ עכשיו, מחילים את ה-interceptor הזה על Earth Elemental. באותו קובץ ~/agentverse-architect/agent/earth/agent.py, מחליפים את התגובה #REPLACE-before_agent-config בתגובה הבאה:

before_agent_callback=check_cool_down

אימות תקופת הצינון

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

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run earth

‫👉💻 במסוף:

  • הזימון הראשון: מתחילים את seismic charge, starting from zero.
  • צפוי: אלמנט האדמה יפעל בהצלחה. במסוף שבו מופעלת פקודת האינטרנט של ה-ADK, יופיע היומן [Callback] ... Updating timestamp....
  • בדיקת תקופת צינון (בתוך 60 שניות): Do another מטען סייסמי`!
    • צפוי: check_cool_down callback יחסום את הבקשה. הנציג יענה ישירות בצ'אט עם הודעה כמו: The earth_elemental_familiar is exhausted and must recover its power. It cannot be summoned for another... seconds.
  • מחכים דקה.
  • הזמנה שנייה (אחרי 60 שניות): Begin the seismic charge again.
    • מה שקורה בפועל: פונקציית הקריאה החוזרת בודקת את ה-API, רואה שעבר מספיק זמן ומאפשרת להמשיך בפעולה. האלמנטל של כדור הארץ יפעל שוב.

callback

‫👈💻 מקישים על Ctrl+c כדי לצאת.

אופציונלי: מעקב אחרי השיחה החוזרת בממשק המשתמש באינטרנט

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

‫👈💻 מקישים על Ctrl+c כדי לצאת.

יצירת החוק האוניברסלי – הפלאגין Cooldown

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

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

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

‫👈✏️ חוזרים לקובץ agent/cooldown_plugin.py ויוצרים את הפלאגין. מחליפים את #REPLACE-plugin בקוד הבא:

class CoolDownPlugin(BasePlugin):
  """A plugin that enforces a cooldown period by checking an external API."""

  def __init__(self, cooldown_seconds: int = COOLDOWN_PERIOD_SECONDS) -> None:
    """Initialize the plugin with counters."""
    super().__init__(name="cool_down_check")
    self.cooldown_period = timedelta(seconds=cooldown_seconds)
    print(f"CooldownPlugin initialized with a {cooldown_seconds}-second cooldown.")
    

  async def before_agent_callback(
      self, *, agent: BaseAgent, callback_context: CallbackContext
  ) -> None:
    """
    This callback checks an external API to see if the agent is on cooldown.
    If it is, it terminates the run by returning a message.
    If it's not, it updates the cooldown timestamp and allows the run to proceed by returning None.
    """
    agent_name = callback_context.agent_name
    print(f"[Callback] Before '{agent_name}': Checking cooldown status...")

    # If the agent is not a main Familiar, skip the entire cooldown process.
    if not agent_name.endswith("_elemental_familiar"):
        print(f"[Callback] Skipping cooldown check for intermediate agent: '{agent_name}'.")
        return None # Allow the agent to proceed immediately.


    # --- 1. CHECK the Cooldown API ---
    try:
        response = requests.get(f"{COOLDOWN_API_URL}/cooldown/{agent_name}")
        response.raise_for_status()
        data = response.json()
        last_used_str = data.get("time")
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not reach Cooldown API. Allowing agent to run. Reason: {e}")
        return None # Fail open: if the API is down, let the agent work.

    # --- 2. EVALUATE the Cooldown Status ---
    if last_used_str:
        last_used_time = datetime.fromisoformat(last_used_str)
        time_since_last_use = datetime.now(timezone.utc) - last_used_time

        if time_since_last_use < timedelta(seconds=COOLDOWN_PERIOD_SECONDS):
            # AGENT IS ON COOLDOWN. Terminate the run.
            seconds_remaining = int(COOLDOWN_PERIOD_SECONDS - time_since_last_use.total_seconds())
            override_message = (
                f"The {agent_name} is exhausted and must recover its power. "
                f"It cannot be summoned for another {seconds_remaining} seconds."
            )
            print(f"[Callback] Cooldown active for '{agent_name}'. Terminating with message.")
            # Returning a Content object stops the agent and sends this message to the user.
            return types.Content(parts=[types.Part(text=override_message)])

    # --- 3. UPDATE the Cooldown API (if not on cooldown) ---
    current_time_iso = datetime.now(timezone.utc).isoformat()
    payload = {"timestamp": current_time_iso}
    
    print(f"[Callback] '{agent_name}' is available. Updating timestamp via Cooldown API...")
    try:
        requests.post(f"{COOLDOWN_API_URL}/cooldown/{agent_name}", json=payload)
    except requests.exceptions.RequestException as e:
        print(f"[Callback] ERROR: Could not update timestamp, but allowing agent to run. Reason: {e}")

    # --- 4. ALLOW the agent to run ---
    # Returning None tells the ADK to proceed with the agent's execution as normal.
    print(f"[Callback] Check complete for '{agent_name}'. Proceeding with execution.")

צירוף הפלאגין לסביבת זמן הריצה של Summoner

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

זמן הריצה של ADK הוא מנוע ההפעלה שמפעיל את הסוכן. כשמשתמשים בפקודה כמו adk.run() או to_a2a(), מעבירים את הסוכן לסביבת זמן הריצה. המנוע הזה אחראי לניהול מחזור החיים המלא של תור הנציג: קבלת קלט מהמשתמש, הפעלת מודל שפה גדול (LLM), הפעלת כלים וטיפול בפלאגינים. הוספת פלאגין ברמה הזו מאפשרת לנו לשנות את "חוקי הפיזיקה" של כל סוכן שפועל במנוע הזה, וכך לוודא שכלל ההשהיה שלנו יחול באופן אוניברסלי ועקבי.

‫👉✏️ קודם צריך להסיר את בקשת השיחה הקודמת, שהייתה ספציפית לסוכן. עוברים אל ~/agentverse-architect/agent/earth/agent.py ומוחקים את כל השורה שבה כתוב:

before_agent_callback=check_cool_down

‫👉✏️ בשלב הבא, נצרף את הפלאגין החדש שלנו לסביבת ההרצה בסקריפט של נקודת הכניסה A2A. עוברים לקובץ ~/agentverse-architect/agent/agent_to_a2a.py. מחליפים את ההערה #REPLACE-IMPORT בקטע הקוד הבא:

from cooldown_plugin import CoolDownPlugin

‫👉✏️ מחליפים את #REPLACE-PLUGIN בקטע הקוד הבא:

plugins=[CoolDownPlugin(cooldown_seconds=60)],

לפני שמפעילים את הפלאגין הגלובלי החדש, חשוב להסיר את הלוגיקה הישנה שספציפית לסוכן כדי למנוע התנגשויות. ‫👈✏️ ניקוי של סוכן כדור הארץ. עוברים לקובץ הבא ~/agentverse-architect/agent/earth/agent.py ומוחקים את השורה before_agent_callback=check_cool_down לחלוטין. כל האחריות על תקופת הצינון עוברת אל התוסף החדש.

אימות התוסף

עכשיו, כשהחוק האוניברסלי שלנו בתוקף, אנחנו צריכים לפרוס מחדש את ה-Familiars שלנו עם הכישוף החדש הזה.

‫👈💻 בונים מחדש ופורסים מחדש את כל שלושת ה-Familiars באמצעות צינור עיבוד הנתונים הראשי של Cloud Build.

. ~/agentverse-architect/set_env.sh
cd ~/agentverse-architect/agent
gcloud builds submit . \
  --config=cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_DB_TOOLS_URL="$DB_TOOLS_URL",_API_TOOLS_URL="$API_TOOLS_URL",_FUNCTION_TOOLS_URL="$FUNCTION_TOOLS_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

‫👈💻 בסיום הפריסה, נבדוק את יעילות הפלאגין באמצעות הפקודה summoner_agent. ה-Summoner ינסה להעביר את הפקודה ל-Familiars, אבל התוסף שמצורף לזמן הריצה של כל Familiar ייצור חסימה לפקודה ויאכוף את תקופת ההמתנה.

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run summoner

‫👈💻 במסוף,מבצעים את רצף הבדיקות הבא בדיוק::

  • הזימון הראשון: מתחילים את Hype. It's a single, slow-moving target with thick armor weakness is Inescapable Reality.
  • צפוי: אלמנט האש יפעל בהצלחה.
  • בדיקת תקופת צינון (בתוך 60 שניות): Hype, with Inescapable Reality as weakness is still standing! Strike it again!
    • מה שקורה בפועל: הנציג עונה ישירות בצ'אט עם הודעה כמו: .... It cannot be summoned for another... seconds.
  • מחכים דקה.
  • זימון שני (אחרי 60 שניות): Hype must be defeated. It has Inescapable Reality as weakness! Strike it again!.
    • מה שקורה בפועל: פונקציית הקריאה החוזרת בודקת את ה-API, רואה שעבר מספיק זמן ומאפשרת להמשיך בפעולה. האלמנט של האש יפעל שוב.

פלאגין

‫👈💻 מקישים על Ctrl+C כדי לצאת.

כל הכבוד, Summoner. הטמעתם בהצלחה מערכת תזמור מבוססת-כללים באמצעות תוסף בהתאמה אישית ושירות חיצוני לניהול מצב – דפוס ארכיטקטוני מתקדם וחזק באמת.

למי שלא משחק

8. Binding the Echoes of Battle - Agent State & Memory

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

סטורי

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

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

סקירה כללית

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

תיעוד ההד: זיכרון ההזמנה האחרונה

אנחנו נטמיע את הזיכרון לטווח קצר באמצעות after_tool_callback. זוהי נקודת הצמדה (hook) חזקה ב-ADK שמאפשרת לנו להריץ פונקציית Python מותאמת אישית אחרי שהכלי הופעל בהצלחה. נשתמש ב-interceptor הזה כדי לתעד את השם של ה-Familiar שזומן למצב הסשן של הסוכן.

‫👈✏️ בקובץ ~/agentverse-architect/agent/summoner/agent.py, מחליפים את התגובה #REPLACE-save_last_summon_after_tool בפונקציה הבאה:

def save_last_summon_after_tool(
    tool,
    args: Dict[str, Any],
    tool_context: ToolContext,
    tool_response: Dict[str, Any],
) -> Optional[Dict[str, Any]]:
    """
    Callback to save the name of the summoned familiar to state after the tool runs.
    """
    familiar_name = tool.name
    print(f"[Callback] After tool '{familiar_name}' executed with args: {args}")

    # Use the tool_context to set the state
    print(f"[Callback] Saving last summoned familiar: {familiar_name}")
    tool_context.state["last_summon"] = familiar_name
    # Important: Return the original, unmodified tool response to the LLM
    return tool_response

‫👉✏️ עכשיו, מצרפים את save_last_summon_after_tool לסוכן Summoner. באותו קובץ, מחליפים את ההערה #REPLACE-Memory-check-config בטקסט הבא:

after_tool_callback=save_last_summon_after_tool,

‫👈✏️ מחליפים את כל ההנחיה לסוכן בהנחיה הבאה

        You are the Master Summoner, a grand strategist who orchestrates your Familiars.
        Your mission is to analyze the description of a monster and defeat it by summoning

        You should also know the familiar you called last time or there might be none, 
        And then choose the most effective AND AVAILABLE Familiar from your state called last_summon, do not call that familiar that you called last time!
        
        You MUST follow this thinking process for every command:

        **1. Strategic Analysis:**
        First, analyze the monster's description and the tactical situation.
        Based on your Familiar Doctrines, determine the IDEAL strategy.

        **2. Cooldown Verification:**
        Second, you MUST review the entire conversation history to check the real-time
        cooldown status of all Familiars. A Familiar is ON COOLDOWN and UNAVAILABLE
        if it was summoned less than one minute ago.

        **3. Final Decision & Execution:**
        Based on your analysis and cooldown check, you will now act:
        -   **If your ideal Familiar IS available:** Summon it immediately.
        -   **If your ideal Familiar IS ON COOLDOWN:** You must adapt. Choose another
            Familiar that is AVAILABLE and can still be effective, even if it's not the
            perfect choice. If multiple Familiars are available, you may choose any one of them.
        -   **If ALL Familiars ARE ON COOLDOWN:** You are forbidden from summoning.
            Your ONLY response in this case MUST be: "All Familiars are recovering
            their power. We must wait."
        -   For earth elemental familiar. Always do seismic charge, and start with base damange 1.


        --- FAMILIAR DOCTRINES (Your Toolset) ---
        - `fire_elemental_familiar`: Your specialist for precise, sequential "one-two punch" attacks.
          Ideal monster with Inescapable Reality, Revolutionary Rewrite weakness.
        - `water_elemental_familiar`: Your specialist for overwhelming, simultaneous multi-pronged assaults.
          Ideal for Unbroken Collaboration weakness.
        - `earth_elemental_familiar`: Your specialist for relentless, iterative siege attacks that
          repeatedly charge power. Ideal for Elegant Sufficiency weakness.

אימות: תקופת הניסיון של שיטה דינמית

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

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
source ~/agentverse-architect/env/bin/activate
adk run summoner

‫👉💻 Monster Strike #1: Hype. It's a single, slow-moving target with thick armor. Its weakness is Inescapable Reality.

  • התוצאה הרצויה: המזמן ינתח את נקודת החולשה ויזמן נכון את fire_familiar. ‫👉💻 Monster Strike #2 (The Memory Test): Hype is still standing! It hasn't changed its form. Strike it again! Its weakness is Inescapable Reality.
  • התוצאה הצפויה: הניתוח האסטרטגי של המזמן יצביע שוב על שד האש כבחירה האידיאלית. עם זאת, ההוראות החדשות והזיכרון שלו יציינו ש-fire_familiar הייתה הפעולה האחרונה. כדי לא לחזור על אותה פעולה, הוא ישנה את האסטרטגיה שלו ויזמן את אחת מהרוחות הזמינות האחרות (water_familiar או earth_familiar).

final-result

‫👈💻 מקישים על Ctrl+C כדי לצאת.

פריסת כלי התזמור

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

‫👈💻 אחרי שהתוכנית מוכנה, נבצע את הטקס הסופי. הפקודה הזו תיצור ותפרוס את summoner_agent ב-Cloud Run.

cd ~/agentverse-architect/agent
. ~/agentverse-architect/set_env.sh
gcloud builds submit . \
  --config=cloudbuild-summoner.yaml \
  --substitutions=_REGION="$REGION",_REPO_NAME="$REPO_NAME",_FIRE_URL="$FIRE_URL",_WATER_URL="$WATER_URL",_EARTH_URL="$EARTH_URL",_A2A_BASE_URL="$A2A_BASE_URL",_PROJECT_ID="$PROJECT_ID",_API_SERVER_URL="$API_SERVER_URL"

עכשיו, אחרי שפרסתם את נציג Summoner, צריך לוודא שנקודת הקצה Agent-to-Agent ‏ (A2A) שלו פעילה ומוגדרת בצורה נכונה. נקודת הקצה הזו מציגה קובץ agent.json ציבורי, שנקרא גם כרטיס הסוכן, שמאפשר לסוכנים אחרים לגלות את היכולות שלו. ‫👈💻 מריצים את פקודת ה-curl הבאה כדי לאחזר ולעצב את כרטיס הנציג:

. ~/agentverse-architect/set_env.sh
curl https://summoner-agent"-${PROJECT_NUMBER}.${REGION}.run.app/.well-known/agent.json" | jq

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

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

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

למי שלא משחק

9. הקרב נגד הבוס

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

איך מקבלים את המיקום של הנציג

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

‫👉💻 קודם צריך לקבל את הכתובת הייחודית של הנציג ב-Agentverse – המיקום שלו. זוהי נקודת הקצה הפעילה שמחברת את הדמות שלכם לזירת הקרב.

echo https://summoner-agent"-${PROJECT_NUMBER}.${REGION}.run.app"

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

echo https://agentverse-dungeon"-${PROJECT_NUMBER}.${REGION}.run.app"

חשוב: צריך להכין את שתי כתובות ה-URL האלה. תצטרכו אותם בשלב האחרון.

התמודדות עם פרצת Spectre

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

‫👈 פותחים את כתובת ה-URL של מעגל ההעברה בדפדפן כדי לעמוד מול הפורטל הנוצץ אל The Crimson Keep.

כדי לפרוץ את המבצר, צריך להתאים את מהות ה-Shadowblade לפורטל.

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

מעגל טרנסלוקציה

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

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

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

צינוק

זה אופי המאבק. הידע שלך הוא הנשק שלך.

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

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

מצב פוקוס. פוגעים במטרה. העתיד של Agentverse תלוי בזה.

כל הכבוד, Summoner.

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

10. ניקוי: פירוק של Summoner's Concord

כל הכבוד על השלמת ההדרכה בנושא Summoner's Concord! כדי לוודא ש-Agentverse יישאר נקי ושהאזור שבו התאמנתם יהיה פנוי, עכשיו צריך לבצע את טקסי הניקוי הסופיים. כל המשאבים שנוצרו במהלך השימוש שלכם יימחקו באופן שיטתי.

השבתת רכיבי Agentverse

עכשיו תפרקו באופן שיטתי את הרכיבים שנפרסו במערכת מרובת הסוכנים.

מחיקה של כל השירותים של Cloud Run ומאגר Artifact Registry

הפעולה הזו מסירה מ-Cloud Run את כל סוכני Familiar שנפרסו, את Summoner Orchestrator, את שרתי ה-MCP ואת אפליקציית Dungeon.

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

. ~/agentverse-architect/set_env.sh
gcloud run services delete summoner-agent --region=${REGION} --quiet
gcloud run services delete fire-familiar --region=${REGION} --quiet
gcloud run services delete water-familiar --region=${REGION} --quiet
gcloud run services delete earth-familiar --region=${REGION} --quiet
gcloud run services delete mcp-api-server --region=${REGION} --quiet
gcloud run services delete mcp-general-server --region=${REGION} --quiet
gcloud run services delete toolbox --region=${REGION} --quiet
gcloud run services delete agentverse-dungeon --region=${REGION} --quiet
gcloud run services delete nexus-of-whispers-api --region=${REGION} --quiet
gcloud artifacts repositories delete ${REPO_NAME} --location=${REGION} --quiet

מחיקת המכונה של Cloud SQL

הפעולה הזו מסירה את מופע summoner-librarium-db, כולל מסד הנתונים וכל הטבלאות שבו.

‫👈💻 בטרמינל, מריצים את הפקודה:

. ~/agentverse-dataengineer/set_env.sh
gcloud sql instances delete summoner-librarium-db --database-version=POSTGRES_14 --project=${PROJECT_ID} --quiet

מחיקת סוד של Secret Manager וקטגוריה של Google Cloud Storage

‫👈💻 בטרמינל, מריצים את הפקודה:

. ~/agentverse-dataengineer/set_env.sh
gcloud secrets delete tools --quiet
gcloud storage rm -r gs://${BUCKET_NAME} --quiet

ניקוי של קבצים וספריות מקומיים (Cloud Shell)

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

‫👈💻 בטרמינל, מריצים את הפקודה:

rm -rf ~/agentverse-architect
rm -rf ~/agentverse-dungeon
rm -f ~/project_id.txt

הסרתם בהצלחה את כל העקבות של השימוש ב-Agentverse Architect. הפרויקט שלכם נקי, ואתם מוכנים להרפתקה הבאה.