Cómo crear agentes de IA con ADK: Organiza flujos de trabajo de agentes

1. Descripción general

Para cumplir con una solicitud de viaje con múltiples restricciones (como diseñar un itinerario de un día completo en Kioto por menos de USD 100 centrado en templos históricos y gastronomía local, sin galerías de arte moderno), se deben extraer las restricciones, investigar las atracciones y los restaurantes de forma simultánea, armar un programa detallado y auditar el plan final. Confiar en un solo agente monolítico con muchas herramientas puede omitir pasos de verificación o infringir exclusiones, por lo que la organización coordina subagentes especializados a través de controladores de flujo de trabajo determinísticos.

En esta tercera parte de la serie Crea agentes de IA con ADK, crearás un planificador de viajes multiagente independiente en Agent Platform con los controladores de flujo de trabajo de Kit de desarrollo de agentes (ADK) 2 (SequentialAgent, ParallelAgent y LoopAgent). En tres etapas progresivas (sin necesidad de configurar el espacio de trabajo de la parte 1 o 2), coordinarás seis agentes especializados con la tecnología de gemini-3.8-flash con un estado de sesión compartido (output_key), ejecución simultánea de google_search y un bucle de perfeccionamiento iterativo de creador-verificador.

Requisitos previos

Qué aprenderá

  • Cómo crear un proyecto de ADK 2 multiagente desde cero
  • Cómo diseñar un equipo de agentes especializados que compartan el estado de la sesión con output_key
  • Cómo usar SequentialAgent para ejecutar agentes secundarios en una canalización determinística paso a paso
  • Cómo usar ParallelAgent para ejecutar agentes de investigación independientes de forma simultánea y reducir la latencia
  • Cómo usar el escalamiento de LoopAgent y ToolContext para implementar un bucle de perfeccionamiento iterativo de creador-verificador
  • Cómo combinar patrones secuenciales, paralelos y de bucle en un flujo de trabajo jerárquico de varios agentes

Requisitos

  • Una Cuenta de Google (usa una cuenta personal de @gmail.com si reclamas créditos del taller)
  • Un vínculo de crédito para el taller que te haya proporcionado el instructor (además de la cámara de un teléfono para escanear el código QR) o una cuenta de Facturación de Cloud activa
  • Google Chrome (se recomienda usar una ventana de incógnito para evitar mezclar cuentas personales y laborales)

2. Reclama créditos de Google Cloud (opcional)

Si asistes a un taller con un vínculo de crédito para el evento, reclama tu crédito de Google Developer Program para aprovisionar una cuenta de facturación sin tarjeta de crédito.

Reclama tu crédito para el evento

  1. Abre el vínculo de crédito del taller en una ventana de incógnito y accede con tu cuenta de @gmail.com.
  2. En Reclama tu beneficio, haz clic en Reclamar crédito:

Tarjeta Reclama tu beneficio de Google Builders Hub que muestra el botón Reclamar crédito

  1. Si se te solicita que crees un perfil del Programa para desarrolladores de Google, completa el formulario.
  2. Cuando aparezca Escanea para verificar que eres una persona, escanea el código QR con tu teléfono y completa la verificación (actualiza la página y vuelve a hacer clic en Reclamar crédito si no aparece el código QR):

Diálogo del código QR de Escanea para verificar que eres una persona de Google Developer Program

  1. Confirma que aparezca el mensaje Successfully claimed your event credit! y, luego, haz clic en Open Billing Account:

Google Builders Hub mostrando el mensaje Successfully claimed your event credit y el botón Open Billing Account

🔍 Revisa tu trabajo

La configuración de la cuenta de facturación tarda hasta 3 minutos:

  1. Abre la Facturación de Google Cloud (o copia la URL en tu ventana de incógnito) y selecciona Tus cuentas de facturación:
https://console.cloud.google.com/billing
  1. Actualiza hasta que tu cuenta de GDP Credit muestre el estado Activa:

Administración de la cuenta de Facturación de Google Cloud que muestra una cuenta de facturación de crédito de GDP activa

3. Crea un proyecto de Google Cloud (opcional)

Crea un proyecto de Google Cloud dedicado para que todos los recursos de este codelab permanezcan aislados y sean fáciles de limpiar.

  1. Abre Crear un proyecto (o copia la URL en tu ventana de incógnito):
https://console.cloud.google.com/projectcreate
  1. Ingresa los detalles de tu proyecto:
    • Nombre del proyecto: Por ejemplo, google-cloud-workshop
    • Cuenta de facturación (si se muestra): Selecciona GDP Credit (o tu cuenta de facturación activa).
    • Recurso superior: Sin organización (o tu organización si es necesario)
  2. Anota el ID del proyecto generado que aparece debajo del nombre del proyecto y, luego, haz clic en Crear:

Pantalla de creación de un proyecto de Google Cloud en la que se muestra el nombre del proyecto, el ID del proyecto, el recurso superior y el botón Crear

🔍 Revisa tu trabajo

Haz clic en Notificaciones en la barra de herramientas de la esquina superior derecha y, luego, en Seleccionar proyecto una vez que finalice la creación del proyecto:

Menú Notificaciones de la consola de Google Cloud que muestra Crear proyecto y el vínculo Seleccionar proyecto

4. Configura tu entorno

Configurar Google Cloud Shell, habilitar la API de Agent Platform y crear un entorno virtual aislado de Python 3.12 con uv

Configura Cloud Shell

  1. Haz clic en Activar Cloud Shell (>_) en la barra de herramientas de la consola de Google Cloud o abre Google Cloud Shell directamente (o copia la URL en tu ventana de incógnito):
https://shell.cloud.google.com/?show=ide,terminal

Botón Activar Cloud Shell en la barra de herramientas de la consola de Google Cloud

  1. Haz clic en Autorizar cuando se te solicite:

Cuadro de diálogo Autorizar Cloud Shell

  1. Selecciona el ID del proyecto de Google Cloud activo en el menú numerado de la terminal:
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

Deberías ver un resultado similar al siguiente (los proyectos sin etiquetas también imprimen una línea informativa [environment: untagged]):

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

Verifica que el ID del proyecto que seleccionaste aparezca destacado en amarillo en el mensaje de Cloud Shell:

Terminal de Cloud Shell que muestra el ID del proyecto seleccionado destacado en amarillo

Habilita las APIs obligatorias

Habilita la API de Agent Platform para que tus agentes de ADK puedan invocar modelos de Gemini:

gcloud services enable aiplatform.googleapis.com

Deberías ver un resultado similar a este:

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

Crea un entorno virtual de Python e instala el ADK

Crea el espacio de trabajo de ~/adk-agents y activa un entorno virtual de 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

Confirma que el prefijo (.venv) aparezca al principio del mensaje de la terminal:

Terminal de Cloud Shell que muestra el prefijo .venv en un entorno virtual de Python activo

Instala el ADK 2 dentro del entorno virtual activo:

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

🔍 Revisa tu trabajo

Verifica la versión instalada de la CLI de adk:

adk --version

Deberías ver un resultado similar a este:

adk, version 2.14.0

5. Crea la estructura del agente de planificación de viajes

Con tu entorno listo, usa el comando adk create integrado del ADK para generar los archivos de inicio de tu paquete de agente de travel_planner.

Genera el paquete de inicio

Ejecuta adk create desde tu directorio ~/adk-agents:

cd ~/adk-agents
adk create travel_planner

