\n\n\n\n Estou construindo protocolos de agente para agente: aqui está a fricção. - AgntDev \n

Estou construindo protocolos de agente para agente: aqui está a fricção.

📖 13 min read2,476 wordsUpdated Apr 5, 2026

Bene, ragazzi, Leo Grant qui, di nuovo su agntdev.com, e oggi ci immergiamo a capofitto in qualcosa che ha attirato l’attenzione nei miei canali Slack e nelle sessioni di coding notturne: a surpreendente complexidade do que parece ser um simples processo de “build” quando se trata de agentes autônomos. Em particular, quero falar sobre os pontos de atrito frequentemente negligenciados na construção de protocolos de comunicação entre agentes. Não é apenas fazer dois programas conversarem; é fazer com que dois agentes interajam de maneira significativa, cada um com seus próprios objetivos e estados internos, sem fazer sua simulação cuidadosamente projetada explodir ou, pior ainda, uma implementação no mundo real.

Ricordo qualche mese fa, stavo aiutando una piccola startup che cercava di coordinare una flotta de drones para entregas. O abordagem inicial deles era bastante padrão: um orquestrador central que enviava comandos. Mas logo eles se depararam com um muro. A latência, o ponto único de falha e o volume de decisões que o sistema central tinha que gerenciar tornaram-se um pesadelo. A solução óbvia? Descentralizar. Fazer os drones conversarem entre si. Simples, certo? Ahah. Oh, Leo, doce garoto de verão.

A Ilusão de uma Comunicação Simples entre Agentes

Quando você pensa pela primeira vez em agentes conversando, sua mente provavelmente salta para REST API, gRPC, talvez algumas filas de mensagens. E sim, essas são as mecânicas subjacentes. Mas para os agentes, especialmente aqueles que operam com um certo grau de autonomia, o “o que” e o “como” daquela comunicação são profundamente diferentes da típica interação cliente-servidor.

Pense nisso: uma chamada API padrão geralmente implica um esquema conhecido, uma resposta previsível e um ciclo claro de solicitação-resposta. Um agente, no entanto, pode não ter sempre uma “solicitação” no sentido tradicional. Pode precisar transmitir informações, escutar eventos específicos, negociar um recurso ou até mesmo deduzir a intenção a partir das ações de outro agente. Não é apenas uma questão de sintaxe; trata-se de semântica, contexto e compreensão compartilhada entre duas entidades que podem não ter sido projetadas pela mesma pessoa, sem mencionar ter exatamente os mesmos modelos internos.

Meu amigo da startup de drones, vamos chamá-lo de Mark, estava inicialmente tentando expor simplesmente endpoints em cada drone. O Drone A precisava saber se o Drone B pousaria na mesma plataforma. Assim, o Drone A acessava /api/v1/drones/{id}/landing_status. Parece certo à primeira vista. Mas e se o Drone B estiver em uma manobra crítica e não puder responder imediatamente? E se seu estado interno for ambíguo? E se precisar pedir esclarecimentos ao Drone A antes de se comprometer a um estado? De repente, aquela simples chamada API se torna uma conversa de múltiplos turnos, cheia de possíveis impasses e mal-entendidos.

Além de Solicitações/Respostas: A Necessidade de Protocolos Conversacionais

É aqui que os protocolos de rede padrão começam a mostrar seus limites e precisamos pensar em protocolos conversacionais. Não se trata apenas de troca de dados; trata-se de troca de informações no contexto de objetivos em curso e potenciais conflitos.

Vamos fazer um exemplo básico. Imagine dois agentes, Agente A e Agente B, tentando coordenar uma tarefa. O Agente A deve coletar um objeto, e o Agente B deve transportá-lo. O Agente A deve sinalizar que está pronto, e o Agente B deve confirmar o recebimento. Se usarmos simples solicitações POST, pode parecer assim:

“`html


// Agente A (raccogliere)
function segnaleProntoPerRitiro(itemId) {
 fetch('http://agent-b.com/api/v1/pickup_ready', {
 method: 'POST',
 headers: { 'Content-Type': 'application/json' },
 body: JSON.stringify({ item_id: itemId })
 })
 .then(response => response.json())
 .then(data => {
 if (data.status === 'ack') {
 console.log(`Agente B reconheceu a coleta para ${itemId}.`);
 // Proceder com a coleta efetiva
 } else {
 console.error(`Agente B não reconheceu a coleta: ${data.reason}`);
 // Lidar com repetição ou plano alternativo
 }
 })
 .catch(error => console.error('Erro ao sinalizar pronto:', error));
}

// Agente B (transporte)
// (Endpoint para /api/v1/pickup_ready)
app.post('/api/v1/pickup_ready', (req, res) => {
 const itemId = req.body.item_id;
 console.log(`Recebido sinal de prontidão para a coleta para ${itemId}.`);
 // Verificar estado interno, disponibilidade, etc.
 if (podeTransportar(itemId)) {
 res.json({ status: 'ack' });
 } else {
 res.status(400).json({ status: 'nack', reason: 'Atualmente ocupado' });
 }
});

Este é um começo. Mas o que acontece se podeTransportar(itemId) levar 5 segundos porque o Agente B precisa consultar um sistema externo ou negociar com outro agente? O Agente A permanece em espera. E se o Agente B responder com ‘nack’ devido a ‘Atualmente ocupado’? O Agente A deve agora interpretar isso e decidir sua próxima ação. Não se trata apenas de um código de erro; trata-se de informações contextuais que o Agente A deve considerar em seu ciclo decisional.

É aqui que comecei a empurrar Mark para algo mais parecido com um diálogo mantido. Precisávamos de um protocolo compartilhado que fosse além do simples pedido/resposta. Examinamos uma versão simplificada do FIPA ACL (Agent Communication Language), que define performativos como ‘informar’, ‘pedir’, ‘concordar’, ‘recusar’, etc. Não é necessário implementar toda a especificação, mas compreender a filosofia subjacente é extremamente útil.

Exemplo Prático: Um Simples Protocolo de Negociação

Refinamos nosso exemplo de coleta em uma negociação muito básica. O Agente A precisa de uma coleta, o Agente B pode transportar. O Agente A propõe, o Agente B responde, possivelmente com uma contraproposta ou uma recusa.

Primeiramente, precisamos de uma estrutura de mensagem comum. Algo que delineie claramente o ato comunicativo (o “performativo”) do conteúdo.


// Estrutura de mensagem comum
{
 "sender_id": "agent-A",
 "receiver_id": "agent-B",
 "performative": "propose", // e.g., propose, accept, refuse, inform, query
 "conversation_id": "pickup-task-XYZ", // Para conectar as mensagens em um diálogo
 "reply_to": "message-ABC", // Se esta é uma resposta a uma mensagem específica
 "content": {
 // O payload real específico para o performativo
 "task_type": "item_pickup",
 "item_id": "widget-123",
 "location": "warehouse-bay-3",
 "pickup_window": { "start": "2026-03-28T10:00:00Z", "end": "2026-03-28T10:30:00Z" }
 }
}

Agora, pensemos no fluxo. O Agente A quer propor uma coleta. O Agente B a recebe. O Agente B avalia. O Agente B responde. Cada passo é uma mensagem com um performativo específico.

“““html


// Lado do Agente A (simplificado)
class AgenteA {
 constructor(id, commService) {
 this.id = id;
 this.commService = commService;
 this.outstandingConversations = new Map(); // Armazena o estado para os diálogos em andamento
 }

 async avviaRitirare(itemId, location, window) {
 const conversationId = `pickup-${this.id}-${Date.now()}`;
 const message = {
 sender_id: this.id,
 receiver_id: 'agent-B',
 performative: 'propose',
 conversation_id: conversationId,
 content: {
 task_type: 'item_pickup',
 item_id: itemId,
 location: location,
 pickup_window: window
 }
 };

 this.outstandingConversations.set(conversationId, {
 status: 'proposto',
 itemId: itemId,
 expectedReply: ['accept', 'refuse', 'propose_counter']
 });

 console.log(`Agente A: Propondo retirada para ${itemId}. ID Conv: ${conversationId}`);
 await this.commService.sendMessage(message);
 }

 // Este método seria chamado pelo commService quando chega uma mensagem para o Agente A
 async gestisciMessaggioInArrivo(message) {
 const { sender_id, performative, conversation_id, content } = message;

 if (this.outstandingConversations.has(conversation_id)) {
 const convoState = this.outstandingConversations.get(conversation_id);

 if (performative === 'accept' && convoState.expectedReply.includes('accept')) {
 console.log(`Agente A: Agente B aceitou a retirada para ${convoState.itemId}!`);
 this.outstandingConversations.delete(conversation_id); // Diálogo concluído
 // Prosseguir com a execução da tarefa
 } else if (performative === 'refuse' && convoState.expectedReply.includes('refuse')) {
 console.log(`Agente A: Agente B recusou a retirada para ${convoState.itemId}. Motivo: ${content.reason}`);
 this.outstandingConversations.delete(conversation_id); // Diálogo concluído
 // Iniciar plano alternativo
 } else if (performative === 'propose_counter' && convoState.expectedReply.includes('propose_counter')) {
 console.log(`Agente A: Agente B fez uma contraproposta com uma nova proposta para ${convoState.itemId}. Nova janela: ${content.pickup_window.start}`);
 // Avaliar a contraproposta, potencialmente aceitar ou fazer outra contraproposta
 // Para simplicidade, vamos aceitar por enquanto
 const acceptMessage = {
 sender_id: this.id,
 receiver_id: sender_id,
 performative: 'accept',
 conversation_id: conversation_id,
 reply_to: message.message_id, // Supondo que as mensagens tenham IDs exclusivos
 content: { task_type: 'item_pickup', item_id: convoState.itemId }
 };
 await this.commService.sendMessage(acceptMessage);
 this.outstandingConversations.set(conversation_id, { status: 'accepted_counter', itemId: convoState.itemId, expectedReply: [] });
 } else {
 console.warn(`Agente A: Performativo imprevisto '${performative}' para a conversa ${conversation_id}.`);
 }
 } else {
 console.log(`Agente A: Recebida mensagem não solicitada para a conversa ${conversation_id}.`);
 // Lidar com propostas iniciais de outros agentes, ou simplesmente ignorar se não estiverem interessados
 }
 }
}

Isso ainda é uma visão simplificada, obviamente. O commService gerenciaria o transporte de rede efetivo (WebSockets, RabbitMQ, etc.) e o roteamento das mensagens para a instância correta do agente. A chave é que cada agente mantém um estado em relação às suas conversas em andamento, esperando tipos específicos de respostas com base na fase atual do diálogo. Isso representa um enorme avanço em relação às chamadas de API “fire-and-forget”.

A beleza dessa abordagem é que torna a comunicação explícita. Quando Mark implementou uma versão simplificada disso para seus drones, começou a ver menos colisões e uma alocação de tarefas mais eficiente. Um drone poderia explicitamente ‘propor’ um ponto de aterrissagem, e outro drone poderia ‘recusar’ fornecendo uma razão, ou ‘propor_contrário’ com uma alternativa. O sistema ganhou resiliência e clareza.

Os Custos Ocultos: Ontologias Compartilhadas e Confiança

Mudar para protocolos conversacionais expõe dois desafios mais profundos que muitas vezes são subestimados:

1. Ontologias Compartilhadas (ou a falta delas)

Para que os agentes possam se comunicar de maneira significativa, eles precisam de uma compreensão compartilhada dos termos que estão usando. O que significa “pickup_window”? É UTC? Horário local? É “location” uma coordenada GPS, um geohash ou um número de plataforma? Se o Agente A usa “item_id” e o Agente B espera “product_sku”, você tem um problema. Este é o problema da “Torre de Babel” para os agentes.

“`

