Pular para o conteúdo principal
André Costa
Blog
Claude Code Hermes Agent
Serviços Método Meu Sistema Contato
Falar comigo
4 de julho de 2026

Quando NÃO Usar MCP ou A2A: Filas, Retries e Idempotência para Agentes de IA

Guia prático para decidir quando usar filas em vez de MCP ou A2A em agentes de IA: retries, DLQ, idempotência e workers em produção.

Agentes IA MCP A2A Filas RabbitMQ Produção Python Arquitetura
Tempo de leitura 18 min
Nível Intermediário / Avançado
Stack Python + RabbitMQ
Foco Produção
Quando NÃO Usar MCP ou A2A: Filas, Retries e Idempotência para Agentes de IA
Sumário
  • O Erro: Usar Protocolo Agentic para Tudo
  • Três Problemas que Parecem um Só
  • Quando MCP é a Escolha Certa
  • Quando A2A é a Escolha Certa
  • Quando uma Fila é Melhor que um Protocolo Agentic
  • Arquitetura Recomendada: Worker Agent Atrás da Fila
  • O Contrato da Mensagem Deve Ser Pequeno
  • Idempotência: a Parte que Impede Desastre
  • Exemplo Prático com RabbitMQ e Python
  • Retry Não é “Tentar de Novo para Sempre”
  • DLQ: Onde as Mensagens Ruins Vão para Serem Entendidas
  • Onde Entram MCP e A2A nessa Arquitetura?
  • Matriz de Decisão
  • Observabilidade para Worker Agents
  • Segurança: Fila Não é Zona Livre
  • Anti-Patterns Comuns
  • Checklist de Produção
  • Conclusão
  • Referências e Próximos Passos
Sumário do Artigo
  • O Erro: Usar Protocolo Agentic para Tudo
  • Três Problemas que Parecem um Só
  • Quando MCP é a Escolha Certa
  • Quando A2A é a Escolha Certa
  • Quando uma Fila é Melhor que um Protocolo Agentic
  • Arquitetura Recomendada: Worker Agent Atrás da Fila
  • O Contrato da Mensagem Deve Ser Pequeno
  • Idempotência: a Parte que Impede Desastre
  • Exemplo Prático com RabbitMQ e Python
  • Retry Não é “Tentar de Novo para Sempre”
  • DLQ: Onde as Mensagens Ruins Vão para Serem Entendidas
  • Onde Entram MCP e A2A nessa Arquitetura?
  • Matriz de Decisão
  • Observabilidade para Worker Agents
  • Segurança: Fila Não é Zona Livre
  • Anti-Patterns Comuns
  • Checklist de Produção
  • Conclusão
  • Referências e Próximos Passos

Nem todo sistema que usa LLM precisa de um protocolo agentic. Às vezes, a decisão mais profissional é não usar MCP, não usar A2A e colocar o agente atrás de uma fila comum, com retry, idempotência, dead-letter queue e logs decentes.

MCP e A2A são importantes. MCP resolve muito bem o problema de expor ferramentas para modelos. A2A resolve o problema de coordenação entre agentes autônomos. Mas nenhum dos dois substitui a camada de infraestrutura que sistemas distribuídos usam há décadas para absorver falha, controlar vazão e processar trabalho assíncrono.

Este guia mostra quando uma fila é a escolha certa, como desenhar um worker agent em produção e como evitar o clássico desastre: o agente executa a mesma ação duas vezes porque um retry caiu no lugar errado.

Você vai aprender:

  • A diferença entre acesso a ferramentas, coordenação entre agentes e integração sistêmica
  • Quando MCP é exagero, quando A2A é exagero e quando REST ainda basta
  • Como desenhar uma arquitetura com RabbitMQ, idempotência e DLQ
  • Código Python para processar tarefas com ack só depois de commit
  • Como observar custo, latência, falhas e tentativas por task_id

O Erro: Usar Protocolo Agentic para Tudo

Quando uma tecnologia nova aparece, a tentação é transformar qualquer problema em vitrine dela.

