← Volver al listado

Agent Card en A2A: ejemplo JSON completo y desglose de campos

Una Agent Card es un documento JSON que indica a un agente cliente a quién llamar, dónde enviar una tarea y qué habilidades están disponibles. En el protocolo A2A (Agent2Agent) la tarjeta suele publicarse en /.well-known/agent-card.json: sin ella el agente es difícil de descubrir; con una descripción vaga, difícil de enrutar bien.

  • Agent Card - contrato público de las capacidades del agente
  • Discovery - localización de la tarjeta por URL well-known o registry
  • skills - habilidades concretas, no un genérico «sé hacerlo todo»
  • capabilities - streaming, push, tarjeta extendida
  • security - esquemas de autenticación al estilo OpenAPI

Para qué sirve la Agent Card

A2A conecta agentes independientes: uno actúa como cliente y otro como ejecutor. Antes de enviar una tarea, el cliente lee la tarjeta y responde:

  1. ¿Encaja este agente con la intención del usuario?
  2. ¿Qué endpoint acepta tareas?
  3. ¿Qué tipos MIME admite en entrada y salida?
  4. ¿Hace falta autenticación y de qué tipo?
  5. ¿Hay streaming de eventos y notificaciones webhook?

La tarjeta no es texto de marketing. La analizan orquestadores y routers LLM. Cuanto más precisos sean description, skills y examples, más estable será la elección del ejecutor.

Ejemplo JSON completo

Abajo hay un ejemplo funcional para un agente que busca productos en un sitio, calcula el precio y crea una solicitud tras la confirmación del usuario. Los campos usan camelCase, como en las tarjetas JSON típicas de A2A.

{
  "name": "Site Commerce Agent",
  "description": "Busca productos en el catálogo del sitio, calcula precio y plazo de entrega, y crea una solicitud tras la confirmación del usuario. Trabaja con catálogo, carrito borrador y estados de pedido. No procesa pagos ni cambia precios.",
  "version": "1.2.0",
  "protocolVersion": "0.3.0",
  "url": "https://api.example.com/a2a",
  "documentationUrl": "https://docs.example.com/a2a/commerce-agent",
  "iconUrl": "https://example.com/icons/commerce-agent.svg",
  "provider": {
    "organization": "Example Shop",
    "url": "https://example.com"
  },
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "stateTransitionHistory": true,
    "extendedAgentCard": false
  },
  "defaultInputModes": [
    "text/plain",
    "application/json"
  ],
  "defaultOutputModes": [
    "text/plain",
    "application/json"
  ],
  "skills": [
    {
      "id": "search-products",
      "name": "Búsqueda de productos",
      "description": "Busca productos por consulta, categoría, precio y disponibilidad. Devuelve candidatos con id, nombre, precio y descripción breve.",
      "tags": ["catalog", "search", "products"],
      "examples": [
        "Busca portátiles de menos de 800 euros con entrega esta semana",
        "Muestra tarifas disponibles para un equipo de 20 personas"
      ],
      "inputModes": ["text/plain", "application/json"],
      "outputModes": ["application/json", "text/plain"]
    },
    {
      "id": "calculate-quote",
      "name": "Cálculo de presupuesto",
      "description": "Calcula precio, impuestos, envío y plazo para las posiciones y cantidades seleccionadas. No crea el pedido.",
      "tags": ["pricing", "quote", "shipping"],
      "examples": [
        "Calcula el coste de 3 unidades de product_id=sku-1042 con entrega a Berlín",
        "Compara las tarifas Basic y Pro para 50 usuarios"
      ],
      "inputModes": ["application/json", "text/plain"],
      "outputModes": ["application/json"]
    },
    {
      "id": "create-lead",
      "name": "Creación de solicitud",
      "description": "Crea un borrador de solicitud o lead tras la confirmación explícita del usuario. Requiere contacto y consentimiento para el tratamiento de datos.",
      "tags": ["lead", "order-draft", "crm"],
      "examples": [
        "Crea una solicitud del plan Pro para ACME, contacto: ops@acme.example",
        "Prepara un borrador de pedido a partir de quote_id=q-7781"
      ],
      "inputModes": ["application/json"],
      "outputModes": ["application/json", "text/plain"]
    },
    {
      "id": "get-order-status",
      "name": "Estado del pedido",
      "description": "Devuelve el estado de pago y entrega por order_id para un usuario autenticado o un número de seguimiento público.",
      "tags": ["orders", "status", "tracking"],
      "examples": [
        "¿Cuál es el estado del pedido ORD-20441?",
        "¿Dónde está el paquete con el tracking TRK-998877?"
      ]
    }
  ],
  "securitySchemes": {
    "bearer": {
      "type": "http",
      "scheme": "bearer",
      "bearerFormat": "JWT"
    },
    "oauth2": {
      "type": "oauth2",
      "flows": {
        "clientCredentials": {
          "tokenUrl": "https://auth.example.com/oauth/token",
          "scopes": {
            "catalog:read": "Lectura de catálogo y presupuestos",
            "leads:write": "Creación de solicitudes",
            "orders:read": "Lectura de estados de pedido"
          }
        }
      }
    }
  },
  "security": [
    {
      "oauth2": ["catalog:read"]
    },
    {
      "bearer": []
    }
  ]
}

