Protocolo A2A: Comunicación y Federación Inter-Agente

El estándar abierto para el descubrimiento dinámico mediante Agent Cards, delegación de tareas y colaboración segura entre agentes autónomos heterogéneos.

Resumen Ejecutivo & Respuestas Rápidas (AEO)

¿Qué es el Protocolo A2A (Agent2Agent)? Es el estándar abierto alojado en la Linux Foundation (impulsado originalmente por Google) para la comunicación horizontal (East-West), descubrimiento dinámico y delegación asíncrona de tareas entre agentes de IA autónomos y heterogéneos.

  • Auto-descubrimiento con Agent Cards: Todo agente publica su contrato de capacidades, esquemas de seguridad y skills en /.well-known/agent-card.json.
  • Opacidad de Caja Negra: A diferencia de los frameworks monolíticos, dos agentes colaboran sin compartir su system prompt, memoria privada ni claves API internas.
  • Máquina de Estados de Tarea: Modela encargos complejos de larga duración mediante estados deterministas (submitted, working, input-required, completed, failed, canceled) y entrega de Artifacts verificables.
  • Transporte Tri-Modal: Soporta JSON-RPC 2.0, RESTful HTTP y gRPC con actualizaciones en tiempo real por Server-Sent Events (SSE) o webhooks push.
  • Tríada Arquitectónica: Se complementa con MCP (herramientas Southbound), AG-UI (interfaz de usuario Northbound), Identidad Agéntica (IETF AIMS) y ejecución aislada en OpenSandbox.

1. La Frontera East-West: Hacia la Malla Multi-Agente Federada

En la arquitectura de sistemas autónomos basados en modelos fundacionales, el aislamiento de un único agente ("monolito cognitivo") ha tocado techo. Ningún modelo, por amplio que sea su contexto o especializada que sea su parametrización, puede abarcar simultáneamente la orquestación empresarial, la auditoría legal, el diagnóstico de firmware IoT de bajo nivel y la gestión de infraestructura de nube sin sufrir alucinaciones de rol o saturación cognitiva.

La ingeniería agéntica moderna se articula en torno a la especialización y federación de múltiples agentes. Si el Protocolo MCP resuelve la conexión vertical hacia abajo (Southbound: Agente ↔ Herramientas) y el Protocolo AG-UI resuelve la conexión vertical hacia arriba (Northbound: Agente ↔ Interfaz de Usuario), el Protocolo A2A (Agent2Agent) ocupa el eje horizontal: la frontera East-West (Este-Oeste) que permite la interacción, subcontratación y entrega de tareas entre agentes autónomos independientes.

Lanzado inicialmente bajo el liderazgo de Google con el respaldo de una amplia coalición de la industria (AWS, Microsoft, IBM, Salesforce, SAP, LangChain, CrewAI y ServiceNow) y gestionado como especificación abierta bajo la Linux Foundation (organización a2aproject), A2A funciona como el protocolo HTTP para agentes de IA: una capa estandarizada para que cualquier agente pueda descubrir qué sabe hacer otro agente, encargarle una tarea compleja y recibir el resultado verificado.

Diagrama de arquitectura del Protocolo A2A: Frontera Northbound AG-UI, Agente Orquestador, Frontera East-West A2A con Agent Cards y Máquina de Estados de Tarea, y Frontera Southbound MCP + OpenSandbox
Figura 1. Topología de las tres fronteras agénticas: Northbound (AG-UI hacia el usuario), East-West (Protocolo A2A con descubrimiento vía agent-card.json y ciclo de vida de tareas) y Southbound (MCP y ejecución aislada en OpenSandbox).
Especificación Topológica en Texto (Esquema RFC / ASCII para Agentes & Docs)
┌────────────────────────────────────────────────────────────────────────┐
│               1. CAPA DE INTERFAZ & EXPERIENCIA DE USUARIO             │
│   Web / React  •  Mobile App  •  IDE Sidecar  •  Generative UI         │
└───────────────────────────────────┬────────────────────────────────────┘
                                    ▲  [NORTHBOUND]
                                    │  PROTOCOLO AG-UI (SSE / JSON Patch)
                                    ▼
