Ir al contenido

Arquitectura: del filesystem compartido a A2A

En el sistema local, todos los agentes comparten un directorio de salida. Cada agente escribe sus decisiones en archivos y el siguiente los lee directamente:

OUTPUT_DIR = os.getenv('ADK_OUTPUT_DIR', '/app/outputs')

Esto funciona porque todos corren en el mismo contenedor Docker con acceso al mismo filesystem. En Cloud Run, cada servicio tiene su propio contenedor aislado — no hay /app/outputs/ compartido.

Por qué no filesystem compartido en Cloud Run

Sección titulada «Por qué no filesystem compartido en Cloud Run»

Existen opciones como GCS FUSE o Filestore NFS para montar volúmenes compartidos. Sin embargo, Google no las recomienda para comunicación entre servicios. El patrón correcto en arquitecturas serverless es: el estado viaja en los mensajes, no en el filesystem.

Agent-to-Agent (A2A) es un protocolo abierto bajo la Linux Foundation. Cada agente se expone como un servidor HTTP independiente con su propia URL. La comunicación es via mensajes JSON — el orquestador envía una tarea y recibe una respuesta.

El orquestador encadena los 7 agentes y acumula el contexto de cada uno. Cada agente recibe todo lo que generaron los anteriores:

Orquestador
├──→ Platform Architect (recibe: tarea)
├──→ Infrastructure (recibe: tarea + contexto PA)
├──→ Security (recibe: tarea + contexto PA + Infra)
├──→ CI/CD (recibe: tarea + contexto PA + Infra + Sec)
├──→ Observability (recibe: tarea + PA + Infra + Sec + CICD)
├──→ DevEx (recibe: tarea + PA + Infra + Sec + CICD + Obs)
└──→ Web Portal (recibe: tarea + todos los 6 anteriores)

El contexto crece en cada paso. Web Portal recibe el output acumulado de los 6 agentes previos para construir el portal con toda la información del IDP.

El cambio principal está en cómo cada agente obtiene el contexto de los anteriores.

Antes (sistema local) — lee del disco:

def get_platform_config() -> dict:
"""Lee platform-config.yaml del filesystem compartido."""
config_path = os.path.join(OUTPUT_DIR, 'platform-config.yaml')
with open(config_path) as f:
return yaml.safe_load(f)

Después (Cloud Run) — lee del mensaje, con fallback a disco:

def get_platform_config(context_json: str = "") -> dict:
"""Lee contexto del mensaje A2A. Fallback a disco si está vacío."""
if context_json:
return json.loads(context_json)
# Fallback para ejecución local
config_path = os.path.join(OUTPUT_DIR, 'platform-config.yaml')
with open(config_path) as f:
return yaml.safe_load(f)

Este patrón se repite en 6 de los 7 agentes. Platform Architect no lo necesita porque es el primero de la cadena — no tiene contexto previo que recibir.


Siguiente paso: Los 7 agentes — Dockerfile, agent.json y tools →