1. סקירה כללית
כדי למלא בקשה מורכבת לתכנון טיול (למשל, תכנון טיול יומי בקיוטו בתקציב של 100 דולר, שכולל מקדשים היסטוריים, ראמן מקומי ואפס מוזיאונים לאומנות מודרנית), המודל צריך לחלץ העדפות מובנות, לחקור מקומות במקביל, לסנתז טיוטה מפורטת ולבדוק את העלות הכוללת לפני שהוא מגיב. ב-ADK 1.x, כדי לתזמר את השלבים האלה היה צריך להוסיף רכיבי wrapper מסוג SequentialAgent, ParallelAgent ו-LoopAgent, לשמור כל פלט ביניים במצב הסשן ולהפעיל קריאת API נוספת לכלי של LLM רק כדי לצאת מלולאת הליטוש.
ב-Codelab הזה תבנו מתכנן נסיעות מרובה סוכנים בAgent Platform באמצעות תהליכי עבודה של תרשימים (Workflow) בערכה לפיתוח סוכנים (ADK) גרסה 2. בשלושה שלבים מתקדמים, תחברו צומתי Agent מומחים (שמופעלים על ידי gemini-3.8-flash) בשרשרת קצוות רציפה (node_input), תפרסו חוקרי google_search בו-זמנית שמסונכרנים עם JoinNode, ותאכפו כללי תקציב וכללים להחרגה באמצעות נתב Python דטרמיניסטי (Event(route=...)) שמדלג על שיפור בכל פעם שהטיוטה הראשונית עוברת ביקורת.
דרישות מוקדמות
- מיומנות בסיסית בתכנות ב-Python
- היכרות עם מושגים של AI גנרטיבי ויסודות של סוכני AI
מה לומדים
- איך להצהיר על צינור עיבוד נתונים מרובה סוכנים ב-ADK 2 באמצעות טאפלים של קצוות
Workflow - איך ADK 2 מעביר פלטים ישירות לאורך קצוות בתור
node_inputומקשר מפתחות של מצב סשן בתור פרמטרים של פונקציות - איך לפצל את המחקר לכמה ענפים במקביל ולמזג את הפלט שלהם באמצעות
JoinNode - איך מנתבים מחזורי maker-checker מוגבלים באופן דטרמיניסטי ב-Python באמצעות
Event(route=...) - איך בודקים תרשימים של תהליכי עבודה שעברו הידור, צירי זמן של הפעלה במקביל ושינויים במצב בממשק האינטרנט של ADK
מה צריך
- חשבון Google (אם רוצים לקבל קרדיטים על הסדנה, צריך להשתמש בחשבון
@gmail.comאישי) - קישור לקרדיט לסדנה שקיבלתם מהמדריך (וגם מצלמה של טלפון כדי לסרוק את קוד ה-QR) או חשבון פעיל לחיוב ב-Cloud
- Google Chrome (מומלץ להשתמש בחלון פרטי כדי למנוע ערבוב בין החשבון האישי לחשבון לצורכי עבודה)
2. מימוש קרדיטים ב-Google Cloud (אופציונלי)
אם אתם משתתפים בסדנה עם קישור לקרדיט לאירוע, אתם יכולים לממש את הקרדיט של Google Developer Program כדי להקצות חשבון לחיוב בלי כרטיס אשראי.
מימוש שובר הפרסום לאירוע
- פותחים את הקישור לקרדיט לסדנה בחלון פרטי ונכנסים לחשבון
@gmail.com. - בקטע Claim Your Benefit, לוחצים על Claim Credit:

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

- מוודאים שמופיעה ההודעה Successfully claimed your event credit! ולוחצים על Open Billing Account:

🔍 בדיקת העבודה שלכם
הגדרת החשבון לחיוב נמשכת עד 3 דקות:
- פותחים את חיוב ב-Cloud (או מעתיקים את כתובת ה-URL לחלון פרטי) ובוחרים באפשרות חשבונות לחיוב:
https://console.cloud.google.com/billing
- מרעננים את הדף עד שמופיע הסטטוס פעיל בחשבון
GDP Credit:

3. יצירת פרויקט ב-Google Cloud (אופציונלי)
יוצרים פרויקט ייעודי ב-Google Cloud כדי שכל המשאבים מה-Codelab הזה יישארו מבודדים ויהיה קל לנקות אותם.
- פותחים את הדף Create a Project (או מעתיקים את כתובת ה-URL לחלון הפרטי):
https://console.cloud.google.com/projectcreate
- ממלאים את פרטי הפרויקט:
- שם הפרויקט: לדוגמה,
google-cloud-workshop - חשבון לחיוב (אם מוצג): בוחרים באפשרות
GDP Credit(או בחשבון הפעיל לחיוב) - משאב הורה: ללא ארגון (או בחרו את הארגון שלכם, אם נדרש)
- שם הפרויקט: לדוגמה,
- שימו לב ל-מזהה הפרויקט שנוצר מתחת לשם הפרויקט, ואז לחצו על Create:

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

4. הגדרת הסביבה
מגדירים את Google Cloud Shell, מפעילים את Agent Platform API ויוצרים סביבה וירטואלית מבודדת של Python 3.12 באמצעות uv.
הגדרת Cloud Shell
- לוחצים על Activate Cloud Shell (
>_) בסרגל הכלים של מסוף Google Cloud, או פותחים את Google Cloud Shell ישירות (או מעתיקים את כתובת ה-URL לחלון הפרטי):
https://shell.cloud.google.com/?show=ide,terminal

- אם מוצגת בקשה, לוחצים על Authorize:

- בוחרים את מזהה הפרויקט הפעיל ב-Google Cloud מהתפריט הממוספר בטרמינל:
unset CLOUDSDK_CORE_PROJECT
PS3="Select your project (e.g. 1): "
select PROJECT_ID in $(gcloud projects list --format="value(projectId)"); do
[ -n "$PROJECT_ID" ] && gcloud config set project "$PROJECT_ID" && break
done
הפלט אמור להיראות כך (פרויקטים ללא תגים גם מדפיסים שורת מידע של [environment: untagged]):
1) google-cloud-workshop-4210 2) my-cloud-project-8812 Select your project (e.g. 1): 1 Updated property [core/project].
מוודאים שמזהה הפרויקט שבחרתם מופיע מודגש בצהוב בהנחיה של Cloud Shell:

הפעלת ממשקי ה-API הנדרשים
מפעילים את Agent Platform API כדי שהסוכנים ב-ADK יוכלו להפעיל מודלים של Gemini:
gcloud services enable aiplatform.googleapis.com
הפלט אמור להיראות כך:
Operation "operations/acat.p2-..." finished successfully.
יצירת סביבה וירטואלית של Python והתקנת ADK
יוצרים את סביבת העבודה ~/adk-graph-agents ומפעילים סביבה וירטואלית של Python 3.12:
cd ~
mkdir -p adk-graph-agents && cd ~/adk-graph-agents
which uv >/dev/null 2>&1 || curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
uv venv .venv --python 3.12
source .venv/bin/activate
מוודאים שהקידומת (.venv) מופיעה בתחילת ההנחיה בטרמינל:

מתקינים את ADK 2 בסביבה הווירטואלית הפעילה:
uv pip install --no-cache "google-adk==2.14.0"
🔍 בדיקת העבודה שלכם
בודקים את גרסת ה-CLI של adk שהותקנה:
adk --version
הפלט אמור להיראות כך:
adk, version 2.14.0
5. הכנת תוכנית לנסיעה
יוצרים את חבילת travel_planner למתחילים באמצעות adk create ובודקים את קו הבסיס של סוכן יחיד שמוגדר כברירת מחדל ב-adk web.
יצירת חבילת ההתחלה
מריצים את adk create מתוך ~/adk-graph-agents:
cd ~/adk-graph-agents
adk create travel_planner
בוחרים את האפשרויות הבאות כשמוצגת בקשה (אם מוצגת בקשה עם Enable telemetry? [Y/n]: בהפעלה הראשונה, לוחצים על Enter או מקלידים n ולוחצים על Enter):
- בחירת מודל לסוכן הבסיס: מקלידים
2כדי לבחור אתgemini-3.8-flash(אפשרות1בוחרת אתgemini-3.5-flash) ולוחצים על Enter. - בחירת קצה עורפי: מקלידים
2כדי לבחור את הקצה העורפי של פלטפורמת הנציגים של Google Cloud (אפשרות2בתפריט ה-CLI שבהמשך) ולוחצים על Enter. - Enter Google Cloud project ID: מקישים על Enter כדי לאשר את מזהה פרויקט בענן שזוהה בסוגריים.
- Enter Google Cloud region: מקלידים
global(כדי להשתמש בנקודת הקצה הגלובלית של Gemini) ולוחצים על Enter.
הפקודה adk create כותבת את GOOGLE_GENAI_USE_ENTERPRISE=1, את מזהה הפרויקט ואת GOOGLE_CLOUD_LOCATION=global לתוך travel_planner/.env, כדי שפרטי הכניסה יישארו ללא שינוי כשתחליפו את agent.py בהמשך.
הפלט אמור להיראות כך:
Choose a model for the root agent: 1. gemini-3.5-flash 2. gemini-3.8-flash 3. Other models (fill later) Choose model (1, 2, 3): 2 1. Google AI 2. Vertex AI 3. Login with Google Choose a backend (1, 2, 3): 2 You need an existing Google Cloud account and project, check out this link for details: https://google.github.io/adk-docs/get-started/quickstart/#gemini---google-cloud-vertex-ai Enter Google Cloud project ID [google-cloud-workshop-4210]: Enter Google Cloud region [us-central1]: global Agent created in /home/your_username/adk-graph-agents/travel_planner: - .env - .gitignore - __init__.py - agent.py ⚠️ WARNING: Secrets (like GOOGLE_API_KEY) are stored in .env. Next steps: - Chat with your agent in the terminal: adk run travel_planner - Or in the browser: adk web . - Have your coding agent evaluate and deploy it: uvx google-agents-cli setup (other install options: https://adk.dev/get-started/agents-cli/)
פותחים את ~/adk-graph-agents בעורך הקוד של Cloud Shell:
which cloudshell >/dev/null 2>&1 && cloudshell workspace ~/adk-graph-agents || true
מפעילים מחדש את הסביבה הווירטואלית בטרמינל שנטען מחדש:
cd ~/adk-graph-agents
source .venv/bin/activate
בדיקת הנציג הבסיסי היחיד
מפעילים את ממשק המשתמש של ADK באינטרנט כדי לראות איך סוכן בסיסי אחד, שלא מנוהל על ידי סוכן אחר, עונה על הנחיה שקשורה לנסיעות:
cd ~/adk-graph-agents
adk web --allow_origins "*"
לוחצים על הסמל Web Preview בסרגל הכלים של Cloud Shell בפינה הימנית העליונה, בוחרים באפשרות Change Port, מזינים 8000 ולוחצים על Change and Preview:

🔍 בדיקת העבודה שלכם
בוחרים באפשרות travel_planner בתפריט הנפתח שבפינה הימנית העליונה של adk web ושולחים את ההודעה "Help me plan a trip to Japan":

בחלונית הצ'אט אמורה להופיע תשובה אחת לשיחה (עם הפעלה אחת של root_agent באירועים):
root_agent -> responds in one pass without structured preference extraction, live search, or budget verification
מקישים על Ctrl + C בטרמינל של Cloud Shell כדי לעצור את adk web לפני שעורכים קבצים בשלב הבא.
6. יצירת תהליך עבודה של תרשים ליניארי
יוצרים את ה-ADK 2 הראשון Workflow: שרשרת רציפה שמחברת את נקודת הכניסה השמורה "START" אל user_profiler_agent ואל itinerary_synthesizer_agent (כל צומת בלי קצוות יוצאים פועל כצומת סיום). כל קצה (a, b) מריץ באופן אוטומטי צמתים של Agent (כינוי של LlmAgent) במצב single_turn מבודד ומעביר את הפלט של הצומת a בתור node_input (הודעת המשתמש הנכנסת) לצומת b, בעוד ש-{user_preferences} במחרוזת הוראות מבצע אינטרפולציה של מפתח מצב הסשן התואם שנשמר באמצעות output_key.

