← Blog
20 de mayo, 2026 · 15 min

Protocolo A2A: el estándar de interoperabilidad entre agentes, anatomía completa, y cómo lo usamos en LLM4Agents

Si MCP es cómo un agente le habla a sus herramientas, A2A es cómo un agente le habla a otro agente. Google anunció el protocolo en abril de 2025 con cincuenta partners tecnológicos en la slide de lanzamiento, lo donó a la Linux Foundation en junio de 2025, y shippeó v1.0 a principios de 2026 con más de 150 organizaciones soportándolo — Microsoft, AWS, Salesforce, SAP, ServiceNow, Workday, IBM, MongoDB, Atlassian, PayPal entre ellas. En el año desde el lanzamiento A2A absorbió el rol que la spec de nadie más podía llenar del todo: la capa horizontal de interoperabilidad para agentes autónomos. Este post recorre el protocolo de punta a punta — schema de Agent Card, once métodos JSON-RPC, lifecycle de tasks de ocho estados, tres mecanismos de update, cinco esquemas de auth — explica por qué importó esta capa y no otra, muestra cómo LLM4Agents cablea A2A con Agent Gen, x402 y ERC-8004, y cierra con las cuatro mejoras concretas que al protocolo todavía le faltan.

Por qué A2A y no otra API hecha a medida

Antes de A2A, cada plataforma comercial de agentes shippeaba su propia RPC. Los agentes Einstein de Salesforce hablaban con cosas de Salesforce. Los agentes Now Assist de ServiceNow hablaban con cosas de ServiceNow. Los agentes Microsoft Copilot Studio hablaban con Microsoft Graph. La comunicación cross-vendor de agentes era un backlog de integraciones one-off, cada una un adaptador frágil contra un schema privado, ninguna componible.

Es la misma forma de problema que tenía la web en los 2000s tempranos antes de que las convenciones REST hicieran rutinaria la composición cross-vendor de servicios. La apuesta de A2A — y la razón por la que 150 organizaciones firmaron tan rápido — es que la misma convergencia le pasa a los agentes ahora: un solo transport, un solo mecanismo de discovery, un solo modelo de task, y el efecto red hace el resto. Un agente que hable A2A puede ser contratado por cualquier otro agente que hable A2A, sin importar quién construyó cualquiera de los dos. El primer vendor en negarse a la interoperabilidad paga el precio; el último vendor en negarse es no-contratable.

Las decisiones técnicas que hicieron exitoso a A2A donde fallaron los intentos previos (protocolos de agentes de LangChain, handoffs de AutoGen, IBM ACP) son todas conservadoras. HTTPS como transport. JSON-RPC 2.0 como envelope. SSE como mecanismo de streaming. Webhooks como callback async. Esquemas de auth empresariales — OAuth 2.0, OIDC, mTLS, API keys — en lugar de inventar nuevos. Nada de esto es novedoso. Son las primitivas aburridas, probadas en batalla, que todo equipo de integración empresarial ya sabe operar. El protocolo shippeó como algo que la infraestructura existente podía absorber el día uno.

La Agent Card

Una Agent Card es un documento JSON que un agente sirve en una well-known URL — por convención /.well-known/agent-card.json — que describe todo lo que otro agente necesita para interactuar con este. Es el equivalente como archivo de un registro TXT de DNS para discovery de capacidades: legible por máquina, cacheable, firmable.

Una Agent Card mínima pero realista luce así:

{
  "name": "research-agent",
  "description": "Agente de investigación de larga duración especializado en analítica de tokens",
  "version": "1.4.2",
  "provider": {
    "organization": "LLM4Agents",
    "url": "https://llm4agents.com"
  },
  "url": "https://agent.example/a2a",
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "extendedAgentCard": true
  },
  "defaultInputModes": ["text", "data", "file"],
  "defaultOutputModes": ["text", "data"],
  "securitySchemes": {
    "oauth2": {
      "type": "oauth2",
      "flows": { "clientCredentials": {
        "tokenUrl": "https://auth.example/token",
        "scopes": { "agent:invoke": "Invocar el agente" }
      }}
    }
  },
  "security": [{ "oauth2": ["agent:invoke"] }],
  "skills": [
    {
      "id": "market-research",
      "name": "Investigación de mercado de tokens",
      "description": "Compilar un reporte estructurado sobre dinámica de mercado, liquidez, top holders y actividad on-chain reciente de un token.",
      "tags": ["crypto", "research", "on-chain"],
      "inputModes": ["text", "data"],
      "outputModes": ["text", "data"],
      "examples": [
        "Investigar liquidez de SOL en DEXs de Solana en los últimos 30 días"
      ]
    }
  ],
  "extensions": [
    { "uri": "https://llm4agents.com/ext/x402-payable", "required": false },
    { "uri": "https://llm4agents.com/ext/erc8004-bound", "required": false }
  ]
}

