ساختن «عامل‌های هوشواره» با ADK: هماهنگ‌سازی گردش کار عامل

۱. نمای کلی

برآورده کردن درخواست سفر با محدودیت‌های متعدد (مانند طراحی برنامه سفر یک‌روزه به کیوتو با بودجه کمتر از ۱۰۰ دلار با تمرکز بر معابد تاریخی و غذاهای محلی و بدون گالری‌های هنر مدرن) مستلزم استخراج محدودیت‌ها، تحقیق هم‌زمان درباره جاذبه‌ها و غذاخوری‌ها، تنظیم برنامه زمان‌بندی تفکیک‌شده، و بازرسی طرح نهایی است. تکیه بر یک عامل یکپارچه با ابزارهای متعدد می‌تواند مراحل درستی‌سنجی را نادیده بگیرد یا موارد استثنا را نقض کند، بنابراین سازمان‌دهی عوامل فرعی تخصصی را ازطریق کنترل‌کننده‌های گردش کار قطعی هماهنگ می‌کند.

در این بخش سوم از مجموعه ساختن عامل‌های هوشواره‌ای با ADK، یک برنامه‌ریز سفر چندعاملی مستقل در Agent Platform بااستفاده از کنترل‌کننده‌های گردش کار Agent Development Kit (ADK) 2 (SequentialAgent، ParallelAgent، و LoopAgent) می‌سازید. در سه مرحله پیش‌رونده (بدون نیاز به راه‌اندازی فضای کاری بخش ۱ یا بخش ۲)، شش عامل متخصص با پشتیبانی gemini-3.8-flash را با وضعیت جلسه مشترک (output_key)، اجرای هم‌زمان google_search، و یک حلقه پالایش سازنده-بررسی‌کننده تکراری هماهنگ می‌کنید.

پیش‌نیازها

آنچه می‌آموزید

  • نحوه داربست‌بندی پروژه ADK 2 چندعاملی از صفر
  • نحوه طراحی تیمی از عامل‌های تخصصی که بااستفاده از output_key وضعیت جلسه را هم‌رسانی می‌کنند
  • نحوه استفاده از SequentialAgent برای اجرای زیرعامل‌ها در خط لوله گام‌به‌گام قطعی
  • نحوه استفاده از ParallelAgent برای اجرای هم‌زمان عامل‌های پژوهش مستقل برای تأخیر کمتر
  • نحوه استفاده از ارجاع LoopAgent و ToolContext برای پیاده‌سازی حلقه پالایش تکراری سازنده-بررسی‌کننده
  • نحوه ترکیب کردن الگوهای متوالی، موازی، و حلقه‌ای در گردش کار چندعاملی سلسله‌مراتبی

آنچه نیاز دارید

  • حساب Google (اگر اعتبار کارگاه را مطالبه می‌کنید، از حساب شخصی @gmail.com استفاده کنید)
  • پیوند اعتبار کارگاه از مربی (به‌علاوه دوربین تلفن برای اسکن کردن رمزینه پاسخ‌سریع) یا حساب Cloud Billing فعال
  • Google Chrome (توصیه می‌شود از پنجره «ناشناس» استفاده کنید تا حساب‌های شخصی و کاری باهم تداخل پیدا نکنند)

۲. مطالبه کردن اعتبارهای Google Cloud (اختیاری)

اگر در کارگاهی با پیوند اعتبار رویداد شرکت می‌کنید، اعتبار Google Developer Program خود را مطالبه کنید تا حساب صورت‌حساب را بدون کارت اعتباری تأمین کنید.

اعتبار رویدادتان را مطالبه کنید

  1. پیوند اعتبار کارگاه را در پنجره ناشناس باز کنید و با حساب @gmail.com خود به سیستم وارد شوید.
  2. در مطالبه مزایا، روی مطالبه اعتبار کلیک کنید:

کارت «مطالبه مزایا» در Google Builders Hub که دکمه «مطالبه اعتبار» را نشان می‌دهد

  1. اگر از شما خواسته شد نمایه Google Developer Program ایجاد کنید، فرم را تکمیل کنید.
  2. وقتی اسکن برای درستی‌سنجی انسان بودن ظاهر شد، رمزینه پاسخ‌سریع را با تلفنتان اسکن کنید و درستی‌سنجی را تکمیل کنید (اگر رمزینه پاسخ‌سریع ظاهر نشد، صفحه را بازآورید و دوباره روی مطالبه اعتبار کلیک کنید):

