Tworzenie agentów AI z użyciem pakietu ADK: koordynowanie przepływów pracy agentów

1. Przegląd

Spełnienie prośby o zaplanowanie podróży z uwzględnieniem wielu ograniczeń (np. opracowanie całodniowego planu podróży po Kioto za mniej niż 100 USD, skupionego na zabytkowych świątyniach i lokalnej kuchni, bez nowoczesnych galerii sztuki) wymaga wyodrębnienia ograniczeń, jednoczesnego wyszukiwania atrakcji i miejsc, gdzie można coś zjeść, opracowania szczegółowego harmonogramu i sprawdzenia ostatecznego planu. Poleganie na jednym monolitycznym agencie z wieloma narzędziami może prowadzić do pominięcia etapów weryfikacji lub naruszenia wykluczeń, dlatego orkiestracja koordynuje wyspecjalizowanych podagentów za pomocą deterministycznych kontrolerów przepływu pracy.

W tej trzeciej części serii Tworzenie agentów AI za pomocą ADK utworzysz samodzielny wieloagentowy planer podróży na platformie agentów, korzystając z kontrolerów przepływu pracy (SequentialAgent, ParallelAgent i LoopAgent) pakietu Agent Development Kit (ADK) 2. W 3 etapach (bez konieczności konfigurowania obszaru roboczego z części 1 lub 2) skoordynujesz 6 specjalistycznych agentów opartych na gemini-3.8-flash z udostępnionym stanem sesji (output_key), równoczesnym wykonywaniem google_search i iteracyjną pętlą ulepszania typu „maker-checker”.

Wymagania wstępne

Czego się nauczysz

  • jak utworzyć od podstaw projekt ADK 2 z wieloma agentami,
  • Jak zaprojektować zespół wyspecjalizowanych agentów, którzy współdzielą stan sesji za pomocą output_key
  • Jak używać SequentialAgent do wykonywania zadań przez subagenty w deterministycznym, szczegółowym potoku
  • Jak używać ParallelAgent do jednoczesnego uruchamiania niezależnych agentów badawczych w celu zmniejszenia opóźnienia
  • Jak używać eskalacji LoopAgent i ToolContext do wdrażania iteracyjnej pętli ulepszania z udziałem twórcy i weryfikatora
  • jak łączyć wzorce sekwencyjne, równoległe i pętli w hierarchiczny przepływ pracy z wieloma agentami;

Wymagania

  • konto Google (jeśli chcesz otrzymać punkty za warsztaty, użyj osobistego konta @gmail.com);
  • link do środków na warsztaty od instruktora (oraz aparat w telefonie do zeskanowania kodu QR) lub aktywne konto rozliczeniowe Cloud.
  • Google Chrome (zalecamy używanie okna incognito, aby uniknąć mieszania kont osobistych i służbowych).

2. Odbierz środki na Google Cloud (opcjonalnie)

Jeśli uczestniczysz w warsztatach z linkiem do środków na wydarzenie, odbierz środki w ramach programu Google Developer Program, aby utworzyć konto rozliczeniowe bez karty kredytowej.

Odbierz środki na wydarzenie

  1. Otwórz link do środków na warsztaty w oknie incognito i zaloguj się na konto @gmail.com.
  2. W sekcji Odbierz korzyści kliknij Odbierz środki:

Karta „Odbierz korzyści” w Google Builders Hub z przyciskiem „Odbierz środki”

  1. Jeśli pojawi się prośba o utworzenie profilu w programie Google Developer Program, wypełnij formularz.
  2. Gdy pojawi się komunikat Zeskanuj, aby potwierdzić, że jesteś człowiekiem, zeskanuj kod QR telefonem i dokończ weryfikację (jeśli kod QR się nie pojawi, odśwież stronę i ponownie kliknij Odbierz środki):

Okno kodu QR „Zeskanuj, aby potwierdzić, że jesteś człowiekiem” w programie Google Developer Program

  1. Sprawdź, czy pojawił się komunikat Udało Ci się odebrać środki na wydarzenie, a następnie kliknij Otwórz konto rozliczeniowe:

Google Builders Hub z informacją o odebraniu środków na wydarzenie i przyciskiem Otwórz konto rozliczeniowe

🔍 Sprawdź swoją pracę

Konfigurowanie konta rozliczeniowego zajmuje do 3 minut:

  1. Otwórz Rozliczenia usługi Google Cloud (lub skopiuj adres URL do okna incognito) i wybierz Twoje konta rozliczeniowe:
https://console.cloud.google.com/billing
  1. Odświeżaj stronę, dopóki konto GDP Credit nie będzie miało stanu Aktywne:

Zarządzanie kontem rozliczeniowym Google Cloud z aktywnym kontem rozliczeniowym środków Google Cloud

3. Tworzenie projektu Google Cloud (opcjonalnie)

Utwórz dedykowany projekt Google Cloud, aby wszystkie zasoby z tego ćwiczenia były odizolowane i łatwe do usunięcia.

  1. Otwórz stronę Utwórz projekt (lub skopiuj adres URL do okna incognito):
https://console.cloud.google.com/projectcreate
  1. Wpisz szczegóły projektu:
    • Nazwa projektu: na przykład google-cloud-workshop.
    • Konto rozliczeniowe (jeśli jest widoczne): wybierz GDP Credit (lub aktywne konto rozliczeniowe).
    • Zasób nadrzędny: Brak organizacji (lub Twoja organizacja, jeśli jest to wymagane)
  2. Zanotuj wygenerowany identyfikator projektu pod nazwą projektu, a następnie kliknij Utwórz:

Ekran tworzenia projektu Google Cloud z nazwą projektu, identyfikatorem projektu, zasobem nadrzędnym i przyciskiem Utwórz

🔍 Sprawdź swoją pracę

Na pasku narzędzi w prawym górnym rogu kliknij Powiadomienia, a po zakończeniu tworzenia projektu kliknij Wybierz projekt:

Menu Powiadomienia w konsoli Google Cloud z opcją Utwórz projekt i linkiem Wybierz projekt

4. Konfigurowanie środowiska

Skonfiguruj Google Cloud Shell, włącz interfejs Agent Platform API i utwórz odizolowane środowisko wirtualne Python 3.12 za pomocą uv.

Konfigurowanie Cloud Shell

  1. Kliknij Aktywuj Cloud Shell (>_) na pasku narzędzi konsoli Google Cloud lub otwórz Google Cloud Shell bezpośrednio (albo skopiuj adres URL do okna incognito):
https://shell.cloud.google.com/?show=ide,terminal

Przycisk Aktywuj Cloud Shell na pasku narzędzi konsoli Google Cloud

  1. Jeśli pojawi się prośba o autoryzację, kliknij Autoryzuj:

Okno dialogowe autoryzacji Cloud Shell

  1. Wybierz aktywny identyfikator projektu Google Cloud z menu numerycznego w terminalu:
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

Dane wyjściowe powinny być podobne do tych (projekty bez tagów zawierają też wiersz informacyjny [environment: untagged]):

1) google-cloud-workshop-4210
2) my-cloud-project-8812
Select your project (e.g. 1): 1
Updated property [core/project].

Sprawdź, czy wybrany identyfikator projektu jest podświetlony na żółto w promptu Cloud Shell:

Terminal Cloud Shell z wybranym identyfikatorem projektu zaznaczonym na żółto

Włącz wymagane interfejsy API

Włącz Agent Platform API, aby agenty ADK mogły wywoływać modele Gemini:

gcloud services enable aiplatform.googleapis.com

Dane wyjściowe powinny być podobne do tych:

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

Tworzenie środowiska wirtualnego Pythona i instalowanie pakietu ADK

Utwórz obszar roboczy ~/adk-agents i aktywuj środowisko wirtualne Pythona 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

Sprawdź, czy na początku promptu w terminalu pojawia się prefiks (.venv):

Terminal Cloud Shell z prefiksem .venv w aktywnym środowisku wirtualnym Pythona

Zainstaluj ADK 2 w aktywnym środowisku wirtualnym:

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

🔍 Sprawdź swoją pracę

Sprawdź zainstalowaną wersję interfejsu wiersza poleceń adk:

adk --version

Dane wyjściowe powinny być podobne do tych:

adk, version 2.14.0

5. Tworzenie szkieletu agenta do planowania podróży

Gdy środowisko jest gotowe, użyj wbudowanego polecenia adk create ADK, aby wygenerować pliki startowe pakietu agenta travel_planner.

Wygeneruj pakiet startowy

Uruchom adk create z katalogu ~/adk-agents:

cd ~/adk-agents
adk create travel_planner