La estructura es intencionalmente angosta. Un consumidor lee la card y aprende cinco cosas en orden: qué es el agente, dónde llamarlo, cómo autenticarse, qué puede hacer (el array skills), y qué extensiones opcionales soporta. Las skills son la unidad de advertencia de capacidad. Cada skill es una capacidad nombrada, etiquetada y descrita con modalidades concretas de input/output y ejemplos en lenguaje natural. Un servicio de discovery puede indexar skills de la misma forma que un motor de búsqueda indexa páginas web.

La capability extendedAgentCard es la puerta de privacidad. Una Agent Card baseline puede declarar solo lo que el agente quiere que la internet abierta vea. Los callers que autentiquen reciben una card más rica — herramientas internas, skills premium, rate limits más altos — llamando GetExtendedAgentCard. Esto resuelve la objeción "¿tengo que publicar cada capacidad interna al mundo?" que las empresas levantan en la primera revisión de diseño.

Los once métodos JSON-RPC

A2A es un protocolo JSON-RPC 2.0. Cada método es un POST a la URL del agente con un cuerpo JSON que nombra el método, fija un id, y carga params tipados. La superficie completa de métodos son once llamadas, divididas en tres grupos.

Mensajería (2):

  1. SendMessage — enviar un mensaje al agente, recibir o un Message directo o un handle de Task para trabajo de larga duración
  2. SendStreamingMessage — mismo envío, pero la respuesta es un stream Server-Sent Events de updates incrementales (requiere capabilities.streaming)

Lifecycle de Tasks (4):

  1. GetTask — obtener el estado actual de una task, sus artifacts, e historia opcional
  2. ListTasks — listado paginado y filtrable de las tasks de un agente (basado en cursor)
  3. CancelTask — pedir cancelación, idempotente
  4. SubscribeToTask — abrir un stream SSE de updates incrementales para una task ya en curso

Push notifications (4):

  1. CreateTaskPushNotificationConfig — registrar un webhook para updates async de una task
  2. GetTaskPushNotificationConfig — obtener una configuración registrada de webhook
  3. ListTaskPushNotificationConfigs — listar todos los webhooks de una task
  4. DeleteTaskPushNotificationConfig — eliminar un webhook

Discovery (1):

  1. GetExtendedAgentCard — obtener la Agent Card privilegiada después de autenticar

Once métodos es chico suficiente para implementarse en un weekend y completo suficiente para operar a escala. La decisión de mantener la superficie angosta fue deliberada: cada método adicional es una cosa más sobre la cual 150 implementaciones tienen que ponerse de acuerdo.

El lifecycle de Tasks

Las tasks son la abstracción de primera clase de A2A para trabajo que no retorna sincrónicamente. Un agente recibe un SendMessage, decide que el trabajo es asíncrono, devuelve un handle de Task, y emite transiciones de estado hasta que la task llega a un estado terminal.

Los ocho estados definidos forman una máquina de estados chica:

Inicial:
  TASK_STATE_SUBMITTED       // task aceptada, encolada

Activo:
  TASK_STATE_WORKING         // el agente está haciendo el trabajo

Interrumpible (no terminal):
  TASK_STATE_INPUT_REQUIRED  // esperando que el caller provea más info
  TASK_STATE_AUTH_REQUIRED   // esperando que el caller autentique

Terminal:
  TASK_STATE_COMPLETED       // éxito, artifacts adjuntos
  TASK_STATE_FAILED          // el agente no pudo completar
  TASK_STATE_CANCELED        // caller canceló o el sistema abortó
  TASK_STATE_REJECTED        // el agente se negó (policy, capacity, scope)