کادر گفتگوی رمزینه پاسخ‌سریع «برای درستی‌سنجی انسان بودن خود، اسکن کنید» در Google Developer Program

  1. مطمئن شوید اعتبار رویداد شما باموفقیت مطالبه شد! نشان داده شود، سپس روی باز کردن حساب صورت‌حساب کلیک کنید:

Google Builders Hub که «اعتبار رویداد باموفقیت مطالبه شد» و دکمه «باز کردن حساب صورت‌حساب» را نشان می‌دهد

🔍 بررسی کردن کارتان

راه‌اندازی حساب صورت‌حساب تا ۳ دقیقه طول می‌کشد:

  1. Google Cloud Billing را باز کنید (یا نشانی وب را در پنجره «ناشناس» کپی کنید) و حساب‌های صورت‌حساب خود را انتخاب کنید:
https://console.cloud.google.com/billing
  1. بازآوری کنید تا حساب GDP Credit شما وضعیت فعال را نشان دهد:

مدیریت حساب «صورت‌حساب Google Cloud» که حساب صورت‌حساب «اعتبار GDP» فعال را نشان می‌دهد

۳. ایجاد پروژه Google Cloud (اختیاری)

یک پروژه Google Cloud اختصاصی ایجاد کنید تا همه منابع این codelab مجزا بمانند و به‌راحتی پاک شوند.

  1. ایجاد پروژه را باز کنید (یا نشانی وب را در پنجره «ناشناس» کپی کنید):
https://console.cloud.google.com/projectcreate
  1. جزئیات پروژه را وارد کنید:
    • نام پروژه: برای مثال، google-cloud-workshop
    • حساب صورت‌حساب (اگر نشان داده شده است): GDP Credit (یا حساب صورت‌حساب فعال خود) را انتخاب کنید
    • منبع ولی: بدون سازمان (یا سازمان شما درصورت نیاز)
  2. شناسه پروژه تولیدشده را در زیر نام پروژه یادداشت کنید، سپس روی ایجاد کلیک کنید:

صفحه «ایجاد پروژه Google Cloud» که «نام پروژه»، «شناسه پروژه»، «منبع والد»، و دکمه «ایجاد» را نشان می‌دهد

🔍 بررسی کردن کارتان

روی اعلان‌ها در نوار ابزار بالا سمت چپ کلیک کنید و پس‌از اتمام ایجاد پروژه، روی انتخاب پروژه کلیک کنید:

منو اعلان‌های کنسول Google Cloud که «ایجاد پروژه» و پیوند «انتخاب پروژه» را نشان می‌دهد

۴. راه‌اندازی محیط

Google Cloud Shell را پیکربندی کنید، Agent Platform API را فعال کنید، و محیط مجازی Python 3.12 مجزایی با uv ایجاد کنید.

پیکربندی Cloud Shell

  1. روی فعال کردن Cloud Shell (>_) در نوارابزار کنسول Google Cloud کلیک کنید، یا Google Cloud Shell را مستقیماً باز کنید (یا نشانی وب را در پنجره «ناشناس» خود کپی کنید):
https://shell.cloud.google.com/?show=ide,terminal

دکمه «فعال کردن Cloud Shell» در نوارابزار کنسول Google Cloud

  1. درصورت درخواست، روی مجاز کردن کلیک کنید:

کادر گفتگوی «مجاز کردن Cloud Shell»

  1. شناسه پروژه فعال 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 با رنگ زرد برجسته شده باشد:

پایانه Cloud Shell که «شناسه پروژه» انتخاب‌شده را با رنگ زرد برجسته کرده است

فعال کردن میاناهای برنامه‌سازی کاربردی لازم

Agent Platform API را فعال کنید تا عامل‌های ADK شما بتوانند مدل‌های Gemini را فراخوانی کنند:

gcloud services enable aiplatform.googleapis.com

باید بروندادی مشابه زیر ببینید:

Operation "operations/acat.p2-..." finished successfully.

