Cómo crear un sistema multiagente

1. Introducción

Descripción general

En este lab, irás más allá de los chatbots simples y crearás un sistema multiagente distribuido.

Si bien un solo LLM puede responder preguntas, la complejidad del mundo real a menudo requiere roles especializados. No le pides a tu ingeniero de backend que diseñe la IU, y no le pides a tu diseñador que optimice las consultas de la base de datos. Del mismo modo, podemos crear agentes de IA especializados que se enfoquen en una tarea y se coordinen entre sí para resolver problemas complejos.

Compilarás un sistema de creación de cursos que constará de los siguientes elementos:

  1. Agente de investigación: Usa google_search para encontrar información actualizada.
  2. Agente de evaluación: Critica la investigación en cuanto a calidad y completitud.
  3. Agente de Content Builder: Convierte la investigación en un curso estructurado.
  4. Agente organizador: Administra el flujo de trabajo y la comunicación entre estos especialistas.

Requisitos previos

  • Conocimientos básicos de Python
  • Conocimientos sobre la consola de Google Cloud

Actividades

  • Define un agente que usa herramientas (researcher) que puede buscar en la Web.
  • Implementa un resultado estructurado con Pydantic para judge.
  • Conéctate a agentes remotos con el protocolo Agent-to-Agent (A2A).
  • Construye un LoopAgent para crear un ciclo de retroalimentación entre el investigador y el evaluador.
  • Ejecuta el sistema distribuido de forma local con el ADK.
  • Implementa el sistema multiagente en Google Cloud Run.

Principios de arquitectura y organización

Antes de escribir código, comprendamos cómo trabajan juntos estos agentes. Estamos creando una canalización de creación de cursos.

El diseño del sistema

Diagrama de arquitectura

Organización con agentes

Los agentes estándar (como el Investigador) funcionan. Los agentes orquestadores (como LoopAgent o SequentialAgent) administran otros agentes. No tienen sus propias herramientas; su "herramienta" es la delegación.

  1. LoopAgent: Actúa como un bucle while en el código. Ejecuta una secuencia de agentes de forma repetida hasta que se cumple una condición (o se alcanza la cantidad máxima de iteraciones). Usamos esta información para la Investigación con Loop:
    • El investigador encuentra información.
    • El juez la critica.
    • Si Judge dice "Fail", EscalationChecker permite que continúe el bucle.
    • Si Judge dice "Pass", EscalationChecker interrumpe el bucle.
  2. SequentialAgent: Actúa como una ejecución de secuencia de comandos estándar. Ejecuta los agentes uno tras otro. Usamos esto para la canalización de alto nivel:
    • Primero, ejecuta el Circuito de investigación (hasta que finalice con datos adecuados).
    • Luego, ejecuta Content Builder (para escribir el curso).

Si combinamos estos elementos, creamos un sistema sólido que puede autocorregirse antes de generar el resultado final.

2. Configuración

Configuración del entorno

Abre Cloud Shell: Abre una pestaña nueva y escribe shell.cloud.google.com.

Obtén el código de partida

  1. Clona el repositorio de inicio en tu directorio principal:
    cd ~
    git clone https://github.com/amitkmaraj/prai-roadshow-lab-1-starter.git
    cd prai-roadshow-lab-1-starter
    
  2. Ejecuta la secuencia de comandos init para asociar los créditos de la rampa de acceso con la facturación.
    chmod +x ./init.sh
    ./init.sh
    
  3. Abre esta carpeta en tu editor.

Habilita las APIs

Ahora que tienes un proyecto nuevo, ejecuta el siguiente comando para habilitar los servicios de Google Cloud necesarios:

gcloud services enable \
    run.googleapis.com \
    artifactregistry.googleapis.com \
    cloudbuild.googleapis.com \
    aiplatform.googleapis.com \
    compute.googleapis.com

Esto podría demorar unos segundos.

Instala las dependencias