Los estados interrumpibles son la movida de diseño que separa a A2A de un RPC ingenuo de "llamá al agente y esperá". Una task tiene permitido pausarse y pedirle al caller más input o autenticación, y después reanudarse. El caller reanuda la task mandando un nuevo SendMessage contra el mismo task id con el input pedido. Esto maneja los modos de falla dominantes del mundo real (el agente se topó con ambigüedad a mitad de camino; el agente necesitó una herramienta que requiere el consentimiento OAuth del usuario) sin forzarlos a o "fallar la task" o "adivinar y degradar silenciosamente".

REJECTED como un estado terminal distinto importa más de lo que parece. Es la affordance a nivel protocolo para que un agente diga "no voy a hacer este trabajo" — sobrecapacidad, scope mismatch, violación de política — sin reclamar falla. La distinción es lo que permite a los orquestadores downstream rutear correctamente: una task fallida puede valer la pena reintentar con un agente distinto; una task rechazada es una respuesta definitiva que no debería reintentarse contra el mismo agente.

Messages, parts, y artifacts

La estructura de mensajes es intencionalmente cercana a la estructura de los content blocks de Claude o las message parts de OpenAI, lo cual significa que agentes escritos contra una API LLM existente pueden serializarse a A2A sin mucha traducción.

Un Message tiene un role (user o agent) y un array de Parts. Cada Part es uno de cuatro tipos:

Un Artifact es el contenedor de output que un agente adjunta a una task completada (o en progreso). Los artifacts tienen su propio ID, un nombre y descripción human-readable, y un array de Parts. La forma espeja Messages a propósito: un artifact es lo que un agente produce; un message es lo que un agente recibe o emite en conversación.

La separación de artifacts de messages es la respuesta de la spec a "dónde va el work product". Una task larga de agente puede emitir docenas de mensajes incrementales en el camino (progreso, razonamiento intermedio, pedidos de input) y un número pequeño de artifacts al final (el reporte, el diff, el plan). Los callers que polean la task pueden leer los artifacts independientemente del historial conversacional.

Tres mecanismos de update, elegidos deliberadamente

¿Cómo aprende un caller que una task progresó? A2A da tres opciones y deja que el agente declare cuáles soporta.

Polling. El baseline aburrido. El caller invoca GetTask en un horario. Siempre disponible. Mayor latencia, infraestructura más simple.

Server-Sent Events (SSE). El caller abre una conexión HTTP de larga duración vía SendStreamingMessage o SubscribeToTask y lee updates incrementales a medida que llegan. Requiere capabilities.streaming. Adecuado para UIs interactivas y tasks de duración corta-a-media donde el caller está vivo durante la duración.

Push notifications (webhooks). El caller registra un webhook HTTPS sobre la task vía CreateTaskPushNotificationConfig. El agente postea updates al webhook cuando cambia el estado. Requiere capabilities.pushNotifications. Adecuado para tasks de larga duración donde el caller no puede mantenerse conectado (jobs nocturnos, workflows multi-día, handoffs agente-a-agente).

El enfoque de tres canales es la respuesta correcta porque ningún canal solo cubre todas las cargas reales. SSE se rompe cuando el proceso del caller muere. Los webhooks se rompen cuando el caller está detrás de un NAT o no corre un servidor. El polling funciona en todos lados pero desperdicia round-trips. Un protocolo que soporta los tres y deja que el caller elija es el protocolo que una empresa puede deployar sin reescribir su infraestructura de eventos.

Autenticación, el detalle poco glamoroso que importó

A2A reusa los security schemes de OpenAPI textualmente:

Reusar los schemes de OpenAPI significa que todo API gateway, todo identity provider, todo equipo de seguridad empresarial ya sabe operar A2A. Esto suena como un detalle poco sexy. Es la razón por la que 150 organizaciones pudieron shippear soporte en sus productos existentes sin auditar un protocolo nuevo desde cero.

A2A vs MCP, el modelo mental correcto

La pregunta más común que recibimos de equipos adoptando ambos es "cuál uso". La respuesta es "los dos, en capas distintas".

MCP — capa vertical: agente ↔ herramientas
  agente  ──MCP──>  filesystem, base de datos, search, API custom

