1. Introducción

En este codelab, se te guía para crear sistemas basados en agentes de próxima generación con flujos de trabajo y gráficos en el Kit de desarrollo de agentes (ADK). Implementarás patrones de arquitectura comunes, organizarás interacciones con interacción humana (HITL) y controlarás la ejecución asíncrona de larga duración. También integrarás bases de conocimiento empresarial y memoria persistente para personalizar y desarrollar el comportamiento del agente. Por último, conectarás estas capacidades para impulsar una canalización automatizada de generación de videos.
Situación hipotética
Tienes un canal digital en VibeTube con un público activo y una lista de ideas creativas en expansión. La producción de cada video requiere una ejecución continua en varias etapas: investigación de formatos populares, síntesis de comentarios de los usuarios, desarrollo de guiones, verificación del cumplimiento de las políticas y generación de clips de video. Los modelos generativos pueden crear borradores de recursos individuales, pero para lanzar versiones coherentes se requiere una arquitectura de agentes coordinada.
Para automatizar este ciclo de vida, compilarás VibeStudio. Esta canalización basada en agentes ejecuta investigaciones de rutina en paralelo, presenta opciones seleccionadas para la aprobación con interacción humana, aplica puertas de políticas automatizadas antes de generar el video y conserva el contexto en todas las ejecuciones de producción.

Qué aprenderá

- Fundamentos de la ingeniería de grafos: Las arquitecturas de agentes de varios pasos requieren un flujo de control explícito y rutas de ejecución estructuradas. Compilas un
Workflowdel ADK con tuplas de borde, el punto de entradaSTART,JoinNodepara la agregación de fan-out paralela y nodos de router determinísticos para dirigir la ejecución según el estado. - Modos y devoluciones de llamada de ciclo de vida del agente: Las tareas especializadas requieren comportamientos operativos distintos y rieles determinísticos. Configuras instancias de
Agentdel ADK con los modoschat,single_turnytaskhabilitado para herramientas como nodos de flujo de trabajo, y aplicas interceptores conbefore_model_callbackyafter_agent_callback. - Orquestación con interacción humana: Las canalizaciones de producción se pausan para que se realice una evaluación humana en los puntos de control creativos críticos. Implementas
RequestInputpara suspender la ejecución del flujo de trabajo, aplicar esquemas de respuesta estructurados y reanudar la ejecución sin mantener activos los procesos de tiempo de ejecución inactivos. - Memoria jerárquica del agente: Los sistemas de producción separan el estado de ejecución efímero del contexto duradero. Administras el estado de la sesión a corto plazo con
Event(state=...)y la vinculación de parámetros, y conectas GEAP Memory Bank para extraer, consolidar y conservar las preferencias del creador en todas las ejecuciones. - Fundamentación con bases de conocimiento empresarial: Los agentes autónomos requieren contexto dinámico del dominio y opiniones del público. Conectas un corpus del motor de RAG de GEAP como un nodo de recuperación dedicado dentro del fan-out paralelo para fundamentar semánticamente los resultados del agente.
- Flujos de trabajo y la implementación de larga duración: La renderización de video multimodal funciona de forma asíncrona durante períodos prolongados. Implementas
LongRunningFunctionToolcon recibos de llamadas pendientes para suspender y reanudar el flujo de trabajo por ID de llamada, y, luego, implementas la canalización finalizada con el ADKRunneren Cloud Run.
Cómo se organiza este codelab
Este codelab sirve como referencia conceptual y arquitectónica. En cada sección, se explican las construcciones del ADK implementadas en el paso correspondiente del banco de trabajo, se proporciona código de referencia y se establecen principios de diseño básicos. Revisa cada sección antes de completar el ejercicio correspondiente en el banco de trabajo.
El trabajo práctico se realiza en VibeStudio Workbench, una interfaz web complementaria que incluye un editor de código interactivo, verificadores de tiempo de ejecución y un inspector de ADK integrado. La numeración de los pasos en el banco de trabajo se alinea directamente con este codelab para mantener sincronizado tu progreso. Las ediciones de gráficos fundamentales persisten en todos los pasos, y el banco de trabajo verifica automáticamente los requisitos previos a medida que avanzas.
Cuando completes los ejercicios del banco de trabajo, ensamblarás una canalización de agente integral y, luego, implementarás una aplicación de VibeStudio en ejecución en Cloud Run para generar contenido de video.
El entorno consta de tres componentes principales: VibeStudio Workbench (la interfaz web local para la edición de código y la verificación del tiempo de ejecución), tu backend (el ADK Workflow y las zonas de pruebas de etapa en agent/) y Google Cloud (modelos de Gemini, GEAP Memory Bank, RAG Engine y generación de video de Veo).
2. Configuración
Reclama los créditos de tu taller
Si asistes a un lab dirigido por un instructor, este distribuirá créditos para tu proyecto de Google Cloud. Sigue las instrucciones del instructor para canjear tus créditos y asegúrate de que la facturación esté activa en tu cuenta antes de continuar.
Abre Cloud Shell
Cloud Shell es un entorno de desarrollo basado en navegador con gcloud, Python y git preinstalados.
Para iniciar Cloud Shell, haz lo siguiente:
- Navega a la consola de Google Cloud.
- En el encabezado de navegación superior, haz clic en Activar Cloud Shell (el ícono de ventana de terminal).

Se abrirá una sesión de terminal en la parte inferior de la ventana del navegador.
Clona e inicializa el repositorio
Ejecuta los siguientes comandos en la terminal de Cloud Shell para clonar el proyecto:
git clone https://github.com/gca-americas/vibetube-studio cd ~/vibetube-studio
Mensajes de configuración
Durante la configuración, se te solicitarán los siguientes detalles:
- ID del proyecto de Google Cloud: Cuando
setup_project.shte lo solicite, presiona Intro para crear un proyecto nuevo automáticamente. Si prefieres usar un proyecto existente (como un proyecto preasignado), ingresa tu ID del proyecto y asegúrate de que la ortografía sea correcta y de que la facturación esté activa. - Código del evento: Ingresa el código de la sala que te proporcionó el instructor. Si no recibiste uno, consulta con un asistente de enseñanza o un vecino. Si completas este lab en casa, presiona Intro para aceptar la habitación
sandboxpredeterminada. - Nombre visible del canal: Ingresa tu nombre o el identificador de canal que prefieras cuando
setup_codelab.shte lo solicite, o presiona Intro para aceptar el valor predeterminado generado a partir de tu Cuenta de Google.
Ejecuta las dos secuencias de comandos de configuración en orden:
./setup_project.sh ./setup_codelab.sh
setup_project.sh: Crea o reutiliza un proyecto de Google Cloud con facturación activa, guarda el ID del proyecto en~/project_id.txty configura el contexto activo degcloud.setup_codelab.sh: Instalauvy las dependencias de Python en.venv, habilita las APIs de Google Cloud requeridas, configura los parámetros del canal en.env, verifica el acceso al modelo con Gemini, aprovisiona los recursos de Memory Bank y RAG, compila la interfaz del banco de trabajo y, luego, inicia VibeStudio Workbench.
La secuencia de comandos ejecuta la verificación previa y, luego, inicia VibeStudio Workbench en segundo plano. En sus últimas líneas, se muestra el vínculo para abrirlo.
7 · Preflight
✓ python 3.12
✓ auth path A: Vertex via ADC (STUDIO_VERTEX=1)
✓ Google Cloud ADC (project <your-project>)
✓ stage0_prompt loads
...
✓ stage6_video loads (13 edges)
✓ aiplatform.googleapis.com enabled (Gemini, Veo, Memory Bank, RAG Engine)
✓ vectorsearch.googleapis.com enabled (the vector store a RAG corpus is built on)
✓ Memory Bank connected
✓ RAG corpus connected
✓ VibeStudio Workbench running on port 4600
PREFLIGHT GREEN
Setup finished. The VibeStudio Workbench is already running.
Open this and start at step 1
https://4600-<your cloud shell host>/step/story
It runs in the background. You do not need to start anything else.
log runs/lab.log
stop kill $(cat runs/lab.pid)
start scripts/start.sh
Haz clic en ese vínculo. La misma dirección está disponible en Vista previa en la Web → Cambiar puerto → 4600.
Para volver a verificar el entorno en cualquier momento, ejecuta python scripts/preflight.py. Para reiniciar el banco de trabajo, ejecuta scripts/restart.sh. Para volver a configurarlo, ejecuta ./setup_codelab.sh, que conserva tu configuración y progreso.
Con el archivo abierto, lee el paso 1, La historia, para conocer la situación, y el paso 2, Lo que compilarás, para conocer la forma del gráfico terminado. Ninguno de los dos tiene un ejercicio. Luego, regresa aquí para el paso 3.