Em um sistema rigidamente controlado com agentes construídos pela mesma equipe, você pode impor um modelo de dados comum. Mas em sistemas multiagente mais abertos, pode ser necessário construir camadas de tradução ou concordar com uma representação canônica para conceitos críticos. Isso não é apenas um problema técnico; é um problema organizacional, que requer acordos entre equipes diferentes ou até mesmo entre organizações diferentes.

Os drones de Mark inicialmente tinham definições ligeiramente diferentes para “altitude.” Um usava metros acima do nível do mar, o outro metros acima do nível do solo. Um erro simples. Potencialmente catastrófico ao coordenar as trajetórias de voo. Tivemos que impor uma definição única e inequívoca em seu esquema de comunicação compartilhado.

2. Confiança e Reputação

Quando os agentes tomam decisões com base em informações recebidas de outros agentes, como eles sabem se tais informações são confiáveis? Se o Agente B recusa constantemente tarefas sem uma boa razão, o Agente A deve continuar a propor tarefas a ele? Aqui entram em jogo conceitos de confiança, reputação e até mesmo medidas punitivas (como colocar temporariamente um agente na lista negra).

Construir um sistema de confiança eficaz é incrivelmente complexo e frequentemente requer um componente dedicado dentro da arquitetura do seu agente. Pode incluir:

  • Monitoramento do desempenho histórico de outros agentes.
  • Verificação das afirmações (se possível) por meio de meios independentes.
  • Permitir que os agentes avaliem ou forneçam feedback sobre os outros.
  • Implementar assinaturas criptográficas para garantir a autenticidade das mensagens.

