Ir al contenido

GUION v2 — 7 Agentes ADK en PRODUCCIÓN: Cloud Run + Protocolo A2A

GUION v2 — 7 Agentes ADK en PRODUCCIÓN: Cloud Run + Protocolo A2A

Sección titulada «GUION v2 — 7 Agentes ADK en PRODUCCIÓN: Cloud Run + Protocolo A2A»

“Del local a producción real: 7 agentes ADK como servidores A2A independientes en Cloud Run”

Duración objetivo: 45-50 minutos Patrón: Resultado primero → contexto → concepto → deploy en vivo → momento wow → cierre Fecha: 2026-04-03


[PANTALLA: Terminal — curl a una URL de Cloud Run, respuesta JSON del Platform Architect]

TÚ: “Lo que ves ahí es una llamada HTTP real a un agente de IA corriendo en Google Cloud. No en local. No en Docker. En producción.”

[CORTE A: Terminal mostrando las 7 URLs activas — una por agente]

TÚ: “Siete URLs. Siete agentes ADK. Cada uno es un servidor A2A independiente. Y están todos comunicándose entre ellos usando el protocolo A2A.”

[CORTE A: orchestrator_a2a.py corriendo — la cadena completa respondiendo desde Cloud Run]

TÚ: “En el video anterior construí estos mismos 7 agentes en local, en Docker, usando Google ADK. Hoy vamos a llevarlos a producción real. Y voy a mostrarte exactamente cómo.”

[TÍTULO: “7 Agentes ADK en PRODUCCIÓN — Cloud Run + Protocolo A2A”]


TÚ: “Tres cosas que vas a ver en este video:”

“Primero: vas a ver por qué el sistema del video anterior no podía ir a producción tal como estaba, y qué tuve que cambiar en el código para que funcionara.”

“Segundo: vas a ver el deploy completo en vivo — los siete gcloud run deploy, uno por agente, con los tiempos reales. Sin cortes, sin edición.”

“Tercero: al final, voy a mandar una tarea real al sistema completo en producción. El Platform Architect va a decidir un stack, el Infrastructure va a generar infraestructura, y la cadena entera va a correr desde Cloud Run. Ese es el momento donde todo se valida.”


CONTEXTO — EL VIDEO ANTERIOR (2:30 - 6:00)

Sección titulada «CONTEXTO — EL VIDEO ANTERIOR (2:30 - 6:00)»

[MOSTRAR: Screenshot del video ADK anterior]

TÚ: “Contexto rápido. En el video anterior construí un sistema de 7 agentes ADK que generaba un Internal Developer Platform completo: Platform Architect, Infrastructure, Security, CI/CD, Observability, DevEx, Web Portal.”

“Funcionaba así:”

[MOSTRAR: Diagrama — SequentialAgent, todos en un Docker, filesystem compartido]

“Un solo proceso Docker. Un SequentialAgent de Google ADK. El Platform Architect terminaba, escribía un archivo YAML al disco. El Infrastructure lo leía del disco. Y así en cascada los 7.”

TÚ: “Funcionó. El video anduvo bien. Pero había un problema que no mencioné.”

[PAUSA]

“Todo eso es desarrollo local. No es producción. Y la diferencia importa.”


CONCEPTO — POR QUÉ EL SISTEMA LOCAL NO ESCALA (6:00 - 18:00)

Sección titulada «CONCEPTO — POR QUÉ EL SISTEMA LOCAL NO ESCALA (6:00 - 18:00)»

El problema del filesystem compartido (6:00 - 9:00)

Sección titulada «El problema del filesystem compartido (6:00 - 9:00)»

TÚ: “El problema central es este.”

[MOSTRAR: Código — OUTPUT_DIR = os.getenv(‘ADK_OUTPUT_DIR’, ‘/app/outputs’)]

“Cada agente leía y escribía en este directorio compartido. Funcionaba porque todos los agentes corrían en el mismo contenedor Docker, compartiendo el mismo filesystem.”

[MOSTRAR: Diagrama — un solo contenedor, 7 agentes, filesystem compartido]

“Pero en Cloud Run, cada servicio es un contenedor independiente. Si el Platform Architect escribe en /app/outputs, el Infrastructure no puede leer ese archivo — está en otro contenedor, en otra instancia, posiblemente en otra región.”

[MOSTRAR: Diagrama — 7 contenedores independientes, sin filesystem compartido]

“El modelo mental cambia completamente. De un sistema centralizado a un sistema distribuido. Y eso requiere un refactor.”

La solución — protocolo A2A (9:00 - 14:00)

Sección titulada «La solución — protocolo A2A (9:00 - 14:00)»

TÚ: “La solución se llama A2A. Agent-to-Agent. Es un protocolo abierto que Google donó a la Linux Foundation este año.”

[MOSTRAR: a2a-protocol.org]

“La idea es simple: en lugar de que los agentes compartan estado via filesystem, el estado viaja en los mensajes. El orquestador toma el output de cada agente y lo inyecta como contexto en el siguiente.”