Cada parte práctica de VibeStudio Workbench termina con un panel de verificación que lee los artefactos reales: el archivo en el disco y las sesiones escritas por las ejecuciones.
Diseño del repositorio
El repositorio se estructura en la lógica del flujo de trabajo principal, los entornos de pruebas paso a paso, el entorno de banco de trabajo y la aplicación de producción:
vibe-studio-lab/
├── agent/ # Core ADK workflow, graph definition, and platform services
│ ├── graph.py # Workflow graph definition, node functions, and routers
│ ├── desk.py # Video render desk using LongRunningFunctionTool
│ ├── schemas.py # Pydantic schemas for directions, gates, and scripts
│ ├── trends.py # Trend generation and sampling utilities
│ ├── backlog.txt # Creator video ideas backlog
│ ├── comments.md # Audience comments for RAG Engine corpus seeding
│ ├── policy_words.txt # Blocked subject words for deterministic policy checks
│ └── platform/ # Google Cloud service clients (Memory Bank, RAG, Veo)
│ ├── config.py # Environment variables, locations, and model configurations
│ ├── memory.py # GEAP Memory Bank callbacks and context injection
│ ├── rag.py # GEAP RAG Engine corpus creation and semantic retrieval
│ └── videogen.py # Veo video generation and operation polling
├── stage0_prompt/ # Step sandboxes: isolated agent.py files runnable in adk web
│ └── ... # stage1_fanout through stage6_video for incremental steps
├── server/ & web/ # VibeStudio Workbench (FastAPI backend and React frontend)
├── vibestudio/ # Complete production application deployed to Cloud Run
│ ├── server/ # FastAPI production server and event runner
│ ├── web/ # End-user React web application
agent/: Contiene el gráfico principal del flujo de trabajo. Editarás archivos en este directorio para implementar nodos de fan-out paralelos, enrutamiento de políticas determinístico, devoluciones de llamada de memoria y herramientas de generación de video.agent/platform/: Se comunica con los servicios de Google Cloud, incluidos los modelos de Gemini, el banco de memoria de GEAP, el motor de RAG de GEAP y la síntesis de video de Veo.stage0_prompt/astage6_video/: Entornos de zona de pruebas autónomos. Cada carpeta exporta unroot_agentindependiente para que puedas ejecutar e inspeccionar cada paso de forma aislada a través de la interfaz de desarrollo del ADK integrada.server/yweb/: La aplicación VibeStudio Workbench que se ejecuta de forma local en el puerto 4600. Contiene la documentación de los pasos, el editor de código in-page, los verificadores de evidencia del tiempo de ejecución y la visualización de gráficos.vibestudio/: Es la aplicación de producción completa empaquetada y, luego, implementada en Cloud Run en el paso final. Contiene su propia copia independiente del grafo de flujo de trabajo completado.
3. Agente monolítico
Antes de construir un gráfico de flujo de trabajo de varios nodos, establece una referencia arquitectónica con un solo agente en stage0_prompt/agent.py. Este agente se basa en una instrucción del sistema monolítica que describe la canalización de producción en prosa, con el respaldo de dos herramientas de funciones de Python.
La evaluación de este modelo de referencia demuestra los límites operativos de la coordinación basada en instrucciones y establece por qué los sistemas de producción requieren la organización de gráficos.
Arquitectura de agentes del ADK (3A)
En VibeStudio Workbench, navega a Paso 3: Agente monolítico y abre Arquitectura del agente de ADK (3A). En esta vista, se presentan las capas arquitectónicas principales de un agente del ADK (LlmAgent):

from google.adk.agents import LlmAgent
from google.adk.tools import mcp_toolset
root_agent = LlmAgent(
model="gemini-3.5-flash", # model
instruction=BRAND_INSTRUCTION, # instruction
skills=[load_skill("brand-audit")], # skills
tools=[mcp_toolset("mcp_brand_style")], # tools
output_schema=BrandStyleReport, # structured output
before_agent_callback=setup_ctx, # interceptor
before_model_callback=require_image, # interceptor
after_model_callback=schema_guard, # interceptor
)
El diagrama interactivo agrupa los componentes del agente en cinco dominios operativos:
- Capa de razonamiento (modelo): Es el modelo de lenguaje principal (como Gemini 3 Flash) que ejecuta tareas cognitivas, razonamiento de instrucciones y selección de herramientas. Todo lo demás en la arquitectura informa o limita este modelo.
- Capa de contexto (instrucciones y habilidades): Son directivas que dan forma al razonamiento del modelo.
instructionestablece las instrucciones del sistema, el arquetipo y las reglas operativas permanentes.skillsproporciona orientación procedimental con versiones (SKILL.md) para flujos de trabajo repetibles. - Capa de colaboración y acción (herramientas, subagentes, flujo de trabajo, esquema de salida): Interfaces que permiten que el agente actúe en sistemas externos y emita datos escritos.
toolsproporcionar funciones de Python invocables o extremos del Protocolo de contexto del modelo (MCP)subagentsejecutar tareas subordinadas delegadasworkflowcoordina gráficos multiagente.output_schemaaplica modelos de Pydantic para garantizar que los consumidores posteriores reciban JSON validado en lugar de texto no estructurado. - Capa de interceptores (devoluciones de llamada de ciclo de vida): Son rieles determinísticos que ejecutan código personalizado antes y después de la ejecución del agente (
before_agent/after_agent), los turnos individuales del modelo (before_model/after_model) y las llamadas a herramientas (before_tool/after_tool). Los interceptores aplican las reglas de política sin depender del cumplimiento del modelo. - Estado externo (sesión y memoria): Persistencia con estado separada de la lógica del agente.
Sessionconserva la memoria de trabajo transitoria y el registro de eventos del subproceso de ejecución actual.Memorymantiene hechos y preferencias duraderos entre sesiones con servicios administrados, como GEAP Memory Bank.
El agente monolítico de este paso solo implementa tres de estas primitivas: model, instruction y tools. En los pasos posteriores, se presentan los flujos de trabajo de gráficos, los esquemas estructurados, los interceptores y los servicios de memoria persistente.
Especificación del agente monolítico (3B)
En el banco de trabajo, avanza a Especificación del agente monolítico (3B). Abre stage0_prompt/agent.py para examinar la definición del agente de referencia:
- Instrucción de una sola instrucción: La instrucción del sistema condensa cinco tareas de producción distintas en prosa continua: descubrir tendencias de la plataforma, revisar ideas pendientes, proponer conceptos creativos, aplicar políticas sobre temas prohibidos y redactar listas de tomas.
- Fuentes de datos subyacentes: El agente hace referencia a dos fuentes definidas junto al gráfico:
agent/trends.py: Muestra diez tendencias activas de formato y estilo de un grupo de 250 con puntuaciones de calor dinámicas.agent/backlog.txt: Lee las notas conceptuales sin procesar del creador línea por línea.
Herramientas en el agente (3C)
En el banco de trabajo, avanza a Herramientas en el agente (3C).
¿Qué es una herramienta para un agente?
Un modelo de lenguaje es, por naturaleza, un motor de razonamiento de mundo cerrado: opera únicamente con los pesos entrenados previamente y los tokens presentes en su ventana de contexto inmediata. No puede consultar una base de datos, acceder a APIs en tiempo real ni ejecutar código de forma nativa.
Un objeto Tool une este límite. Le otorga al modelo una agencia externa, lo que le permite recuperar información de referencia y ejecutar acciones determinísticas en sistemas externos.