Usamos uv para administrar dependencias rápidamente.

  1. Instala las dependencias del proyecto:
    # Ensure you have uv installed: pip install uv
    uv sync
    
  2. Establece el ID de tu proyecto de Google Cloud.
    • Sugerencia: Puedes encontrar el ID del proyecto en el panel de la consola de Cloud o ejecutando gcloud config get-value project.
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    
  3. Configura las variables de entorno restantes:
    export GOOGLE_CLOUD_LOCATION=us-central1
    export GOOGLE_GENAI_USE_VERTEXAI=true
    
    Advertencia: Las variables de entorno no persisten en las nuevas sesiones de la terminal. Si abres una nueva pestaña de la terminal, debes volver a ejecutar estos comandos de exportación.

3. 🕵️ El agente de investigación

Agente de investigador

El Investigador es un especialista. Su único trabajo es encontrar información. Para ello, necesita acceder a una herramienta: la Búsqueda de Google.

¿Por qué separar al investigador?

Análisis detallado: ¿Por qué no tener un solo agente que haga todo?

Los agentes pequeños y enfocados son más fáciles de evaluar y depurar. Si la investigación es deficiente, itera sobre la instrucción del investigador. Si el formato del curso es incorrecto, debes iterar en el Creador de contenido. En una instrucción monolítica que "lo hace todo", corregir una cosa a menudo rompe otra.

  1. Si trabajas en Cloud Shell, ejecuta el siguiente comando para abrir el editor de Cloud Shell:
    cloudshell workspace .
    
    Si trabajas en tu entorno local, abre tu IDE favorito.
  2. Abre agents/researcher/agent.py.
  3. Verás un esqueleto con un TODO.
  4. Agrega el siguiente código para definir el agente researcher:
    # ... existing imports ...
    
    # Define the Researcher Agent
    researcher = Agent(
        name="researcher",
        model=MODEL,
        description="Gathers information on a topic using Google Search.",
        instruction="""
        You are an expert researcher. Your goal is to find comprehensive and accurate information on the user's topic.
        Use the `google_search` tool to find relevant information.
        Summarize your findings clearly.
        If you receive feedback that your research is insufficient, use the feedback to refine your next search.
        """,
        tools=[google_search],
    )
    
    root_agent = researcher
    

Concepto clave: Uso de herramientas

Observa que pasamos tools=[google_search]. El ADK controla la complejidad de describir esta herramienta al LLM. Cuando el modelo decide que necesita información, genera una llamada a herramienta estructurada, el ADK ejecuta la función de Python google_search y devuelve el resultado al modelo.

4. ⚖️ El agente juez

Agente de Judge

El investigador trabaja mucho, pero los LLM pueden ser perezosos. Necesitamos un juez para que revise el trabajo. El juez acepta la investigación y devuelve una evaluación estructurada de aprobado o no aprobado.

Resultado estructurado

Análisis detallado: Para automatizar los flujos de trabajo, necesitamos resultados predecibles. Una opinión de texto divagante es difícil de analizar de forma programática. Al aplicar un esquema JSON (con Pydantic), nos aseguramos de que Judge devuelva un valor booleano pass o fail sobre el que nuestro código pueda actuar de manera confiable.

  1. Abre agents/judge/agent.py.
  2. Define el esquema JudgeFeedback y el agente judge.
    # 1. Define the Schema
    class JudgeFeedback(BaseModel):
        """Structured feedback from the Judge agent."""
        status: Literal["pass", "fail"] = Field(
            description="Whether the research is sufficient ('pass') or needs more work ('fail')."
        )
        feedback: str = Field(
            description="Detailed feedback on what is missing. If 'pass', a brief confirmation."
        )
    
    # 2. Define the Agent
    judge = Agent(
        name="judge",
        model=MODEL,
        description="Evaluates research findings for completeness and accuracy.",
        instruction="""
        You are a strict editor.
        Evaluate the 'research_findings' against the user's original request.
        If the findings are missing key info, return status='fail'.
        If they are comprehensive, return status='pass'.
        """,
        output_schema=JudgeFeedback,
        # Disallow delegation because it should only output the schema
        disallow_transfer_to_parent=True,
        disallow_transfer_to_peers=True,
    )
    
    root_agent = judge
    

Concepto clave: Restricción del comportamiento del agente

Establecemos disallow_transfer_to_parent=True y disallow_transfer_to_peers=True. Esto obliga al juez a solo devolver el JudgeFeedback estructurado. No puede decidir "chatear" con el usuario ni delegar la tarea a otro agente. Esto lo convierte en un componente determinístico en nuestro flujo de lógica.