יצירת המומחים הראשונים
מוודאים שהתהליך adk web הופסק (Ctrl + C), ואז פותחים קובץ חדש בשם travel_planner/specialists.py:
cloudshell edit ~/adk-graph-agents/travel_planner/specialists.py
מדביקים את הקוד הבא ב-travel_planner/specialists.py כדי להגדיר את user_profiler_agent ו-itinerary_synthesizer_agent (מייבאים את google_search מראש לשלב הבא):
from google.adk import Agent
from google.adk.tools import google_search
MODEL = "gemini-3.8-flash"
# --- Specialist 1: The User Profiler ---
user_profiler_agent = Agent(
model=MODEL,
name="user_profiler_agent",
description="Extracts travel preferences and constraints from user input.",
instruction="""
Extract destination, duration (default 1 day), budget, interests, and exclusions.
Return a single JSON object with keys: "destination", "duration", "budget", "interests", "exclusions".
""",
output_key="user_preferences", # Saved for multi-hop constraints downstream
)
# --- Specialist 2: The Synthesizer ---
itinerary_synthesizer_agent = Agent(
model=MODEL,
name="itinerary_synthesizer_agent",
description="Compiles preferences and research into a final Markdown itinerary.",
instruction="""
You are an elite Travel Concierge. Using the incoming input and
User Preferences ({user_preferences}), write a Markdown itinerary
with an itemized USD and local currency cost breakdown.
""",
output_key="final_itinerary",
)
הגדרת שרשרת הקצוות הרציפה
פותחים קובץ חדש בשם travel_planner/workflows.py:
cloudshell edit ~/adk-graph-agents/travel_planner/workflows.py
מדביקים את ההגדרה הבאה של Workflow (כאשר קבוצה של 3 צמתים או יותר מתקמפלת לשרשרת רציפה מ-"START"):
from google.adk import Workflow
from .specialists import (
itinerary_synthesizer_agent,
user_profiler_agent,
)
# 1. SEQUENTIAL GRAPH: START -> user_profiler_agent -> itinerary_synthesizer_agent
travel_workflow = Workflow(
name="travel_workflow",
description="Orchestrates the end-to-end travel planning process as a graph workflow.",
edges=[
("START", user_profiler_agent, itinerary_synthesizer_agent),
],
)
הצגת תהליך העבודה בתור root_agent
פותחים את travel_planner/agent.py:
cloudshell edit ~/adk-graph-agents/travel_planner/agent.py
מחליפים את כל התוכן של travel_planner/agent.py בשתי השורות הבאות:
from .workflows import travel_workflow
root_agent = travel_workflow
🔍 בדיקת העבודה שלכם
הפעלת adk web מ-~/adk-graph-agents:
cd ~/adk-graph-agents
adk web --allow_origins "*"
פותחים את Web Preview ביציאה 8000, לוחצים על + New Session ושולחים:
Help me plan a trip to Kyoto
בתצוגה אירועים, אמור להופיע רצף אירועים שדומה לזה:
1. user_profiler_agent -> outputs JSON {"destination": "Kyoto", "duration": "1 day", ...} and writes state["user_preferences"]
2. itinerary_synthesizer_agent -> receives preferences via node_input and outputs the Markdown itinerary

לוחצים על אירוע כלשהו בקטע Events ואז על סמל התרשים (account_tree בסרגל הכלים של פרטי האירוע) כדי לבדוק את הטופולוגיה של START -> user_profiler_agent -> itinerary_synthesizer_agent שעברה הידור. לאחר מכן בודקים בכרטיסייה State אם הערכים user_preferences ו-final_itinerary מאוכלסים.
כדי להפסיק את adk web, לוחצים על Ctrl + C בטרמינל.
7. פיצול ואיחוד באמצעות JoinNode
כדי לבסס את מסלול הנסיעה על נתונים עדכניים מהאינטרנט, מוסיפים שני מומחי google_search בו-זמנית (activity_finder_agent ו-restaurant_finder_agent) ומסנכרנים אותם עם JoinNode:
- Fan-out tuple: Placing
(activity_finder_agent, restaurant_finder_agent)inside the edge tuple deliversuser_profiler_agent's output asnode_inputto both researchers concurrently. - מחסום Fan-in (
JoinNode): הצבתJoinNode(name="research_join")מיד אחרי ה-tuple ממתינה עד שכל הענפים הנכנסים מסתיימים ומעבירהdict({"activity_finder_agent": ..., "restaurant_finder_agent": ...}) ממוזג אחד בתורnode_inputאלitinerary_synthesizer_agentבמקום להפעיל סינתזה פעמיים.

