Pular para o conteúdo principal

Documentação oficial desta página · v0.20.6

A2A (Agente para Agente)

O A2A é o protocolo aberto Agent2Agent (v1.0, mantido pela Linux Foundation) para comunicação entre agentes de IA independentes. O plugin de A2A do Hermes funciona nos dois sentidos: o seu agente pode chamar outros agentes A2A como ferramentas, e outros agentes podem mandar tarefas para o seu Hermes por HTTP.

Ele conversa com qualquer par compatível com A2A — outro Hermes, LangChain, CrewAI, agentes do Google ADK ou qualquer coisa construída sobre o a2a-sdk oficial.

Quando usar A2A​

  • Hermes ↔ Hermes entre máquinas — deixe o agente do seu desktop passar tarefas a um Hermes num servidor, ou o contrário, cada um com memória, ferramentas e credenciais próprias.
  • Delegar a agentes especialistas — um par que anuncia skills de web_search/research/coding no Cartão de Agente dele pode ser descoberto e chamado no meio da conversa.
  • Ser um serviço chamável — exponha o seu Hermes para que agentes de outros frameworks mandem tarefas a ele.

Quando você quer vários agentes na mesma máquina, prefira a delegação (subagentes no mesmo processo) ou o quadro kanban (fila de trabalho durável com vários perfis) — o A2A é para cruzar fronteiras de processo, de máquina ou de framework.

Ligar​

hermes gateway setup # escolha A2A

Ou no ~/.hermes/config.yaml:

gateway:
platforms:
a2a:
enabled: true
extra:
port: 9900

As ferramentas de cliente de saída vêm no conjunto a2a, desligado por padrão — ligue por plataforma:

hermes tools enable a2a --platform cli # sessões de CLI/TUI
hermes tools enable a2a --platform telegram # ou qualquer plataforma de mensagem
hermes tools enable a2a --platform a2a # deixa tarefas A2A que chegam chamarem outros pares (encadeamento de agentes)

As ferramentas ficam disponíveis em todo tipo de processo — CLI, TUI, gateway e cron — sem necessidade de ligar a plataforma de entrada.

Saída: chamar outros agentes​

Com o conjunto de ferramentas a2a ligado, o agente ganha:

FerramentaO que faz
a2a_discover(url)Busca e resume o Cartão de Agente de um par
a2a_call(agent, message, context_id?)Manda uma tarefa e recebe a resposta; várias rodadas via context_id
a2a_list()Pares configurados, conversas salvas e métricas
a2a_history(context_id)Recupera uma conversa A2A persistida
a2a_orchestrate(capability, message, mode?)Espalha uma tarefa para todo par que anuncia uma capacidade (all / first / best)

Configure os pares conhecidos no config.yaml:

a2a_agents:
researcher:
url: "http://caixa-de-pesquisa.local:9900"
auth: { type: bearer, token: "..." }
timeout: 120
capabilities: [web_search, research]

Aí é só pedir: "Peça ao agente researcher para resumir as publicações de hoje no arXiv." URLs diretas também funcionam — o a2a_call aceita qualquer endpoint A2A.

Entrada: ser chamável​

Com a plataforma ligada, o Hermes serve:

  • Cartão de Agente em GET /.well-known/agent-card.json (o caminho canônico da v1.0; o antigo agent.json também responde) — anuncia o nome do seu agente, as skills (derivadas dos conjuntos de ferramentas ligados) e as exigências de autenticação.
  • JSON-RPC 2.0 em POST / — métodos canônicos da v1.0 (SendMessage, SendStreamingMessage, GetTask, ListTasks, CancelTask, SubscribeToTask, CRUD da configuração de notificação push) mais os apelidos em formato de caminho anteriores à 1.0 (message/send, …).
  • Streaming por SSE para o SendStreamingMessage, com quadros envelopados em JSON-RPC conforme a especificação.
  • Notificações push (webhooks) para tarefas longas, assinadas com HMAC-SHA256.