Cuando se te solicite en la terminal, selecciona las siguientes opciones de configuración (si se te solicita Enable telemetry? [Y/n]: en la primera ejecución, presiona Intro o escribe n y presiona Intro):

  1. Elige un modelo para el agente raíz: Escribe 2 para seleccionar gemini-3.8-flash (la opción 1 selecciona gemini-3.5-flash) y presiona Intro.
  2. Elige un backend: Escribe 2 para seleccionar el backend de Agent Platform de Google Cloud (opción 2 en el menú de la CLI que aparece a continuación) y presiona Intro.
  3. Ingresa el ID del proyecto de Google Cloud: Confirma el ID del proyecto que se muestra entre corchetes presionando Intro.
  4. Ingresa la región de Google Cloud: Escribe global y presiona Intro.

adk create escribe GOOGLE_GENAI_USE_ENTERPRISE=1, el ID del proyecto y GOOGLE_CLOUD_LOCATION=global en travel_planner/.env, por lo que tus credenciales permanecen configuradas cuando actualizas agent.py más adelante.

🔍 Revisa tu trabajo

Deberías ver un resultado similar a este:

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

Abre la carpeta actual en el editor de código de Cloud Shell para que puedas inspeccionar y editar archivos junto con la terminal:

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

Prueba el agente único predeterminado

Antes de crear flujos de trabajo multiagente, inicia la IU de desarrollo del ADK para observar cómo responde el agente único predeterminado a una consulta amplia de planificación de viajes:

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

Abre la IU de desarrollo en tu navegador con la vista previa en la Web de Cloud Shell:

  1. Haz clic en el ícono de Vista previa en la Web en la barra de herramientas de la esquina superior derecha de Cloud Shell.
  2. Selecciona Cambiar puerto, ingresa 8000 y haz clic en Cambiar y obtener vista previa.

Diálogo de configuración del puerto de la vista previa en la Web de Cloud Shell establecido en 8000

Una vez que se cargue la IU web del ADK, envía un saludo, como "hello, what can you do?" o "Help me plan a trip to Japan":

IU web de desarrollo del ADK que muestra una conversación básica con un solo agente

Observa que el root_agent único responde directamente en una sola pasada sin extracción estructurada de preferencias, investigación web en vivo ni verificación de presupuesto.

Cuando termines de realizar la prueba, presiona Ctrl + C en la terminal de Cloud Shell para detener el servidor de adk web y volver al símbolo del sistema.

6. Crea un flujo de trabajo de SequentialAgent

Ahora, crearás tu primer patrón de organización: un flujo de trabajo lineal con la tecnología de SequentialAgent. En una canalización secuencial, los agentes secundarios se ejecutan en un orden estricto. El primer especialista extrae los parámetros estructurados y los guarda en el estado de la sesión compartida con output_key="user_preferences", y el segundo especialista lee {user_preferences} del estado compartido para redactar el itinerario.

Diagrama de arquitectura que muestra root_agent delegando en master_travel_agent (SequentialAgent), que ejecuta user_profiler_agent seguido de itinerary_synthesizer_agent a través del estado de sesión compartido

Crea los especialistas iniciales (specialists.py)

Abre un archivo nuevo llamado specialists.py dentro de travel_planner/:

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

Pega el siguiente código en travel_planner/specialists.py para definir user_profiler_agent y itinerary_synthesizer_agent (importando ToolContext y google_search por adelantado para los próximos pasos):

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

Conecta la canalización secuencial (workflows.py)

Crea un archivo nuevo llamado workflows.py dentro de travel_planner/ para organizar a los especialistas:

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

Agrega la siguiente definición de SequentialAgent a 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
    ],
)

Conecta el flujo de trabajo a root_agent (agent.py)

Ahora, registra master_travel_agent como un subagente de root_agent. Abre travel_planner/agent.py:

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

Reemplaza el contenido de travel_planner/agent.py con el código que se muestra a continuación:

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

🔍 Revisa tu trabajo

Inicia la IU web del ADK desde la terminal:

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

Abre la vista previa web en el puerto 8000 y, luego, ingresa la instrucción:

Help me plan a trip to Kyoto

Deberías ver un resultado similar al siguiente flujo de ejecución en la vista Events:

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