A2A — capa horizontal: agente ↔ agente
  agente A  ──A2A──>  agente B
                     ↓
                     └──MCP──>  sus propias herramientas

Un agente típicamente habla MCP hacia abajo (para consumir herramientas y recursos) y A2A hacia afuera (para delegar a o ser delegado por otros agentes). Los dos protocolos no compiten; componen. El deployment de producción de PayPal es un ejemplo limpio: un sales agent del lado del comprador habla A2A al agente de facturación hosteado por PayPal, que internamente habla MCP a los sistemas de billing subyacentes de PayPal. El agente del comprador nunca toca el servidor MCP de PayPal — ese borde es propiedad de PayPal — pero igual puede delegar trabajo dentro del territorio de PayPal porque ambos lados hablan A2A.

La otra forma de decir la relación: MCP es el protocolo que implementás para exponer las herramientas de un agente; A2A es el protocolo que implementás para exponer las skills de un agente. Las herramientas son operaciones unitarias. Las skills son outcomes mediados por agente. Las dos abstracciones corresponden a los dos scopes en los que un sistema de agentes es componible, y el campo está convergiendo en correr ambos lado a lado.

Cómo LLM4Agents construye sobre A2A

Cada agente generado por Agent Gen shippea con un endpoint A2A por defecto. El endpoint vive en la URL pública del agente, la Agent Card se sirve en /.well-known/agent-card.json, y el registration file ERC-8004 del agente referencia el endpoint A2A bajo endpoints.a2a. Los cuatro archivos están cableados juntos para que una contraparte descubriendo al agente a través del registry on-chain pueda sacar la Agent Card sin un paso adicional out-of-band.

La integración con x402 es donde la composición se vuelve interesante. La spec de A2A no incluye primitivas de pago — y deliberadamente; los protocolos que intentan hacer todo terminan no haciendo nada bien. Cerramos la brecha con una URI de extensión publicada, https://llm4agents.com/ext/x402-payable, declarada en el array extensions de la Agent Card. Un agente que soporta la extensión acepta el siguiente patrón:

  1. El caller manda un SendMessage a una skill paga.
  2. El agente responde con una Task en estado TASK_STATE_INPUT_REQUIRED y una Part de mensaje de tipo data conteniendo un requerimiento de pago x402.
  3. El caller firma el pago x402, postea la prueba al agente vía un segundo SendMessage.
  4. El agente verifica vía el facilitator de x402, transiciona la task a TASK_STATE_WORKING, y termina normalmente.

Esto es una interacción puramente A2A con un flag de extensión. No hizo falta ninguna RPC nueva. El estado interrumpible INPUT_REQUIRED fue diseñado exactamente para este tipo de flujo pausar-y-recolectar-del-caller, y lo estamos usando como fue pensado.

El binding con ERC-8004 funciona de la misma forma. Una URI de extensión, https://llm4agents.com/ext/erc8004-bound, declara que la identidad del agente está anclada on-chain. La Agent Card incluye la URI del token de identidad del agente; las contrapartes pueden resolver records de reputación y validación antes de decidir mandar el primer SendMessage. Posteamos recibos de validación de vuelta a ERC-8004 después de cada task completada, lo cual cierra el loop: el track record de un agente desde interacciones A2A se vuelve queryable desde un smart contract.

El patrón de composición que shippeamos por defecto en el SDK luce así:

// Pseudocódigo del flujo de composición del SDK de LLM4Agents

const registry = await erc8004.identityRegistry()
const candidates = await registry.search({ skill: "market-research",
                                            minReputation: 90 })

for (const cand of candidates) {
  const card = await a2a.getAgentCard(cand.endpoint)
  if (!card.skills.find(s => s.id === "market-research")) continue

  const task = await a2a.sendMessage(cand.endpoint, {
    skill: "market-research",
    parts: [{ type: "text", text: "Investigar liquidez de SOL..." }]
  })

  if (task.state === "TASK_STATE_INPUT_REQUIRED" &&
      task.message.parts[0].data.x402) {
    await x402.payAndSubmit(cand.endpoint, task.id, task.message.parts[0].data.x402)
  }

  const result = await a2a.waitForTerminal(cand.endpoint, task.id)
  await erc8004.validation.attest(cand.tokenId, result.success, result.metrics)
  return result
}

