~ / tutoriais /agente-de-ia-loop-infinito $ _

Por que seu agente de IA entra em loop infinito (e como pôr um freio)

Lucas Souza Lucas Souza 11 min de leitura Tutoriais
Por que seu agente de IA entra em loop infinito (e como pôr um freio)

Seu agente chamou a mesma ferramenta 47 vezes e queimou R$ 30 em tokens antes de você matar o processo no Ctrl+C. No tutorial ele funcionava liso. Em produção, ele travou no primeiro pedido real e ficou rodando em círculo até alguém perceber.

Isso não é azar. É o comportamento padrão de um agente mal arquitetado. Um agente é, no fim, um LLM chamando ferramentas num laço, decidindo o próximo passo a partir do resultado do passo anterior. A Anthropic define isso de forma seca: agentes são "LLMs usando ferramentas com base em feedback do ambiente, em um loop". Quando esse laço não tem critério de parada — ou quando o feedback que volta pro modelo é lixo — o agente não para. Ele repete.

Neste post você vai entender por que um agente de IA entra em loop infinito, como identificar qual das três causas clássicas é a sua, e quais freios colocar pra cortar isso antes que vire conta no cartão.

TL;DR

  • O que é: o loop de execução de um agente (pensa → chama ferramenta → lê resultado → repete) sem condição de parada confiável, fazendo o modelo repetir a mesma ação pra sempre.
  • Causas principais: ausência de critério de parada, tool result mal formatado, e prompt ambíguo.
  • Os freios: limite de iterações, detecção de chamada repetida, tool results limpos com sinal de erro claro, e budget/timeout como rede de segurança.
  • Stack de exemplo: conceitos válidos pra qualquer framework — exemplos em LangGraph, OpenAI Agents SDK e loop manual.

Por que um agente de IA entra em loop infinito: o laço é o sistema

Antes de consertar, entenda o que está rodando. Se você ainda trata agente como sinônimo de prompt esperto, vale ler antes o que é (e o que não é) um agente de IA — o loop é o coração da definição.

Um agente não é um prompt mágico. É um laço. O modelo recebe o estado atual, decide uma ação (quase sempre "chamar a ferramenta X com esses argumentos"), o seu código executa a ferramenta, e o resultado volta pro modelo como contexto da próxima rodada. A Anthropic chama esse retorno de "ground truth": é "crucial que o agente ganhe 'ground truth' do ambiente a cada passo (como resultados de chamada de ferramenta) para avaliar seu progresso".

Sacou a pegadinha? O agente decide se continua ou para com base no que a ferramenta devolve. Se o resultado for ambíguo, vazio ou enganoso, o modelo não tem como saber que já resolveu o problema. Então ele tenta de novo. E de novo.

No tutorial isso nunca aparece, porque o caso feliz resolve em 3 passos. Em produção chega o input torto, a API externa devolve 500, o documento não tem a resposta — e aí o laço que parecia inofensivo roda até bater no limite. No LangGraph esse limite existe e é baixo de propósito: o padrão são 25 passos antes de estourar um GraphRecursionError. Quem nunca viu esse erro só não colocou o agente pra trabalhar de verdade ainda.

Causa 1: não existe critério de parada

A mais comum e a mais boba. O laço simplesmente não tem uma condição de saída além de "o modelo disse que terminou".

O problema: o modelo nem sempre diz que terminou. Ele pode continuar achando que falta "só mais uma verificação". Sem um teto, o while True roda pra sempre.

A Anthropic é direta: é "comum incluir condições de parada (como um número máximo de iterações) para manter controle". Não é opcional em produção. É o cinto de segurança.

Se você nunca escreveu esse laço na mão, vale ver como criar um agente de IA do zero em Python — é exatamente o mesmo loop, sem framework escondendo o freio.

# O loop ingênuo do tutorial — sem freio
while True:
    resposta = modelo.chamar(mensagens)
    if not resposta.tool_calls:
        return resposta.texto
    resultado = executar_ferramenta(resposta.tool_calls)
    mensagens.append(resultado)
    # nada aqui garante que isso termina
# Com teto de iterações
MAX_PASSOS = 15

for passo in range(MAX_PASSOS):
    resposta = modelo.chamar(mensagens)
    if not resposta.tool_calls:
        return resposta.texto
    resultado = executar_ferramenta(resposta.tool_calls)
    mensagens.append(resultado)

raise RuntimeError(f"Agente não convergiu em {MAX_PASSOS} passos")

Quanto colocar no teto? Regra de bolso: 3 a 5 vezes o número de passos que a tarefa normal leva. Se o caso feliz resolve em 5 passos, põe o limite em 15–20. Sobra espaço pro modelo trabalhar e ainda assim corta o desastre. Os frameworks já entregam isso pronto: o OpenAI Agents SDK tem o parâmetro max_turns, que estoura um MaxTurnsExceeded quando o limite passa, e o LangGraph aceita config={"recursion_limit": 20} no invoke.