As tarefas que chegam são injetadas numa sessão de gateway viva — o mesmo agente, a mesma memória e as mesmas ferramentas que atendem os seus outros canais — e a resposta final volta a quem chamou como resultado da tarefa. As conversas são indexadas pelo contextId do A2A, então um par consegue manter uma troca de várias rodadas.

A interoperabilidade é verificada contra o a2a-sdk oficial em Python (resolução de cartão, SendMessage e streaming).

Modelo de segurança​

Seguro por padrão; cada passo que amplia o alcance é explícito:

  • Sem token ⇒ só localhost. O servidor escuta em 127.0.0.1. Expor para fora exige um token bearer e um A2A_HOST explícito.
  • Tokens por par — A2A_PEER_TOKENS="alice:tok1,bob:tok2" dá a cada par uma credencial própria; o nome autenticado comanda o limite de taxa, a confiança e a auditoria.
  • Filtro de injeção de prompt — o texto que chega é filtrado e enquadrado como entrada não confiável de um par. Pares remotos não conseguem invocar comandos de barra de operador.
  • Redação na saída — strings com cara de credencial (chaves de API, JWTs, tokens) são apagadas das respostas.
  • Log de auditoria — toda troca é anexada a ~/.hermes/a2a_audit.jsonl.
  • Anti-laço — tetos de rodadas por contexto impedem que dois agentes fiquem batendo bola para sempre.

Referência de configuração​

Variável de ambientePadrãoSignificado
A2A_PEER_TOKENS(não definida)Credenciais por par no formato nome:token,… (preferido)
A2A_BEARER_TOKEN(não definida)Token compartilhado; a identidade recai no IP de quem chama
A2A_HOST127.0.0.1Host de escuta — só amplia quando há um token definido
A2A_PORT9900Porta de entrada
A2A_AGENT_NAMEderivado do hostnameNome no Cartão de Agente
A2A_PUBLIC_URL(não definida)URL roteável anunciada no cartão (proxies reversos / k8s)
A2A_TRUSTED_PEERS(não definida)Lista de permissão de identidades autenticadas
A2A_ALLOW_ALL_USERSfalseAceita qualquer par autenticado (só para desenvolvimento)
A2A_RATE_LIMIT60Requisições por minuto por identidade
A2A_MAX_PINGPONG_TURNS5Teto anti-laço de rodadas por contexto (máximo 20)
A2A_REPLY_TIMEOUT300Segundos de espera pela resposta do agente
A2A_PUSH_SECRETo token bearerSegredo HMAC para assinar as notificações push
A2A_ADVERTISED_TOOLSETStodos os registradosRestringe quais skills aparecem no Cartão de Agente

Atrás de um proxy reverso ou de um Service do Kubernetes, defina A2A_PUBLIC_URL (ou confie em X-Forwarded-Host/X-Forwarded-Proto) para que o Cartão de Agente anuncie uma URL que os pares consigam de fato chamar de volta.

Teste rápido​

# De outra máquina / outro agente:
curl http://seu-host:9900/.well-known/agent-card.json

curl -X POST http://seu-host:9900/ \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <token>' \
-d '{"jsonrpc":"2.0","id":1,"method":"SendMessage",
"params":{"message":{"messageId":"m1","role":"ROLE_USER",
"parts":[{"text":"Quais ferramentas você tem?"}]}}}'

Solução de problemas​

  • Os pares não alcançam a URL do cartão — o cartão estava anunciando o endereço de escuta; defina A2A_PUBLIC_URL com a URL roteável de fora.
  • 401 Unauthorized — token errado; confira A2A_PEER_TOKENS/A2A_BEARER_TOKEN no servidor e o bloco auth: do par.
  • O servidor não escuta fora do localhost — é de propósito: defina um token bearer primeiro e depois A2A_HOST=0.0.0.0.
  • As respostas estouram o tempo em tarefas longas — aumente o A2A_REPLY_TIMEOUT, ou faça quem chama registrar uma configuração de notificação push e consultar o GetTask.