Para os drones de Mark, começamos com um sistema de reputação muito simples: se um drone relatasse constantemente estar “ocupado” mas depois era observado como inativo, sua pontuação de confiabilidade diminuía e outros drones priorizavam aqueles menos “ocupados” primeiro. É rudimentar, mas é um passo em direção a sistemas descentralizados autocorretivos.

Takeaways Acionáveis para Sua Próxima Construção de Agentes

Se você está construindo sistemas com múltiplos agentes autônomos, não se limite a lançar endpoints REST para o problema e chamar isso de dia. Pense mais profundamente. Aqui está o que eu recomendo:

  1. Projete Protocolos Conversacionais, Não Apenas APIs: Mapeie os fluxos de diálogo típicos entre seus agentes. Quais são os estados? Quais são os performativos esperados em cada fase? Use conceitos como conversation_id e reply_to para estruturar suas mensagens.

    • Comece simples: Você não precisa de uma implementação completa de FIPA ACL. Defina simplesmente um conjunto central de performativos relevantes para o seu domínio (por exemplo, propose, accept, refuse, inform, query).
    • Comunicação com estado: Assegure-se de que cada agente possa acompanhar o estado de seus diálogos em andamento.
  2. Estabeleça uma Ontologia Compartilhada: Antes de escrever uma linha de código de comunicação, defina os conceitos críticos e seu significado preciso para seus agentes. Documente rigorosamente. Isso pode significar:

    • Modelos de dados canônicos: Concorde sobre uma representação única para as entidades-chave (por exemplo, artigos, locais, janelas de tempo).
    • Validação do esquema: Use ferramentas como JSON Schema para validar as mensagens de entrada e saída contra a ontologia acordada.
  3. Considere a Confiança e a Reputação Desde o Início: Mesmo em sistemas simples, os agentes confiarão uns nos outros. Pense em como um agente avalia a confiabilidade das informações recebidas. Isso pode ser tão simples quanto:

    • Pontuações de confiabilidade: Uma simples contagem para interações bem-sucedidas em relação aos fracassos.
    • Mecanismos de reconhecimento: Exigir reconhecimentos explícitos para mensagens críticas.
  4. Escolha o Transporte Subjacente Certo: Enquanto o protocolo de nível superior define a conversa, o transporte de nível inferior é importante. Para agentes altamente interativos, considere brokers de mensagens (como RabbitMQ, Kafka) ou WebSockets para uma comunicação persistente e de baixa latência em relação ao tradicional polling HTTP.

    “`html

  5. Testa, Testa, Testa (e Simula!): Os protocolos de comunicação dos agentes são complexos. Você precisa de testes sólidos, especialmente testes de integração que simulam fluxos conversacionais completos. Para sistemas multi-agente, os ambientes de simulação são seus melhores amigos para descobrir padrões de interação inesperados e atalhos.

Construir agentes que se comunicam efetivamente entre si é uma das partes mais desafiadoras, mas gratificantes, do desenvolvimento de agentes. Isso te empurra além dos paradigmas típicos da engenharia de software e para o mundo fascinante da inteligência distribuída e do comportamento emergente. Então, da próxima vez que você estiver delineando sua arquitetura de agente, reserve um momento. Não pense apenas em quais dados precisam ser movidos; pense na conversa que deve ocorrer. Seu eu futuro (e seus logs de depuração) agradecerão.

“`

🕒 Published:

✍️
Written by Jake Chen

AI technology writer and researcher.

Learn more →
Browse Topics: Agent Frameworks | Architecture | Dev Tools | Performance | Tutorials

More AI Agent Resources

ClawseoAgntmaxClawdevBotsec
Scroll to Top