El llamado a herramientas sigue un protocolo explícito de cinco etapas entre el modelo y el tiempo de ejecución del ADK:
- Declaración de esquema: El desarrollador proporciona funciones de Python al agente. El ADK inspecciona el nombre, las anotaciones de tipo y las cadenas de documentación de cada función para generar una declaración de esquema JSON compatible con OpenAPI que describa sus parámetros y su propósito.
- Razonamiento del modelo: Durante la inferencia, el modelo evalúa si la instrucción del usuario requiere datos externos. Si es necesario, el modelo emite un evento
function_callestructurado que contiene el nombre de la función objetivo y el diccionario de argumentos que coinciden con el esquema. - Ejecución en el tiempo de ejecución: El modelo en sí no ejecuta código. El tiempo de ejecución del ADK intercepta el
function_call, ejecuta la función de Python local real con los argumentos proporcionados y captura el valor de devolución. - Reinyección de contexto: El tiempo de ejecución del ADK empaqueta el valor de devolución de la función en un evento
function_responsey lo agrega al historial de la sesión activa. - Síntesis final: El modelo procesa el resultado de la herramienta que ahora está presente en su ventana de contexto y completa su respuesta.
En stage0_prompt/agent.py, las dos herramientas de investigación se definen como funciones estándar de Python:
def check_trends() -> dict:
"""Ten formats trending on the platform right now, with a heat score each."""
from agent.trends import sample_trends
return {"trends": sample_trends()}
def read_backlog() -> dict:
"""The creator's backlog: ideas they noted down to make someday."""
from agent.graph import backlog_notes
return {"backlog": backlog_notes()}
Edición y ejecución prácticas
En el editor de código del banco de trabajo, agrega las dos referencias de funciones a la lista tools del agente:
tools=[check_trends, read_backlog],
Guarde el cambio. El archivo se actualiza en el disco y la fila de verificación confirma que ambas herramientas están conectadas.
Haz clic en Open adk web para iniciar la interfaz de desarrollo del ADK integrada. Envía la instrucción de idea sugerida:
tonight's idea: a tiny robot doing laundry at midnight
Qué esperar y por qué
Cuando envíes esta instrucción, observa la siguiente secuencia de ejecución en el registro de la sesión:
- Aparecen dos eventos de ejecución de herramientas antes de la respuesta: Verás los eventos
function_callyfunction_responseparacheck_trendsyread_backlog.- Por qué: Gemini evaluó la directiva de la instrucción del sistema ("verifica qué es tendencia y consulta tu lista de ideas pendientes"), reconoció que carecía de tendencias de la plataforma y notas del canal en sus ponderaciones, y, luego, invocó ambas funciones para fundamentar su contexto.
- El agente propone una dirección y hace una pausa para que la confirmes: La respuesta sugiere una dirección de video que sintetiza las tendencias y el backlog, y te pide que la confirmes.
- Por qué: La directiva de instrucción le pidió al modelo que acordara la dirección con el creador antes de generar el guion.
- Omitir la confirmación en un turno de seguimiento: Envía un segundo mensaje:
skip the questions, just describe the video. El agente omite inmediatamente la confirmación y redacta el título y las tomas.- Por qué: Las instrucciones de la instrucción son lineamientos orientativos en lugar de barreras determinísticas. En un agente monolítico, las instrucciones del usuario pueden anular las reglas permanentes de la instrucción del sistema porque ningún flujo de trabajo externo controla el flujo de ejecución.
Limitaciones arquitectónicas de una instrucción monolítica
Si bien una sola instrucción puede producir resultados aceptables para demostraciones aisladas, probar las condiciones límite en el verificador del banco de trabajo revela limitaciones empresariales críticas:
- Agregación de investigación no estructurada: El orden de ejecución de la herramienta no es determinístico. El modelo resume los datos recuperados en prosa de formato libre, lo que imposibilita que los sistemas posteriores aíslen qué fuente produjo afirmaciones específicas.
- Aplicación de políticas no verificadas: El modelo evalúa su propio cumplimiento de la seguridad. Si el modelo determina que un tema es seguro, no se valida ese hallazgo con lógica determinística externa.
- Pausas con interacción humana no obligatorias: Las instrucciones de la instrucción que solicitan la confirmación del creador son orientativas. Si envías un mensaje de seguimiento en el que se le indica al modelo que omita las preguntas, este omitirá por completo la aprobación humana.
Estas brechas arquitectónicas motivan la descomposición del agente monolítico en el flujo de trabajo de grafo explícito que se compila en el siguiente paso.
4. Fundamentos del flujo de trabajo de agentes
En VibeStudio Workbench, navega a Paso 4: Aspectos básicos del flujo de trabajo agentic, partes 4A a 4D.
En este paso, se pasa de un modelo de referencia de un solo agente a una organización determinística de gráficos con el ADK Workflow. Crearás un fan-out de investigación paralelo, sincronizarás las ramas con un nodo de unión, generarás candidatos de creatividades validados por el esquema y presentarás una puerta de aprobación determinística con interacción humana.
Arquitectura de gráficos y cadenas de ejecución (4A)
En el banco de trabajo, abre Graph architecture and execution chains (4A).
Un ADK Workflow estructura la ejecución del agente como un grafo dirigido definido por una lista de bordes:
- Cadenas: Las tuplas secuenciales definen la ejecución lineal de nodos (
(node_a, node_b, node_c)). - Ramas paralelas: Las cadenas independientes que comparten un nodo de origen se ejecutan de forma simultánea.
- Sincronización: Las cadenas que convergen en un
JoinNodeesperan hasta que todas las ramas entrantes envían su informe antes de liberarse. - Control determinístico: El flujo de ejecución se rige por estructuras de código declaradas en lugar de inferirse a partir del texto de la instrucción.

Arquetipos de nodos en el ADK
Los flujos de trabajo del ADK componen varios tipos de nodos especializados. Cada arquetipo desempeña un rol operativo específico en el grafo, lo que separa la ejecución de código determinístico del razonamiento del modelo generativo:
Arquetipo de nodo | Implementación | Rol en la canalización |
Nodo de función | Función de Python que devuelve un | Ejecuta lógica determinística, recuperación de datos y mutaciones de estado. |
Nodo de unión | Instancia de | Sincroniza las ramas simultáneas en un diccionario agregado. |
Nodo de agente |
| Evalúa las instrucciones en función de la entrada upstream y emite datos validados. |
Nodo de router | Función que devuelve un | Evalúa la lógica condicional para seleccionar las ramas de ejecución posteriores. |
Nodo de entrada humana | Función de rendimiento | Suspende el estado de ejecución hasta que llega una respuesta externa del usuario. |
root_agent = Workflow(
name="stage1_fanout",
description="2 real readers -> join -> one research dict",
edges=[...])
En esta configuración, root_agent es una instancia de Workflow en lugar de un Agent independiente. El ADK trata los flujos de trabajo como agentes de primera clase, lo que permite cargar, publicar y revisar un gráfico completo como una aplicación unificada. El name registra la aplicación en ADK Web, mientras que la lista edges define su topología de ejecución.
Fan-out de investigación paralela (4B)
En el banco de trabajo, avanza a Parallel research fan-out (4B). Abre stage1_fanout/agent.py.