5. 🧪 Cómo realizar pruebas de forma aislada

Antes de conectarlos, podemos verificar que cada agente funcione. El ADK te permite ejecutar agentes de forma individual.

Concepto clave: El tiempo de ejecución interactivo

adk run inicia un entorno ligero en el que tú eres el "usuario". Esto te permite probar las instrucciones del agente y el uso de herramientas de forma aislada. Si el agente falla aquí (p.ej., no puede usar la Búsqueda de Google), definitivamente fallará en la orquestación.

  1. Ejecuta Researcher de forma interactiva. Ten en cuenta que apuntamos al directorio del agente específico:
    # This runs the researcher agent in interactive mode
    uv run adk run agents/researcher
    
  2. En la instrucción del chat, escribe lo siguiente:
    Find the population of Tokyo in 2020
    
    Debe usar la herramienta de Búsqueda de Google y devolver la respuesta.Nota: Si ves un error que indica que no se configuraron el proyecto, la ubicación y el uso de Vertex, asegúrate de que esté configurado el ID de tu proyecto y ejecuta lo siguiente:
    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    export GOOGLE_CLOUD_LOCATION=us-central1
    export GOOGLE_GENAI_USE_VERTEXAI=true
    
  3. Sal del chat (Ctrl + C).
  4. Ejecuta Judge de forma interactiva:
    uv run adk run agents/judge
    
  5. En la instrucción del chat, simula la entrada:
    Topic: Tokyo. Findings: Tokyo is a city.
    
    Debería devolver status='fail' porque los resultados son demasiado breves.

6. ✍️ El agente Creador de contenido

Creador de contenido

El Creador de contenido es el escritor creativo. Toma la investigación aprobada y la convierte en un curso.

  1. Abre agents/content_builder/agent.py.
  2. Define el agente content_builder.
    content_builder = Agent(
        name="content_builder",
        model=MODEL,
        description="Transforms research findings into a structured course.",
        instruction="""
        You are an expert course creator.
        Take the approved 'research_findings' and transform them into a well-structured, engaging course module.
    
        **Formatting Rules:**
        1. Start with a main title using a single `#` (H1).
        2. Use `##` (H2) for main section headings.
        3. Use bullet points and clear paragraphs.
        4. Maintain a professional but engaging tone.
    
        Ensure the content directly addresses the user's original request.
        """,
    )
    root_agent = content_builder
    

Concepto clave: Propagación del contexto

Quizás te preguntes: "¿Cómo sabe el Creador de contenido lo que encontró el Investigador?". En el ADK, los agentes de una canalización comparten un session.state. Más adelante, en el orquestador, configuraremos el investigador y el juez para que guarden sus resultados en este estado compartido. La instrucción de Content Builder tiene acceso efectivo a este historial.

7. 🎻 El organizador

Agente de Orchestrator

El Orchestrator es el administrador de nuestro equipo de varios agentes. A diferencia de los agentes especializados (Investigador, Juez y Creador de contenido) que realizan tareas específicas, el trabajo del Organizador es coordinar el flujo de trabajo y garantizar que la información fluya correctamente entre ellos.

🌐 La arquitectura: Agent-to-Agent (A2A)

Arquitectura de A2A

En este lab, crearemos un sistema distribuido. En lugar de ejecutar todos los agentes en un solo proceso de Python, los implementamos como microservicios independientes. Esto permite que cada agente se escale de forma independiente y falle sin que se bloquee todo el sistema.

Para que esto sea posible, usamos el protocolo Agent-to-Agent (A2A).

El protocolo A2A