O time tem um processo de backoffice: ler PDFs, extrair campos, chamar um LLM para classificar o documento, salvar resultado no banco e enviar um alerta se houver inconsistência. Alguém olha para isso e diz: “vamos fazer com MCP”. Outro diz: “melhor A2A, porque tem agentes”. Duas semanas depois, existe um grafo de agentes elegante, streaming de eventos, contratos JSON-RPC e uma pergunta sem resposta: quem garante que esse documento será processado exatamente uma vez?

A resposta não deveria estar no LLM. Também não deveria estar em prompt. E, muitas vezes, não deveria estar em MCP ou A2A.

Esse é um problema clássico de infraestrutura:

  • aceitar trabalho sem bloquear o usuário;
  • controlar quantos jobs rodam ao mesmo tempo;
  • tentar de novo quando uma dependência falha;
  • mandar mensagens ruins para uma DLQ;
  • gravar resultado sem duplicar efeitos colaterais;
  • reconstruir o histórico quando algo dá errado.

Filas, workers e bancos transacionais foram feitos para isso. O agente entra como trabalhador especializado, não como o dono da confiabilidade do sistema.

Três categorias de comunicação para agentes: MCP para acesso a ferramentas, A2A para coordenação entre agentes e filas ou eventos para integração sistêmica

A pergunta certa não é “qual protocolo está na moda?”. A pergunta certa é: qual tipo de falha eu preciso absorver?


Três Problemas que Parecem um Só

Sistemas com agentes costumam misturar três problemas diferentes. Quando você mistura os três, a arquitetura fica bonita no desenho e frágil em produção.

Acesso a ferramentas

O modelo precisa descobrir e chamar capacidades externas: buscar documentos, consultar SQL, ler arquivos, abrir navegador, criar ticket, enviar e-mail.

Aqui o MCP brilha porque oferece:

  • descoberta de ferramentas;
  • schemas explícitos;
  • entrada e saída estruturadas;
  • separação entre modelo e sistemas internos;
  • uma forma padronizada de adicionar novas capacidades.

Use MCP quando a parte inteligente do sistema precisa perguntar: “quais ferramentas eu tenho e como devo chamá-las?”.

Coordenação entre agentes

Um agente precisa delegar uma tarefa para outro agente que tem autonomia própria. Não é só uma função. É uma entidade com objetivo, estado, progresso e artefatos.

Aqui A2A faz sentido porque modela:

  • descoberta de agentes;
  • delegação de tarefa;
  • status de execução;
  • resposta assíncrona ou streaming;
  • artefatos produzidos ao longo do trabalho.

Use A2A quando você consegue nomear dois agentes independentes e explicar por que cada um toma decisões próprias.

Integração sistêmica

Um job precisa ser processado com confiabilidade. Pode demorar. Pode falhar. Pode depender de serviço externo. Pode precisar de retry. Pode não ter humano esperando na tela.

Aqui filas e event buses são a resposta mais simples:

  • RabbitMQ;
  • Redis Queue;
  • Celery;
  • SQS;
  • Kafka;
  • Pub/Sub;
  • NATS.

Use fila quando o trabalho é assíncrono, idempotente e sensível a throughput.

Se ninguém precisa ficar olhando a resposta em tempo real, provavelmente você não precisa começar com A2A. Talvez você precise de uma fila.


Quando MCP é a Escolha Certa

MCP é ótimo quando você tem um modelo ou agente que precisa acessar ferramentas de forma dinâmica.

Exemplos:

  • Um agente de suporte que consulta base de conhecimento, CRM e histórico de tickets.
  • Um agente de análise que escolhe entre run_sql, vector_search e summarize_report.
  • Um ambiente de coding onde o modelo descobre comandos disponíveis, arquivos e ferramentas.
  • Um assistente interno que precisa acessar ferramentas diferentes conforme o departamento.

O ponto forte do MCP é a camada de contrato. O modelo não fica com uma lista hardcoded de funções. Ele vê capacidades descritas com schema, parâmetros e descrições. Isso reduz improviso e melhora governança.