Nodos de función y barreras de sincronización
La fase de investigación usa dos nodos de función importados de agent/graph.py:
scan_trends: DevuelveEvent(output={"trends": [...]})que contiene diez tendencias de la plataforma con puntuación.read_backlog: DevuelveEvent(output={"backlog": [...], "idea": "..."})que contiene quince ideas de tareas pendientes del canal junto con la instrucción de ejecución inicial.
Cada función acepta node_input (la salida del nodo anterior) y devuelve un Event.
Un JoinNode sirve como barrera de sincronización: se detiene hasta que cada cadena entrante entrega un evento y, luego, agrega todos los resultados de las ramas en un diccionario con el nombre del nodo como clave ({"scan_trends": {...}, "read_backlog": {...}}).
Edición práctica: cómo definir las uniones y los bordes paralelos
En stage1_fanout/agent.py, crea una instancia de JoinNode y conecta las dos cadenas paralelas que comienzan en START:
join_research = JoinNode(name="join_research")
edges=[(START, scan_trends, join_research),
(START, read_backlog, join_research)])
Guarda los cambios. El verificador de la mesa de trabajo confirma que la unión y los bordes están conectados. Ejecuta la etapa con Run Stage 1 o a través de la interfaz web integrada del ADK.
Qué esperar y por qué
- Ejecución simultánea de lectores: En el gráfico de ejecución,
scan_trendsyread_backlogse ejecutan de forma simultánea.- Motivo: Ambas cadenas se originan en
START. El motor del ADK programa ramas independientes de forma simultánea.
- Motivo: Ambas cadenas se originan en
- Resultado del diccionario agregado: El flujo de trabajo se completa en
join_researchy genera un diccionario con entradas para ambos lectores.- Motivo:
JoinNodegarantiza la captura completa de datos antes de permitir que se ejecuten los nodos posteriores.
- Motivo:
Nodos de agentes (4C)
En el banco de trabajo, avanza a Nodos de agentes (4C). Abre stage2_direction/agent.py.

Modos de operación y esquemas estructurados
Cuando se incorpora dentro de un Workflow, un Agent se ejecuta en modo single_turn de forma predeterminada:
- Recibe el resultado del nodo anterior como entrada de contexto.
- Ejecuta una sola llamada de inferencia sin una conversación fluida.
- Genera datos estructurados para el siguiente nodo.
Al asignar output_schema=Directions, el agente aplica la validación de Pydantic en el resultado del modelo. El gráfico de nivel inferior recibe objetos escritos en lugar de prosa no estructurada:
class Direction(BaseModel):
title: str # <=60 chars, filmable, characterful
angle: str # the twist, one line
hook: str = "" # 2-4 words, the video's sticker line
evidence: list[Evidence]
class Directions(BaseModel):
candidates: list[Direction] # exactly 4
PROPOSE_INSTRUCTION le indica al modelo que proponga cuatro candidatos citando evidencia de las tendencias y el backlog. Los candidatos del 1 al 3 ofrecen conceptos de canales viables. El candidato 4 introduce intencionalmente un concepto que incumple la política para probar la puerta de seguridad en el siguiente paso.
Edición práctica: Definición del nodo del agente y encadenamiento de la unión
En stage2_direction/agent.py, configura propose_directions y extiende los bordes del flujo de trabajo:
propose_directions = Agent(
name="propose_directions",
model=config.MODEL,
instruction=PROPOSE_INSTRUCTION,
output_schema=Directions)
edges=[(START, scan_trends, join_research),
(START, read_backlog, join_research),
(join_research, propose_directions, direction_gate)])
Qué esperar y por qué
- Consumo directo del diccionario:
propose_directionsconsume la carga útil de JSON que emitejoin_researchsin necesidad de un formato manual. - Salida de candidato escrita: El agente emite un objeto
Directionsvalidado que contiene cuatro candidatos discretos. Los nodos posteriores leen los campos por nombre de atributo (candidate.title) sin analizar cadenas.
Con interacción humana (4D)
En el banco de trabajo, avanza a Human-in-the-loop (4D). Abre agent/graph.py.

Instrucciones de la instrucción frente a la suspensión determinística
Los flujos de trabajo de producción que generan costos financieros o publican contenido requieren supervisión humana en los puntos de decisión críticos. En una sola instrucción, las solicitudes de confirmación son instrucciones de asesoramiento que un usuario puede solicitar fácilmente al modelo que omita. En un flujo de trabajo del ADK, el motor de ejecución aplica la aprobación humana: el gráfico se detiene en un nodo designado y no puede avanzar hasta que recibe una entrada externa validada por el esquema:
- La instrucción
RequestInputsuspende la ejecución del flujo de trabajo de inmediato. - El ADK registra una llamada de interrupción abierta en el almacén de sesiones y emite un
interrupt_idúnico. - El proceso de ejecución se detiene sin consumir tokens ni subprocesos del servidor.
- La ejecución por grafos se reanuda solo cuando se envía un
function_responseválido que coincide con el esquema y el ID de interrupción.
Edición práctica: Suspender la ejecución con RequestInput
En agent/graph.py, implementa la llamada de suspensión dentro de direction_gate:
yield RequestInput(
message="Pick tonight's direction: 1, 2, 3 or 4.",
response_schema={
"type": "object",
"properties": {
"pick": {"type": "string", "enum": ["1", "2", "3", "4"]}}},
payload={"candidates": cands})
RequestInput configura tres atributos:
message: Es el mensaje de revisión que se le presenta al usuario.response_schema: Es un esquema JSON que el frontend renderiza como un formulario de entrada y que el ADK valida cuando se envía.payload: Son metadatos incluidos en la solicitud (los cuatro candidatos) que permiten que las interfaces del cliente rendericen tarjetas de opiniones sin consultar el estado de la sesión.
Qué esperar y por qué
- El flujo de trabajo se detiene en direction_gate: En la Web del ADK o en la interfaz del banco de trabajo, la ejecución se pausa y se muestra un formulario interactivo de selección de candidatos.
- Por qué: El motor encontró un
RequestInputdiferido y persistió el estado de ejecución enruns/sessions.db.
- Por qué: El motor encontró un
- La reanudación requiere una entrada estructurada: Enviar texto de chat arbitrario no avanza el gráfico. Si seleccionas una opción (1, 2, 3 o 4), se envía un
function_responseescrito que satisfaceresponse_schemay se reanuda la ejecución.
5. Estado y router
En VibeStudio Workbench, navega a Paso 5: Estado y Router, partes (5A) a (5C).
Conservarás las selecciones del usuario en el estado de la sesión, aplicarás las políticas de seguridad del canal con nodos de enrutador determinísticos y ensamblarás un agente de tareas iterativo para corregir automáticamente los incumplimientos de políticas antes de generar guiones de video.
Estado del flujo de trabajo (5A)
En Workbench, navega a Estado del flujo de trabajo (5A).

Estado de la sesión vs. salida del nodo
En un flujo de trabajo del ADK, los datos se mueven por el grafo a través de dos mecanismos distintos:
- Salida del nodo (
Event(output=...)): Son los datos dirigidos estrictamente a los consumidores inmediatos posteriores definidos en la lista de aristas. - Estado de la sesión (
Event(state=...)): Es un diccionario compartido de par clave-valor al que puede acceder cualquier nodo posterior en el ciclo de vida de la ejecución.