Causa 2: o tool result está mal formatado

Essa é a mais traiçoeira, porque o limite de iterações até existe — mas o agente queima todas as 15 rodadas porque não consegue interpretar o que a ferramenta devolveu.

Lembra que o agente decide o próximo passo a partir do resultado da ferramenta? Se esse resultado for confuso, o modelo entra em loop de "tentar entender".

Os padrões clássicos:

  • Erro silencioso. A ferramenta falha e devolve string vazia ou null. O modelo interpreta como "não achei nada, vou tentar de novo com outro argumento" — e tenta a mesma coisa eternamente.
  • Stack trace cru. A exceção vaza pro contexto inteira. O modelo se perde em 80 linhas de traceback Python em vez de receber um "erro: parâmetro data inválido, use formato AAAA-MM-DD".
  • Sucesso ambíguo. A ferramenta funcionou mas devolveu algo que parece erro (um array vazio legítimo, por exemplo). O modelo acha que falhou e refaz.

A correção não é no modelo. É na fronteira da ferramenta. Devolva sempre um resultado estruturado, com status explícito e mensagem de erro que o modelo consiga acionar — não o humano.

def buscar_pedido(pedido_id: str) -> dict:
    try:
        pedido = api.get(pedido_id)
        if pedido is None:
            return {
                "status": "nao_encontrado",
                "mensagem": f"Pedido {pedido_id} nao existe. Nao tente de novo com o mesmo id.",
            }
        return {"status": "ok", "dados": pedido}
    except ValidacaoError as e:
        return {
            "status": "erro_input",
            "mensagem": f"Argumento invalido: {e}. Corrija o formato antes de chamar de novo.",
        }

Repare na frase "não tente de novo com o mesmo id". Parece bobo, mas funciona: você está dando ao modelo o sinal que falta pra ele sair do laço. A própria documentação do LangGraph aponta isso como a solução de fundo — melhorar as mensagens de erro da ferramenta pra que o agente consiga "raciocinar" pra fora do loop, em vez de só aumentar o recursion_limit e pagar por mais chamadas inúteis.

Causa 3: o prompt é ambíguo sobre quando parar

A terceira causa mora no system prompt. Se você não disse claramente qual é a condição de "pronto", o modelo inventa uma — e às vezes ela é inalcançável.

Exemplos reais de instrução que gera loop:

  • "Verifique cuidadosamente se a resposta está completa antes de finalizar." → o modelo verifica, verifica, verifica.
  • "Continue até ter certeza absoluta." → certeza absoluta não existe; ele nunca para.
  • "Use as ferramentas disponíveis para resolver o problema." → sem dizer quando o problema está resolvido.

O conserto é definir o critério de saída de forma operacional, não emocional:

Você é um agente de suporte. Seu objetivo é responder a dúvida do cliente.

CRITÉRIO DE PARADA — pare e responda ao cliente quando QUALQUER um for verdade:
- Você tem a informação necessária para responder.
- A ferramenta de busca retornou status "nao_encontrado" duas vezes.
- Você já chamou ferramentas 5 vezes nesta conversa.

Nunca chame a mesma ferramenta com os mesmos argumentos duas vezes.
NÃO busque "confirmação extra" se você já tem a resposta.

"Pare quando tiver a informação" é acionável. "Pare quando tiver certeza" não é. A diferença entre um agente que converge e um que roda pra sempre costuma ser exatamente essa.

Os freios que você coloca em produção

Junta tudo numa lista de verificação. Um agente pronto pra produção tem, no mínimo:

  1. Teto de iterações. max_turns / recursion_limit. Não negociável.
  2. Detecção de chamada repetida. Se o agente chamou a mesma ferramenta com os mesmos argumentos duas vezes seguidas, intercepte: ou aborta, ou injeta um aviso no contexto ("você já tentou isso, o resultado foi X").
  3. Tool results estruturados. Status explícito, erro legível pro modelo, sem stack trace cru.
  4. Budget e timeout. Teto de tokens e de tempo de parede, independentes da contagem de passos. É a rede embaixo da rede.
  5. Critério de parada no prompt. Operacional, não emocional.
# Detecção de chamada repetida — o freio que evita o "47 vezes"
historico = []

def executar_com_guarda(tool_call):
    assinatura = (tool_call.nome, tuple(sorted(tool_call.args.items())))
    if historico.count(assinatura) >= 2:
        return {
            "status": "loop_detectado",
            "mensagem": "Voce ja fez essa chamada identica. Mude de abordagem ou finalize.",
        }
    historico.append(assinatura)
    return executar_ferramenta(tool_call)

Os freios não são exclusivos — você usa todos. O teto de iterações corta o caso degenerado, a detecção de repetição corta o loop apertado, e o tool result limpo evita que o loop comece. Pensar nessas camadas como uma coisa só — arquitetura, e não um patch de última hora — é a diferença entre um demo e um produto. É exatamente esse tipo de decisão que a gente coloca na mesa no Workshop Arquitetando Soluções de IA, com agente rodando e os freios sendo discutidos no código, não no slide.