Mas MCP não resolve tudo.

Se você tem um job de importação que sempre faz a mesma coisa — pega documento, extrai texto, classifica, salva — não existe muita descoberta. O worker não precisa perguntar quais ferramentas existem. Ele já sabe qual pipeline executar.

Nesse caso, MCP pode virar só uma camada a mais:

  • mais latência;
  • mais logs para correlacionar;
  • mais autenticação para manter;
  • mais superfície para erro;
  • mais código para explicar no incidente.

A regra prática: se há várias ferramentas e o modelo precisa escolher entre elas, considere MCP. Se há um pipeline fixo, comece mais simples.


Quando A2A é a Escolha Certa

A2A é útil quando o sistema tem agentes realmente independentes.

Exemplo: um agente pesquisador coleta fontes, um agente escritor produz uma versão inicial, um agente revisor valida riscos e outro agente legal verifica compliance. Cada um tem objetivo, prompt, ferramentas, política de falha e artefatos próprios.

Nesse cenário, tratar tudo como “tool call” fica estranho. O escritor não é só uma função chamada pelo pesquisador. Ele pode trabalhar por mais tempo, pedir mais contexto, devolver artefatos intermediários e falhar de maneira própria.

A2A ajuda quando existem:

  • tarefas longas;
  • coordenação entre pares;
  • handoff de artefatos;
  • status de progresso;
  • agentes com capacidades distintas;
  • necessidade de pausar, retomar ou cancelar tarefa.

Mas A2A também pode ser usado cedo demais.

Se o “segundo agente” é apenas o mesmo modelo com outro prompt, talvez você não tenha um sistema multiagente. Talvez você tenha uma função de revisão. Ou uma etapa de pipeline. Ou um worker.

A pergunta de corte é simples:

O segundo agente decide algo de forma independente ou só executa uma etapa previsível?

Se só executa uma etapa previsível, uma fila ou uma chamada interna pode ser melhor.


Quando uma Fila é Melhor que um Protocolo Agentic

Use fila quando o trabalho tem uma ou mais destas características:

  • o usuário não precisa da resposta imediatamente;
  • a tarefa demora segundos, minutos ou horas;
  • a tarefa pode ser repetida com segurança;
  • o sistema precisa controlar concorrência;
  • dependências externas falham com frequência;
  • você precisa de retry com backoff;
  • mensagens inválidas devem ir para DLQ;
  • throughput importa mais que latência interativa;
  • o LLM é uma etapa de processamento, não o orquestrador central.

Exemplos claros:

  • classificar leads em lote;
  • gerar embeddings de documentos;
  • resumir chamadas gravadas;
  • revisar descrições de produtos;
  • gerar relatórios agendados;
  • enriquecer contatos de CRM;
  • processar notas fiscais;
  • auditar páginas de um site;
  • reprocessar tickets antigos com uma nova taxonomia.

Nesses casos, o LLM pode ser excelente. Mas ele é um worker inteligente. A confiabilidade vem da fila, do banco e da política de idempotência.


Arquitetura Recomendada: Worker Agent Atrás da Fila

A arquitetura base é simples:

  1. Uma API, cron ou evento cria uma tarefa.
  2. O sistema grava um task_id no banco com status queued.
  3. Uma mensagem pequena é publicada na fila com task_id e metadados.
  4. Um worker consome a mensagem.
  5. O worker carrega dados no banco, chama LLM e ferramentas necessárias.
  6. O worker grava resultado, custo, logs e status final.
  7. Só depois do commit ele envia ack para a fila.
  8. Se falhar de forma recuperável, a mensagem volta com retry.
  9. Se falhar repetidamente, vai para DLQ.
Fluxo de arquitetura com entrada, registro de task id, fila, worker agent, banco de estado, DLQ e observabilidade

O detalhe mais importante está no passo 7: ack só depois do commit.

Se o worker confirma a mensagem antes de gravar o resultado, uma queda no meio do caminho perde o job. Se grava resultado sem idempotência e cai antes do ack, a fila pode entregar de novo e você duplica efeito colateral.