Cuando un usuario selecciona un candidato en direction_gate, la selección llega como un índice numérico ({"pick": "2"}). Los nodos posteriores necesitan el objeto de dirección completo: título, ángulo narrativo y gancho. En lugar de pasar metadatos detallados a través de cada carga útil de nodo intermedio, persist_direction escribe el candidato resuelto en el estado de sesión compartido.
Los nodos no necesitan pasar todo el diccionario de estado de la sesión. Cuando un nodo genera Event(state=...), solo proporciona los pares clave-valor nuevos o actualizados. El ADK combina automáticamente estas actualizaciones en el almacén de sesiones:
yield Event(state={"direction": chosen["title"], "angle": chosen.get("angle", ""),
"hook": hook, "user:prefs": {"last_direction": chosen["title"]}})
Cuando se genera este Event, se entrega el control al tiempo de ejecución de Workflow, que persiste los valores nuevos en el registro de la sesión en runs/sessions.db.
Vinculación de parámetros
Los nodos de función del ADK leen el estado de la sesión automáticamente a través de la inspección de parámetros. Si la firma de una función declara un nombre de parámetro que coincide con una clave de estado existente, el ADK extrae esa clave del estado y la pasa directamente:
def persist_direction(node_input, candidates: list = []):
ni = node_input if isinstance(node_input, dict) else {}
raw = ni.get("pick")
pick = str(raw).strip() if raw is not None else ""
if candidates:
i = int(pick) - 1 if pick.isdigit() else 0
chosen = candidates[max(0, min(len(candidates) - 1, i))]
else:
chosen = {"title": "untitled", "angle": "", "evidence": []}
hook = chosen.get("hook") or " ".join(chosen["title"].split()[:4])
Aquí, candidates se escribió en el estado de la sesión con direction_gate. El ADK lo vincula directamente a persist_direction(node_input, candidates: list = []) sin necesidad de búsquedas explícitas en el diccionario.
Las claves con el prefijo user: persisten en todas las sesiones en el almacenamiento a nivel del usuario, lo que permite que las ejecuciones posteriores del flujo de trabajo accedan a las preferencias del creador.
Edición práctica: cómo conservar el estado y conectar el nodo
- En
agent/graph.py, dentro depersist_direction, reemplaza la líneaTODO: PERSIST_STATEpor el rendimiento del evento de estado:
yield Event(state={"direction": chosen["title"], "angle": chosen.get("angle", ""),
"hook": hook, "user:prefs": {"last_direction": chosen["title"]}})
- En
stage3_router/agent.py, agregapersist_directiona la tercera cadena de la listaedges:
(join_research, propose_directions, direction_gate,
persist_direction)
Guarda tus archivos. En el banco de trabajo, verifica que state write in place y persist_direction in the chain muestren marcas de verificación verdes.
El nodo del router (5B)
En el banco de trabajo, navega a El nodo del router (5B).

Enrutamiento determinístico basado en políticas
Un router es un nodo de función especializado que evalúa el resultado de la transmisión ascendente y dirige la ejecución a lo largo de las ramas condicionales del gráfico. A diferencia de los agentes generativos, un router ejecuta lógica determinística sin realizar llamadas a LLM.
Un router devuelve un Event que especifica una etiqueta route:
def length_check(node_input):
too_long = len(node_input.get("title", "")) > 60
return Event(output=node_input, route="TRIM" if too_long else "PASS")
En la definición del flujo de trabajo, un destino de borde definido como un diccionario asigna nombres de rutas a nodos de destino:
(length_check, {"TRIM": shorten, "PASS": scripter}),
El enrutador de flujo de trabajo policy_check lee las frases prohibidas de agent/policy_words.txt y realiza la correlación de palabras completas con el título y el ángulo de la dirección elegida:
return Event(output=node_input, route="BLOCK" if bad else "OK")
Almacenar la política como datos en lugar de instrucciones codificadas permite realizar actualizaciones sin modificar el gráfico de flujo de trabajo: la actualización del archivo de texto se aplica de inmediato a las ejecuciones posteriores. Dado que la evaluación es una coincidencia de regex determinística, se ejecuta en milisegundos con un costo de cero tokens antes de que comience la generación de código.
Destinos: Scripter y cuarentena
El router dirige el tráfico a uno de los dos nodos de transmisión:
scripter: Es un nodo de agentesingle_turnque convierte la dirección aprobada en un guion de producción estructurado que se ajusta al esquemaScriptde Pydantic:
scripter = Agent(
name="scripter",
model=config.MODEL,
instruction=SCRIPT_INSTRUCTION,
output_schema=Script)
quarantine: Inicialmente, es una función de marcador de posición que detiene las instrucciones marcadas, reemplazada en la siguiente parte por un agente de corrección autónomo.
Edición práctica: Enruta la verificación de políticas
- En
agent/graph.py, dentro depolicy_check, completa la sentencia return:
return Event(output=node_input, route="BLOCK" if bad else "OK")
- En
stage3_router/agent.py, actualizaedgespara que dirija apolicy_checky vuelve a unir la rama de cuarentena enscripter:
(join_research, propose_directions, direction_gate,
persist_direction, policy_check),
(policy_check, {"OK": scripter, "BLOCK": quarantine}),
(quarantine, scripter)])
Guarda tus archivos. En el banco de trabajo, verifica que se hayan verificado las asignaciones de borde del router.
Modos del agente y el nodo de tareas (5C)
En Workbench, navega a Agent modes and the task node (5C).