[DIAGRAMA — flujo A2A]

Orchestrator → POST /tasks/send → Platform Architect
Platform Architect responde → config del stack
Orchestrator toma esa respuesta → POST /tasks/send → Infrastructure
con el contexto: "el Platform Architect decidió Python + FastAPI + PostgreSQL"
Infrastructure responde → docker-compose generado
Y así con los 7 agentes en cadena.

TÚ: “Cada agente expone dos cosas: un agent card en /.well-known/agent.json que describe sus capacidades, y un endpoint POST /tasks/send donde recibe sus tareas.”

[MOSTRAR: Ejemplo de request A2A]

POST https://platform-architect-xxx.run.app/tasks/send
{
"jsonrpc": "2.0",
"method": "tasks/send",
"params": {
"id": "task-001",
"message": {
"role": "user",
"parts": [{ "text": "Build IDP for a Python FastAPI app" }]
}
}
}

“JSON-RPC 2.0 sobre HTTPS. Stateless. Cada agente recibe su tarea, la procesa, responde. Sin estado compartido.”

El refactor que tuve que hacer (14:00 - 18:00)

Sección titulada «El refactor que tuve que hacer (14:00 - 18:00)»

TÚ: “Para que esto funcionara en Cloud Run, tuve que hacer tres cambios al proyecto del video anterior.”

[MOSTRAR: Estructura de carpetas — antes vs después]

“Primero: cada agente necesitaba su propio servidor HTTP. Agregué un __main__.py a cada carpeta que inicia adk api_server — el servidor A2A que viene incluido en el paquete de Google ADK.”

[MOSTRAR: main.py]

agents_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
app = get_fast_api_app(agents_dir=agents_dir, web=False)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

“Segundo: cada agente necesitaba su propio Dockerfile para poder deployar independientemente.”

[MOSTRAR: Dockerfile]

FROM python:3.13-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
EXPOSE 8080
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --no-dev --frozen
COPY . /app/platform_architect/
ENTRYPOINT ["uv", "run", "adk", "api_server", "--host", "0.0.0.0", "--port", "8080"]

“Noten python:3.13-slim. No Alpine. Alpine rompe con grpcio — que es una dependencia de ADK — porque usa musl libc en lugar de glibc. Ese detalle me costó tiempo encontrarlo.”

“Tercero: los tools de cada agente que leían del filesystem tuvieron que cambiar para aceptar el contexto via mensaje.”

[MOSTRAR: Cambio en get_platform_config() — antes vs después]

# Antes — lee del disco
def get_platform_config() -> dict:
config_path = Path(OUTPUT_DIR) / "platform-config.yaml"
with open(config_path, 'r') as f:
return yaml.safe_load(f)
# Después — acepta contexto del mensaje A2A, fallback al disco para modo local
def get_platform_config(context_json: str = "") -> dict:
if context_json:
data = json.loads(context_json)
return data.get("platform_config") or data
# fallback local
config_path = Path(OUTPUT_DIR) / "platform-config.yaml"
with open(config_path, 'r') as f:
return yaml.safe_load(f)

“Este cambio mantiene compatibilidad hacia atrás. En local sigue funcionando igual. En Cloud Run el contexto llega via mensaje.”


TÚ: “Okay. Vamos al deploy. Tengo el proyecto listo.”

[MOSTRAR: estructura de carpetas agents_adk/]

“Siete carpetas, una por agente. Cada una autosuficiente con su Dockerfile, pyproject.toml y uv.lock.”

[MOSTRAR: gcloud auth list — proyecto activo]

“Tengo GCP configurado. El proyecto es [PROJECT_ID]. La región va a ser us-central1.”

“El comando para cada agente es este:”

gcloud run deploy platform-architect \
--source=agents_adk/platform_architect/ \
--region=us-central1 \
--no-allow-unauthenticated \
--memory=1Gi \
--port=8080

“Siete veces. Uno por uno. Voy a narrar mientras corre.”

[DEPLOY 1 — platform-architect]

TÚ: “Platform Architect. Este es el primer agente — el que decide el stack tecnológico. Cloud Build va a construir la imagen, subirla, y deployar el servicio.”

[narrar mientras corre — ~3-4 minutos por agente]

[URL aparece]

TÚ: “Ahí está. https://platform-architect-[hash].run.app. Online.”

[DEPLOY 2 — infrastructure] TÚ: “Infrastructure. Genera el docker-compose basado en lo que decidió el Platform Architect.”

[DEPLOY 3 — security] TÚ: “Security. Escanea vulnerabilidades.”

[DEPLOY 4 — cicd] TÚ: “CI/CD. Genera los scripts de build, test y deploy.”

[DEPLOY 5 — observability] TÚ: “Observability. Configura Prometheus y Grafana.”

[DEPLOY 6 — devex] TÚ: “DevEx. Genera el CLI tool para el IDP.”

[DEPLOY 7 — web-portal] TÚ: “Web Portal. El último. Este genera el dashboard web completo.”

[URL 7 aparece]

TÚ: “Siete de siete. Todos online.”