┌────────────────────────────────────────────────────────────────────────┐
│              2. AGENTE ORQUESTADOR / GENERALISTA (Cliente A2A)         │
│   Descubrimiento de Agent Cards • Enrutamiento Semántico • Validación  │
└───────────────────┬────────────────────────────────┬───────────────────┘
    [EAST-WEST]     │                                │  [SOUTHBOUND]
    PROTOCOLO A2A   │ (JSON-RPC 2.0 / gRPC / REST)   │  PROTOCOLO MCP
                    ▼                                ▼  (JSON-RPC 2.0)
┌───────────────────────────────────────┐   ┌────────────────────────────┐
│  3A. AGENTE ESPECIALISTA REMOTO (A2A) │   │  3B. HERRAMIENTAS LOCALES  │
│  • /.well-known/agent-card.json       │   │  • Bases de Datos SQL/Vec  │
│  • Task State: submitted ➔ working    │   │  • Telemetría IoT & Logs   │
│    ➔ input-required ➔ completed       │   └────────────────────────────┘
│  • Southbound Privado: MCP + Sandbox  │
└───────────────────────────────────────┘

2. El Problema: Los Silos Multi-Agente y la Necesidad de Opacidad

Antes del advenimiento de A2A, cuando dos equipos de ingeniería querían coordinar agentes construidos en diferentes tecnologías, se enfrentaban a barreras insalvables:

  • Incompatibilidad de Runtimes: Un agente implementado con LangGraph en Python no podía colaborar de forma nativa con un agente desarrollado en Semantic Kernel (.NET) o CrewAI sin desplegar adaptadores ad-hoc y wrappers frágiles.
  • Violación del Principio de Caja Negra (Falta de Opacidad): Los enfoques primitivos de multi-agente forzaban a compartir el historial completo de mensajes (*chat history*), los *system prompts* propietarios, la memoria de largo plazo o incluso las claves de API de las herramientas. Esto es inaceptable en entornos corporativos donde un agente contable de un cliente interactúa con el agente logístico de un proveedor externo.
  • Fragilidad ante Tareas Asíncronas y Lentas: Delegar una tarea a otro agente no es una llamada RPC instantánea. Puede requerir minutes de razonamiento, consultas a sensores o pausas de validación. Sin un ciclo de vida estandarizado, las peticiones HTTP sufrían constantes timeouts.

A2A soluciona esta fragmentación garantizando la opacidad absoluta: el agente remoto se comporta como un servicio autónomo delimitado. El agente cliente no necesita saber qué modelo de lenguaje ejecuta el especialista ni qué herramientas internas utiliza; solo necesita consultar su tarjeta de presentación pública, enviar un mensaje con parámetros estructurados y supervisar el ciclo de vida de la tarea.

3. Descubrimiento Dinámico: La Tarjeta de Presentación (Agent Card)

El primer pilar fundamental del protocolo A2A es el mecanismo de auto-descubrimiento. Todo agente compatible con A2A expone un documento JSON público accesible mediante una ruta canónica estándar:

https://<base-url>/.well-known/agent-card.json  (o agent.json)

Este archivo, denominado Agent Card, es la "tarjeta de visita digital" del agente. Permite a orquestadores u otros agentes inspeccionar programáticamente qué problemas sabe resolver, qué formatos de entrada y salida acepta, qué esquemas de autenticación exige y qué capacidades de transporte soporta.

Ejemplo Canónico de una Agent Card (agent-card.json)