Gdy pojawi się prośba w terminalu, wybierz te opcje konfiguracji (jeśli przy pierwszym uruchomieniu pojawi się prośba o Enable telemetry? [Y/n]:, naciśnij Enter lub wpisz n i naciśnij Enter):

  1. Wybierz model agenta głównego: wpisz 2, aby wybrać gemini-3.8-flash (opcja 1 wybiera gemini-3.5-flash), i naciśnij Enter.
  2. Wybierz backend: wpisz 2, aby wybrać backend Agent Platform Google Cloud (opcja 2 w menu interfejsu wiersza poleceń poniżej), i naciśnij Enter.
  3. Enter Google Cloud project ID (Wpisz identyfikator projektu Google Cloud): naciśnij Enter, aby potwierdzić identyfikator projektu podany w nawiasach.
  4. Enter Google Cloud region (Wpisz region Google Cloud): wpisz global i naciśnij Enter.

adk create zapisuje GOOGLE_GENAI_USE_ENTERPRISE=1, identyfikator projektu i GOOGLE_CLOUD_LOCATION=global w travel_planner/.env, dzięki czemu dane logowania pozostają skonfigurowane, gdy później zaktualizujesz agent.py.

🔍 Sprawdź swoją pracę

Dane wyjściowe powinny być podobne do tych:

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/)

Otwórz bieżący folder w edytorze kodu Cloud Shell, aby móc sprawdzać i edytować pliki obok terminala:

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

Testowanie domyślnego pojedynczego agenta

Zanim utworzysz przepływy pracy z wieloma agentami, uruchom interfejs programistyczny ADK, aby zobaczyć, jak domyślny pojedynczy agent odpowiada na ogólne zapytanie dotyczące planowania podróży:

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

Otwórz interfejs programistyczny w przeglądarce, korzystając z podglądu w przeglądarce w Cloud Shell:

  1. Kliknij ikonę Podgląd w przeglądarce na pasku narzędzi w prawym górnym rogu Cloud Shell.
  2. Wybierz Zmień port, wpisz 8000 i kliknij Zmień i wyświetl podgląd.

Okno konfiguracji portu podglądu Cloud Shell w przeglądarce ustawione na 8000

Po wczytaniu interfejsu internetowego ADK wyślij powitanie, np. "hello, what can you do?" lub "Help me plan a trip to Japan":

Interfejs internetowy ADK Development pokazujący podstawową rozmowę z jednym agentem

Zauważ, że pojedynczy model root_agent odpowiada bezpośrednio w jednym przebiegu bez wyodrębniania ustrukturyzowanych preferencji, wyszukiwania w internecie na żywo czy weryfikacji budżetu.

Po zakończeniu testowania naciśnij Ctrl + C w terminalu Cloud Shell, aby zatrzymać serwer adk web i wrócić do znaku zachęty.

6. Tworzenie przepływu pracy SequentialAgent

Teraz utworzysz swój pierwszy wzorzec orkiestracji: liniowy przepływ pracy oparty na SequentialAgent. W potoku sekwencyjnym subagenty są wykonywane w ścisłej kolejności. Pierwszy specjalista wyodrębnia ustrukturyzowane parametry i zapisuje je w udostępnionym stanie sesji za pomocą output_key="user_preferences", a drugi specjalista odczytuje {user_preferences} z udostępnionego stanu, aby przygotować plan podróży.

Schemat architektury przedstawiający agenta root_agent przekazującego zadania agentowi master_travel_agent (SequentialAgent), który uruchamia agenta user_profiler_agent, a następnie agenta itinerary_synthesizer_agent za pomocą udostępnionego stanu sesji

Tworzenie początkowych specjalistów (specialists.py)

Otwórz nowy plik o nazwie specialists.py w katalogu travel_planner/:

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

Wklej ten kod do pliku travel_planner/specialists.py, aby zdefiniować user_profiler_agent i itinerary_synthesizer_agent (importując ToolContext i google_search na potrzeby kolejnych kroków):

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",
)

Połączenie potoku sekwencyjnego (workflows.py)

Utwórz nowy plik o nazwie workflows.py w katalogu travel_planner/, aby zarządzać specjalistami:

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

Dodaj do pliku travel_planner/workflows.py tę definicję SequentialAgent:

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
    ],
)

Połącz przepływ pracy z: root_agent (agent.py)

Teraz zarejestruj master_travel_agent jako subagenta root_agent. Otwórz travel_planner/agent.py:

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

Zamień zawartość pliku travel_planner/agent.py na taki kod:

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],
)

🔍 Sprawdź swoją pracę

Uruchom interfejs internetowy ADK z terminala:

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

Otwórz podgląd w przeglądarce na porcie 8000 i wpisz prompta:

Help me plan a trip to Kyoto

W widoku Zdarzenia powinny pojawić się dane wyjściowe podobne do tego przepływu wykonywania:

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