Produção mora nesses detalhes chatos.


O Contrato da Mensagem Deve Ser Pequeno

Não coloque o documento inteiro, o prompt inteiro e o histórico inteiro dentro da mensagem da fila.

A mensagem deve carregar referência, não payload gigante.

Exemplo de mensagem boa:

{
  "task_id": "task_01JZ8W4W9GZK4K2GZ7Q2",
  "type": "classify_document",
  "tenant_id": "acme",
  "attempt": 1,
  "created_at": "2026-07-04T10:15:00Z"
}

O worker usa task_id para buscar o conteúdo real no banco ou no object storage. Isso tem quatro vantagens:

  • mensagens ficam pequenas e rápidas;
  • dados sensíveis não circulam pela fila;
  • retries usam o mesmo estado canônico;
  • auditoria fica concentrada no banco.

A fila transporta intenção. O banco guarda verdade.


Idempotência: a Parte que Impede Desastre

Uma operação idempotente pode ser executada mais de uma vez sem gerar resultado duplicado.

Isso é essencial porque filas sérias normalmente trabalham com semântica de at-least-once delivery: a mensagem será entregue pelo menos uma vez, mas pode ser entregue duas vezes se o worker cair, perder conexão ou demorar demais.

Sem idempotência, estes bugs aparecem:

  • dois e-mails enviados para o mesmo lead;
  • duas cobranças tentadas;
  • dois relatórios publicados;
  • dois tickets criados;
  • custo duplicado de LLM;
  • resultado final sobrescrito por uma tentativa antiga.

A forma mais simples é criar uma chave única para o efeito colateral.

CREATE TABLE agent_tasks (
  task_id TEXT PRIMARY KEY,
  tenant_id TEXT NOT NULL,
  task_type TEXT NOT NULL,
  status TEXT NOT NULL,
  input_ref TEXT NOT NULL,
  result_ref TEXT,
  attempts INTEGER NOT NULL DEFAULT 0,
  last_error TEXT,
  created_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL
);

CREATE TABLE agent_effects (
  effect_key TEXT PRIMARY KEY,
  task_id TEXT NOT NULL,
  effect_type TEXT NOT NULL,
  external_id TEXT,
  created_at TIMESTAMP NOT NULL
);

Antes de executar uma ação externa, você registra ou verifica o effect_key.

Exemplos de effect_key:

  • send_followup:lead_123:sequence_4
  • create_ticket:task_01JZ8:billing_issue
  • publish_report:client_acme:2026-07
  • charge_card:order_789:payment_attempt_1

Se a chave já existe, o worker sabe que aquele efeito já aconteceu. Ele pode pular a ação externa, recuperar o external_id salvo e concluir o job.

Idempotência não é otimização. É cinto de segurança.


Exemplo Prático com RabbitMQ e Python

Abaixo está um worker mínimo usando pika. Ele mostra a estrutura, não uma biblioteca final para produção.

A regra é: processar, gravar, commitar, só então confirmar a mensagem.

import json
import os
import sqlite3
from datetime import datetime, timezone

import pika

DB_PATH = os.environ.get("DB_PATH", "agent_tasks.db")
AMQP_URL = os.environ["AMQP_URL"]


def now():
    return datetime.now(timezone.utc).isoformat()


def connect_db():
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn


def classify_with_llm(text):
    # Troque por sua chamada real: OpenAI, Anthropic, Gemini, modelo local etc.
    if "reembolso" in text.lower():
        return {"category": "financeiro", "priority": "alta"}
    return {"category": "geral", "priority": "normal"}


