Por que muitos sistemas agentivos falham em produção e como projetar agentes confiáveis com máquinas de estado, contratos de ferramentas claros, retries e observabilidade profunda.

Sistemas agentivos são aplicações nas quais um LLM não se limita a responder a um prompt, mas decide o que fazer a seguir: quais ferramentas chamar, quais dados buscar, quais passos executar e quando está “feito”. Eles combinam um modelo, um conjunto de ferramentas (APIs, bancos de dados, serviços), um loop de planejamento/execução e a infraestrutura que junta tudo isso.
Em uma demo, isso parece mágico: um agente elabora um plano, chama algumas ferramentas e retorna um resultado perfeito. O caminho feliz é curto, a latência é baixa e nada falha ao mesmo tempo.
Sob cargas reais, o mesmo agente é pressionado de maneiras que a demo nunca viu:
O resultado: comportamento instável difícil de reproduzir, corrupção silenciosa de dados e fluxos de usuário que ocasionalmente travam ou giram para sempre.
Agentes instáveis não apenas prejudicam a “experiência”:
Este artigo trata de padrões de engenharia, não de “prompts melhores”. Vamos ver máquinas de estado, contratos explícitos de ferramentas, estratégias de retry e tratamento de falhas, controle de memória e concorrência, e padrões de observabilidade que tornam sistemas agentivos predizíveis sob carga — não apenas impressionantes no palco.
A maioria dos sistemas de agentes parece funcionar bem em uma demo com caminho feliz único. Eles falham quando tráfego, ferramentas e casos de borda aparecem juntos.
Orquestrações ingênuas presumem que o modelo “fará a coisa certa” em uma ou duas chamadas. No uso real, você vê padrões recorrentes:
Sem estados explícitos e condições finais, esses comportamentos são inevitáveis.
A amostragem do LLM, variabilidade de latência e tempos das ferramentas criam não‑determinismo oculto. A mesma entrada pode percorrer ramos diferentes, invocar ferramentas distintas ou interpretar resultados de maneira diversa.
Em escala, problemas das ferramentas dominam:
Cada um desses vira loops espúrios, retries ou respostas finais incorretas.
O que raramente quebra a 10 RPS quebrará constantemente a 1.000 RPS. A concorrência revela:
Times de produto frequentemente esperam fluxos determinísticos, SLAs claros e auditabilidade. Agentes, deixados sem restrições, oferecem comportamento probabilístico, best‑effort com garantias fracas.
Quando arquiteturas ignoram esse desalinhamento — tratando agentes como serviços tradicionais em vez de planejadores estocásticos — os sistemas se comportam de forma imprevisível justamente quando a confiabilidade importa mais.
Agentes prontos para produção têm menos a ver com “prompts inteligentes” e mais com design disciplinado de sistemas. Uma forma útil de pensá‑los é como pequenas máquinas previsíveis que ocasionalmente chamam um LLM, não como blobs misteriosos de LLM que ocasionalmente tocam seus sistemas.
Quatro propriedades importam mais:
Você não obtém essas propriedades apenas com prompts. Você as obtém com estrutura.
O padrão inicial de muitas equipes é: “enquanto não estiver pronto, chame o modelo, deixe‑o pensar, talvez chame uma ferramenta, repita”. Isso é fácil de prototipar e difícil de operar.
Um padrão mais seguro é representar o agente como um fluxo explícito:
COLLECTING_INPUT, PLANNING, EXECUTING_STEP, WAITING_ON_HUMAN, DONE).Isso transforma o agente em uma máquina de estado onde cada passo é inspecionável, testável e replayable. Loops livres parecem flexíveis, mas fluxos explícitos é o que torna incidentes depuráveis e comportamentos auditáveis.
Agentes monolíticos que “fazem tudo” são atraentes, mas criam acoplamento entre responsabilidades não relacionadas: planejamento, recuperação, lógica de negócio, orquestração de UI e mais.
Em vez disso, componha agentes pequenos e bem escopados ou skills:
Cada skill pode ter sua própria máquina de estados, ferramentas e regras de segurança. A lógica de composição vira então um fluxo de nível superior, não um prompt em crescimento contínuo dentro de um único agente.
Essa modularidade mantém cada agente simples o suficiente para raciocinar e permite evoluir uma capacidade sem desestabilizar as demais.
Um modelo mental útil é dividir um agente em três camadas:
Política de decisão (prompts + modelo)
Encapsula como o agente escolhe próximas ações, interpretado sob restrições estritas. Você deve poder trocar o modelo, ajustar temperatura ou refinar prompts sem tocar o encanamento do sistema.
Máquina de estado / motor de workflow
Assume onde você está no processo, quais transições são possíveis e como persistir progresso. A política sugere um movimento; a máquina de estado valida e aplica.
Camada de ferramentas
Implementa o que pode realmente acontecer no mundo: APIs, bancos, filas, serviços externos. Ferramentas expõem contratos estreitos e bem tipados e aplicam autorização, limites de taxa e validação de entrada.
Ao impor essa separação, você evita o erro de esconder lógica de negócio em prompts ou descrições de ferramentas. O LLM vira um componente de decisão dentro de uma concha determinística clara, não a concha em si.
Os sistemas agentivos mais confiáveis não são as demos mais impressionantes — são aqueles cujo comportamento você consegue explicar em um quadro branco.
Concretamente:
Esse viés para agentes pequenos, componíveis e bem estruturados permite que sistemas cresçam em escopo sem desabar sob sua própria complexidade.
A maioria das implementações de agente começa como um loop de “pensar, agir, observar” em volta de uma chamada de LLM. Isso funciona para demos, mas rapidamente vira opaco e frágil. Uma abordagem melhor é tratar o agente como uma máquina de estados explícita: um conjunto finito de estados, com transições bem definidas acionadas por eventos.
Em vez de deixar o modelo decidir implicitamente o que fazer a seguir, defina um pequeno diagrama de estados:
Transições entre esses estados são acionadas por eventos tipados como UserRequestReceived, ToolCallSucceeded, ToolValidationFailed, TimeoutExceeded ou HumanOverride. Cada evento, junto com o estado atual, determina o próximo estado e ações.
Isso torna retries e timeouts diretos: você anexa políticas a estados individuais (por exemplo, CALL_TOOL pode re-tentar 3 vezes com backoff exponencial; PLAN pode não re-tentar) em vez de espalhar lógica de retry pelo código.
Persista o estado atual e o contexto mínimo em uma store externa (banco de dados, fila ou motor de workflow). O agente então vira uma função pura:
next_state, actions = transition(current_state, event, context)
Isso permite:
Com uma máquina de estados, cada passo do comportamento do agente é explícito: em qual estado estava, que evento ocorreu, qual transição disparou e quais efeitos colaterais foram produzidos. Essa clareza acelera a depuração, simplifica investigações de incidentes e cria uma trilha de auditoria natural para compliance. Você pode provar, a partir de logs e histórico de estado, que certas ações de risco só são tomadas a partir de estados específicos e sob condições definidas.
Agentes se comportam de forma muito mais previsível quando ferramentas parecem menos com “APIs escondidas em prosa” e mais com interfaces bem desenhadas com garantias explícitas.
Cada ferramenta deve ter um contrato que cubra:
InvalidInput, NotFound, RateLimited, TransientFailure) com semânticas claras.Exponha esse contrato ao modelo como documentação estruturada, não como um muro de texto. O planner do agente deve saber quais erros são re‑tentáveis, quais requerem intervenção humana e quais devem parar o workflow.
Trate I/O de ferramenta como qualquer outra API de produção:
Isso permite simplificar prompts: em vez de instruções verbosas, confie em orientação guiada por schema. Restrições claras reduzem argumentos alucinados e sequências de ferramenta sem sentido.
Ferramentas evoluem; agentes não devem quebrar sempre que isso ocorre.
v1, v1.1, v2) e fixe agentes a uma versão.A lógica de planejamento pode então misturar agentes e ferramentas em diferentes estágios de maturidade com segurança.
Projete contratos com falha parcial em mente:
O agente pode então adaptar: continuar o fluxo com funcionalidade reduzida, pedir confirmação ao usuário ou trocar para uma ferramenta alternativa.
Contratos de ferramenta são um local natural para codificar limites de segurança:
confirm: true).Combine isso com checagens server‑side; nunca confie apenas no modelo para “se comportar”.
Quando ferramentas têm contratos claros, validados e versionados, prompts podem ser mais curtos, a orquestração fica mais simples e a depuração muito mais fácil. Você move complexidade de instruções em linguagem natural para schemas e políticas determinísticas, reduzindo chamadas de ferramenta alucinadas e efeitos colaterais inesperados.
Sistemas agentivos confiáveis assumem que tudo falhará eventualmente: modelos, ferramentas, redes, até sua própria camada de coordenação. O objetivo não é evitar falhas, mas torná‑las baratas e seguras.
Idempotência significa: repetir a mesma requisição produz o mesmo efeito externamente visível que executá‑la uma vez. Isso é crítico para agentes LLM, que frequentemente reemitem chamadas de ferramenta após falhas parciais ou respostas ambíguas.
Torne ferramentas idempotentes por design:
request_id estável. A ferramenta armazena isso e retorna o mesmo resultado se vir o ID novamente.Use retries estruturados para falhas transitórias (timeouts, limites de taxa, 5xx): backoff exponencial, jitter para evitar revoadas e máximo de tentativas rígido. Registre cada tentativa com IDs de correlação para traçar o comportamento do agente.
Para falhas permanentes (4xx, erros de validação, violação de regras de negócio), não re‑tente. Exponha um erro estruturado ao policy do agente para que ele replaneje, pergunte ao usuário ou escolha outra ferramenta.
Implemente circuit breakers tanto na camada do agente quanto na das ferramentas: após falhas repetidas, bloqueie temporariamente chamadas àquela ferramenta e falhe rápido. Pareie isso com fallbacks bem definidos: modos degradados, dados em cache ou ferramentas alternativas.
Evite retries cegos a partir do loop do agente. Sem ferramentas idempotentes e classes de falha claras, você só multiplica efeitos colaterais, latência e custo.
Agentes confiáveis começam com pensamento claro sobre o que é estado e onde ele vive.
Trate um agente como você trataria um serviço que atende uma requisição:
Misturar esses tipos leva a confusão e bugs. Por exemplo, colocar resultados efêmeros de ferramentas na “memória” faz agentes reutilizarem contexto stale em conversas futuras.
Você tem três opções principais:
Uma boa regra: o LLM é uma função stateless sobre um objeto de estado explícito. Persista esse objeto fora do modelo e regenere prompts a partir dele.
Um padrão comum de falha é usar logs de conversa, traces ou prompts brutos como memória de fato.
Problemas:
Em vez disso, defina schemas de memória estruturada: user_profile, project, task_history, etc. Derive logs a partir do estado, não o contrário.
Quando múltiplas ferramentas ou agentes atualizam as mesmas entidades (ex.: um registro de CRM ou status de tarefa), você precisa de controles básicos de consistência:
Para operações de alto valor, registre um log de decisões separado do log conversacional: o que mudou, por quê e com base em quais entradas.
Para sobreviver a crashes, deploys e limites de taxa, workflows devem ser retomáveis:
Isso também possibilita debugging com viagem no tempo: inspecionar e reproduzir o estado exato que levou a uma decisão ruim.
Memória é tanto ativo quanto passivo. Para agentes em produção:
Trate memória como um produto: projetada, versionada e governada — não um despejo de texto em crescimento preso ao seu agente.
Agentes parecem sequenciais em um quadro, mas se comportam como sistemas distribuídos sob carga real. Assim que você tem muitos usuários concorrentes, ferramentas e jobs em background, você está lidando com condições de corrida, trabalho duplicado e problemas de ordenação.
Modos comuns de falha:
Você mitiga isso com contratos idempotentes de ferramentas, estado de workflow explícito e locking otimista/pessimista na camada de dados.
Fluxos síncronos request–response são simples mas frágeis: cada dependência deve estar ativa, dentro dos limites de taxa e rápida. Quando agentes se ramificam para muitas ferramentas ou subtarefas em paralelo, mova etapas longas ou com efeitos colaterais para trás de uma fila.
Orquestração baseada em fila permite:
Agentes normalmente atingem três classes de limites:
Você precisa de uma camada de rate‑limit explícita com throttles por usuário, por tenant e globais. Use baldes de tokens ou leaky buckets para aplicar políticas, e exponha erros claros (ex.: RATE_LIMIT_SOFT, RATE_LIMIT_HARD) para que agentes possam retroceder com elegância.
Backpressure é como o sistema se protege sob estresse. Estratégias incluem:
Monitore sinais de saturação: profundidade de filas, utilização de workers, taxas de erro de modelo/ferramenta e percentis de latência. Filas crescendo combinadas com latência e erros 429/503 são seu aviso precoce de que agentes estão derrubando o ambiente.
Você não consegue tornar um agente confiável se não consegue responder duas perguntas rapidamente: o que ele fez? e por que ele fez isso? Observabilidade para sistemas agentivos é sobre tornar essas respostas baratas e precisas.
Projete observabilidade para que uma única tarefa tenha um trace que atravesse:
Dentro desse trace, anexe logs estruturados para decisões-chave (escolha de roteamento, revisão de plano, acionamentos de guardrail) e métricas para volume e saúde.
Um trace útil normalmente inclui:
Log prompts, entradas e saídas de ferramentas em forma estruturada, mas passe‑os por uma camada de redacção antes:
Mantenha conteúdo bruto atrás de feature flags em ambientes não‑prod; a produção deve padronizar visualizações redigidas.
No mínimo, monitore:
Quando incidentes acontecem, bons traces e métricas permitem transformar “o agente parece instável” em uma afirmação precisa como: “P95 de tarefas falhando em ToolSelection após 2 retries devido a novo schema em billing_service”, cortando o diagnóstico de horas para minutos e dando alavancas concretas para ajuste.
Testar agentes significa testar tanto as ferramentas que eles chamam quanto os fluxos que unem tudo. Trate isso como teste de sistemas distribuídos, não apenas ajuste de prompts.
Comece com testes unitários na fronteira da ferramenta:
Esses testes não dependem do LLM. Chame a ferramenta diretamente com entradas sintéticas e afirme a saída ou contrato de erro exato.
Testes de integração exercitam o workflow do agente end‑to‑end: LLM + ferramentas + orquestração.
Modele‑os como testes baseados em cenários:
Esses testes afirmam transições de estado e chamadas de ferramenta, não cada token do LLM. Verifique: quais ferramentas foram chamadas, com quais argumentos, em que ordem e qual estado/resultado final o agente alcançou.
Para manter testes repetíveis, fixe respostas do LLM e saídas de ferramentas.
Um padrão típico:
with mocked_llm(fixtures_dir="fixtures/llm"), mocked_tools():
result = run_agent_scenario(input_case)
assert result.state == "COMPLETED"
Qualquer mudança de prompt ou schema deve acionar uma execução de regressão inegociável:
Evolução de schema (adicionar campos, apertar tipos) recebe seus próprios casos de regressão para detectar agentes ou ferramentas que ainda assumem o contrato antigo.
Nunca envie um novo modelo, política ou estratégia de roteamento direto para produção.
Em vez disso:
Só após passar por portões offline é que uma nova variante deve chegar à produção, idealmente atrás de feature flags e rollout gradual.
Logs de agentes frequentemente contêm dados sensíveis. Testes devem respeitar isso.
Codifique essas regras no pipeline de CI para que nenhum artefato de teste seja gerado ou armazenado sem checagens de anonimização.
Operar agentes em produção é mais parecido com rodar um sistema distribuído do que entregar um modelo estático. Você precisa de controles para rollout, metas de confiabilidade claras e gestão disciplinada de mudanças.
Introduza novos agentes ou comportamentos gradualmente:
Sustente tudo isso com feature flags e políticas dirigidas por configuração: regras de roteamento, ferramentas habilitadas, temperatura, ajustes de segurança. Mudanças devem ser configuráveis, não codificadas, e instantaneamente reversíveis.
Defina SLOs que reflitam saúde do sistema e valor ao usuário:
Ligue isso a alertas e trate incidentes como em qualquer serviço de produção: propriedade clara, runbooks de triagem e passos padrão de mitigação (rollback de flag, drenagem de tráfego, modo seguro).
Use logs, traces e transcrições para refinar prompts, ferramentas e políticas. Trate cada mudança como um artefato versionado com revisão, aprovação e capacidade de rollback.
Evite mudanças silenciosas de prompt ou ferramenta. Sem controle de mudanças, você não consegue correlacionar regressões a edições específicas, e resposta a incidentes vira tentativa e erro em vez de engenharia investigativa.
Um sistema agentivo pronto para produção se beneficia de separação clara de responsabilidades. O objetivo é manter o agente inteligente nas decisões, mas pouco inteligente na infraestrutura.
1. Gateway / borda de API
Ponto de entrada único para clientes (apps, serviços, UIs). Ele lida com:
2. Orquestrador
O orquestrador é o “tronco”, não o cérebro. Ele coordena:
Os LLMs ficam atrás do orquestrador, usados pelo planner e por ferramentas específicas que precisam de entendimento de linguagem.
3. Camada de ferramentas e armazenamento
Lógica de negócio permanece em microservices existentes, filas e sistemas de dados. Ferramentas são wrappers finos em torno de:
O orquestrador invoca ferramentas via contratos estritos, enquanto sistemas de armazenamento continuam sendo a fonte de verdade.
Aplique auth e cotas no gateway; aplique segurança, acesso a dados e políticas no orquestrador. Todas as chamadas (LLM e ferramentas) emitem telemetria estruturada para um pipeline que alimenta:
Uma arquitetura simples (gateway → orquestrador único → ferramentas) é mais fácil de operar; adicionar planners separados, motores de política e gateways de modelo aumenta flexibilidade, ao custo de mais coordenação, latência e complexidade operacional.
Você agora tem os ingredientes centrais para agentes que se comportam de forma previsível sob carga real: máquinas de estado explícitas, contratos de ferramenta claros, retries disciplinados e observabilidade profunda. O passo final é transformar essas ideias em prática repetível para seu time.
Pense em cada agente como um workflow com estado:
Quando essas peças se alinham, você obtém sistemas que degradam com graça em vez de colapsar diante de casos de borda.
Antes de enviar um agente protótipo a usuários reais, confirme:
Se algum item estiver faltando, você ainda está em modo protótipo.
Uma configuração sustentável normalmente separa:
Isso permite que times de produto avancem rapidamente enquanto times de plataforma impõem confiabilidade, segurança e controles de custo.
Com fundações estáveis, você pode explorar:
Progresso aqui deve ser incremental: introduza novos componentes de aprendizado atrás de feature flags, com avaliação offline e guardrails fortes.
O tema em tudo isso é o mesmo: projete para falha, favoreça clareza sobre esperteza e itere onde você pode observar e reverter com segurança. Com essas restrições, sistemas agentivos deixam de ser protótipos assustadores e viram infraestrutura em que sua organização pode confiar.
Um sistema agentivo é uma aplicação em que um LLM não se limita a responder a um único prompt, mas decide o que fazer a seguir: quais ferramentas chamar, quais dados buscar, qual passo de um fluxo executar e quando parar.
Ao contrário de uma simples finalização de chat, um sistema agentivo combina:
Em produção, o LLM passa a ser apenas um componente de decisão dentro de um invólucro determinístico maior — não o sistema inteiro.
Demos normalmente executam um único caminho feliz: um usuário, comportamento ideal das ferramentas, sem timeouts, sem drift de schema e conversas curtas. Em produção, os agentes enfrentam:
Sem fluxos explícitos, contratos e tratamento de falhas, esses fatores geram loops, bloqueios, trabalho parcial e erros silenciosos que não aparecem em ambientes de demo.
Faça o LLM operar dentro de uma estrutura clara em vez de um loop livre:
Modele o agente como um fluxo com estados nomeados e eventos tipados em vez de while not done: call LLM.
Estados típicos incluem:
Projete ferramentas como APIs de produção, não como descrições em prosa. Cada ferramenta deve ter:
Presuma que toda chamada externa falhará às vezes e projete em torno disso.
Padrões-chave:
Separe estado de curto prazo de memória de longo prazo, e mantenha o LLM stateless.
Pense no seu sistema de agentes como um sistema distribuído sob carga, mesmo que cada fluxo pareça sequencial.
Para manter a confiabilidade:
Você deve ser capaz de responder “o que o agente fez?” e “por que ele fez isso?” para qualquer tarefa.
Requisitos práticos:
Trate agentes como serviços em evolução, não como prompts estáticos, e gerencie-os com o mesmo rigor que outros sistemas de produção.
Práticas recomendadas:
Isso permite explicar, testar e depurar o comportamento passo a passo em vez de perseguir loops opacos de “pensamento” do agente.
PLAN – interpretar a solicitação e produzir um plano passo a passoCALL_TOOL – invocar uma ferramenta específica ou um lote de ferramentasVERIFY – checar saídas contra regras simples ou verificações adicionais de modeloRECOVER – tratar erros via retries, fallbacks ou escalonamentoDONE / FAILED – resultados terminaisEventos (por exemplo, ToolCallSucceeded, TimeoutExceeded) mais o estado atual determinam o próximo estado. Isso torna retries, timeouts e tratamento de erro explícitos em vez de escondidos em prompts ou código de ligação.
InvalidInput, NotFound, RateLimited, TransientFailureValide entradas antes da chamada e saídas depois. Versione contratos de ferramenta e fixe agentes a versões específicas para que mudanças de schema não quebrem fluxos silenciosamente.
request_id estável ou uma chave de negócio e retornam o mesmo resultado quando chamadas novamente.Isso mantém a confiabilidade alta sem criar loops descontrolados, efeitos colaterais duplicados ou custos inesperados.
Evite usar logs brutos ou histórico de conversas como “memória”; derive registros compactos e estruturados com regras claras de retenção e privacidade.
Monitore profundidade de filas, percentis de latência e taxas 429/503 para detectar sobrecarga antes que vire incidente.
Com isso, a triagem de incidentes sai de “o agente parece instável” para localizar exatamente o estado, a ferramenta e a mudança que causaram a regressão.
Isso permite melhorar agentes continuamente mantendo falhas contidas, diagnosticáveis e reversíveis.