Análisis detallado: En un sistema de producción, los agentes se ejecutan en diferentes servidores (o incluso en diferentes nubes). El protocolo A2A crea una forma estándar para que se descubran y se comuniquen entre sí a través de HTTP. RemoteA2aAgent es el cliente del ADK para este protocolo.

  1. Abre agents/orchestrator/agent.py.
  2. Ubica el comentario # TODO: Define Remote Agents o la sección para las definiciones de agentes remotos.
  3. Agrega el siguiente código para definir las conexiones. Asegúrate de colocarlo después de las importaciones y antes de cualquier otra definición de agente.
    # ... existing code ...
    
    # Connect to the Researcher (Localhost port 8001)
    researcher_url = os.environ.get("RESEARCHER_AGENT_CARD_URL", "http://localhost:8001/a2a/agent/.well-known/agent-card.json")
    researcher = RemoteA2aAgent(
        name="researcher",
        agent_card=researcher_url,
        description="Gathers information using Google Search.",
        # IMPORTANT: Save the output to state for the Judge to see
        after_agent_callback=create_save_output_callback("research_findings"),
        # IMPORTANT: Use authenticated client for communication
        httpx_client=create_authenticated_client(researcher_url)
    )
    
    # Connect to the Judge (Localhost port 8002)
    judge_url = os.environ.get("JUDGE_AGENT_CARD_URL", "http://localhost:8002/a2a/agent/.well-known/agent-card.json")
    judge = RemoteA2aAgent(
        name="judge",
        agent_card=judge_url,
        description="Evaluates research.",
        after_agent_callback=create_save_output_callback("judge_feedback"),
        httpx_client=create_authenticated_client(judge_url)
    )
    
    # Content Builder (Localhost port 8003)
    content_builder_url = os.environ.get("CONTENT_BUILDER_AGENT_CARD_URL", "http://localhost:8003/a2a/agent/.well-known/agent-card.json")
    content_builder = RemoteA2aAgent(
        name="content_builder",
        agent_card=content_builder_url,
        description="Builds the course.",
        httpx_client=create_authenticated_client(content_builder_url)
    )
    

8. 🛑 El verificador de derivaciones

Un bucle necesita una forma de detenerse. Si el juez dice "Aprobar", queremos salir del bucle de inmediato y pasar al Creador de contenido.

Lógica personalizada con BaseAgent

Análisis detallado: No todos los agentes usan LLMs. A veces, necesitas una lógica de Python simple. BaseAgent te permite definir un agente que solo ejecuta código. En este caso, verificamos el estado de la sesión y usamos EventActions(escalate=True) para indicarle a LoopAgent que se detenga.

  1. Aún en agents/orchestrator/agent.py.
  2. Busca el marcador de posición TODO de EscalationChecker.
  3. Reemplázala por la siguiente implementación:
    class EscalationChecker(BaseAgent):
        """Checks the judge's feedback and escalates (breaks the loop) if it passed."""
    
        async def _run_async_impl(
            self, ctx: InvocationContext
        ) -> AsyncGenerator[Event, None]:
            # Retrieve the feedback saved by the Judge
            feedback = ctx.session.state.get("judge_feedback")
            print(f"[EscalationChecker] Feedback: {feedback}")
    
            # Check for 'pass' status
            is_pass = False
            if isinstance(feedback, dict) and feedback.get("status") == "pass":
                is_pass = True
            # Handle string fallback if JSON parsing failed
            elif isinstance(feedback, str) and '"status": "pass"' in feedback:
                is_pass = True
    
            if is_pass:
                # 'escalate=True' tells the parent LoopAgent to stop looping
                yield Event(author=self.name, actions=EventActions(escalate=True))
            else:
                # Continue the loop
                yield Event(author=self.name)
    
    escalation_checker = EscalationChecker(name="escalation_checker")
    

Concepto clave: Control de flujo a través de eventos

Los agentes se comunican no solo con texto, sino también con eventos. Cuando se genera un evento con escalate=True, este agente envía un indicador a su elemento superior (el LoopAgent). El LoopAgent está programado para captar este indicador y finalizar el bucle.

9. 🔁 El ciclo de investigación

Bucle de investigación

Necesitamos un circuito de retroalimentación: Investigación -> Evaluación -> (Falla) -> Investigación -> …

  1. Aún en agents/orchestrator/agent.py.
  2. Agrega la definición research_loop. Coloca este elemento después de la clase EscalationChecker y la instancia escalation_checker.
    research_loop = LoopAgent(
        name="research_loop",
        description="Iteratively researches and judges until quality standards are met.",
        sub_agents=[researcher, judge, escalation_checker],
        max_iterations=3,
    )
    

Concepto clave: LoopAgent