{
  "name": "AuditAgent Pro",
  "description": "Agente autónomo especializado en auditoría forense de contratos inteligentes y análisis de cumplimiento regulatorio NIS2.",
  "url": "https://audit.quijotech.com/a2a",
  "version": "1.2.0",
  "provider": {
    "name": "Quijotech Agentic Research Lab",
    "url": "https://quijotech.com"
  },
  "documentationUrl": "https://quijotech.com/tutoriales/protocolo-a2a.html",
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "stateTransitionHistory": true
  },
  "securitySchemes": [
    {
      "type": "oauth2",
      "description": "Requiere delegación Zero-Trust compatible con RFC 8693 / IETF WIMSE AIMS.",
      "tokenUrl": "https://auth.quijotech.com/token"
    }
  ],
  "defaultInputModes": [
    "application/json",
    "text/plain"
  ],
  "defaultOutputModes": [
    "application/json",
    "text/markdown"
  ],
  "skills": [
    {
      "id": "audit_smart_contract",
      "name": "Auditoría de Smart Contracts",
      "description": "Examina código fuente Solidity o Rust en busca de vulnerabilidades de reentrancia, desbordamiento y control de acceso.",
      "tags": ["blockchain", "security", "audit"],
      "inputModes": ["application/json"],
      "outputModes": ["application/json", "text/markdown"],
      "examples": [
        {
          "description": "Analizar contrato de bóveda de liquidez",
          "input": {
            "sourceCode": "contract Vault { ... }",
            "evmTarget": "cancun"
          }
        }
      ]
    }
  ]
}

Gracias a esta tarjeta, un agente orquestador no necesita estar cableado estáticamente: puede consultar un catálogo o registro distribuido de agentes, descargar sus Agent Cards, seleccionar al especialista más capacitado mediante un algoritmo de licitación o *routing semántico*, y negociar la tarea al instante.

4. El Ciclo de Vida de una Tarea: Máquina de Estados de A2A

En el protocolo A2A, cualquier asignación de trabajo delegada a un agente remoto se modela como una Tarea (Task) con estado. La especificación define un modelo formal de ciclo de vida con estados atómicos:

1. submitted
➔
2. working
➔
(input-required)
➔
3. completed / failed
Estado (TaskState) Significado Técnico Acción Esperada del Agente Cliente
submitted La tarea ha sido recibida y encolada por el servidor A2A. Almacenar el taskId y aguardar o suscribirse a eventos.
working El agente especialista está razonando o ejecutando herramientas. Consumir streaming de progreso (si streaming: true) o esperar webhook.
input-required El especialista necesita información adicional o aclaración de contexto. Enviar un nuevo mensaje enlazado al taskId para desbloquear la ejecución.
completed La tarea ha culminado exitosamente. Los artifacts están listos. Descargar artefactos resultantes y realizar validación ciega.
failed Ocurrió un error irrecuperable en el agente remoto. Activar un Circuit Breaker Cognitivo o redirigir a otro par.
canceled La tarea fue cancelada explícitamente por el agente cliente. Liberar recursos y actualizar métricas de auditoría.

El objeto Task devuelto por el servidor A2A no es un simple mensaje de texto; encapsula una estructura integral:

// Contrato del Objeto Task (a2a.proto / JSON schema)
interface Task {
  id: string;                     // Identificador global de la tarea
  sessionId?: string;             // Sesión lógica para correlacionar tareas múltiples
  status: {
    state: "submitted" | "working" | "input-required" | "completed" | "failed" | "canceled";
    message?: Message;            // Mensaje o pensamiento explicativo del cambio de estado
    timestamp: string;            // Marca temporal ISO 8601
  };
  artifacts?: Artifact[];         // Documentos, código, tablas o binarios generados
  history?: Message[];            // Registro cronológico de interacción
  metadata?: Record<string, any>; // Metadatos libres de auditoría y telemetría
}

5. Mecanismos de Transporte y Operaciones del Protocolo

A2A ofrece un diseño tri-modal para adaptarse tanto a microservicios en la nube de baja latencia como a APIs públicas a través de Internet:

  1. JSON-RPC 2.0 sobre HTTP: Formato universal basado en llamadas a procedimientos remotos enviando objetos JSON estructurados con method y params.
  2. RESTful HTTP / JSON: Mapeo estándar con métodos GET y POST sobre endpoints limpios (ej. GET /v1/tasks/{id}, POST /v1/message:send).
  3. gRPC (Protocol Buffers): Transporte binario multiplexado sobre HTTP/2 para mallas internas de alta eficiencia (microservicios de agentes en clústeres Kubernetes).

Invocación Inicial: Creando una Tarea con message/send