ایجاد کردن محیط مجازی Python و نصب ADK

فضای کاری ~/adk-agents را ایجاد کنید و محیط مجازی Python 3.12 را فعال کنید:

cd ~
mkdir -p adk-agents && cd ~/adk-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) در ابتدای پیام‌واره پایانه شما ظاهر می‌شود:

ترمینال Cloud Shell که پیشوند .venv را در محیط مجازی فعال Python نشان می‌دهد

‫ADK 2 را در محیط مجازی فعال نصب کنید:

uv pip install --no-cache "google-adk==2.14.0"

🔍 بررسی کردن کارتان

نسخه adk CLI نصب‌شده را درستی‌سنجی کنید:

adk --version

باید بروندادی مشابه زیر ببینید:

adk, version 2.14.0

۵. داربست‌بندی عامل برنامه‌ریز سفر

وقتی محیط آماده شد، از فرمان adk create داخلی ADK برای تولید فایل‌های آغازگر برای بسته عامل travel_planner استفاده کنید.

تولید بسته آغازگر

adk create را از دایرکتوری ~/adk-agents اجرا کنید:

cd ~/adk-agents
adk create travel_planner

وقتی در پایانه از شما خواسته شد، گزینه‌های پیکربندی زیر را انتخاب کنید (اگر در اولین اجرا از شما خواسته شد Enable telemetry? [Y/n]: را وارد کنید، کلید ورود را فشار دهید یا n را تایپ کنید و کلید ورود را فشار دهید):

  1. مدلی برای عامل ریشه انتخاب کنید: 2 را تایپ کنید تا gemini-3.8-flash را انتخاب کنید (گزینه 1 gemini-3.5-flash را انتخاب می‌کند) و Enter را فشار دهید.
  2. انتخاب پس‌رانه: 2 را تایپ کنید تا پس‌رانه Agent Platform در Google Cloud را انتخاب کنید (گزینه 2 در منو CLI زیر) و Enter را فشار دهید.
  3. وارد کردن شناسه پروژه Google Cloud: «شناسه پروژه» خود را که در کروشه نشان داده شده است با فشار دادن کلید Enter تأیید کنید.
  4. منطقه Google Cloud را وارد کنید: global را تایپ کنید و کلید 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-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/)

پوشه فعلی را در ویرایشگر کد Cloud Shell باز کنید تا بتوانید فایل‌ها را در کنار ترمینال خود بررسی و ویرایش کنید:

which cloudshell >/dev/null 2>&1 && cloudshell workspace ~/adk-agents || true
cd ~/adk-agents
source .venv/bin/activate

آزمایش کردن عامل تکی پیش‌فرض

قبل‌از ساختن گردش‌های کاری چندعاملی، «میانای کاربر توسعه ADK» را راه‌اندازی کنید تا ببینید عامل تکی پیش‌فرض چگونه به پُرسمان گسترده برنامه‌ریزی سفر پاسخ می‌دهد:

cd ~/adk-agents
adk web --allow_origins "*"

بااستفاده از پیش‌نمایش وب Cloud Shell، «رابط کاربری توسعه» را در مرورگرتان باز کنید:

  1. روی نماد پیش‌نمایش وب در نوار ابزار بالا سمت چپ Cloud Shell کلیک کنید.
  2. تغییر درگاه را انتخاب کنید، 8000 را وارد کنید، و روی تغییر و پیش‌نمایش کلیک کنید.

کادر گفتگوی پیکربندی درگاه «پیش‌نمایش وب Cloud Shell» روی ۸۰۰۰ تنظیم شده است

وقتی ADK Web UI بار شد، سلامی مثل "hello, what can you do?" یا "Help me plan a trip to Japan" بفرستید:

میانای کاربری وب توسعه ADK که مکالمه تک‌عاملی پایه را نشان می‌دهد

توجه داشته باشید که root_agent تکی مستقیماً در یک مرحله بدون استخراج اولویت ساختاریافته، پژوهش وب زنده، یا درستی‌سنجی بودجه پاسخ می‌دهد.

وقتی آزمایش تمام شد، Ctrl + C را در پایانه Cloud Shell فشار دهید تا سرور adk web متوقف شود و به پیام‌واره فرمان برگردید.

