Agent Card em A2A: exemplo JSON completo e análise dos campos
Um Agent Card é um documento JSON que indica a um agente cliente quem chamar, para onde enviar a tarefa e quais skills estão disponíveis. No protocolo A2A (Agent2Agent) o cartão costuma ser publicado em /.well-known/agent-card.json: sem ele o agente é difícil de descobrir; com uma descrição vaga, difícil de rotear bem.
- Agent Card - contrato público das capacidades do agente
- Discovery - localização do cartão via URL well-known ou registry
- skills - habilidades concretas, não um genérico «sei fazer tudo»
- capabilities - streaming, push, cartão estendido
- security - esquemas de autenticação no estilo OpenAPI
Para que serve o Agent Card
A2A liga agentes independentes: um atua como cliente, outro como executor. Antes de enviar a tarefa, o cliente lê o cartão e responde:
- Este agente corresponde à intenção do utilizador?
- Que endpoint aceita tarefas?
- Que tipos MIME são suportados na entrada e na saída?
- É necessária autenticação e de que tipo?
- Há streaming de eventos e notificações webhook?
O cartão não é texto de marketing. Orquestradores e routers LLM analisam-no. Quanto mais precisos forem description, skills e examples, mais estável será a escolha do executor.
Exemplo JSON completo
Abaixo está um exemplo funcional para um agente que pesquisa produtos no site, calcula o preço e cria um pedido após confirmação do utilizador. Os campos usam camelCase, como nos cartões JSON típicos de A2A.
{
"name": "Site Commerce Agent",
"description": "Pesquisa produtos no catálogo do site, calcula preço e prazo de entrega, e cria um pedido após confirmação do utilizador. Trabalha com catálogo, carrinho-rascunho e estados de encomenda. Não processa pagamentos nem altera preços.",
"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": "Pesquisa de produtos",
"description": "Pesquisa produtos por consulta, categoria, preço e disponibilidade. Devolve candidatos com id, nome, preço e descrição curta.",
"tags": ["catalog", "search", "products"],
"examples": [
"Encontra portáteis até 800 euros com entrega esta semana",
"Mostra planos disponíveis para uma equipa de 20 pessoas"
],
"inputModes": ["text/plain", "application/json"],
"outputModes": ["application/json", "text/plain"]
},
{
"id": "calculate-quote",
"name": "Cálculo de orçamento",
"description": "Calcula preço, impostos, envio e prazo para os itens e quantidades selecionados. Não cria a encomenda.",
"tags": ["pricing", "quote", "shipping"],
"examples": [
"Calcula o custo de 3 unidades de product_id=sku-1042 com entrega em Berlim",
"Compara os planos Basic e Pro para 50 utilizadores"
],
"inputModes": ["application/json", "text/plain"],
"outputModes": ["application/json"]
},
{
"id": "create-lead",
"name": "Criação de pedido",
"description": "Cria um rascunho de lead ou pedido após confirmação explícita do utilizador. Exige contacto e consentimento para tratamento de dados.",
"tags": ["lead", "order-draft", "crm"],
"examples": [
"Cria um pedido do plano Pro para a ACME, contacto: ops@acme.example",
"Prepara um rascunho de encomenda a partir de quote_id=q-7781"
],
"inputModes": ["application/json"],
"outputModes": ["application/json", "text/plain"]
},
{
"id": "get-order-status",
"name": "Estado da encomenda",
"description": "Devolve o estado de pagamento e entrega por order_id para um utilizador autenticado ou um número de tracking público.",
"tags": ["orders", "status", "tracking"],
"examples": [
"Qual é o estado da encomenda ORD-20441?",
"Onde está a encomenda com 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": "Leitura de catálogo e orçamentos",
"leads:write": "Criação de pedidos",
"orders:read": "Leitura de estados de encomenda"
}
}
}
}
},
"security": [
{
"oauth2": ["catalog:read"]
},
{
"bearer": []
}
]
}
No A2A v1.0 o endpoint costuma ser descrito com o array supportedInterfaces em vez de um único url de topo. A ideia é a mesma: indicar para onde enviar tarefas e que binding usar (JSONRPC, HTTP+JSON, GRPC, etc.).
Fragmento de exemplo para v1.0:
{
"supportedInterfaces": [
{
"url": "https://api.example.com/a2a",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
]
}
Análise dos campos de topo
| Campo | Obrigatório | Finalidade |
|---|---|---|
name |
Sim | Nome legível do agente |
description |
Sim | Resumo concreto: o que faz e o que não faz |
version |
Sim | Versão da implementação (preferível semver) |
url / supportedInterfaces |
Sim* | Endpoint(s) de tarefas, não a URL do cartão |
skills |
Sim | Pelo menos um skill |
capabilities |
Recomendado | Flags honestas de capacidades |
defaultInputModes / defaultOutputModes |
Recomendado | MIME por omissão |
provider |
Não | Organização proprietária |
documentationUrl / iconUrl |
Não | Documentação e ícone para a UI |
protocolVersion |
Depende do esquema | Versão do protocolo (muitas vezes no topo em v0.3) |
securitySchemes / security |
Não | Como o cliente se deve autenticar |
* Nos esquemas v0.3 url costuma ser obrigatório. No v1.0 o papel do endpoint passa para supportedInterfaces.
name e description
name serve a pessoas e logs. description é lida pelos routers. Mau: «Um agente útil para o site». Bom: listar operações, limites e formato do resultado.
version
É a versão da implementação do agente, não necessariamente a do protocolo. Incremente major em breaking changes de skills ou do contrato de resposta. Clientes podem cachear o cartão e atualizá-lo quando a versão muda.
url - erro frequente
url é o endereço para onde vão message/send / as tarefas. Não é o caminho para /.well-known/agent-card.json.
Errado:
"url": "https://example.com/.well-known/agent-card.json"
Correto:
"url": "https://api.example.com/a2a"
capabilities
| Flag | Significado |
|---|---|
streaming |
Suporta respostas em streaming (SSE / stream) |
pushNotifications |
Webhooks para tarefas longas |
stateTransitionHistory |
Histórico de transições de estado da tarefa |
extendedAgentCard |
Após auth há um cartão estendido/privado |
Coloque true só se o comportamento estiver realmente implementado. Um cliente que abrir um stream contra um agente sem streaming receberá erro.
defaultInputModes e defaultOutputModes
MIME por omissão para todo o agente. Um skill pode sobrescrevê-los. Valores típicos: text/plain, application/json, application/pdf, image/png.
Análise de skills
Um skill é uma unidade de routing. Um skill = uma capacidade clara.
| Campo | Obrigatório | Comentário |
|---|---|---|
id |
Sim | Único no agente; kebab-case funciona bem |
name |
Sim | Nome curto para a UI |
description |
Sim | O que aceita, o que devolve, que limites tem |
tags |
Não | Palavras-chave para pesquisa e filtragem |
examples |
Não, mas muito recomendado | 2-3 prompts reais para o orquestrador |
inputModes / outputModes |
Não | Override MIME deste skill |
Os exemplos não são decoração. Sem eles o orquestrador adivinha as entradas só pela descrição e falha mais.
Skill mau:
{
"id": "website",
"name": "Website",
"description": "Trabalha com o site"
}
Um skill bom é como no exemplo completo: id concreto, limites claros, tags e examples.
Autenticação: securitySchemes e security
Os esquemas costumam seguir a abordagem OpenAPI:
apiKeyhttp(Basic / Bearer)oauth2openIdConnectmutualTLS
securitySchemes descreve os métodos disponíveis. security define o requisito por omissão:
- vários objetos no array
security= alternativas (OR); - várias chaves num mesmo objeto = é preciso tudo de uma vez (AND).
Publique como autenticar, não os segredos. Não coloque API keys, refresh tokens nem hostnames internos no JSON.
Discovery: como o cartão é encontrado
Fluxo típico:
- O cliente conhece o domínio base do agente.
- Pede
https://agent.example.com/.well-known/agent-card.json. - Valida os campos obrigatórios.
- Escolhe um skill por descrição, tags e examples.
- Autentica-se segundo
security. - Envia a tarefa para
url/supportedInterfaces.
O cartão também é publicado em registries ou diretórios. Nesse caso o discovery passa por pesquisa, e o well-known continua a ser a fonte de verdade do proprietário.
Verificação local:
curl -s https://api.example.com/.well-known/agent-card.json
O que não publicar no Agent Card
- API keys, passwords, private keys;
- URLs internas de admin ou staging sem proteção;
- operações indisponíveis a clientes externos;
- capabilities infladas (
streaming: truesem implementação); - skills vagos do tipo «faz tudo no site».
O cartão público é ao mesmo tempo superfície de ataque e de routing. Mantenha-o preciso e minimamente suficiente.
Erros frequentes
- Confundir
urlcom a URL do cartão. - Array
skillsvazio. O agente fica quase impossível de rotear. - Descrição sem limites. Não se diz o que o agente não faz (pagamento, eliminação, alteração de preços).
- Sem
examples. O orquestrador entende pior a entrada válida. - localhost num cartão de produção. O endpoint tem de ser alcançável.
- Um único skill para todo o produto. Prefira vários skills estreitos com direitos e MIME diferentes.
Mini checklist antes de publicar
- O cartão é servido por HTTPS com
Content-Type: application/json. - Tem
name,description,version, endpoint e pelo menos um skill. - As descrições são concretas.
- Os skills-chave têm
examplesetags. capabilitiescorrespondem ao servidor real.- O JSON não contém segredos.
- O endpoint do cartão responde a uma tarefa de teste.
- A versão sobe em breaking changes.
Conclusão
O Agent Card é o principal contrato de discovery no A2A. Um JSON completo com skills precisos, capabilities honestas e security explícita dá aos agentes cliente dados suficientes para encontrar o executor certo e não chamar o errado.
Se precisa de ajuda a desenhar um Agent Card, um servidor A2A ou a ligação de um agente à API do site - contacte-me.
Perguntas frequentes
Onde deve ficar o Agent Card?
O caminho público padrão é /.well-known/agent-card.json no domínio do agente. Também pode registá-lo num catálogo ou registry, mas a URL well-known continua a ser um ponto de discovery conveniente sem um índice separado.
Em que url difere do endereço do cartão?
O endereço do cartão serve para discovery; url (ou supportedInterfaces) para executar tarefas. O cliente primeiro lê o JSON e depois envia mensagens/tarefas para o endpoint de trabalho do agente.
Quantos skills deve ter um cartão?
Tantos quantas capacidades realmente distintas com entradas ou permissões diferentes. Em geral 3-7 skills estreitos são melhores do que um genérico «faz tudo». Para o routing importam limites claros, tags e examples.
A autenticação é obrigatória no Agent Card?
Nem sempre. Um agente público só de leitura pode omitir security. Para escrita, dados pessoais e operações pagas declare securitySchemes e security, e guarde os segredos fora do cartão.
É preciso atualizar o cartão em cada deploy?
Atualize quando mudarem skills, endpoint, capabilities, auth ou o significado do agente. Um patch técnico sem mudança de contrato pode refletir-se em version; breaking changes merecem major e documentação explícita.