Para encargar un trabajo al agente especialista, el cliente emite una llamada JSON-RPC o una petición REST con el bloque de configuración y el mensaje:

// Petición JSON-RPC 2.0: Host -> A2A Server
{
  "jsonrpc": "2.0",
  "id": "req-98741",
  "method": "message/send",
  "params": {
    "configuration": {
      "acceptedOutputModes": ["application/json", "text/markdown"],
      "historyLength": 10
    },
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "Audita este fragmento de contrato y evalúa riesgo de reentrancia."
        },
        {
          "kind": "data",
          "data": {
            "solidity": "function withdraw() public { msg.sender.call{value: bal}(''); balances[msg.sender] = 0; }"
          }
        }
      ],
      "messageId": "msg-client-001"
    }
  }
}

El servidor responde inmediatamente con un identificador de tarea y su estado inicial, o con el resultado final si la ejecución fue síncrona:

// Respuesta JSON-RPC 2.0: A2A Server -> Host
{
  "jsonrpc": "2.0",
  "id": "req-98741",
  "result": {
    "taskId": "task-sec-4402",
    "status": {
      "state": "working",
      "message": {
        "role": "agent",
        "parts": [{"kind": "text", "text": "Compilando AST y verificando flujos de llamadas externas..."}]
      },
      "timestamp": "2026-10-23T12:05:00Z"
    }
  }
}

Tres Métodos para Recibir Actualizaciones de la Tarea

Dependiendo de las capacidades declaradas en la Agent Card del especialista, el cliente puede optar por tres vías:

  • Streaming en Tiempo Real (message/stream o tasks/subscribe): El servidor abre un canal Server-Sent Events (SSE) transmitiendo eventos incrementales (TaskStatusUpdateEvent, TaskArtifactUpdateEvent).
  • Notificaciones Push (Webhooks): El cliente registra una URL de retorno en POST /v1/tasks/{id}/pushNotificationConfigs y el agente remoto envía una notificación HTTP cuando la tarea cambia de estado.
  • Sondeo (Polling): El cliente realiza peticiones GET /v1/tasks/{id} periódicamente hasta alcanzar un estado terminal.

6. Implementación Práctica: Servidor A2A y Cliente Federado en Python

A continuación se presenta una implementación concisa y funcional de un microservicio que expone una Agent Card oficial y gestiona tareas A2A con FastAPI, junto con un cliente que consume sus servicios.

A. Servidor A2A Especialista (FastAPI)

# a2a_specialist_server.py
import uuid
from typing import Any, Dict, List, Optional
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI(title="Quijotech Code Review A2A Specialist")

# Almacén de tareas en memoria
tasks_db: Dict[str, dict] = {}

# 1. Endpoint Canónico de Descubrimiento (Agent Card)
@app.get("/.well-known/agent-card.json")
async def get_agent_card():
    return {
        "name": "StaticReviewAgent",
        "description": "Especialista en revisión de código estático y detección de fugas de memoria para sistemas distribuidos.",
        "url": "http://localhost:8000",
        "version": "1.0.0",
        "provider": {"name": "Quijotech", "url": "https://quijotech.com"},
        "capabilities": {
            "streaming": False,
            "pushNotifications": False,
            "stateTransitionHistory": True
        },
        "defaultInputModes": ["application/json", "text/plain"],
        "defaultOutputModes": ["application/json"],
        "skills": [
            {
                "id": "review_python_ast",
                "name": "Python AST Security Review",
                "description": "Detecta usos peligrosos de eval, exec o subprocesos no saneados.",
                "tags": ["security", "ast", "python"]
            }
        ]
    }

# Modelos para la creación de tareas
class MessagePart(BaseModel):
    kind: str
    text: Optional[str] = None
    data: Optional[Dict[str, Any]] = None

class Message(BaseModel):
    role: str
    parts: List[MessagePart]

class SendMessagePayload(BaseModel):
    message: Message
    configuration: Optional[Dict[str, Any]] = None