Discovery vía ERC-8004, chequeo de capacidad vía Agent Card de A2A, pago vía x402 dentro de una task A2A, validación de vuelta a ERC-8004 una vez que la task aterriza. Cuatro protocolos componiendo a través de sus seams bien definidos. Ninguno de ellos propiedad de un vendor único.

Dónde A2A todavía tiene que mejorar

A2A v1.0 es production-grade para su scope. La crítica honesta — y el trabajo que el working group del protocolo tiene por delante — está en lo que el scope excluye deliberadamente.

Métodos payment-aware. El patrón x402-vía-INPUT_REQUIRED funciona, pero es un workaround. El comercio de agentes va a ser el caso de uso dominante del tráfico agente-a-agente, y el protocolo debería estandarizar el handshake de pago en lugar de dejar a cada implementación inventar su propia URI de extensión. Un método nativo (algo como SendPaidMessage con un schema embebido de requerimiento de pago) le permitiría a marketplaces downstream filtrar, auditar y reconciliar pagos de agentes sin que cada uno parsee una extensión distinta de cada vendor.

Primitivas de negociación. Project Deal volvió concreto que el comercio agente-a-agente está dominado por la negociación. Hoy, la negociación pasa dentro de las Parts text de mensajes de forma libre — los agentes regatean en lenguaje natural, y el orquestador no tiene estructura a nivel protocolo para registrar o auditar. Una extensión chica definiendo un tipo de Part negotiation con campos estructurados de oferta/contraoferta, flags opcionales de revelación de precio de reserva, y un outcome settle/refuse le daría a los marketplaces la forma que necesitan para hacer auditable el comercio de agentes.

Alineación semántica. A2A estandariza el wire. No estandariza qué significan las palabras que cruzan el wire. Dos agentes pueden completar una task A2A perfectamente mientras discrepan sobre qué significa "vendor aprobado" o "entregado". El campo va a necesitar o una capa de ontología compartida (en la tradición de W3C / schema.org) o un registry de extensiones semánticas por dominio donde las industrias publiquen sus diccionarios de referencia. Sin esto, los ecosistemas de agentes se fragmentan en pares bilaterales "ambos sabemos qué significa este término".

Binding de identidad. La Agent Card de A2A tiene un campo signature para autenticidad de la card pero no una forma canónica de bindear la identidad A2A de un agente a una identidad portable, legible por marketplaces. ERC-8004 es el candidato obvio — anclado en cadena, vendor-neutral, ya deployado — y esperamos que la próxima versión menor de A2A o la referencie directamente o defina una extensión genérica de binding de identidad que ERC-8004 (y cualquier futuro equivalente) pueda implementar.

Ninguna de estas brechas es un defecto en v1.0. Son las cosas correctas para dejar fuera de un v1.0. Son el trabajo que el campo va a llenar a lo largo de v1.x a medida que el comercio agéntico pase de piloto a volumen.

Cierre

La forma del stack agéntico en 2026 finalmente es legible. MCP carga el borde agente-a-herramientas. A2A carga el borde agente-a-agente. x402 carga el pago que cierra un deal. ERC-8004 carga la identidad, reputación y validación que permiten que dos agentes que nunca se conocieron decidan transaccionar en primer lugar. Cada protocolo cubre una capa; ninguno es el producto de un vendor; todos están gobernados por la Linux Foundation, la Ethereum Foundation, o casas neutrales equivalentes.

A2A es la capa que más tiempo quedó vacía, y aquella cuya ausencia mantuvo a las plataformas de agentes amuralladas entre sí más tiempo. Su release v1.0 es el momento en que el borde agente-a-agente finalmente tiene una spec sobre la que el campo puede converger. El trabajo restante — métodos payment-aware, primitivas de negociación, alineación semántica, binding de identidad — es el tipo de trabajo que se hace en v1.x de un protocolo exitoso, no el tipo que se re-litiga. La historia de composición está saldada. Ahora construimos.

La spec está en a2a-protocol.org/latest/specification. La implementación de referencia está en github.com/a2aproject/A2A. Si estás construyendo cualquier cosa que otro agente eventualmente vaya a necesitar llamar, ambos pertenecen a tu stack este trimestre.