Interfejs internetowy ADK 2.14.0 pokazujący wykres wykonywania od root_agent przez master_travel_agent do user_profiler_agent i itinerary_synthesizer_agent wraz z wygenerowanym planem podróży do Kioto

Kliknij dowolną plakietkę zdarzenia (lub element State: final_itinerary) i przejdź na kartę Stan w panelu inspektora po lewej stronie, aby sprawdzić, czy w stanie sesji są wypełnione pola user_preferences i final_itinerary.

Po zakończeniu sprawdzania logu czasu naciśnij Ctrl + C w terminalu, aby zatrzymać adk web.

7. Przeprowadzanie badań za pomocą ParallelAgent

Chociaż sekwencyjny przepływ pracy wyraźnie oddziela wyodrębnianie preferencji od tworzenia planu podróży, jego rekomendacje nadal opierają się wyłącznie na statycznej wiedzy treningowej modelu. Możesz oprzeć plan podróży na aktualnych danych z internetu, dodając 2 dedykowanych badaczy korzystających z wbudowanego narzędzia google_search:

  • activity_finder_agent: znajduje 3 konkretne atrakcje pasujące do miejsca docelowego i zainteresowań użytkownika, wraz z szacunkowymi cenami biletów.
  • restaurant_finder_agent: znajduje 3 wysoko oceniane lokalne restauracje i podaje szacowany koszt na osobę.

Ponieważ wyszukiwanie atrakcji i restauracji nie zależy od siebie, wykonywanie tych czynności jedna po drugiej jest stratą czasu. Zamiast tego umieścisz obu badaczy w elemencie ParallelAgent (parallel_research_agent), aby ADK wykonywał oba przepływy pracy wyszukiwarki Google jednocześnie i wypełniał zmienne {activity_recommendations?} i {restaurant_recommendations?} przed przekazaniem ich do itinerary_synthesizer_agent.

Schemat architektury przedstawiający agenta master_travel_agent, który uruchamia agenta user_profiler_agent na etapie 1, agenta parallel_research_agent (ParallelAgent z agentami activity_finder_agent i restaurant_finder_agent) na etapie 2 oraz agenta itinerary_synthesizer_agent na etapie 3

Dołącz specjalistów ds. badań równoległych do: specialists.py

Otwórz travel_planner/specialists.py:

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

Dodaj tych 2 specjalistów ds. wyszukiwarki Google na dole pliku travel_planner/specialists.py (tuż pod 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",
)

Włóż ParallelAgent do workflows.py

Otwórz travel_planner/workflows.py:

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

Zaktualizuj travel_planner/workflows.py, aby zdefiniować parallel_research_agent za pomocą ParallelAgent, i umieść go między user_profiler_agent a 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
    ],
)

🔍 Sprawdź swoją pracę

Uruchom ponownie adk web, aby przetestować równoległy potok badań:

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

W interfejsie podglądu w przeglądarce wyślij prompta:

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

W widoku Zdarzenia powinny pojawić się dane wyjściowe podobne do tej sekwencji:

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. Widok logów czasu oczekiwania: kliknij Logi czasu oczekiwania u góry panelu rozmowy (obok Zdarzeń) i sprawdź swoją turę. W sekcji parallel_research_agent zobaczysz nakładające się przedziały czasu dla activity_finder_agent i restaurant_finder_agent, co oznacza, że całkowity czas oczekiwania na wyniki wyszukiwania w internecie jest prawie o połowę krótszy niż w przypadku sekwencyjnego wykonywania tych operacji.
  2. Karta Stan: kliknij kartę Stan w lewym panelu inspektora, aby sprawdzić słownik sesji na żywo (user_preferences, activity_recommendations, restaurant_recommendations i final_itinerary).

Po zakończeniu testowania naciśnij Ctrl + C w terminalu, aby zatrzymać adk web.

8. Udoskonalanie wersji roboczych dzięki LoopAgent

Nawet w przypadku wyników wyszukiwania na żywo początkowa wersja robocza wygenerowana przez itinerary_synthesizer_agent może przekroczyć łączny budżet użytkownika lub przypadkowo uwzględnić wykluczoną kategorię (np. galerię sztuki nowoczesnej, mimo że użytkownik o nią nie prosił).