Modos de ejecución del agente
Las instancias de ADK Agent admiten tres modos de ejecución adaptados a los requisitos específicos de la canalización:
Modo | Ciclo de vida de la ejecución | Rol en la canalización |
| Es un bucle conversacional de varios turnos. El modelo determina cuándo invocar herramientas, solicitar entrada o finalizar el turno. | Agentes raíz que interactúan con un usuario humano. |
| Es una sola llamada de inferencia del modelo. Acepta la entrada del nodo anterior y emite un objeto de esquema estructurado. | Transformaciones de gráficos secuenciales ( |
| Es un bucle autónomo con ejecución de herramientas. El agente itera hasta que llama a la herramienta integrada | Inspección y corrección de varios pasos ( |
Corrección autónoma de políticas
Para reescribir una dirección marcada, se requiere el modo task, ya que la cantidad de iteraciones de corrección es variable. El agente recibe la instrucción marcada, invoca find_policy_hits para detectar incumplimientos, solicita alternativas aprobadas a través de suggest_replacement, vuelve a escribir la instrucción y verifica que no haya incumplimientos antes de continuar.
Ambas herramientas se definen en agent/cleanup_tools.py con firmas escritas y cadenas de documentación:
def find_policy_hits(text: str) -> dict:
"""Which refused words appear in `text`. Matches whole words and phrases
from agent/policy_words.txt, case-insensitive.
Returns {"hits": [...], "clean": bool}. clean is true when hits is empty.
"""
def suggest_replacement(word: str) -> dict:
"""The channel's approved stand-in for a refused word, read from
agent/policy_replacements.txt.
Returns {"word", "replacement", "listed"}. When the word has no entry,
listed is false and replacement is a hint to pick a gentle synonym.
"""
Edición práctica: Ensamblaje del agente de tareas de cuarentena
En stage3_router/agent.py, reemplaza la función de marcador de posición quarantine por la definición del agente de tareas:
quarantine = Agent(
name="quarantine",
model=config.MODEL,
instruction=QUARANTINE_INSTRUCTION,
mode="task",
tools=[find_policy_hits, suggest_replacement],
output_schema=CleanedDirection,
)
El modo de tareas equipa al agente con herramientas y finaliza la ejecución llamando a finish_task. Cuando se configura mode="task", el ADK proporciona automáticamente finish_task y deriva sus parámetros de output_schema, lo que garantiza que el nodo genere un objeto CleanedDirection escrito que coincida con el esquema de entrada del nodo del guionista.

Qué esperar y por qué
Prueba ambas rutas de ejecución en la Web del ADK o en VibeStudio Workbench:
- Ruta aprobada (candidato 1, 2 o 3):
- Selecciona una ruta candidata aprobada desde
policy_checkdirectamente hastascripter(route="OK"). - El guionista genera un guion de producción de 3 tomas que se ajusta al esquema
Script.
- Selecciona una ruta candidata aprobada desde
- Ruta de corrección de cuarentena (candidato 4):
- La opción 4 contiene vocabulario marcado ("cebo de clics", "truco viral").
policy_checkrutas aquarantine(route="BLOCK").- En el registro de seguimiento de la sesión, observa que
quarantinellama afind_policy_hits, llama asuggest_replacementpara cada incumplimiento, reescribe el título y llama afinish_task. - La ejecución se une a
scriptery produce un guion a partir de la dirección filtrada.
6. Memory Bank
En VibeStudio Workbench, navega a Paso 6 · Memory Bank, partes (6A) y (6B).
Actualmente, el flujo de trabajo funciona sin memoria entre sesiones. Cada ejecución comienza desde cero, sin saber qué seleccionó el creador anteriormente ni qué géneros prefiere. En este paso, conectarás Vertex AI Agent Engine Memory Bank para almacenar y recuperar las preferencias del creador en diferentes ejecuciones.
Es fundamental que la memoria se integre a través de devoluciones de llamada del ciclo de vida del agente en lugar de nodos de canalización. Dado que la extracción y la recuperación de la memoria sirven a agentes individuales en lugar de etapas de datos intermedias, adjuntar devoluciones de llamada preserva una topología de gráfico limpia y desacoplada.
Memory Bank (6A)
En Workbench, navega a Memory Bank (6A).

Memoria administrada a nivel del usuario
Memory Bank es un servicio administrado para la memoria del usuario a largo plazo. Organiza los datos sobre una persona en un alcance definido, que aquí se identifica por el nombre de la aplicación y el ID de usuario:
SCOPE = {"app_name": config.APP, "user_id": config.USER}
TOPICS = {
"CREATOR_TASTE": "Which video directions this creator picks and passes on, "
"and how that preference changes over time.",
"CHANNEL_RULES": "Standing instructions the creator states for every video "
"(style, subjects to avoid, format rules).",
}
Los temas de memoria personalizados definen los límites de lo que registra el banco:
- Extracción de temas: Cuando se envía texto de conversación nuevo a través de
memories.generate, el servicio aplica un modelo de extracción a cada descripción del tema. El texto que no coincide con un tema no genera recuerdos. - Consolidación y eliminación de duplicados: El servicio convierte los hechos recién extraídos en incorporaciones y los compara con los recuerdos existentes en el alcance. Cuando una observación coincide con un recuerdo existente, el servicio actualiza ese recuerdo. Cuando representa información nueva, el servicio crea una entrada nueva. Este proceso de consolidación garantiza que varias sesiones sobre un tema se fusionen en un resumen coherente en lugar de producir entradas redundantes.
- Recuperación: Llamar a
memories.retrievecon el alcance del usuario devuelve hechos almacenados, ordenados del más antiguo al más reciente.
Ambas operaciones se implementan en agent/platform/memory.py. El nombre del recurso bancario aprovisionado se almacena en caché de forma local en runs/memorybank.json.
Cómo configurar Memory Bank
Usa los controles del banco de trabajo o ejecuta los comandos de la CLI en tu terminal:
- Conecta y aprovisiona el banco:
Crea la instancia de Agent Engine y configura los temaspython -m agent.platform.bankCREATOR_TASTEyCHANNEL_RULES. - Propaga sesiones históricas:
Carga cuatro sesiones históricas de creadores (dos temas de animales con restricciones de estilo, un tema de dispositivos y un tema de fantasía reciente).python -m agent.platform.bank load - Inspecciona los hechos consolidados:
Examina el resultado. Observa cómo las transcripciones narrativas se convirtieron en declaraciones de hechos estructuradas y consolidadas.python -m agent.platform.bank list
Devoluciones de llamada (6B)
En el banco de trabajo, navega a Devoluciones de llamada (6B). Abre stage4_memory/agent.py.

Devoluciones de llamada del ciclo de vida del agente del ADK
Una devolución de llamada es una función que se pasa como argumento a un Agent. El ADK invoca devoluciones de llamada en momentos predefinidos del ciclo de vida y pasa el contexto activo. Devolver None continúa la ejecución normal; devolver un objeto de reemplazo anula o intercepta la operación.

El ADK proporciona tres pares de devoluciones de llamada:
Par de devolución de llamada | Punto de invocación | Parámetros recibidos | Comportamiento del valor de retorno |
| Rodea todo el turno del agente. |
| La devolución de |
| Rodea cada llamada de inferencia del LLM |
| Si se devuelve |
| Alrededor de cada ejecución de la herramienta | Definición, argumentos y resultado de la herramienta | Si se devuelve un dict, se anula el resultado de la herramienta y se continúa con |
Las devoluciones de llamada proporcionan una ubicación limpia para la inyección de contexto, los rieles de protección, la telemetría y las búsquedas en caché sin introducir nodos externos en el gráfico de flujo de trabajo.
Edición práctica: Conexión de devoluciones de llamada de recuperación y recuerdo
- En
stage4_memory/agent.py, actualizapropose_directionspara adjuntarbefore_model_callback=recall_taste:
output_schema=Directions,
before_model_callback=recall_taste)
recall_taste se ejecuta inmediatamente antes de que Gemini genere direcciones candidatas. Recupera el historial del creador de Memory Bank, da formato a los recuerdos de más antiguo a más reciente y los agrega al objeto LlmRequest saliente. La instrucción dirige al modelo para que los candidatos de inclinación 1 a 3 se acerquen al gusto actual del creador y, al mismo tiempo, traten las reglas del canal como restricciones estrictas.
- En
stage4_memory/agent.py, actualizascripterpara adjuntarafter_agent_callback=remember_pick:
output_schema=Script,
after_agent_callback=remember_pick)
remember_pick se ejecuta después de que scripter completa su turno. Lee la dirección elegida del estado de la sesión, sintetiza una declaración concisa que resume la decisión del creador y llama a memories.generate para actualizar Memory Bank.
Qué esperar y por qué
Prueba el flujo de trabajo aumentado con devolución de llamada en el banco de trabajo o en la Web del ADK:
- Ejecuta una ejecución con una instrucción vacía:
- En el registro de seguimiento de la sesión, inspecciona
LlmRequestpara verpropose_directions. Observa el contexto de memoria agregado que detalla la preferencia del creador por los temas de fantasía y el ritmo conciso. - Observa las direcciones propuestas: Los candidatos del 1 al 3 se alinean con las preferencias históricas del creador, incluso cuando las tendencias enfatizan otros temas.
- En el registro de seguimiento de la sesión, inspecciona
- Selecciona un candidato en
direction_gate. - Después de que se complete
scripter, revisa los registros de Memory Bank: Ahora, el banco refleja la elección más reciente y la consolida con los registros de preferencias anteriores.python -m agent.platform.bank list
7. RAG Engine
En VibeStudio Workbench, navega a Paso 7 · RAG Engine, partes (7A) y (7B).