הוספת מומחי המחקר
מוודאים שהשירות adk web הופסק (Ctrl + C), ואז פותחים את travel_planner/specialists.py:
cloudshell edit ~/adk-graph-agents/travel_planner/specialists.py
מוסיפים את activity_finder_agent ואת restaurant_finder_agent לחלק התחתון של travel_planner/specialists.py (אף אחד מהם לא צריך את output_key כי research_join מעביר את שני הפלטים ישירות דרך node_input):
# --- Specialist 3: The Activity Finder ---
activity_finder_agent = Agent(
model=MODEL,
name="activity_finder_agent",
description="Finds 3 attractions matching the user's destination and interests.",
instruction="""
Using the travel preferences in the input, call google_search to find 3 specific attractions
(including budget-friendly options).
Return a JSON list with keys: "attraction_name", "estimated_cost_local", "estimated_cost_usd", "notes".
""",
tools=[google_search],
)
# --- Specialist 4: The Restaurant Finder ---
restaurant_finder_agent = Agent(
model=MODEL,
name="restaurant_finder_agent",
description="Finds 3 restaurants matching the destination and budget.",
instruction="""
Using the travel preferences in the input, call google_search to find 3 highly-rated restaurants
across price points.
Return a JSON list with keys: "restaurant_name", "cuisine", "estimated_cost_local", "estimated_cost_usd".
""",
tools=[google_search],
)
הוספת fan-out ו-JoinNode אל workflows.py
פותחים את travel_planner/workflows.py:
cloudshell edit ~/adk-graph-agents/travel_planner/workflows.py
מחליפים את כל התוכן של travel_planner/workflows.py בתרשים של ה-fan-out ו-JoinNode:
from google.adk import Workflow
from google.adk.workflow import JoinNode
from .specialists import (
activity_finder_agent,
itinerary_synthesizer_agent,
restaurant_finder_agent,
user_profiler_agent,
)
research_join = JoinNode(name="research_join")
# 2. FAN-OUT / FAN-IN GRAPH: Profile -> (Activities || Restaurants) -> Join -> Synthesize
travel_workflow = Workflow(
name="travel_workflow",
description="Orchestrates the end-to-end travel planning process as a graph workflow.",
edges=[
(
"START",
user_profiler_agent,
(activity_finder_agent, restaurant_finder_agent),
research_join,
itinerary_synthesizer_agent,
),
],
)
🔍 בדיקת העבודה שלכם
מפעילים את adk web כדי לבדוק את החיפוש בו-זמנית ואת הסנכרון של JoinNode:
cd ~/adk-graph-agents
adk web --allow_origins "*"
פותחים את Web Preview ביציאה 8000, לוחצים על + New Session ושולחים:
Help me plan a trip to Kyoto focused on historic temples and ramen
בתצוגה אירועים, אמור להופיע רצף אירועים שדומה לזה:
1. user_profiler_agent -> emits JSON preferences via node_input
2. activity_finder_agent & restaurant_finder_agent -> invoke google_search concurrently
3. research_join -> merges both researcher outputs into one dict node_input
4. itinerary_synthesizer_agent -> drafts final_itinerary from the merged dict + {user_preferences}
כדי להמשיך, צריך ללחוץ על Ctrl + C בטרמינל כדי לעצור את adk web.
8. מחזורי בדיקה של מסלולים
כדי לאכוף את התקציב והאילוצים השליליים, מוסיפים itinerary_critic_agent, itinerary_refiner_agent ושני צומתי פונקציות דטרמיניסטיות של Python (route_critique ו-finalize_itinerary) שמחזירים אובייקטים של ADK Event:
-
route: בוחר איזה מפתח של הסתעפות בעלת שם ב-dict edge ({"revise": ..., "approved": ...}) יופעל בשלב הבא. -
output: מעביר ערך או מחרוזת של Python שהוקלדו לאורך הקצה בתורnode_inputלצומת הבא בלי ליצור הודעת צ'אט. -
messageו-state: הפונקציהmessageמפיקה טקסט שגלוי למשתמש בתמליל השיחה, והפונקציהstateמבצעת עדכונים של מפתח/ערך (stateDelta) במצב הסשן.