El LoopAgent recorre sus sub_agents en orden.

  1. researcher: Busca datos.
  2. judge: Evalúa datos.
  3. escalation_checker: Decide si se debe yield Event(escalate=True). Si sucede escalate=True, el bucle se interrumpe antes. De lo contrario, se reinicia en el investigador (hasta max_iterations).

10. 🔗 La canalización final

Canalización final

Por último, une todo.

  1. Aún en agents/orchestrator/agent.py.
  2. Define el root_agent en la parte inferior del archivo. Asegúrate de que este reemplazo se aplique a cualquier marcador de posición root_agent = None existente.
    root_agent = SequentialAgent(
        name="course_creation_pipeline",
        description="A pipeline that researches a topic and then builds a course from it.",
        sub_agents=[research_loop, content_builder],
    )
    

Concepto clave: Composición jerárquica

Ten en cuenta que research_loop es en sí mismo un agente (un LoopAgent). Lo tratamos como cualquier otro agente secundario en SequentialAgent. Esta componibilidad te permite crear lógica compleja anidando patrones simples (bucles dentro de secuencias, secuencias dentro de routers, etcétera).

11. 💻 Ejecuta de forma local

Antes de ejecutar todo, veamos cómo el ADK simula el entorno distribuido de forma local.

Análisis detallado: Cómo funciona el desarrollo local

En una arquitectura de microservicios, cada agente se ejecuta como su propio servidor. Cuando realices la implementación, tendrás 4 servicios de Cloud Run diferentes. Simular esto de forma local puede ser doloroso si tienes que abrir 4 pestañas de terminal y ejecutar 4 comandos.

Esta secuencia de comandos inicia los procesos de uvicorn para el investigador (puerto 8001), el evaluador (8002) y el creador de contenido (8003). Establece variables de entorno, como RESEARCHER_AGENT_CARD_URL, y las pasa al organizador (puerto 8004). Así es exactamente como lo configuraremos en la nube más adelante.

App en ejecución

  1. Ejecuta la secuencia de comandos de orquestación:
    ./run_local.sh
    
    Esto inicia 4 procesos separados.
  2. Prueba lo siguiente:
    • Si usas Cloud Shell: Haz clic en el botón Vista previa en la Web (en la parte superior derecha de la terminal) -> Vista previa en el puerto 8080 -> Cambiar puerto a 8000.
    • Si ejecutas el servidor de forma local: Abre http://localhost:8000 en tu navegador.
    • Instrucción: "Crea un curso sobre la historia del café".
    • Observa: Orchestrator llamará al investigador. El resultado se envía al juez. Si el juez la rechaza, el bucle continúa.
    Solución de problemas:
    • "Internal Server Error" o errores de autenticación: Si ves errores de autenticación (p.ej., relacionados con google-auth), asegúrate de haber ejecutado gcloud auth application-default login si se ejecuta en una máquina local. En Cloud Shell, asegúrate de que la variable de entorno GOOGLE_CLOUD_PROJECT esté configurada correctamente.
    • Errores de terminal: Si el comando falla en una nueva ventana de terminal, recuerda volver a exportar tus variables de entorno (GOOGLE_CLOUD_PROJECT, etcétera).
  3. Prueba de agentes de forma aislada: Incluso cuando se ejecuta el sistema completo, puedes probar agentes específicos segmentando sus puertos directamente. Esto es útil para depurar un componente específico sin activar toda la cadena.
    • Researcher Only (Port 8001): http://localhost:8001
    • Solo para jueces (puerto 8002): http://localhost:8002
    • Solo Content Builder (puerto 8003): http://localhost:8003
    • Organizador (puerto 8004): http://localhost:8004 (acceso directo a la lógica del organizador)

12. 🚀 Implementa en Cloud Run

La validación final se ejecuta en la nube. Implementaremos cada agente como un servicio independiente.

Información sobre la configuración de la implementación