def process_task(task_id):
    conn = connect_db()
    try:
        task = conn.execute(
            "SELECT * FROM agent_tasks WHERE task_id = ?",
            (task_id,),
        ).fetchone()

        if task is None:
            raise RuntimeError(f"task inexistente: {task_id}")

        if task["status"] == "done":
            return "already_done"

        conn.execute(
            "UPDATE agent_tasks SET status = ?, attempts = attempts + 1, updated_at = ? WHERE task_id = ?",
            ("running", now(), task_id),
        )
        conn.commit()

        input_ref = task["input_ref"]
        document = conn.execute(
            "SELECT content FROM documents WHERE id = ?",
            (input_ref,),
        ).fetchone()

        if document is None:
            raise RuntimeError(f"documento não encontrado: {input_ref}")

        result = classify_with_llm(document["content"])
        result_json = json.dumps(result, ensure_ascii=False)

        conn.execute(
            "INSERT OR REPLACE INTO task_results (task_id, result_json, created_at) VALUES (?, ?, ?)",
            (task_id, result_json, now()),
        )
        conn.execute(
            "UPDATE agent_tasks SET status = ?, result_ref = ?, updated_at = ? WHERE task_id = ?",
            ("done", task_id, now(), task_id),
        )
        conn.commit()
        return "done"
    except Exception as exc:
        conn.rollback()
        conn.execute(
            "UPDATE agent_tasks SET status = ?, last_error = ?, updated_at = ? WHERE task_id = ?",
            ("failed_retryable", str(exc), now(), task_id),
        )
        conn.commit()
        raise
    finally:
        conn.close()


def on_message(channel, method, properties, body):
    message = json.loads(body)
    task_id = message["task_id"]

    try:
        process_task(task_id)
        channel.basic_ack(delivery_tag=method.delivery_tag)
    except Exception:
        # Rejeita sem requeue direto. Em produção, use exchange de retry com TTL
        # ou plugin de delayed message. Depois do limite, roteie para DLQ.
        channel.basic_nack(delivery_tag=method.delivery_tag, requeue=False)


def main():
    connection = pika.BlockingConnection(pika.URLParameters(AMQP_URL))
    channel = connection.channel()
    channel.basic_qos(prefetch_count=4)
    channel.basic_consume(queue="agent_tasks", on_message_callback=on_message)
    channel.start_consuming()


if __name__ == "__main__":
    main()

Esse exemplo esconde detalhes de produção, mas acerta a espinha dorsal:

  • prefetch_count=4 limita trabalho em voo;
  • o banco guarda o estado da tarefa;
  • status == done torna reentrega segura;
  • resultado é gravado antes do basic_ack;
  • falha gera basic_nack e vai para a política de retry/DLQ.

O LLM pode ser trocado sem mudar o contrato operacional.


Retry Não é “Tentar de Novo para Sempre”

Retry sem política vira amplificador de incidente.

Se a API do modelo está fora do ar e você tem 50 workers tentando de novo imediatamente, você não tem resiliência. Você tem um ataque distribuído contra sua própria dependência.

Uma política mínima deve definir:

  • quantas tentativas são permitidas;
  • qual backoff usar;
  • quais erros são recuperáveis;
  • quais erros devem ir direto para DLQ;
  • como alertar quando DLQ cresce;
  • como reprocessar DLQ com segurança.

Erros recuperáveis:

  • timeout temporário;
  • rate limit;
  • erro 502/503 do provedor;
  • conexão de banco encerrada;
  • indisponibilidade temporária de API externa.

Erros não recuperáveis:

  • payload inválido;
  • documento inexistente;
  • tenant sem permissão;
  • schema incompatível;
  • arquivo corrompido;
  • regra de negócio violada.

Não trate tudo como “retry”. Algumas mensagens precisam falhar rápido para alguém investigar.


DLQ: Onde as Mensagens Ruins Vão para Serem Entendidas

Dead-letter queue não é lixeira. É a caixa-preta do pipeline.

Toda mensagem que excede o limite de tentativas ou falha por erro não recuperável deve ir para DLQ com contexto suficiente:

{
  "task_id": "task_01JZ8W4W9GZK4K2GZ7Q2",
  "type": "classify_document",
  "tenant_id": "acme",
  "failed_at": "2026-07-04T10:22:31Z",
  "error_type": "invalid_payload",
  "error_message": "campo document_id ausente",
  "attempts": 3
}