Los videos publicados acumulan comentarios continuos de los usuarios. En agent/comments.md, se recopilan treinta comentarios representativos que capturan los elogios de los usuarios, las críticas sobre el ritmo de los videos patrocinados y las preferencias de audio. En este paso, indexarás estos comentarios con Vertex AI RAG Engine y conectarás la recuperación semántica en el fan-out de la investigación.
Recuperación sobre documentos (7A)
En Workbench, navega a RAG Engine (7A).
Comparación entre Memory Bank y RAG Engine
Ambas herramientas basan los flujos de trabajo en datos externos, pero tienen propósitos arquitectónicos distintos:
Dimensión | Memory Bank | RAG Engine |
Caso de uso principal | Preferencias del usuario a largo plazo y reglas operativas | Recuperación semántica en grandes colecciones de documentos |
Alcance | Se limita a los IDs de usuario y nombres de aplicaciones individuales | Se limita a los recursos del corpus compartido entre todos los usuarios. |
Procesamiento de datos | Extracción, incorporación y consolidación semántica en tiempo real | Fragmentación de documentos, incorporación de vectores y búsqueda de vecinos más cercanos |
Integración de grafos | Devoluciones de llamada del ciclo de vida del agente ( | Nodo de función dedicado en fan-out de investigación ( |

Fragmentación y embeddings de documentos
RAG Engine indexa documentos dividiendo el texto en pasajes semánticos y almacenando sus vectores en una base de datos administrada:
corpus = rag.create_corpus(
display_name="vibestudio-feedback",
description="Vibe Studio: what the audience wrote under the channel's past videos.",
backend_config=rag.RagVectorDbConfig(
rag_embedding_model_config=rag.RagEmbeddingModelConfig(
vertex_prediction_endpoint=rag.VertexPredictionEndpoint(
publisher_model="publishers/google/models/text-embedding-005"))))
rag.upload_file(
corpus_name=corpus.name, path="agent/comments.md", display_name="comments.md",
transformation_config=rag.TransformationConfig(
chunking_config=rag.ChunkingConfig(chunk_size=120, chunk_overlap=20)))
- Tamaño del fragmento: Se configuró en 120 tokens con 20 tokens de superposición. Esto captura de dos a tres comentarios por pasaje, lo que garantiza que cada vector represente un sentimiento cohesivo sin diluir el significado en comentarios no relacionados.
- Modelo de embedding:
text-embedding-005convierte texto en vectores de alta dimensión. Cuando se envía una búsqueda, el modelo la convierte en un vector y encuentra las coincidencias más cercanas según la distancia semántica. Un comentario sobre un dragón pequeño que cuida calcetines coincide con una instrucción sobre criaturas mágicas sin requerir una coincidencia exacta de palabras clave.
Configura el corpus de RAG
Inicializa el corpus con los botones del banco de trabajo o los comandos de la terminal:
- Crea el corpus:
Aprovisiona la base de datos vectorial administrada y registra el ID del recurso enpython -m agent.platform.ragruns/ragcorpus.json. - Upload and index comments: Sube
agent/comments.mdcon la configuración de fragmentación y espera a que se complete la indexación. - Consulta el corpus: Prueba la recuperación de similitud con búsquedas que no compartan palabras exactas con los comentarios (por ejemplo, busca "criaturas mágicas pequeñas" para recuperar comentarios sobre dragones).
El nodo de recuperación (7B)
En Workbench, navega a The third reader (7B). Abre stage5_rag/agent.py.

Recuperación como nodo de gráfico
Los comentarios del público representan los datos de investigación que se comparten en todo el flujo de trabajo. A diferencia de la memoria personal del creador, el sentimiento de los usuarios se incorpora directamente a join_research junto con los datos de tendencias y de la lista de tareas pendientes. Por lo tanto, se implementa como un nodo de función:

def read_feedback(node_input):
"""The third reader (step 7): what the audience wrote under past videos,
the passages nearest to tonight's idea. Retrieval, not a model call."""
from .platform import rag
idea = idea_text(node_input)
query = idea or "what viewers liked and what they complained about"
try:
hits = rag.retrieve(query)
except Exception as e:
print(f" [rag] feedback unavailable ({str(e)[:80]})")
return Event(output={"query": query, "feedback": [],
"note": "no corpus connected - run: python -m agent.platform.rag"})
return Event(output={"query": query, "feedback": [h["text"] for h in hits]})
read_feedback extrae la idea inicial del usuario y ejecuta una consulta vectorial en el corpus de RAG Engine. Emite los comentarios recuperados en una carga útil de Event(output=...).
Edición práctica: Cableado del tercer lector en el fan-out
En stage5_rag/agent.py, actualiza edges para agregar read_feedback como una tercera rama paralela que ingresa a join_research:
(START, read_backlog, join_research),
(START, read_feedback, join_research),
Como join_research es un JoinNode, sincroniza todas las ramas entrantes y espera hasta que scan_trends, read_backlog y read_feedback hayan emitido todos los eventos antes de pasar el paquete agregado a la siguiente etapa.
Qué esperar y por qué
Ejecuta el flujo de trabajo en el banco de trabajo:
- Envía una instrucción de idea (como "un dragón en miniatura que cuida una encimera de cocina").
- En el registro de ejecución, verifica que los tres nodos de lectura se ejecuten de forma simultánea.
- Observa
join_research: Su diccionario de salida ahora contienetrends,backlogyfeedback. - Inspecciona los candidatos generados en
propose_directions: El modelo incorpora los comentarios de los usuarios en sus propuestas y hace referencia al sentimiento del público en los campos de evidencia. - Ten en cuenta que la recuperación de RAG es determinística (las consultas idénticas devuelven pasajes de comentarios idénticos), mientras que el nodo de propuesta generativa produce variaciones creativas.
8. Generación asíncrona de video con Veo
En VibeStudio Workbench, navega a Paso 8: El video, partes (8A) y (8B).
Generar videos en alta definición con Google Veo requiere varios minutos por renderización. Bloquear la ejecución por grafos durante este período desperdicia recursos de cómputo, bloquea grupos de subprocesos y expone la ejecución a interrupciones de la conexión HTTP. En este paso, harás que la renderización de video sea asíncrona con el elemento LongRunningFunctionTool del ADK.
Herramientas de larga duración (8A)
En Workbench, navega a A long-running tool (8A). Abre stage6_video/agent.py y agent/deliver.py.

Herramientas síncronas vs. herramientas de ejecución prolongada
Las herramientas de funciones del ADK estándar se ejecutan de forma síncrona dentro de un turno del agente: el modelo llama a la herramienta, espera la carga útil de devolución y, luego, incorpora el resultado al turno en curso.
La renderización de video no se puede completar en un solo turno. En su lugar, render_submit inicia el trabajo de generación y, de inmediato, devuelve un recibo operativo con el estado "pending":
def render_submit(prompt: str) -> dict:
"""Submit one Veo render of `prompt`. Returns at once with a pending
receipt; the clip is delivered later, to this call, by id."""
receipt = videogen.start(f"{prompt} {videogen.NO_TEXT}")
return {"status": "pending", "operation": receipt["operation"], "prompt": receipt["prompt"]}
Cuando se incluye en LongRunningFunctionTool, el ADK intercepta el estado "pending". Finaliza el turno del agente, el flujo de trabajo se suspende en el nodo y los metadatos de la llamada pendiente (incluidos el ID y el recibo de la llamada) se registran en runs/sessions.db. El proceso de ejecución sale de forma limpia sin mantener conexiones de red activas ni subprocesos de trabajo.
Edición práctica: cómo unir la herramienta de renderización
En stage6_video/agent.py, actualiza render_desk para unir render_submit en LongRunningFunctionTool:
tools=[LongRunningFunctionTool(render_submit)])
Reanudación por ID de llamada
El patrón de reanudación universal
El ADK aplica un mecanismo idéntico para suspender y reanudar flujos de trabajo tanto para humanos como para herramientas externas:
Activador de suspensión | Cómo iniciar Construct | Estado de suspensión almacenado | Evento de reanudación |
Decisión humana |
| Abrir la instrucción de entrada en el almacén de sesiones |
|
Herramienta de larga duración |
| Abrir la llamada a herramienta en el almacén de sesiones |
|
En ambos casos, el flujo de trabajo se detiene por completo y se reanuda solo cuando llega un evento con un FunctionResponse coincidente desde una fuente externa: una interfaz de usuario, un webhook o un trabajador en segundo plano.
Edición práctica: Cómo completar la respuesta de entrega
En agent/deliver.py, construye la parte de reanudación FunctionResponse:
part = Part(function_response=FunctionResponse(
id=row["call_id"], name=row["name"], response=response))
El daemon de entrega sondea Veo hasta que se genera el archivo de video y, luego, envía este FunctionResponse a la sesión. El ADK coincide con el ID de llamada y reanuda el flujo de trabajo directamente en el siguiente nodo. Los nodos completados no se vuelven a ejecutar, y el agente no toma otro turno generativo.
Configurar STUDIO_REAL_VIDEO=0 en .env habilita la renderización simulada: start devuelve un recibo de prueba inmediato y check simula la finalización en cinco segundos sin realizar llamadas facturables a la API de Veo.
Integración de canalizaciones (8B)
En el banco de trabajo, navega a render_desk en el gráfico (8B). Abre stage6_video/agent.py.
El nodo terminal de la canalización es store_video. Lee la información de renderización completada de runs/state.json (donde se registró el proceso de entrega) y confirma la URL del video y el estado de generación en el estado de sesión compartido.

Edición práctica: Cableado de la canalización de video completa
En stage6_video/agent.py, actualiza edges para agregar render_desk y store_video:
(quarantine, scripter),
(scripter, render_desk, store_video)])
Qué esperar y por qué
Prueba el flujo de generación asíncrono en el banco de trabajo:
- Ejecuta el flujo de trabajo a través de la selección de candidatos y la generación de secuencias de comandos.
- En
render_desk, observa cómo el agente invocarender_submit. - El flujo de trabajo se suspende de inmediato. En el banco de trabajo o en ADK Web, observa el estado pendiente: la sesión contiene el ID de llamada abierta y ningún proceso en segundo plano consume recursos.
- Ejecuta el daemon de entrega con la consola de la estación de trabajo o en tu terminal:
El proceso de entrega supervisa a Veo hasta que el video está listo y, luego, envía el evento de reanudación.python -m agent.deliver - En ADK Web, actualiza la sesión: la ejecución se reanuda en
store_video, confirma la URL del video en el estado de la sesión y completa el flujo de trabajo.
9. Implementa en Cloud Run
En VibeStudio Workbench, navega a Paso 9: Implementar.
Desarrollaste y verificaste cada componente de la canalización en zonas de pruebas dedicadas. En este paso, ensamblarás la canalización de producción completa y la implementarás en Google Cloud Run.