‫۶. ساختن گردش کار SequentialAgent

اکنون اولین الگوی هماهنگ‌سازی خود را خواهید ساخت: یک گردش کار خطی که توسط SequentialAgent پشتیبانی می‌شود. در خط لوله متوالی، زیرنماینده‌ها به‌ترتیب دقیق اجرا می‌شوند. کارشناس اول پارامترهای ساختاریافته را استخراج می‌کند و آن‌ها را بااستفاده از output_key="user_preferences" در وضعیت جلسه هم‌رسانی‌شده ذخیره می‌کند، و کارشناس دوم {user_preferences} را از وضعیت هم‌رسانی‌شده می‌خواند تا پیش‌نویس برنامه سفر را تهیه کند.

نمودار معماری که نشان می‌دهد root_agent به master_travel_agent (SequentialAgent) واگذار می‌کند، که user_profiler_agent را اجرا می‌کند و سپس itinerary_synthesizer_agent را ازطریق وضعیت جلسه مشترک اجرا می‌کند

ایجاد متخصصان اولیه (specialists.py)

فایل جدیدی با نام specialists.py در travel_planner/ باز کنید:

cloudshell edit ~/adk-agents/travel_planner/specialists.py

کد زیر را در travel_planner/specialists.py جای‌گذاری کنید تا user_profiler_agent و itinerary_synthesizer_agent را تعریف کنید (ToolContext و google_search را برای مراحل بعدی ازقبل وارد کنید):

from google.adk import Agent
from google.adk.tools import ToolContext, google_search

# --- Specialist 1: The User Profiler ---
user_profiler_agent = Agent(
    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",  # Saves output to state['user_preferences']
)

# --- Specialist 2: The Synthesizer ---
itinerary_synthesizer_agent = Agent(
    name="itinerary_synthesizer_agent",
    description="Compiles preferences and research into a final Markdown itinerary.",
    instruction="""
        You are an elite Travel Concierge. Write a Markdown itinerary with an itemized USD and local currency cost breakdown using:
        - User Preferences: {user_preferences}
        - Activities (if available): {activity_recommendations?}
        - Restaurants (if available): {restaurant_recommendations?}
    """,
    output_key="final_itinerary",
)

سیم‌کشی خط لوله متوالی (workflows.py)

فایل جدیدی با نام workflows.py در travel_planner/ ایجاد کنید تا متخصصان را هماهنگ کنید:

cloudshell edit ~/adk-agents/travel_planner/workflows.py

این تعریف SequentialAgent به travel_planner/workflows.py اضافه شود:

from google.adk.agents import SequentialAgent
from .specialists import (
    user_profiler_agent,
    itinerary_synthesizer_agent,
)

# 1. SEQUENTIAL PHASE: A linear two-step workflow
master_travel_agent = SequentialAgent(
    name="master_travel_agent",
    description="Orchestrates the end-to-end travel planning process for trip and itinerary requests.",
    sub_agents=[
        user_profiler_agent,         # Step 1: Extract constraints into user_preferences
        itinerary_synthesizer_agent,  # Step 2: Draft itinerary from user_preferences
    ],
)

متصل کردن گردش کار به root_agent (agent.py)

اکنون master_travel_agent را به‌عنوان نماینده فرعی root_agent ثبت کنید. باز کردن travel_planner/agent.py:

cloudshell edit ~/adk-agents/travel_planner/agent.py

محتویات travel_planner/agent.py را با کد زیر جایگزین کنید:

from google.adk import Agent
from .workflows import master_travel_agent

MODEL = "gemini-3.8-flash"

root_agent = Agent(
    model=MODEL,
    name="root_agent",
    description="A helpful assistant for user questions.",
    instruction=(
        "Greet the user and delegate any travel or trip planning requests "
        "to master_travel_agent."
    ),
    sub_agents=[master_travel_agent],
)

🔍 بررسی کردن کارتان

رابط کاربری وب ADK را از پایانه خود شروع کنید:

cd ~/adk-agents
adk web --allow_origins "*"

«پیش‌نمایش وب» را در درگاه 8000 باز کنید و پیام‌واره را وارد کنید:

Help me plan a trip to Kyoto