En A2A v1.0 el endpoint suele describirse con el array supportedInterfaces en lugar de un único url de nivel superior. La idea es la misma: indicar dónde enviar tareas y qué binding usar (JSONRPC, HTTP+JSON, GRPC, etc.).

Fragmento de ejemplo para v1.0:

{
  "supportedInterfaces": [
    {
      "url": "https://api.example.com/a2a",
      "protocolBinding": "JSONRPC",
      "protocolVersion": "1.0"
    }
  ]
}

Desglose de campos de nivel superior

Campo Obligatoriedad Propósito
name Nombre legible del agente
description Resumen concreto: qué hace y qué no
version Versión de la implementación (mejor semver)
url / supportedInterfaces Sí* Endpoint(s) de tareas, no la URL de la tarjeta
skills Al menos un skill
capabilities Recomendado Flags honestos de capacidades
defaultInputModes / defaultOutputModes Recomendado MIME por defecto
provider No Organización propietaria
documentationUrl / iconUrl No Documentación e icono para la UI
protocolVersion Depende del esquema Versión del protocolo (a menudo arriba en v0.3)
securitySchemes / security No Cómo debe autenticarse el cliente

* En esquemas v0.3 suele ser obligatorio url. En v1.0 el rol del endpoint lo asume supportedInterfaces.

name y description

name sirve a personas y logs. description lo leen los routers. Mal: «Un agente útil para el sitio». Bien: listar operaciones, límites y forma del resultado.

version

Es la versión de la implementación del agente, no necesariamente la del protocolo. Sube major ante breaking changes en skills o en el contrato de respuesta. Los clientes pueden cachear la tarjeta y actualizarla al cambiar la versión.

url - error frecuente

url es la dirección a la que van message/send / las tareas. No es la ruta a /.well-known/agent-card.json.

Incorrecto:

"url": "https://example.com/.well-known/agent-card.json"

Correcto:

"url": "https://api.example.com/a2a"

capabilities

Flag Significado
streaming Soporta respuestas en streaming (SSE / stream)
pushNotifications Webhooks para tareas largas
stateTransitionHistory Historial de transiciones de estado de la tarea
extendedAgentCard Tras auth hay una tarjeta extendida/privada

Pon true solo si el comportamiento está implementado de verdad. Un cliente que abra un stream contra un agente sin streaming recibirá un error.

defaultInputModes y defaultOutputModes

MIME por defecto para todo el agente. Un skill puede sobrescribirlos. Valores típicos: text/plain, application/json, application/pdf, image/png.

Desglose de skills

Un skill es una unidad de enrutado. Un skill = una capacidad clara.

Campo Obligatoriedad Comentario
id Único en el agente; kebab-case es práctico
name Nombre corto para la UI
description Qué acepta, qué devuelve, qué límites tiene
tags No Palabras clave para búsqueda y filtrado
examples No, pero muy recomendable 2-3 prompts reales para el orquestador
inputModes / outputModes No Override MIME de este skill

Los ejemplos no son decoración. Sin ellos el orquestador adivina las entradas solo con la descripción y falla más.

Skill malo:

{
  "id": "website",
  "name": "Website",
  "description": "Trabaja con el sitio"
}