הוספת מומחי הביקורת והשיפור
מוודאים שהשירות adk web הופסק (Ctrl + C), ואז פותחים את travel_planner/specialists.py:
cloudshell edit ~/adk-graph-agents/travel_planner/specialists.py
מוסיפים את itinerary_critic_agent ו-itinerary_refiner_agent לתחתית של travel_planner/specialists.py (למזקק לא נדרש כלי google_search או exit_loop כי הוא מחליף פריטים שכבר נאספו ב-{final_itinerary} ופועל רק כש-route_critique בוחר ב-"revise"):
# --- Specialist 5: The Budget & Constraint Critic ---
itinerary_critic_agent = Agent(
model=MODEL,
name="itinerary_critic_agent",
description="Audits the itinerary draft against budget and negative constraints.",
instruction="""
Audit the itinerary in the input against User Preferences ({user_preferences}).
Verify that the USD total stays within the user's budget and no excluded venue types appear.
If all checks pass, respond EXACTLY with the single word "APPROVED".
Otherwise, output 1-2 concise revision instructions explaining what to swap or adjust.
""",
)
# --- Specialist 6: The Itinerary Refiner ---
itinerary_refiner_agent = Agent(
model=MODEL,
name="itinerary_refiner_agent",
description="Revises the itinerary draft using the critic's feedback.",
instruction="""
Revise Current Itinerary ({final_itinerary}) using the auditor critique in the input
so all USD budget and exclusion rules in {user_preferences} pass.
Output ONLY the updated Markdown itinerary.
""",
output_key="final_itinerary",
)
מוסיפים את route_critique ואת המחזור
פותחים את travel_planner/workflows.py:
cloudshell edit ~/adk-graph-agents/travel_planner/workflows.py
מחליפים את כל התוכן של travel_planner/workflows.py בתהליך העבודה המלא של התרשים:
from google.adk import Event, Workflow
from google.adk.workflow import JoinNode
from .specialists import (
activity_finder_agent, itinerary_critic_agent, itinerary_refiner_agent,
itinerary_synthesizer_agent, restaurant_finder_agent, user_profiler_agent,
)
MAX_REVISIONS = 2
research_join = JoinNode(name="research_join")
def route_critique(node_input: str, revision_count: int = 0):
"""Routes to 'approved' when constraints pass, or 'revise' up to MAX_REVISIONS."""
approved = node_input.strip().rstrip(".").upper() == "APPROVED"
if approved or revision_count >= MAX_REVISIONS:
return Event(route="approved", output=approved)
return Event(
route="revise", output=node_input, state={"revision_count": revision_count + 1}
)
def finalize_itinerary(node_input: bool, final_itinerary: str, revision_count: int = 0):
"""Emits the verified itinerary and resets revision_count for the next turn."""
status = (
f"Itinerary approved after {revision_count} revision(s)."
if node_input
else f"Max revisions ({revision_count}) reached; returning best-effort draft."
)
return Event(
message=f"{status}\n\n{final_itinerary}",
output=final_itinerary,
state={"revision_count": 0},
)
travel_workflow = Workflow(
name="travel_workflow",
description="Orchestrates the end-to-end travel planning process as a graph workflow.",
edges=[
(
"START",
user_profiler_agent,
(activity_finder_agent, restaurant_finder_agent),
research_join,
itinerary_synthesizer_agent,
itinerary_critic_agent,
route_critique,
),
(route_critique, {"revise": itinerary_refiner_agent, "approved": finalize_itinerary}),
(itinerary_refiner_agent, itinerary_critic_agent),
],
)
🔍 בדיקת העבודה שלכם
מוודאים ש-travel_planner/workflows.py עובר הידור (קומפילציה) בצורה נקייה ומדפיס את קצוות הגרף המכוון:
cd ~/adk-graph-agents && source .venv/bin/activate
python3 -c "from travel_planner.agent import root_agent; print('\n'.join(f'{e.from_node.name} -> {e.to_node.name} (route={e.route})' for e in root_agent.graph.edges))"
הפלט אמור להיראות כך:
__START__ -> user_profiler_agent (route=None) user_profiler_agent -> activity_finder_agent (route=None) user_profiler_agent -> restaurant_finder_agent (route=None) activity_finder_agent -> research_join (route=None) restaurant_finder_agent -> research_join (route=None) research_join -> itinerary_synthesizer_agent (route=None) itinerary_synthesizer_agent -> itinerary_critic_agent (route=None) itinerary_critic_agent -> route_critique (route=None) route_critique -> itinerary_refiner_agent (route=revise) route_critique -> finalize_itinerary (route=approved) itinerary_refiner_agent -> itinerary_critic_agent (route=None)
אחר כך, צריך להפעיל את adk web כדי לבדוק גם אישור מיידי וגם שינויים שמופעלים על ידי התקציב:
adk web --allow_origins "*"
פותחים את Web Preview ביציאה 8000, לוחצים על + New Session ושולחים את ההנחיה עם האילוצים המרובים לגבי קיוטו:
Design a full-day itinerary for Kyoto with a total budget of $100. My main interests are historical landmarks, temples, and authentic local cuisine. Please do not include any modern art museums or galleries.
כדי לראות את הלולאה של route="revise" בפעולה, שולחים הנחיה נוספת עם תקציב מצומצם של $15:
Now design a full-day Kyoto itinerary with paid temple admissions, lunch, and dinner on a strict total budget of $15 USD.
בתצוגה Events, אמור להופיע רצף ביצוע שדומה לזה:
1. user_profiler_agent -> writes JSON constraints to state["user_preferences"] 2. (activity_finder_agent, restaurant_finder_agent) -> run google_search concurrently -> research_join 3. itinerary_synthesizer_agent -> writes initial draft to state["final_itinerary"] 4. itinerary_critic_agent -> outputs "APPROVED" (or revision instructions when over budget) 5. route_critique -> emits route="approved" (skipping refiner) or route="revise" -> itinerary_refiner_agent -> itinerary_critic_agent 6. finalize_itinerary -> emits "Itinerary approved after N revision(s)." (or max-revisions notice) and resets revision_count=0
מקישים על Ctrl + C בטרמינל כדי לעצור את adk web.
9. פתרון בעיות
התפריט הנפתח של הנציג ריק ב-adk web
- הסיבה: הפעלתם את
adk webבתוךtravel_planner/במקום בספריית האם~/adk-graph-agents, או שהסשן ב-Cloud Shell הופעל מחדש. - תיקון: מקישים על
Ctrl + C, חוזרים לספריית האם ומתחילים מחדש עםcd ~/adk-graph-agents && source .venv/bin/activate && adk web --allow_origins "*".
שגיאה במודל 404 NOT_FOUND
- הסיבה: הקשתם על Enter כדי לאשר את אזור ברירת המחדל
us-central1במהלךadk createבמקום להקלידglobal. - תיקון: פותחים את
~/adk-graph-agents/travel_planner/.envומוודאים שהוגדרGOOGLE_CLOUD_LOCATION=global.
ERROR: [Errno 98] address already in use ביציאה 8000
- הסיבה: שרת
adk webקודם עדיין פועל ב-Cloud Shell. - תיקון: מקישים על
Ctrl + Cבטרמינל הפעיל או עוצרים את התהליך הקיים באמצעותpkill -f "adk web"לפני שמפעילים שוב אתadk web.
10. הסרת המשאבים
מסירים את סביבת העבודה המקומית, ואם רוצים, משביתים את ה-API או מוחקים פרויקט ייעודי לסדנה.
מחיקת קובצי הפרויקט המקומיים
מסירים את הספרייה ~/adk-graph-agents ואת הסביבה הווירטואלית:
cd ~
rm -rf ~/adk-graph-agents
השבתת Agent Platform API (אופציונלי)
משביתים את Agent Platform API אם לא צריכים אותו יותר בפרויקט הזה:
gcloud services disable aiplatform.googleapis.com --quiet
🔍 בדיקת העבודה שלכם
מוודאים ש-~/adk-graph-agents הוסר:
test ! -d ~/adk-graph-agents && echo "Workspace ~/adk-graph-agents removed"
הפלט אמור להיראות כך:
Workspace ~/adk-graph-agents removed
11. מזל טוב
יצרתם מתכנן נסיעות עם כמה סוכנים באמצעות ADK 2 Workflow, שמאחד שרשראות רציפות, פיצול בו-זמני google_search עם JoinNode ומחזורי maker-checker מותנים בתרשים קצה הצהרתי אחד.
מה השגתם
- הצהרה על צינור עיבוד נתונים מרובה סוכנים באמצעות ADK 2
Workflow(edges=[...]) - העברת נתונים ישירות בין צומתי פונקציות של
Agent,JoinNodeו-Python באמצעותnode_inputופרמטרים שקשורים למצב, תוך שמירה על מצב סשן מינימלי - התפצלו
google_searchענפים בו-זמנית וסונכרנו עםJoinNode - החלפנו את
LoopAgentואת ההסלמה של הלולאה שמבוססת על כלים בנתבEvent(route=...)דטרמיניסטי, שמדלג על קריאות מיותרות ל-LLM בטיוטות שאושרו
השלבים הבאים
- מערכות מרובות סוכנים ב-ADK
- הצטרפו לתוכנית GEAR (Gemini Enterprise Agent Ready) ולתוכנית ההסמכות כדי להשתתף בסדנאות מעשיות ובתוכניות לימודים.