باید بروندادی مشابه با جریان اجرای زیر در نمای رویدادها ببینید:

1. root_agent -> calls transfer_to_agent(agent_name="master_travel_agent")
2. user_profiler_agent -> outputs JSON {"destination": "Kyoto", "duration": "1 day", ...} to state['user_preferences']
3. itinerary_synthesizer_agent -> reads {user_preferences} and outputs the formatted Markdown itinerary

رابط کاربری وب ADK 2.14.0 که نمودار اجرا را از root_agent ازطریق master_travel_agent به user_profiler_agent و itinerary_synthesizer_agent درکنار برنامه سفر تولیدشده کیوتو نشان می‌دهد

روی هر نشان رویداد (یا تراشه State: final_itinerary) کلیک کنید و به برگه وضعیت در پانل بازرس سمت راست بروید تا مطمئن شوید که user_preferences و final_itinerary هر دو در وضعیت جلسه پر شده‌اند.

وقتی بازرسی ردیابی تمام شد، Ctrl + C را در پایانه فشار دهید تا adk web متوقف شود.

‫۷. اجرای پژوهش با ParallelAgent

اگرچه گردش کار متوالی به‌طور واضح استخراج اولویت‌ها را از پیش‌نویس برنامه سفر جدا می‌کند، توصیه‌های آن همچنان صرفاً به دانش آموزشی ایستا مدل متکی است. می‌توانید با افزودن دو پژوهشگر اختصاصی که از ابزار داخلی google_search بهره می‌برند، برنامه سفر را براساس داده‌های زنده وب پایه‌ریزی کنید:

  • activity_finder_agent: سه جاذبه خاص را که با مقصد و علایق کاربر مطابقت دارد، به‌همراه قیمت تخمینی بلیت پیدا می‌کند.
  • ‫restaurant_finder_agent: ۳ رستوران محلی با رتبه‌بندی بالا و هزینه تخمینی برای هر نفر را پیدا می‌کند.

چون تحقیق درباره جاذبه‌ها و تحقیق درباره رستوران‌ها به یکدیگر وابسته نیستند، اجرای آن‌ها یکی پس‌از دیگری باعث اتلاف وقت می‌شود. درعوض، هر دو پژوهشگر را در یک ParallelAgent (parallel_research_agent) قرار می‌دهید تا ADK هر دو گردش کار «جستجوی Google» را به‌طور هم‌زمان اجرا کند و {activity_recommendations?} و {restaurant_recommendations?} را قبل‌از واگذاری به itinerary_synthesizer_agent پر کند.

نمودار معماری که master_travel_agent را درحال اجرای user_profiler_agent در مرحله ۱، parallel_research_agent (ParallelAgent با activity_finder_agent و restaurant_finder_agent) در مرحله ۲، و itinerary_synthesizer_agent در مرحله ۳ نشان می‌دهد

افزودن متخصصان پژوهش موازی به specialists.py

باز کردن travel_planner/specialists.py:

cloudshell edit ~/adk-agents/travel_planner/specialists.py

دو متخصص «جستجوی Google» زیر را به پایین travel_planner/specialists.py (درست زیر itinerary_synthesizer_agent) اضافه کنید:

# --- Specialist 3: The Activity Finder ---
activity_finder_agent = Agent(
    name="activity_finder_agent",
    description="Finds 3 attractions matching the user's destination and interests.",
    instruction="""
        Based on {user_preferences}, use 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],
    output_key="activity_recommendations",
)

# --- Specialist 4: The Restaurant Finder ---
restaurant_finder_agent = Agent(
    name="restaurant_finder_agent",
    description="Finds 3 restaurants matching the destination and budget.",
    instruction="""
        Based on {user_preferences}, use 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],
    output_key="restaurant_recommendations",
)

ParallelAgent را در workflows.py درج کن

باز کردن travel_planner/workflows.py:

cloudshell edit ~/adk-agents/travel_planner/workflows.py

‫travel_planner/workflows.py را به‌روز کنید تا parallel_research_agent را بااستفاده از ParallelAgent تعریف کنید و آن را بین user_profiler_agent و itinerary_synthesizer_agent قرار دهید:

from google.adk.agents import ParallelAgent, SequentialAgent
from .specialists import (
    activity_finder_agent,
    itinerary_synthesizer_agent,
    restaurant_finder_agent,
    user_profiler_agent,
)

# Parallel branch: Run activity and restaurant research simultaneously
parallel_research_agent = ParallelAgent(
    name="parallel_research_agent",
    description="Runs activity and restaurant research concurrently.",
    sub_agents=[
        activity_finder_agent,
        restaurant_finder_agent,
    ],
)

# Master pipeline: Profile -> Parallel Research -> Synthesize
master_travel_agent = SequentialAgent(
    name="master_travel_agent",
    description="Orchestrates the end-to-end travel planning process for trip and itinerary requests.",
    sub_agents=[
        user_profiler_agent,          # Step 1: Extract constraints
        parallel_research_agent,      # Step 2: Research activities & restaurants in parallel
        itinerary_synthesizer_agent,  # Step 3: Synthesize into an itinerary
    ],
)

🔍 بررسی کردن کارتان

adk web را دوباره راه‌اندازی کنید تا خط لوله پژوهش موازی را آزمایش کنید:

cd ~/adk-agents
adk web --allow_origins "*"

در میانای کاربری «پیش‌نمایش وب»، پیام‌واره زیر را ارسال کنید:

Help me plan a trip to Kyoto focused on historic temples and ramen

باید خروجی مشابه با توالی زیر را در نمای رویدادها ببینید:

1. user_profiler_agent -> writes state['user_preferences']
2. parallel_research_agent -> fans out concurrently:
   - activity_finder_agent invokes google_search -> writes state['activity_recommendations']
   - restaurant_finder_agent invokes google_search -> writes state['restaurant_recommendations']
3. itinerary_synthesizer_agent -> merges all three state keys into state['final_itinerary']
  1. نمای ردگیری‌ها: روی ردگیری‌ها در بالای قاب مکالمه (کنار رویدادها) کلیک کنید و نوبت خود را بررسی کنید. بازه زمانی هم‌پوشانی‌شده‌ای را برای activity_finder_agent و restaurant_finder_agent در parallel_research_agent خواهید دید که تأخیر کل پژوهش وب را درمقایسه با اجرای متوالی آن‌ها تقریباً به نصف کاهش می‌دهد.
  2. برگه State (وضعیت): روی برگه State (وضعیت) در پانل بازرس سمت راست کلیک کنید تا واژه‌نامه جلسه زنده (user_preferences، activity_recommendations، restaurant_recommendations، و final_itinerary) را بازرسی کنید.

وقتی آزمایش تمام شد، Ctrl + C را در پایانه فشار دهید تا adk web متوقف شود.

‫۸. پالایش کردن پیش‌نویس‌ها با LoopAgent

حتی با نتایج جستجوی زنده، پیش‌نویس اولیه‌ای که itinerary_synthesizer_agent تولید می‌کند ممکن است از کل بودجه کاربر فراتر رود یا به‌طور تصادفی شامل دسته‌ای شود که کاربر آن را مستثنی کرده است (مثلاً گالری هنر مدرن، درحالی‌که کاربر خواسته است چنین گالری‌ای در نتایج نباشد).

برای تضمین رعایت محدودیت، بااستفاده از LoopAgent یک حلقه پالایش سازنده-بررسی‌کننده به انتهای خط لوله اضافه خواهید کرد:

  1. ‫itinerary_critic_agent (بررسی‌کننده): {final_itinerary} را درمقابل {user_preferences} ممیزی می‌کند. این عامل هزینه‌های تخمینی را جمع می‌زند، هر محدودیت منفی را بررسی می‌کند، و یا دستورالعمل‌های بازبینی خاصی را برای critique_feedback می‌نویسد یا با عبارت دقیق "APPROVED" پاسخ می‌دهد.
  2. itinerary_refiner_agent (سازنده / خارج‌شونده): {critique_feedback} را می‌خواند. اگر نقد برابر با "APPROVED" باشد، ابزار exit_loop (tool_context.actions.escalate = True) را فراخوانی می‌کند تا فوراً از LoopAgent خارج شود. درغیراین‌صورت، {final_itinerary} را برای رفع مشکلات پرچم‌گذاری‌شده بازبینی می‌کند و final_itinerary را برای مرحله بعدی بازنویسی می‌کند.