Cuando implementamos agentes en Cloud Run, pasamos varias variables de entorno para configurar su comportamiento y conectividad:

  • GOOGLE_CLOUD_PROJECT: Garantiza que el agente use el proyecto de Google Cloud correcto para el registro y las llamadas a Vertex AI.
  • GOOGLE_GENAI_USE_VERTEXAI: Indica al framework del agente (ADK) que use Vertex AI para la inferencia del modelo en lugar de llamar directamente a las APIs de Gemini.
  • [AGENT]_AGENT_CARD_URL: Es fundamental para el orquestador. Le indica al orquestador dónde encontrar los agentes remotos. Si configuras este parámetro en la URL de Cloud Run implementada (específicamente, la ruta de la tarjeta del agente), permitimos que el orquestador descubra al investigador, al juez y al creador de contenido, y se comunique con ellos a través de Internet.
  1. Implementa el investigador:
    gcloud run deploy researcher \
      --source agents/researcher/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    Captura la URL:
    RESEARCHER_URL=$(gcloud run services describe researcher --region us-central1 --format='value(status.url)')
    echo $RESEARCHER_URL
    
  2. Implementa el juez:
    gcloud run deploy judge \
      --source agents/judge/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    Captura la URL:
    JUDGE_URL=$(gcloud run services describe judge --region us-central1 --format='value(status.url)')
    echo $JUDGE_URL
    
  3. Implementa Content Builder:
    gcloud run deploy content-builder \
      --source agents/content_builder/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    Captura la URL:
    CONTENT_BUILDER_URL=$(gcloud run services describe content-builder --region us-central1 --format='value(status.url)')
    echo $CONTENT_BUILDER_URL
    
  4. Implementa el Orchestrator: Usa las variables de entorno capturadas para configurar el Orchestrator.
    gcloud run deploy orchestrator \
      --source agents/orchestrator/ \
      --region us-central1 \
      --allow-unauthenticated \
      --labels dev-tutorial=prod-ready-1 \
      --set-env-vars RESEARCHER_AGENT_CARD_URL=$RESEARCHER_URL/a2a/agent/.well-known/agent-card.json \
      --set-env-vars JUDGE_AGENT_CARD_URL=$JUDGE_URL/a2a/agent/.well-known/agent-card.json \
      --set-env-vars CONTENT_BUILDER_AGENT_CARD_URL=$CONTENT_BUILDER_URL/a2a/agent/.well-known/agent-card.json \
      --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT \
      --set-env-vars GOOGLE_GENAI_USE_VERTEXAI="true"
    
    Captura la URL:
    ORCHESTRATOR_URL=$(gcloud run services describe orchestrator --region us-central1 --format='value(status.url)')
    echo $ORCHESTRATOR_URL
    
  5. Implementa el frontend:
    gcloud run deploy course-creator \
        --source app \
        --region us-central1 \
        --allow-unauthenticated \
        --labels dev-tutorial=prod-ready-1 \
        --set-env-vars AGENT_SERVER_URL=$ORCHESTRATOR_URL \
        --set-env-vars GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT
    
  6. Prueba la implementación remota: Abre la URL de tu Orchestrator implementado. Ahora se ejecuta por completo en la nube y utiliza la infraestructura sin servidores de Google para escalar tus agentes.Sugerencia: Encontrarás todos los microservicios y sus URLs en la interfaz de Cloud Run.

13. Resumen

¡Felicitaciones! Compilaste e implementaste correctamente un sistema multiagente distribuido listo para producción.

Qué logramos

  • Descomposición de una tarea compleja: En lugar de una instrucción gigante, dividimos el trabajo en roles especializados (investigador, juez y creador de contenido).
  • Control de calidad implementado: Utilizamos un LoopAgent y un Judge estructurado para garantizar que solo la información de alta calidad llegue al paso final.
  • Creado para la producción: Con el protocolo Agent-to-Agent (A2A) y Cloud Run, creamos un sistema en el que cada agente es un microservicio independiente y escalable. Esto es mucho más sólido que ejecutar todo en una sola secuencia de comandos de Python.
  • Orquestación: Usamos SequentialAgent y LoopAgent para definir patrones de flujo de control claros.

Próximos pasos

Ahora que tienes la base, puedes extender este sistema:

  • Agregar más herramientas: Otorga acceso al investigador a documentos internos o APIs.
  • Mejora el juez: Agrega criterios más específicos o incluso un paso de "Human in the Loop".
  • Swap Models: Prueba usar diferentes modelos para diferentes agentes (p.ej., un modelo más rápido para el juez y un modelo más potente para el redactor de contenido).

Ahora puedes crear flujos de trabajo complejos y confiables basados en agentes en Google Cloud.