# 2. Endpoint de Recepción y Procesamiento de Tareas (REST /v1/message:send)
@app.post("/v1/message:send")
async def send_message(payload: SendMessagePayload):
    task_id = f"task_{uuid.uuid4().hex[:8]}"
    
    # Extraer código suministrado por el agente cliente
    code_text = ""
    for part in payload.message.parts:
        if part.kind == "text" and part.text:
            code_text += part.text

    # Simulación de análisis cognitivo
    has_vulnerability = "eval(" in code_text or "os.system(" in code_text
    
    task_record = {
        "id": task_id,
        "status": {
            "state": "completed",
            "message": {"role": "agent", "parts": [{"kind": "text", "text": "Revisión de seguridad concluida."}]},
            "timestamp": "2026-10-23T12:15:00Z"
        },
        "artifacts": [
            {
                "name": "security_report.json",
                "mimeType": "application/json",
                "data": {
                    "vulnerable": has_vulnerability,
                    "findings": ["Uso crítico de ejecución insegura detectado"] if has_vulnerability else [],
                    "score": 2.5 if has_vulnerability else 10.0
                }
            }
        ]
    }
    tasks_db[task_id] = task_record
    return {"taskId": task_id, "task": task_record}

# 3. Endpoint de Inspección de Estado (GET /v1/tasks/{id})
@app.get("/v1/tasks/{task_id}")
async def get_task(task_id: str):
    if task_id not in tasks_db:
        raise HTTPException(status_code=404, detail="Tarea no encontrada")
    return tasks_db[task_id]

B. Agente Orquestador Cliente (Python httpx)

El orquestador descubre al agente, verifica sus capacidades, le asigna la tarea y extrae los artefactos producidos:

# a2a_orchestrator_client.py
import httpx
import asyncio

async def delegate_code_review(target_agent_base_url: str, code_snippet: str):
    async with httpx.AsyncClient() as client:
        # 1. Paso de Descubrimiento: Obtener y validar la Agent Card
        card_res = await client.get(f"{target_agent_base_url}/.well-known/agent-card.json")
        card_res.raise_for_status()
        agent_card = card_res.json()
        print(f"[Orquestador] Agente especialista descubierto: {agent_card['name']} v{agent_card['version']}")

        # 2. Paso de Delegación: Enviar tarea formateada en protocolo A2A
        payload = {
            "message": {
                "role": "user",
                "parts": [
                    {"kind": "text", "text": code_snippet}
                ]
            }
        }
        send_res = await client.post(f"{target_agent_base_url}/v1/message:send", json=payload)
        send_res.raise_for_status()
        task_data = send_res.json()["task"]

        # 3. Evaluar estado y procesar entregables
        if task_data["status"]["state"] == "completed":
            artifact = task_data["artifacts"][0]
            print(f"[Orquestador] Tarea finalizada con éxito. Artefacto recibido: {artifact['name']}")
            print(f"[Orquestador] Hallazgos: {artifact['data']}")
            return artifact["data"]

# Ejecución de prueba
if __name__ == "__main__":
    snippet = "import os\ndef run_cmd(user_input): os.system(user_input)"
    asyncio.run(delegate_code_review("http://localhost:8000", snippet))

7. Sinergia Total: La Danza Armónica de MCP, A2A y AG-UI

La verdadera potencia de la ingeniería agéntica se manifiesta cuando los tres protocolos operan en una coreografía integrada:

Caso de Estudio: Malla Agéntica de Gestión de Incidencias IoT

  1. El usuario interactúa vía AG-UI: El operador técnico abre el dashboard de control web y escribe: "Detecto comportamientos extraños en los nodos LoRaWAN del campus. Investiga y corrige."
  2. El orquestador consulta herramientas Southbound vía MCP: El agente orquestador invoca una herramienta MCP local para consultar la base de datos de telemetría y detecta firmas de firmware anómalas.
  3. El orquestador descubre y delega East-West vía A2A: Al comprender que se trata de un problema de bajo nivel en microcontroladores RISC-V, el orquestador descarga la Agent Card del EmbeddedSpecialistAgent, le asigna una tarea A2A con los volcados de memoria y aguarda el análisis forense.
  4. El especialista A2A ejecuta y devuelve artefactos: El agente especialista analiza el volcado, genera un parche de firmware binario como artefacto y marca la tarea A2A como completed.
  5. El orquestador solicita aprobación humana vía AG-UI (HITL): Dado que flashear firmware en producción es de alto riesgo, el orquestador emite un evento RUN_FINISHED con outcome.type = "interrupt" hacia la interfaz web. El usuario pulsa "Autorizar despliegue" en el modal y reanuda el ciclo para culminar la operación.