A DLQ precisa de rotina operacional:

  • dashboard com volume por tipo de erro;
  • alerta quando passa do baseline;
  • botão ou script de reprocessamento;
  • política de expurgo;
  • amostragem para melhorar validação de entrada;
  • link para trace e logs da tarefa.

Sem isso, DLQ vira cemitério. E cemitério não é observabilidade.


Onde Entram MCP e A2A nessa Arquitetura?

A fila não elimina MCP ou A2A. Ela impede que você use os dois para o trabalho errado.

Um desenho comum em produção é:

  • MCP na borda inteligente: o agente worker usa MCP para acessar ferramentas internas de forma padronizada.
  • Fila no pipeline: a entrega, retry e controle de vazão ficam na infraestrutura.
  • A2A apenas quando necessário: se o worker delega uma subtarefa para outro agente independente, aí A2A entra.

Exemplo: um job de auditoria de site.

  1. A fila entrega audit_site:acme para um worker.
  2. O worker usa ferramentas MCP: crawl_page, extract_schema, check_links, run_lighthouse.
  3. Se houver revisão especializada, ele cria uma tarefa A2A para um agente de SEO ou segurança.
  4. O resultado volta para o banco.
  5. O worker confirma a mensagem.

Cada camada faz seu trabalho.

MCP não precisa fingir ser fila. A2A não precisa fingir ser orquestrador de retry. RabbitMQ não precisa fingir ser protocolo semântico para LLM.


Matriz de Decisão

Use esta matriz quando o time estiver discutindo arquitetura.

Tabela comparativa mostrando quando escolher MCP, A2A, fila ou REST em sistemas com agentes de IA

Algumas decisões ficam simples:

  • O modelo precisa descobrir ferramentas? MCP.
  • Um agente precisa delegar trabalho para outro agente autônomo? A2A.
  • O trabalho é assíncrono, pesado e tolera processamento posterior? Fila.
  • É uma chamada interna simples e síncrona? REST ainda é suficiente.

A pior escolha costuma ser usar a camada mais sofisticada para parecer moderno. A melhor costuma ser a que reduz o número de coisas que podem falhar às 3h da manhã.


Observabilidade para Worker Agents

Um worker agent precisa de métricas diferentes de um chatbot.

Métricas mínimas:

  • jobs por minuto;
  • tempo na fila;
  • tempo de processamento;
  • tentativas por task;
  • taxa de sucesso;
  • taxa de DLQ;
  • custo por job;
  • tokens por job;
  • erro por provedor de LLM;
  • quantidade de efeitos externos executados.

Logs mínimos por tentativa:

{
  "task_id": "task_01JZ8W4W9GZK4K2GZ7Q2",
  "attempt": 2,
  "worker_id": "worker-07",
  "tenant_id": "acme",
  "status": "failed_retryable",
  "llm_provider": "anthropic",
  "input_tokens": 1840,
  "output_tokens": 312,
  "duration_ms": 8420,
  "error": "rate_limit"
}

O task_id deve atravessar tudo:

  • mensagem da fila;
  • linha no banco;
  • logs;
  • trace;
  • chamada ao LLM;
  • efeito externo;
  • alerta;
  • DLQ.

Sem correlação, você terá muitos logs e pouca explicação.


Segurança: Fila Não é Zona Livre

Colocar um agente atrás de uma fila não torna o sistema automaticamente seguro.

Aplique as mesmas regras de produção:

  • cada worker deve ter identidade própria;
  • credenciais devem ser scoped por tarefa;
  • tenants devem ser isolados;
  • payload da fila não deve carregar segredo;
  • mensagens devem ser validadas antes do processamento;
  • prompts e documentos devem passar por filtros de entrada;
  • ações destrutivas precisam de approval gate;
  • logs não devem vazar PII;
  • DLQ deve ter acesso restrito.

Um padrão perigoso é dar ao worker uma credencial ampla “porque ele roda no backend”. Isso transforma cada bug de prompt injection em risco operacional.

Prefira credenciais curtas, permissões por ferramenta e validação explícita antes de ação externa.