Un skill bueno es como en el ejemplo completo: id concreto, límites claros, tags y examples.

Autenticación: securitySchemes y security

Los esquemas suelen seguir el enfoque OpenAPI:

  • apiKey
  • http (Basic / Bearer)
  • oauth2
  • openIdConnect
  • mutualTLS

securitySchemes describe los métodos disponibles. security define el requisito por defecto:

  • varios objetos en el array security = alternativas (OR);
  • varias claves en un mismo objeto = hace falta todo a la vez (AND).

Publica cómo autenticarse, no los secretos. No pongas API keys, refresh tokens ni hostnames internos en el JSON.

Discovery: cómo se encuentra la tarjeta

Flujo típico:

  1. El cliente conoce el dominio base del agente.
  2. Solicita https://agent.example.com/.well-known/agent-card.json.
  3. Valida los campos obligatorios.
  4. Elige un skill por descripción, tags y examples.
  5. Se autentica según security.
  6. Envía la tarea a url / supportedInterfaces.

La tarjeta también se publica en registries o directorios. Entonces el discovery pasa por búsqueda, y well-known sigue siendo la fuente de verdad del propietario.

Comprobación local:

curl -s https://api.example.com/.well-known/agent-card.json

Qué no publicar en la Agent Card

  • API keys, contraseñas, private keys;
  • URLs internas de admin o staging sin protección;
  • operaciones no disponibles para clientes externos;
  • capabilities infladas (streaming: true sin implementación);
  • skills vagos del tipo «hace de todo en el sitio».

La tarjeta pública es a la vez superficie de ataque y de enrutado. Mantenla precisa y mínimamente suficiente.

Errores frecuentes

  1. Confundir url con la URL de la tarjeta.
  2. Array skills vacío. El agente queda casi imposible de enrutar.
  3. Descripción sin límites. No se dice qué no hace (pago, borrado, cambio de precios).
  4. Sin examples. El orquestador entiende peor la entrada válida.
  5. localhost en una tarjeta de producción. El endpoint debe ser alcanzable.
  6. Un solo skill para todo el producto. Mejor varios skills estrechos con distintos derechos y MIME.

Mini checklist antes de publicar

  1. La tarjeta se sirve por HTTPS con Content-Type: application/json.
  2. Tiene name, description, version, endpoint y al menos un skill.
  3. Las descripciones son concretas.
  4. Los skills clave tienen examples y tags.
  5. capabilities coinciden con el servidor real.
  6. El JSON no contiene secretos.
  7. El endpoint de la tarjeta responde a una tarea de prueba.
  8. La versión sube ante breaking changes.

Conclusión

La Agent Card es el contrato principal de discovery en A2A. Un JSON completo con skills precisos, capabilities honestas y security explícita da a los agentes cliente datos suficientes para encontrar al ejecutor correcto y no llamar al equivocado.

Si necesitas ayuda para diseñar una Agent Card, un servidor A2A o la conexión de un agente con la API del sitio - contacta conmigo.

Preguntas frecuentes

¿Dónde debe estar la Agent Card?

La ruta pública estándar es /.well-known/agent-card.json en el dominio del agente. También puedes registrarla en un catálogo o registry, pero la URL well-known sigue siendo un punto de discovery cómodo sin un índice aparte.

¿En qué se diferencia url de la dirección de la tarjeta?

La dirección de la tarjeta sirve para discovery; url (o supportedInterfaces) para ejecutar tareas. El cliente primero lee el JSON y luego envía mensajes/tareas al endpoint de trabajo del agente.

¿Cuántos skills debe tener una tarjeta?

Tantos como capacidades realmente distintas con entradas o permisos diferentes. Suele ser mejor 3-7 skills estrechos que uno genérico «hazlo todo». Para el enrutado importan límites claros, tags y examples.

¿Es obligatoria la autenticación en la Agent Card?

No siempre. Un agente público de solo lectura puede omitir security. Para escritura, datos personales y operaciones de pago declara securitySchemes y security, y guarda los secretos fuera de la tarjeta.

¿Hay que actualizar la tarjeta en cada deploy?

Actualízala cuando cambien skills, endpoint, capabilities, auth o el significado del agente. Un patch técnico sin cambio de contrato puede reflejarse en version; los breaking changes merecen major y documentación explícita.

Contacto