نمودار معماری که master_travel_agent را با Stage 4 refinement_loop_agent (LoopAgent)‎ نشان می‌دهد که بین itinerary_critic_agent و itinerary_refiner_agent می‌چرخد تا زمانی که exit_loop فراخوانی شود

افزودن exit_loop، «منتقد»، و «پالایشگر» به specialists.py

باز کردن travel_planner/specialists.py:

cloudshell edit ~/adk-agents/travel_planner/specialists.py

ابزار exit_loop (ToolContext)، itinerary_critic_agent، و itinerary_refiner_agent را به پایین travel_planner/specialists.py اضافه کنید:

def exit_loop(tool_context: ToolContext) -> dict:
    """Call ONLY when the critique is APPROVED to exit the refinement loop."""
    print(f"[Tool Call] exit_loop triggered by {tool_context.agent_name}")
    tool_context.actions.escalate = True
    return {"status": "approved", "message": "Itinerary approved. Exiting refinement loop."}


# --- Specialist 5: The Budget & Constraint Critic (Inside LoopAgent) ---
itinerary_critic_agent = Agent(
    name="itinerary_critic_agent",
    include_contents="none",
    description="Audits the itinerary draft against budget and negative constraints.",
    instruction="""
        Audit Current Itinerary ({final_itinerary}) 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.
    """,
    output_key="critique_feedback",
)

# --- Specialist 6: The Itinerary Refiner / Exiter (Inside LoopAgent) ---
itinerary_refiner_agent = Agent(
    name="itinerary_refiner_agent",
    include_contents="none",
    description="Refines the itinerary from critique feedback, or calls exit_loop when APPROVED.",
    instruction="""
        Review Auditor Critique ({critique_feedback}) for Current Itinerary ({final_itinerary}).
        If the critique is EXACTLY "APPROVED", call `exit_loop` immediately and return the itinerary unchanged.
        Otherwise, revise the draft using {activity_recommendations} and {restaurant_recommendations}
        so all USD budget and exclusion rules pass, and output ONLY the updated Markdown itinerary.
    """,
    tools=[exit_loop],
    output_key="final_itinerary",
)

افزودن LoopAgent به workflows.py

باز کردن travel_planner/workflows.py:

cloudshell edit ~/adk-agents/travel_planner/workflows.py

‫travel_planner/workflows.py را به‌روز کنید تا itinerary_critic_agent و itinerary_refiner_agent را در LoopAgent (max_iterations=3) قرار دهد و آن را به‌عنوان مرحله چهارم master_travel_agent اضافه کند:

from google.adk.agents import LoopAgent, ParallelAgent, SequentialAgent
from .specialists import (
    activity_finder_agent,
    itinerary_critic_agent,
    itinerary_refiner_agent,
    itinerary_synthesizer_agent,
    restaurant_finder_agent,
    user_profiler_agent,
)

# Stage 2: Parallel research branch
parallel_research_agent = ParallelAgent(
    name="parallel_research_agent",
    description="Runs activity and restaurant research concurrently.",
    sub_agents=[
        activity_finder_agent,
        restaurant_finder_agent,
    ],
)

# Stage 4: Iterative Maker-Checker refinement loop
refinement_loop_agent = LoopAgent(
    name="refinement_loop_agent",
    description="Iteratively audits and refines the itinerary until constraints and budget are approved.",
    sub_agents=[
        itinerary_critic_agent,
        itinerary_refiner_agent,
    ],
    max_iterations=3,
)

# Master pipeline: Profile -> Parallel Research -> Synthesize -> Refinement Loop
master_travel_agent = SequentialAgent(
    name="master_travel_agent",
    description="Orchestrates the end-to-end travel planning process for trip and itinerary requests.",
    sub_agents=[
        user_profiler_agent,          # Stage 1: Extract constraints
        parallel_research_agent,      # Stage 2: Research activities & restaurants in parallel
        itinerary_synthesizer_agent,  # Stage 3: Draft initial itinerary
        refinement_loop_agent,        # Stage 4: Audit and refine until approved
    ],
)