IU web de ADK 2.14.0 que muestra el gráfico de ejecución desde root_agent a través de master_travel_agent hasta user_profiler_agent y itinerary_synthesizer_agent junto con el itinerario de Kioto generado

Haz clic en cualquier insignia de evento (o en el chip State: final_itinerary) y cambia a la pestaña State en el panel del inspector de la izquierda para confirmar que user_preferences y final_itinerary se propaguen en el estado de la sesión.

Cuando termines de inspeccionar el seguimiento, presiona Ctrl + C en la terminal para detener adk web.

7. Ejecuta investigaciones con ParallelAgent

Si bien el flujo de trabajo secuencial separa claramente la extracción de preferencias de la redacción del itinerario, sus recomendaciones aún se basan únicamente en el conocimiento de entrenamiento estático del modelo. Puedes fundamentar el itinerario en datos web en tiempo real agregando dos investigadores dedicados con la tecnología de la herramienta integrada de google_search:

  • activity_finder_agent: Busca 3 atracciones específicas que coincidan con el destino y los intereses del usuario, junto con los precios estimados de las entradas.
  • restaurant_finder_agent: Encuentra 3 restaurantes locales con calificaciones altas y su costo estimado por persona.

Como la investigación de atracciones y la de restaurantes no dependen una de la otra, ejecutarlas una después de la otra es una pérdida de tiempo. En su lugar, unirás ambos investigadores dentro de un ParallelAgent (parallel_research_agent) para que el ADK ejecute ambos flujos de trabajo de la Búsqueda de Google de forma simultánea y complete {activity_recommendations?} y {restaurant_recommendations?} antes de pasar a itinerary_synthesizer_agent.

Diagrama de arquitectura que muestra master_travel_agent ejecutando user_profiler_agent en la etapa 1, parallel_research_agent (ParallelAgent con activity_finder_agent y restaurant_finder_agent) en la etapa 2, y itinerary_synthesizer_agent en la etapa 3

Agrega los especialistas en investigación paralela a specialists.py

Abre travel_planner/specialists.py:

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

Agrega los siguientes dos especialistas en la Búsqueda de Google al final de travel_planner/specialists.py (justo debajo de 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",
)

Inserta ParallelAgent en workflows.py

Abre travel_planner/workflows.py:

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

Actualiza travel_planner/workflows.py para definir parallel_research_agent con ParallelAgent y colócalo entre user_profiler_agent y 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
    ],
)

🔍 Revisa tu trabajo

Vuelve a iniciar adk web para probar la canalización de investigación paralela:

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

En la IU de vista previa web, envía la instrucción:

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

Deberías ver un resultado similar a la siguiente secuencia en la vista Eventos:

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. Vista de seguimientos: Haz clic en Seguimientos en la parte superior del panel de conversación (junto a Eventos) y, luego, inspecciona tu turno. Verás intervalos de tiempo superpuestos para activity_finder_agent y restaurant_finder_agent en parallel_research_agent, lo que reduce la latencia total de la investigación web casi a la mitad en comparación con la ejecución secuencial.
  2. Pestaña State: Haz clic en la pestaña State en el panel izquierdo del inspector para inspeccionar el diccionario de la sesión en vivo (user_preferences, activity_recommendations, restaurant_recommendations y final_itinerary).

Cuando termines de realizar la prueba, presiona Ctrl + C en la terminal para detener adk web.

8. Mejora los borradores con LoopAgent

Incluso con los resultados de la búsqueda en vivo, el borrador inicial que produce itinerary_synthesizer_agent podría superar el presupuesto total del usuario o incluir accidentalmente una categoría excluida (como una galería de arte moderno cuando el usuario pidió que no se incluyera ninguna).