El ejecutor de ADK
Durante el desarrollo, adk web orquestó el gráfico. En producción, la aplicación aloja el flujo de trabajo con la clase Runner del ADK:
self._svc = DatabaseSessionService(db_url=config.DB_URL)
self._runner = Runner(app_name=config.APP, agent=wf, session_service=self._svc)
async for ev in self._runner.run_async(user_id=config.USER, session_id=run_id, new_message=message):
self._absorb(ev) # fold the ADK event into the run state, publish one app event
# the gate's answer and the render's delivery are the same call, with a function_response part
part = Part(function_response=FunctionResponse(id=call_id, name=name, response=response))
run_async: Controla la ejecución del flujo de trabajo, genera eventos de forma secuencial a medida que se ejecutan los nodos y persiste las actualizaciones en el servicio de sesión.- Reanudación unificada: Las decisiones del usuario en
direction_gatey las entregas de videos completadas de Veo reanudan la ejecución a través de objetosFunctionResponseidénticos enviados arun_async.
La arquitectura de la aplicación de producción
La aplicación de producción en vibestudio/ integra la canalización completa:
vibestudio/
server/
main.py FastAPI: application server, REST routes, static assets
api.py REST API endpoints: run, pick, publish, backlog, profile, history
runner.py Runner orchestration over the workflow, background render poller
platform/ Event bus (SSE stream), file storage, publishing, telemetry
agent/ Production agent package, verified by checks/verify_app.py
graph.py The complete workflow graph and node definitions
desk.py render_desk and render_submit wrapped with LongRunningFunctionTool
schemas.py Pydantic schemas: Directions, CleanedDirection, Script
cleanup_tools.py Deterministic policy tools: find_policy_hits, suggest_replacement
platform/ Memory Bank, RAG Engine, and Veo integrations
web/ Production React user interface
Dockerfile · deploy.py · run.sh
- Flujo de eventos único: El backend de FastAPI publica eventos en un solo flujo de eventos enviados por el servidor (SSE). El frontend de React visualiza el progreso del gráfico en tiempo real y controla las conexiones tardías sin perder el estado.
- Ejecución desacoplada: La aplicación administra el bucle de eventos. El gráfico de flujo de trabajo se enfoca por completo en la lógica de ejecución, sin tener en cuenta la interfaz de frontend.
La lista de bordes del flujo de trabajo completo en agent/graph.py combina todos los patrones arquitectónicos creados a lo largo de este codelab:
(START, scan_trends, join_research),
(START, read_backlog, join_research),
(START, read_feedback, join_research),
(join_research, propose_directions, direction_gate,
persist_direction, policy_check),
(policy_check, {"OK": scripter, "BLOCK": quarantine}),
(quarantine, scripter),
(scripter, render_desk, store_video),
Implementa en Cloud Run
Google Cloud Run proporciona alojamiento sin servidores con escalamiento automático, enrutamiento de solicitudes y compilaciones de contenedores integradas:
gcloud run deploy vibestudio --source vibestudio \
--project $GOOGLE_CLOUD_PROJECT --region us-central1 \
--labels dev-tutorial-codelab=vibetube --allow-unauthenticated \
--memory 2Gi --cpu 2 --timeout 3600 --concurrency 40 \
--max-instances 1 --min-instances 1 --session-affinity \
--set-env-vars GOOGLE_CLOUD_PROJECT=...,STUDIO_VERTEX=1,STUDIO_MEMORY_BANK=...,STUDIO_RAG_CORPUS=...,VIBETUBE_URL=...,VIBETUBE_EVENT=...,VIBETUBE_NAME=...,VIBETUBE_PROJECT=...
- Compilación de contenedor:
gcloud run deploy --sourceempaqueta el directoriovibestudio/, compila la imagen de contenedor con Cloud Build y, luego, implementa el servicio en una sola operación. - Afinidad de sesión: Dirige las solicitudes del mismo usuario a la misma instancia del contenedor, lo que preserva el estado de la sesión local en los pasos iterativos.
- Observabilidad: La integración de Cloud Trace registra intervalos distribuidos para cada nodo, llamada a LLM y ejecución de herramientas, a los que se puede acceder en la consola de Google Cloud en el Explorador de Trace.
Haz clic en el botón Implementar en el banco de trabajo para ejecutar la secuencia de comandos de implementación. Cuando se complete la compilación, el terminal mostrará la URL del servicio activo.

10. Resumen
En VibeStudio Workbench, ve a Paso 10: Resumen para revisar la arquitectura completa.

Paso | Arquitectura y conceptos | Patrón de implementación |
Una sola instrucción | Instrucción única, herramientas de funciones y bucle de chat secuencial |
|
Fundamentos del flujo de trabajo de agentes | Flujo de trabajo de gráficos, investigación paralela, resultados de esquemas, puerta humana |
|
Estado y router | Estado de sesión compartido, vinculación de parámetros, enrutamiento determinístico, agente de tareas |
|
Memory Bank | Memoria a largo plazo a nivel del usuario, consolidación semántica y hooks de ciclo de vida |
|
RAG Engine | Recuperación de documentos a partir de comentarios del público y de incorporaciones semánticas | Nodo |
Generación asíncrona de video con Veo | Herramientas de ejecución prolongada, recibos pendientes y daemon de entrega externo |
|
Implementa en Cloud Run | Orquestación programática, eventos enviados por el servidor y contenedor sin servidores |
|
Principios básicos de arquitectura
- Suspender en lugar de esperar: Los flujos de trabajo se pausan de forma limpia para la entrada humana (
RequestInput) o las operaciones de larga duración (LongRunningFunctionTool). Los procesos no esperan inactivos en los subprocesos ni en los sockets de red. - Reanudación universal: Cada suspensión se reanuda a través de un mecanismo idéntico: un solo
function_responseque lleva el ID de llamada del nodo suspendido. - Administración de estados desacoplada: Los nodos comparten datos a través de claves de estado de sesión con nombre y vinculación de parámetros en lugar de cargas útiles intermedias detalladas y estrechamente acopladas.
- Enrutamiento determinístico antes del costo generativo: Los enrutadores basados en reglas y los filtros de regex evalúan la política con un costo de cero tokens antes de que se ejecuten los modelos generativos.
- Separación de responsabilidades: El contexto específico de un agente individual pertenece a las devoluciones de llamada del ciclo de vida, mientras que las dependencias de datos compartidos pertenecen