[MOSTRAR: las 7 URLs en pantalla]

TÚ: “Antes del momento principal, verifico que los agent cards están respondiendo.”

curl https://platform-architect-[hash].run.app/.well-known/agent.json \
-H "Authorization: Bearer $(gcloud auth print-identity-token)"

[MOSTRAR: JSON del agent card]

TÚ: “Ahí está el agent card. Nombre, descripción, capacidades. El protocolo A2A funcionando.”


MOMENTO WOW — LA CADENA A2A COMPLETA (36:00 - 44:00)

Sección titulada «MOMENTO WOW — LA CADENA A2A COMPLETA (36:00 - 44:00)»

TÚ: “Ahora el momento que estaba esperando. Voy a correr el orchestrator A2A apuntando a las URLs de Cloud Run.”

[MOSTRAR: orchestrator_a2a.py — AGENT_URLS con las 7 URLs de Cloud Run]

AGENT_URLS = {
"platform_architect": "https://platform-architect-[hash].run.app",
"infrastructure": "https://infrastructure-[hash].run.app",
# ...
}

TÚ: “La tarea: la misma del video anterior. ‘Build IDP for a Python FastAPI application’. Pero esta vez los agentes están en producción.”

python orchestrator_a2a.py "Build IDP for a Python FastAPI application"

[MOSTRAR: logs en tiempo real]

TÚ (narrando): “Platform Architect recibiendo la tarea desde Cloud Run…”

[RESPUESTA del Platform Architect]

TÚ: “Ahí está. Decidió Python 3.11, FastAPI, PostgreSQL, Redis. Desde Cloud Run.”

“Ahora el orchestrator toma ese output y lo inyecta como contexto en el mensaje al Infrastructure…”

[RESPUESTA del Infrastructure]

TÚ: “Infrastructure generó el docker-compose basado en la decisión del Platform Architect. Sin leer ningún archivo. El contexto viajó en el mensaje A2A.”

[continúa con los 7 agentes respondiendo en cadena]

[RESPUESTA FINAL — Web Portal]

TÚ: “Siete de siete. La cadena completa. Desde Cloud Run. Protocolo A2A real.”

[PAUSA]

“Esto no era posible con el sistema del video anterior. El filesystem compartido no existe en Cloud Run. El protocolo A2A lo resuelve.”


TÚ: “Tres cosas que me llevé construyendo esto:”

[LECCIÓN 1] “El filesystem compartido es el mayor limitante para escalar agentes. Mientras el estado viva en disco, estás atado a un solo proceso. El protocolo A2A existe específicamente para romper esa dependencia.”

[LECCIÓN 2] “El refactor fue más quirúrgico de lo que esperaba. No tuve que reescribir los agentes — solo cambié cómo reciben el contexto. El parámetro context_json con fallback al filesystem mantiene compatibilidad local y habilita Cloud Run al mismo tiempo.”

[LECCIÓN 3] “python:3.13-slim. No Alpine. grpcio no compila en Alpine. Ese detalle no está documentado en ningún lado de forma clara — lo aprendí por las malas.”

TÚ: “Espero que les haya gustado. Este video es la continuación directa del anterior — si no lo vieron, lo dejo en la descripción. El código completo está en GitHub, link abajo: los 7 Dockerfiles, el orchestrator A2A, todo el refactor.”

[PAUSA]

“Y una cosa que me quedó pensando después de esto: estos 7 agentes están en producción, tienen URLs, responden al protocolo A2A. Cualquier otro agente — de cualquier framework, de cualquier empresa — puede llamarlos. Eso es exactamente para lo que fue diseñado A2A.”

“¿Qué pasaría si construimos un agente externo que use estos 7 como herramientas? Eso lo he pensado. Quizás en el próximo video.”

[FADE OUT]


  • Tiempos reales de cada gcloud run deploy
  • Si hay un error en algún deploy — resolverlo en vivo
  • Los tiempos de respuesta de la cadena A2A desde Cloud Run
  1. Las 7 URLs apareciendo una por una en terminal
  2. curl al agent card de Cloud Run respondiendo JSON
  3. El orchestrator_a2a.py corriendo con logs de cada agente respondiendo
  4. Comparativa visual: diagrama local (filesystem) vs producción (A2A messages)
  • gcloud auth list — proyecto configurado
  • orchestrator_a2a.py con las 7 URLs de Cloud Run ya seteadas
  • Terminal limpia para cada deploy
# Deploy por agente
gcloud run deploy platform-architect \
--source=agents_adk/platform_architect/ \
--region=us-central1 \
--no-allow-unauthenticated \
--memory=1Gi \
--port=8080
# Verificar agent card
curl https://[URL]/.well-known/agent.json \
-H "Authorization: Bearer $(gcloud auth print-identity-token)"
# Correr cadena completa
python orchestrator_a2a.py "Build IDP for a Python FastAPI application"

  • v1 — descartado (tenía Claude Code Agent Teams)
  • v2 — este archivo
  • Revisión
  • Dry run del deploy completo
  • Grabación