En este flujo integral, ningún protocolo compite con otro: cada uno opera en su estrato natural, proporcionando modularidad, seguridad y observabilidad extrema.

8. Matriz Comparativa de la Tríada: MCP vs. A2A vs. AG-UI

La siguiente tabla sintetiza las diferencias técnicas cardinales entre los tres grandes estándares abiertos:

Parámetro de Arquitectura Model Context Protocol (MCP) Agent2Agent Protocol (A2A) Agent-User Interaction (AG-UI)
Frontera Cardinal Southbound (Sur) East-West (Este-Oeste) Northbound (Norte)
Entidades Conectadas Agente ↔ Herramientas / Fuentes de Datos Agente Autónomo ↔ Agente Especialista Runtime del Agente ↔ Interfaz de Usuario / Frontend
Mecanismo de Descubrimiento Métodos tools/list y resources/list Archivo público /.well-known/agent-card.json Contrato RunAgentInput.tools (herramientas frontend)
Modelo de Ejecución Invocación atómica de herramientas (Tool Calls) Tareas asíncronas con ciclo de vida y artefactos Streaming reactivo de eventos token a token
Protocolo de Transporte JSON-RPC 2.0 sobre stdio o HTTP SSE gRPC (HTTP/2), JSON-RPC 2.0 o REST HTTP HTTP POST con Server-Sent Events (SSE)
Ecosistema e Impulsores Anthropic, Cursor, Zed, ModelContextProtocol Org Google, Linux Foundation, AWS, IBM, Salesforce CopilotKit, Microsoft Agent Framework, Pydantic AI
Metáfora Arquitectónica El puerto USB-C del agente El HTTP / BGP de la red de agentes El HDMI / Monitor Reactivo del agente

9. Preguntas Frecuentes sobre el Protocolo A2A (FAQ & AEO)

¿Qué diferencia hay entre A2A y una simple API REST con OpenAPI?

Aunque A2A puede transportarse sobre HTTP/REST, introduce semántica agéntica nativa: una máquina de estados para tareas no lineales (con soporte para estados intermedios como input-required), contratos para la emisión de artefactos heterogéneos, auto-descubrimiento estandarizado con Agent Cards y mecanismos de streaming o webhook adaptados a la naturaleza reflexiva y de larga duración de la inferencia con LLMs.

¿Cómo garantiza A2A la seguridad entre agentes de distintas organizaciones?

A2A no asume confianza ciega. En su Agent Card declara securitySchemes basados en estándares industriales como OAuth 2.0 (RFC 6749), mTLS o protocolos emergentes de delegación Zero-Trust como el estándar IETF WIMSE AIMS. Además, el aislamiento por diseño evita la inyección accidental de memoria interna o filtración de claves privadas entre organizaciones.

¿Puede un agente A2A utilizar MCP y OpenSandbox internamente?

Totalmente. De hecho, es el patrón de referencia: el agente especialista A2A recibe la encomienda desde el exterior mediante A2A, consulta sus bases de datos conectándose a sus propios servidores MCP internos y ejecuta scripts o compilaciones de forma aislada dentro de OpenSandbox.

¿Qué relación guarda A2A con el "Handover Atómico" de agentes?

El Handover Atómico define el patrón de diseño cognitivo para traspasar la intención y el contexto de un agente a otro sin fugas de tokens ni alucinaciones. A2A proporciona la capa de transporte de red y la especificación de mensaje estandarizada para materializar dicho handover entre diferentes sistemas físicos.

Guías Relacionadas en esta Serie (Topic Cluster)

Referencias y Fuentes Oficiales Tier 1