Para garantizar el cumplimiento de las restricciones, agregarás un bucle de perfeccionamiento de creador-verificador al final de la canalización con LoopAgent:

  1. itinerary_critic_agent (The Checker): Audita {final_itinerary} en comparación con {user_preferences}. Suma los costos estimados, verifica cada restricción negativa y escribe instrucciones de revisión específicas en critique_feedback o responde con la frase exacta "APPROVED".
  2. itinerary_refiner_agent (The Maker / Exiter): Lee {critique_feedback}. Si la crítica es igual a "APPROVED", invoca la herramienta exit_loop (tool_context.actions.escalate = True) para salir del LoopAgent de inmediato. De lo contrario, revisa {final_itinerary} para corregir los problemas marcados y reemplaza final_itinerary para el siguiente pase.

Diagrama de arquitectura que muestra master_travel_agent con refinement_loop_agent (LoopAgent) de la etapa 4 que alterna entre itinerary_critic_agent y itinerary_refiner_agent hasta que se llama a exit_loop

Agrega exit_loop, Critic y Refiner a specialists.py

Abre travel_planner/specialists.py:

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

Agrega la herramienta exit_loop (ToolContext), itinerary_critic_agent y itinerary_refiner_agent a la parte inferior de 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",
)

Se agregó LoopAgent a workflows.py.

Abre travel_planner/workflows.py:

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

Actualiza travel_planner/workflows.py para unir itinerary_critic_agent y itinerary_refiner_agent en un LoopAgent (max_iterations=3) y agrégalo como la cuarta etapa de 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
    ],
)

🔍 Revisa tu trabajo

Inicia adk web para probar el flujo de trabajo multiagente completo:

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

Abre la IU de la vista previa en la Web en el puerto 8000, inicia una nueva sesión y prueba el sistema completo con esta instrucción de varias restricciones sobre 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.

Deberías ver un resultado similar a la siguiente secuencia de ejecución en la vista Events y los registros de la terminal:

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. Vista de eventos: Haz clic en cualquier chip de evento de itinerary_critic_agent o itinerary_refiner_agent para inspeccionar su carga útil en la pestaña Info de la izquierda. Cuando itinerary_refiner_agent invoque exit_loop, inspecciona el evento para ver actions.escalate: true, la señal que le indica a LoopAgent que detenga la iteración antes de llegar a max_iterations=3.
  2. Pestaña State: Haz clic en la pestaña State para ver cómo se actualizan state['critique_feedback'] y state['final_itinerary'] en los pases. Si el borrador inicial superó el valor de $100 USD, critique_feedback contiene las instrucciones de revisión del auditor en el pase 1 antes de que final_itinerary se actualice con alternativas de menor costo y critique_feedback cambie a "APPROVED" en el pase 2.

Cuando termines de realizar la prueba, presiona Ctrl + C en la terminal para detener adk web.

9. Limpia

Borra los archivos del proyecto local

Para quitar el directorio del proyecto adk-agents y el entorno virtual de tu carpeta principal de Cloud Shell, ejecuta lo siguiente:

cd ~
rm -rf ~/adk-agents

Inhabilita la API de Agent Platform

Si ya no necesitas tener habilitada la API de Agent Platform en tu proyecto, inhabilítala con gcloud:

gcloud services disable aiplatform.googleapis.com --quiet

Borra todo el proyecto de Google Cloud (opcional)

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

🔍 Revisa tu trabajo

Confirma que se haya quitado ~/adk-agents:

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

Deberías ver un resultado similar a este:

Workspace ~/adk-agents removed

10. Felicitaciones

¡Felicitaciones! Creaste un sistema multiagente jerárquico con el Kit de desarrollo de agentes (ADK) de Google que coordina un equipo de seis agentes especializados en flujos de trabajo secuenciales, paralelos y de bucle iterativo.

Qué lograste

  • Comunicación estructurada entre agentes a través del estado de sesión compartido (inyección de plantillas output_key y {state_variable})
  • Se creó una canalización determinística paso a paso con SequentialAgent.
  • Ejecutó agentes de investigación independientes de la Búsqueda de Google de forma simultánea con ParallelAgent
  • Implementar un bucle de verificación automatizado de creador-verificador con LoopAgent y tool_context.actions.escalate = True

Próximos pasos