🔍 بررسی کردن کارتان

برای آزمایش گردش کار کامل چندعاملی، adk web را شروع کنید:

cd ~/adk-agents
adk web --allow_origins "*"

رابط کاربری «پیش‌نمایش وب» را در درگاه 8000 باز کنید، جلسه جدیدی شروع کنید، و کل سیستم را با این پیام‌واره چندمحدودیتی کیوتو آزمایش کنید:

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.

باید خروجی مشابه با توالی اجرای زیر را در نمای رویدادها و گزارش‌های پایانه ببینید:

1. user_profiler_agent -> writes JSON with destination="Kyoto", budget="$100", exclusions=["modern art museums", "galleries"]
2. parallel_research_agent -> runs activity_finder_agent and restaurant_finder_agent in parallel
3. itinerary_synthesizer_agent -> produces initial draft in state['final_itinerary']
4. refinement_loop_agent:
   - itinerary_critic_agent -> audits USD budget and exclusions -> outputs "APPROVED" (or revision notes)
   - itinerary_refiner_agent -> triggers [Tool Call] exit_loop triggered by itinerary_refiner_agent and outputs the approved itinerary
  1. نمای رویدادها: روی هر تراشه رویداد از itinerary_critic_agent یا itinerary_refiner_agent کلیک کنید تا بار مفید آن را در برگه اطلاعات سمت راست بررسی کنید. وقتی itinerary_refiner_agent exit_loop را فراخوانی می‌کند، رویداد را بررسی کنید تا actions.escalate: true را ببینید - سیگنالی که به LoopAgent می‌گوید قبل‌از رسیدن به max_iterations=3 تکرار را متوقف کند.
  2. زبانه State (وضعیت): روی زبانه State (وضعیت) کلیک کنید تا state['critique_feedback'] و state['final_itinerary'] را در مجوزها تماشا کنید. اگر پیش‌نویس اولیه از $100 USD فراتر رفت، critique_feedback دستورالعمل‌های بازبینی حسابرس را در مرحله ۱ نگه می‌دارد، سپس final_itinerary با گزینه‌های کم‌هزینه‌تر به‌روزرسانی می‌شود و critique_feedback در مرحله ۲ به "APPROVED" تغییر می‌کند.

وقتی آزمایش تمام شد، Ctrl + C را در پایانه فشار دهید تا adk web متوقف شود.

‫۹. مرتب‌سازی

حذف کردن فایل‌های پروژه محلی

برای برداشتن دایرکتوری پروژه adk-agents و محیط مجازی از پوشه اصلی Cloud Shell، این دستور را اجرا کنید:

cd ~
rm -rf ~/adk-agents

غیرفعال کردن Agent Platform API

اگر دیگر به Agent Platform API فعال‌شده در پروژه‌تان نیاز ندارید، آن را با gcloud غیرفعال کنید:

gcloud services disable aiplatform.googleapis.com --quiet

حذف کل پروژه Google Cloud (اختیاری)

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

🔍 بررسی کردن کارتان

تأیید کنید که ~/adk-agents برداشته شده است:

test ! -d ~/adk-agents && echo "Workspace ~/adk-agents removed"

باید بروندادی مشابه زیر ببینید:

Workspace ~/adk-agents removed

‫۱۰. تبریک می‌گوییم

تبریک! شما یک سیستم چندعاملی سلسله‌مراتبی با Google Agent Development Kit (ADK) ساخته‌اید که تیمی متشکل از شش عامل تخصصی را در گردش‌های کاری متوالی، موازی، و حلقه‌ای تکرارشونده هماهنگ می‌کند.

آنچه انجام داده‌اید

  • ارتباط ساختاریافته بین‌عاملی ازطریق حالت جلسه مشترک (تزریق الگو output_key و {state_variable})
  • ساخت خط لوله گام‌به‌گام قطعی بااستفاده از SequentialAgent
  • اجرای هم‌زمان عامل‌های پژوهشی مستقل «جستجوی Google» بااستفاده از ParallelAgent
  • حلقه درستی‌سنجی سازنده-بررسی‌کننده خودکارشده را بااستفاده از LoopAgent و tool_context.actions.escalate = True پیاده‌سازی کرد

مراحل بعدی