Aby zagwarantować zgodność z ograniczeniami, na końcu potoku dodasz pętlę ulepszania z weryfikacją, używając LoopAgent:

  1. itinerary_critic_agent (The Checker): przeprowadza audyt {final_itinerary} pod kątem {user_preferences}. Sumuje szacowane koszty, sprawdza każde ograniczenie negatywne i albo zapisuje konkretne instrukcje dotyczące wersji w pliku critique_feedback, albo odpowiada dokładną frazą "APPROVED".
  2. itinerary_refiner_agent (The Maker / Exiter): Reads {critique_feedback}. Jeśli krytyka jest równa "APPROVED", wywołuje narzędzie exit_loop (tool_context.actions.escalate = True), aby natychmiast przerwać działanie LoopAgent. W przeciwnym razie poprawia {final_itinerary}, aby rozwiązać zgłoszone problemy, i zastępuje final_itinerary w następnym przebiegu.

Schemat architektury przedstawiający agenta master_travel_agent z agentem refinement_loop_agent (LoopAgent) na etapie 4, który przełącza się między agentami itinerary_critic_agent i itinerary_refiner_agent, dopóki nie zostanie wywołany agent exit_loop

Dołącz exit_loop, krytyka i ulepszacza do specialists.py

Otwórz travel_planner/specialists.py:

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

Dołącz narzędzie exit_loop (ToolContext), itinerary_critic_agent i itinerary_refiner_agent na dole pliku 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",
)

Dodaj listę odbiorców LoopAgent do kampanii workflows.py

Otwórz travel_planner/workflows.py:

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

Zaktualizuj travel_planner/workflows.py, aby opakować itinerary_critic_agent i itinerary_refiner_agent w LoopAgent (max_iterations=3) i dołączyć jako czwarty etap 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
    ],
)

🔍 Sprawdź swoją pracę

Uruchom adk web, aby przetestować cały przepływ pracy z wieloma agentami:

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

Otwórz interfejs podglądu w przeglądarce na porcie 8000, rozpocznij nową sesję i przetestuj cały system za pomocą tego prompta z wieloma ograniczeniami dotyczącego Kioto:

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.

W widoku Zdarzenia i logach terminala powinny pojawić się dane wyjściowe podobne do tej sekwencji wykonywania:

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. Widok zdarzeń: kliknij dowolny element zdarzenia z itinerary_critic_agent lub itinerary_refiner_agent, aby sprawdzić jego ładunek na karcie Informacje po lewej stronie. Gdy itinerary_refiner_agent wywołuje exit_loop, sprawdź zdarzenie, aby zobaczyć actions.escalate: true – sygnał, który informuje LoopAgent, że należy zatrzymać iterację przed osiągnięciem max_iterations=3.
  2. Karta State (Stan): kliknij kartę State (Stan), aby obserwować, jak state['critique_feedback'] i state['final_itinerary'] aktualizują się w kolejnych przejściach. Jeśli początkowa wersja robocza przekroczyła $100 USD, critique_feedback zawiera instrukcje dotyczące wersji audytora w pierwszym przebiegu, zanim final_itinerary zostanie zaktualizowany o tańsze alternatywy, a critique_feedback zmieni się na "APPROVED" w drugim przebiegu.

Po zakończeniu testowania naciśnij Ctrl + C w terminalu, aby zatrzymać adk web.

9. Czyszczenie danych

Usuwanie lokalnych plików projektu

Aby usunąć katalog projektu adk-agents i środowisko wirtualne z folderu domowego Cloud Shell, uruchom:

cd ~
rm -rf ~/adk-agents

Wyłączanie interfejsu Agent Platform API

Jeśli nie potrzebujesz już interfejsu Agent Platform API włączonego w projekcie, wyłącz go za pomocą polecenia gcloud:

gcloud services disable aiplatform.googleapis.com --quiet

Usuwanie całego projektu w chmurze Google (opcjonalnie)

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

🔍 Sprawdź swoją pracę

Potwierdź, że usunięto ~/adk-agents:

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

Dane wyjściowe powinny być podobne do tych:

Workspace ~/adk-agents removed

10. Gratulacje

Gratulacje! Udało Ci się utworzyć hierarchiczny system wieloagentowy za pomocą pakietu Google Agent Development Kit (ADK), który koordynuje zespół 6 wyspecjalizowanych agentów w ramach sekwencyjnych, równoległych i iteracyjnych przepływów pracy w pętli.

osiągnięcia,

  • Ustrukturyzowana komunikacja między agentami za pomocą udostępnionego stanu sesji (wstrzykiwanie szablonów output_key i {state_variable})
  • Utworzono deterministyczny potok krok po kroku za pomocą SequentialAgent
  • Uruchomiono niezależne agenty badawcze wyszukiwarki Google jednocześnie przy użyciu ParallelAgent
  • Wdrożono automatyczną pętlę weryfikacji typu „maker-checker” przy użyciu LoopAgent i tool_context.actions.escalate = True

Dalsze kroki