Integración de A2A con frameworks de agentes existentes: una demostración con Hermes Agent
Por qué A2A importa para la orquestación de agentes
El Agent2Agent Protocol (A2A) es un estándar abierto introducido por Google en abril de 2025 para la comunicación entre agentes. Define cómo un agente de IA descubre las capacidades de otro agente, le envía una tarea, recibe salida en streaming y sigue la tarea a lo largo de su ciclo de vida — todo sobre JSON-RPC 2.0, sin asumir que ambos agentes comparten un framework, un proveedor de modelos o una topología de despliegue.
A2A llena un vacío que MCP no cubre. MCP conecta un agente con herramientas y fuentes de datos — es un protocolo de llamada a herramientas. A2A conecta agentes con agentes. Un agente que necesita una capacidad especializada (lógica de precios, búsqueda en catálogo, procesamiento de RFQ) puede delegar el trabajo a un agente remoto que expone esa capacidad vía un endpoint A2A, recibir el resultado como una tarea A2A y continuar su propio flujo de trabajo. Los dos protocolos son complementarios: MCP le da manos a un agente; A2A le da colegas.
La especificación de A2A define tres primitivas centrales:
- Agent Card — un documento JSON en
/.well-known/agent-card.jsonque describe la identidad, capacidades, habilidades y endpoint de servicio del agente. Así es como los agentes se descubren entre sí. - Task — la unidad de trabajo. Un cliente envía una tarea vía
message/send(sin streaming) omessage/stream(con streaming). La tarea transita por estados:submitted,working,input-required,completed,failed,canceled. - Artifact — salida estructurada producida durante la ejecución de la tarea, transmitida al cliente a medida que está disponible.
Para los despliegues B2B, la propuesta de valor es concreta: en lugar de construir un único agente monolítico que hace todo, compones agentes especializados que cada uno posee un dominio — y se coordinan a través de un protocolo, no a través de memoria compartida o llamadas a funciones cableadas.
El problema de integración
La mayoría de los frameworks de agentes existentes no hablan A2A. Tienen sus propias superficies de API nativas, sus propios modelos de tarea, sus propios mecanismos de streaming. Hermes Agent (de Nous Research) expone un API Server compatible con OpenAI en /v1/chat/completions y una interfaz de streaming SSE basada en runs en /v1/runs y /v1/runs/{id}/events. OpenClaw sirve un API compatible con OpenResponses en POST /v1/responses. LangGraph tiene su propio modelo de ejecución de grafos. CrewAI tiene su propio despacho de crews.
Ninguno de estos frameworks reescribirá sus internals para soportar A2A. Ni debería hacerlo — sus APIs nativas sirven bien a sus propios ecosistemas. La pregunta es: ¿pueden participar en una red de agentes A2A sin cambiar su código?
La respuesta es una capa puente — un componente que se sitúa entre el protocolo A2A y la API nativa del framework. El puente implementa la superficie JSON-RPC de A2A por un lado (Agent Card, ciclo de vida de la tarea, streaming) y traduce a las llamadas nativas del framework por el otro. El framework no sabe que está siendo llamado vía A2A. El cliente A2A no sabe qué framework ejecuta la tarea.
Este artículo recorre el patrón puente usando Hermes Agent como demostración. El mismo patrón se aplica a OpenClaw y otros frameworks — el handler del puente es la única pieza que cambia.
La arquitectura del puente
Una implementación de referencia funcional de este patrón es el a2a_daemon_engine — un daemon del protocolo A2A que se ejecuta como un módulo de gateway y enruta la ejecución a handlers enchufables. La arquitectura es:
A2A Client (cualquier agente o aplicación)
│
POST /{endpoint_id}/a2a (message/send | message/stream)
│
▼
Gateway (auth, enrutamiento, gestión de clientes SSE)
│
▼
A2A Daemon Executor
│
resolve_agent(uuid) → consulta a la base de datos
load_agent_handler() ← enrutamiento data-driven, basado en metadatos
│
├── HermesAgentHandler
│ → POST /v1/runs → GET /v1/runs/{id}/events → streaming SSE
│ → POST /v1/chat/completions (sin streaming)
│
└── [AnyFrameworkHandler] ← misma interfaz, traducción diferente
→ API nativa del framework
El puente tiene tres capas:
Capa de protocolo A2A — maneja el despacho JSON-RPC, el servicio de Agent Card, la máquina de estados de la tarea y el EventQueue del SDK de A2A. Es agnóstica al framework. Es la misma para cada integración.
Capa de transporte del gateway — maneja HTTP, autenticación, el ciclo de vida de los clientes SSE y el enrutamiento. También agnóstica al framework. El gateway posee el cable; el puente posee la traducción.
Handler del framework — el único código específico del framework. Implementa una interfaz
ask_model(): aceptar las partes del mensaje A2A y el contexto, llamar a la API nativa del framework, convertir la respuesta de vuelta a partes del mensaje A2A y (para streaming) reenviar los deltas de tokens al canal SSE.
Añadir un nuevo framework significa escribir una clase handler. Todo lo demás — la superficie del protocolo, el despacho del gateway, la gestión de SSE, la persistencia de tareas — es infraestructura compartida.
Demostración: el puente de Hermes Agent
El HermesAgentHandler es el ejemplo desarrollado. Hace de puente entre la semántica de tareas A2A y el API Server de Hermes Agent. El handler soporta dos modos de ejecución:
Sin streaming: message/send con message_response
El handler llama a POST /v1/chat/completions en el API Server de Hermes — el endpoint compatible con OpenAI. La solicitud lleva las partes del mensaje A2A convertidas como un payload de chat completion. Hermes procesa la solicitud (inferencia del modelo, llamadas a herramientas, razonamiento del agente) y devuelve una única respuesta. El handler convierte la respuesta a un Message A2A con ROLE_AGENT y lo emite al EventQueue del SDK.
El cliente recibe una única respuesta JSON-RPC con el texto completo del agente. Sin eventos de estado intermedios, sin fragmentos de streaming — la solicitud se bloquea hasta que Hermes completa.
Con streaming: message/send con task_execution y stream: true
El handler llama a POST /v1/runs para crear un run, luego abre una conexión SSE a GET /v1/runs/{id}/events. Hermes transmite eventos a medida que ocurren: deltas de tokens, metadatos de razonamiento, notificaciones de llamada/resultado de herramientas, solicitudes de aprobación y eventos de ciclo de vida (run.created, run.completed, run.failed).
El handler ejecuta un bucle de drenaje en un hilo en segundo plano. Cada evento message.delta se empuja al gestor de SSE del gateway para entrega en tiempo real a los clientes conectados. El handler acumula los tokens en un único búfer. Cuando llega run.completed, el texto acumulado se emite como un único Message A2A al EventQueue del SDK, y un evento de estado COMPLETED se empuja solo a SSE.
Este diseño de doble vía — SSE para fragmentos en tiempo real, EventQueue del SDK para el mensaje final acumulado — es una respuesta a una restricción del SDK de A2A v2, discutida más abajo.
Aprobación con humano en el ciclo a través de fronteras de agentes
Hermes soporta puertas de aprobación con humano en el ciclo — cuando un agente necesita permiso para ejecutar una acción sensible, se pausa y emite una solicitud de aprobación. El puente traduce esto al estado INPUT_REQUIRED de A2A, que señala al agente que hace la llamada (u operador humano) que se necesita entrada. La respuesta vuelve a través de POST /v1/runs/{id}/approval, y el run continúa.
Aquí es donde el patrón puente muestra su valor. A2A define INPUT_REQUIRED como un estado de tarea de primera clase. Hermes tiene su propio mecanismo de aprobación. El puente mapea uno al otro, y el agente que llama — que puede ser a su vez un cliente A2A ejecutándose en un framework completamente distinto — ve una transición de estado del protocolo estándar, no un detalle específico de Hermes. Una cadena de delegación de agentes puede incluir un paso que requiere aprobación humana (una autorización de compra, una decisión de acceso a datos, una aprobación de cotización), y el protocolo A2A transporta esa puerta de forma transparente a través de las fronteras de los frameworks.
Mapeo de estados de A2A
A2A define una máquina de estados de tarea: submitted → working → input-required | completed | failed | canceled. Cada framework tiene su propio vocabulario de eventos. El puente mapea entre ellos.
El mapeo de eventos de Hermes a estados:
| Evento SSE de Hermes | Estado de tarea A2A | Acción del puente |
|---|---|---|
run.created |
WORKING |
Registrar run_id para soporte de cancelación |
message.delta |
WORKING |
Acumular token; emitir a SSE por fragmento |
reasoning.available |
WORKING |
Metadatos de razonamiento — sin emisión de tokens |
tool.call / tool.result |
WORKING |
Solo metadatos de ejecución de herramientas |
approval.required |
INPUT_REQUIRED |
Emitir fragmento de aprobación; almacenar pending_approval |
run.completed |
COMPLETED |
Establecer evento de stream; acumular texto final |
run.failed |
FAILED |
Emitir fragmento de error; establecer estado FAILED |
POST /v1/runs/{id}/stop |
CANCELED |
Cancelación externa vía tasks/cancel |
POST /v1/runs/{id}/approval |
(continúa el run) | Resuelto vía operation=\"approval_response\" |
Esta tabla es el corazón del puente. Cada integración de framework produce una tabla equivalente — los eventos nativos del framework a la izquierda, los estados de A2A a la derecha, las acciones del puente en el medio. El documento HERMES_INTEGRATION.md en la implementación de referencia registra el formato exacto de los eventos de Hermes, las claves de configuración y los detalles del flujo de extremo a extremo.
La restricción del SDK de A2A v2 y la solución de doble vía
El SDK de A2A v2 (a2a-sdk==1.0.2) impone dos restricciones en el camino on_message_send que dieron forma a cada implementación del puente:
- Solo un Message. Emitir múltiples objetos
Messageal EventQueue del SDK lanzaInvalidAgentResponseError: Multiple Message objects received. - No TaskStatusUpdateEvent. Los eventos de estado lanzan
InvalidAgentResponseError: Received TaskStatusUpdateEvent in message mode.
Un puente ingenuo emitiría un Message por cada delta de token — el patrón natural de streaming. El SDK rechaza esto. También rechaza los eventos de estado (WORKING, COMPLETED) en el camino message/send.
La solución es un canal de salida de doble vía:
- SSE (gestionado por el gateway): Los fragmentos de tokens se empujan a SSE en tiempo real. Los clientes conectados ven la salida en streaming a medida que ocurre. Los eventos de estado (WORKING, COMPLETED, FAILED) también van solo a SSE.
- EventQueue del SDK: Después de que el stream completa, un único
Messageacumulado que contiene el texto completo de la respuesta se emite al EventQueue del SDK. Esto es lo que devuelve la respuesta JSON-RPC demessage/send.
El cliente obtiene streaming en tiempo real vía SSE y una respuesta JSON-RPC limpia de mensaje único vía el SDK. Ambos canales funcionan; ninguno viola las restricciones del SDK. Este patrón es independiente del framework — se aplica tanto si el backend es Hermes, OpenClaw o cualquier handler futuro.
Aplicación del mismo patrón a OpenClaw
La Gateway API de OpenClaw expone una superficie nativa distinta a la de Hermes, pero el patrón puente es idéntico. Un OpenClawHandler implementaría la misma interfaz ask_model() y traduciría la semántica de tareas A2A a llamadas al Gateway de OpenClaw:
- Sin streaming se mapea a
POST /v1/responsescon las partes del mensaje A2A convertidas a input items de OpenResponses. La respuesta se convierte de vuelta a unMessageA2A. - Con streaming se mapea a
POST /v1/responsesconstream: true, consumiendo el flujo de eventos SSE y reenviando los deltas de tokens al canal SSE de A2A. El formato de streaming de OpenResponses usaresponse.output_text.deltapara los fragmentos de tokens yresponse.completedpara el finalizado — nombres de evento diferentes, misma estructura de puente. - Selección de agente usa el campo
model(openclaw/<agentId>) o el headerx-openclaw-agent-id, mapeado desde los metadatos del agente A2A. - Continuidad de sesión aprovecha el
previous_response_idde OpenClaw o el campouserpara el enrutamiento estable de sesión, que se mapea naturalmente a la persistencia de tareas A2A.
La tabla de mapeo de estados para OpenClaw se vería así:
| Evento de OpenClaw | Estado de tarea A2A | Acción del puente |
|---|---|---|
response.created |
WORKING |
Registrar ID de respuesta |
response.output_text.delta |
WORKING |
Acumular token; emitir a SSE |
response.completed |
COMPLETED |
Acumular texto final; emitir Message |
response.failed |
FAILED |
Emitir error; establecer FAILED |
Mismas columnas, misma estructura, nombres de evento diferentes. El handler del puente es la única pieza que cambia entre frameworks.
Configuración: enrutamiento basado en metadatos
El enrutamiento de agentes está basado en metadatos, no en variables de entorno. Cada registro de agente en la base de datos lleva su configuración de handler en una columna JSON metadata. Para un agente respaldado por Hermes:
{
"module_name": "a2a_daemon_engine.handlers.a2a_hermes_handler",
"class_name": "HermesAgentHandler",
"hermes_api_url": "http://127.0.0.1:8642",
"hermes_api_key": "hermes-local-key",
"hermes_model": "hermes-agent",
"hermes_timeout": 300.0
}
Para un agente respaldado por OpenClaw, los metadatos apuntarían al handler de OpenClaw:
{
"module_name": "a2a_daemon_engine.handlers.a2a_openclaw_handler",
"class_name": "OpenClawHandler",
"openclaw_api_url": "http://127.0.0.1:3000",
"openclaw_api_key": "openclaw-key",
"openclaw_agent_id": "pricing-agent",
"openclaw_timeout": 300.0
}
La resolución de configuración sigue una cadena de prioridad: metadatos del agente (DB) → dict de settings → valores por defecto de Config (variables de entorno). Las sobreescrituras por agente ganan sobre los valores globales por defecto. Dos agentes pueden apuntar a frameworks diferentes — uno a Hermes para tareas intensivas en razonamiento, otro a OpenClaw para tareas de orquestación de flujos de trabajo — y la superficie del protocolo A2A se ve idéntica al agente que llama.
Qué habilita esto
El patrón puente te da tres capacidades que son difíciles de ensamblar desde cero:
1. Delegación de agente a agente con streaming. Los agentes clientes A2A pueden enviar tareas a un agente respaldado por Hermes y recibir streaming de tokens en tiempo real vía SSE. El agente que llama no necesita saber que el agente remoto ejecuta Hermes — ve un endpoint A2A con un Agent Card y una interfaz JSON-RPC.
2. Aprobación con humano en el ciclo a través de fronteras de agentes. Las puertas de aprobación nativas del framework (solicitudes de aprobación de Hermes, aprobaciones de operador de OpenClaw) se mapean a estados INPUT_REQUIRED de A2A. Una cadena de delegación de agentes puede incluir un paso que requiere aprobación humana, y el protocolo A2A transporta esa transición de estado de vuelta al agente u operador de origen — independientemente del framework en el que se ejecute cada agente de la cadena.
3. Enrutamiento multi-framework desde un único gateway. El mismo gateway, el mismo executor, la misma superficie del protocolo A2A sirve handlers para frameworks diferentes. Añadir un nuevo framework es escribir una clase handler e insertar un registro de agente — no un nuevo despliegue, no una nueva implementación de protocolo.
La implementación de referencia también soporta despacho vía AWS Lambda para A2A serverless, transporte experimental con gRPC con streaming bidireccional, y persistencia de doble backend (DynamoDB o PostgreSQL) con aislamiento multi-tenant vía claves de partición compuestas. El repositorio a2a_daemon_engine y su guía de integración con Hermes contienen la implementación completa, la referencia de configuración y los detalles del mapeo de estados.
Un distribuidor de mercado medio necesita agentes de cotización que hablen con agentes de catálogo que hablen con agentes de inventario — cada uno respaldado por un framework diferente, cada uno propiedad de un equipo diferente. A2A da a esos agentes un protocolo compartido. Una capa puente permite que Hermes Agent, OpenClaw y cualquier otro framework participen sin reescribir sus internals. El a2a_daemon_engine es una implementación de referencia funcional de ese patrón puente, demostrada con Hermes Agent.
Solicita un build acotado
Una semana de discovery. Obtienes un inventario de sistemas, un mapa de flujos de trabajo y un alcance fijo — independientemente de si construyes con nosotros.
¿Quieres esto construido para tus sistemas?
Cada documento aquí viene de trabajo real de producción. Si tienes un sistema objetivo y un flujo en mente, podemos definir un proyecto en una semana.
Solicitar un proyectoDescubrimiento de una semana. Obtienes un inventario de sistemas, mapa de flujos y alcance fijo — decidas o no construir con nosotros.