Limitações e pontos de atenção

Freio não conserta arquitetura ruim. Alguns avisos antes de você sair colocando max_turns em tudo:

  • Aumentar o limite não resolve loop. Se o agente está travado, subir o recursion_limit de 25 pra 1000 só significa pagar por 1000 chamadas em vez de 25. O limite é um disjuntor, não a cura. A cura é a causa 2 e a causa 3.
  • Teto alto demais esconde o problema. Se você precisou colocar 80 iterações pra tarefa "funcionar", provavelmente o agente está caminhando errado e você só não percebe. Logue a contagem de passos por execução e monitore a distribuição — um pico de tarefas batendo no teto é alarme.
  • Detecção de repetição pode cortar trabalho legítimo. Um agente que pagina resultados chama a mesma ferramenta com argumentos diferentes — sua assinatura precisa incluir os argumentos, senão você mata paginação válida.
  • Budget cap não substitui critério de parada. Ele corta o prejuízo, mas o usuário ainda recebe uma resposta pela metade. Use como última linha, não como primeira.

FAQ rápido

Por que funciona no tutorial e quebra em produção? Tutorial roda o caso feliz, que converge em poucos passos. Produção entrega input torto, API fora do ar e documento sem a resposta — os cenários em que o loop não tem saída natural e precisa do freio explícito.

Aumentar o recursion_limit resolve? Não, na maioria das vezes. Se o agente está em loop de verdade, você só paga por mais chamadas. Aumente o limite só quando a tarefa legitimamente precisa de muitos passos; caso contrário, ataque a causa (tool result ou prompt).

Como sei qual das três causas é a minha? Olhe o log das chamadas. Mesma ferramenta, mesmos argumentos, repetindo? Tool result mal formatado ou falta de detecção de repetição. Ferramentas diferentes rodando sem nunca finalizar? Critério de parada ausente no prompt. Roda 25 passos e estoura sem nunca repetir? Provavelmente prompt ambíguo sobre o "pronto".

Isso vale pra qualquer framework? Sim. LangGraph, OpenAI Agents SDK, CrewAI, ou loop manual — todos implementam o mesmo laço LLM-ferramenta-resultado. Os nomes mudam (recursion_limit, max_turns), os freios são os mesmos.

Fechando o loop

Agente em loop infinito não é bug exótico. É o que acontece quando você trata o laço como detalhe em vez de tratá-lo como o coração do sistema. As três causas — sem critério de parada, tool result mal formatado, prompt ambíguo — cobrem a esmagadora maioria dos casos, e os freios são baratos de colocar: um teto de iterações, detecção de chamada repetida, tool results limpos e um budget como rede.

O próximo passo é parar de pensar no agente como "um prompt que usa ferramentas" e começar a tratá-lo como o que ele é: um sistema com estado, condições de parada e modos de falha — ou seja, engenharia. Quem arquiteta o loop com essas camadas em mente não tem agente queimando R$ 30 em tokens num domingo de madrugada. Tem agente que para na hora certa.

Lucas Souza
Lucas Souza

{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.

Você também pode gostar

Anatomia de um Agent Harness: state, tool execution, feedback loops e guardrails
Tutoriais

Anatomia de um Agent Harness: state, tool execution, feedback loops e guardrails

Harness é o software que envolve o LLM e separa um demo bonito de um agente que aguenta produção. Quebro a anatomia em cinco peças obrigatórias: estado persistente, roteador de ferramentas, validação de I/O, loop de raciocínio e limites de segurança. É o mapa mental que abre a série de posts sobre engenharia de agentes.

· 14 min
5 anti-patterns que quebram seu agente de IA em produção
Notícias

5 anti-patterns que quebram seu agente de IA em produção

Funcionava na demo, virou conta de US$ 3 mil e loop infinito em produção. Os 5 anti-patterns de arquitetura que mais quebram agentes de IA em produção — context stuffing, tools sem timeout, retry burro, zero observabilidade e ausência de guardrails — cada um com o sintoma e a correção.

· 10 min
System prompt de produção: a espinha dorsal do comportamento do agente
Tutoriais

System prompt de produção: a espinha dorsal do comportamento do agente

O system prompt não é onde você manda o modelo ser legal. É a constituição do agente: papel, políticas, ferramentas e formato. Como estruturar um de produção e por que ele joga num campeonato diferente de um prompt de chat.

· 10 min
O que é Harness Engineering e por que seu Claude Code trava em tarefas longas
Notícias

O que é Harness Engineering e por que seu Claude Code trava em tarefas longas

Quando o agente esquece o que estava fazendo, repete trabalho ou alucina arquivos, raramente é falha do modelo. É falha do harness. Definição do termo, anatomia mínima (loop, tools, contexto, memória) e o ponto onde a maioria dos devs para de evoluir o setup.

· 10 min

VirguIA

beer & code assistant

conectando…

Não foi possível iniciar o chat agora.

tocando