Anti-Patterns Comuns

Colocar conversa em fila

Se o usuário está esperando uma resposta interativa, uma fila no caminho principal pode destruir UX. Use streaming, SSE, WebSocket ou resposta síncrona. Filas entram para trabalhos de bastidor.

Reprocessar sem idempotência

Se você não consegue explicar o que acontece quando o mesmo task_id roda duas vezes, você ainda não tem arquitetura de produção.

Enviar payload gigante na mensagem

Isso dificulta retry, segurança, versionamento e auditoria. Envie referência.

Tratar erro de negócio como erro temporário

Se o tenant não tem permissão, tentar de novo não vai ajudar. Vai só gastar dinheiro.

Misturar orquestração e efeito colateral

O LLM pode decidir “preciso enviar e-mail”. Mas o envio real deve passar por política determinística, idempotência e autorização.

Não versionar prompt

Se o comportamento do worker depende de prompt, grave prompt_version no resultado. Senão você não sabe qual versão produziu qual decisão.


Checklist de Produção

Antes de colocar um worker agent em produção, responda:

  • [ ] Cada tarefa tem task_id único?
  • [ ] O estado da tarefa fica em banco transacional?
  • [ ] A mensagem da fila carrega referência, não payload gigante?
  • [ ] O worker só dá ack depois de gravar resultado?
  • [ ] Reentrega da mesma mensagem é segura?
  • [ ] Efeitos externos têm effect_key idempotente?
  • [ ] Existe limite de tentativas?
  • [ ] Existe DLQ monitorada?
  • [ ] Erros recuperáveis e não recuperáveis são separados?
  • [ ] Logs, traces e métricas usam o mesmo task_id?
  • [ ] Custo de LLM é registrado por tarefa?
  • [ ] Prompt e modelo são versionados?
  • [ ] O worker tem permissões mínimas?
  • [ ] Existe processo para reprocessar DLQ?

Se você respondeu “não” para metade disso, MCP ou A2A não vão salvar a arquitetura.


Conclusão

MCP, A2A e filas não competem no mesmo nível.

MCP é uma excelente camada para ferramentas descobríveis. A2A é uma boa resposta para coordenação entre agentes independentes. Filas são a base para trabalho assíncrono confiável.

O erro é pedir que um protocolo resolva os três problemas. Em produção, sistemas bons costumam ser menos glamourosos: mensagem pequena, task_id, banco como fonte da verdade, idempotência, retry com limite, DLQ e observabilidade.

Se o seu agente precisa responder agora, pense em MCP, A2A ou streaming. Se ele precisa trabalhar direito, mesmo quando tudo falha ao redor, comece pela fila.


Referências e Próximos Passos

  • MCP na Prática — para entender a camada de ferramentas.
  • A2A na Prática — para coordenação entre agentes.
  • Observabilidade de Agentes de IA — para traces, logs e alertas.
  • Segurança de Agentes de IA — para threat model e guardrails.

Publicado em andrecosta.ia.br.

Leia também

  • MCP na Prática Como conectar sua IA a ferramentas, APIs e bases de conhecimento.
  • A2A na Prática Quando agentes precisam conversar entre si e delegar tarefas.
  • Observabilidade de Agentes de IA Traces, logs e alertas para entender o que seus agentes fizeram.
  • Identidade e Permissões para Agentes Como aplicar menor privilégio, tokens scoped e approval gates.

Quer aplicar isso no seu trabalho? Falar comigo no WhatsApp (confiança humana) ou comece seu próximo passo na trilha para construir autonomia real via fundamentos + método.

← Blog Início
André Costa

Fundamentos e método para você projetar e construir automações e agentes com autonomia real. Sem hype.

Páginas

Blog O que faço Método Conteúdos Contato

Legal

Privacidade Termos de Uso
© 2026 André Costa Autonomia com IA / fundamentos práticos / sistemas que você controla

Utilizamos cookies para entender como você interage com nosso site (GA4/GTM) e melhorar sua experiência técnica. Ao continuar, você concorda com nossa Política de Privacidade.