05-04-02 — Loops, terminação e controle de custo

⏱ 10 minFontes validadas em: 2026-04-29

TL;DR

Agentes sem guardrails de terminação são risco financeiro real. As alavancas de controle são: max iterations, token budget, time limit e graceful degradation. Um agente simples que lupa pode custar centenas de dólares em horas sem que ninguém perceba.

Por que loops são perigosos

Um agente entra em loop quando:

  • A ferramenta retorna resultados ambíguos ou inconclusivos em loop
  • O critério de "tarefa concluída" não está bem definido
  • Duas ferramentas se contradizem e o agente fica tentando resolver
  • Erro de tool que o agente tenta corrigir indefinidamente
Caso real: Um agente de coding em GPT-4o sem max_iterations rodando por 2 horas com 50 iterações em loop = ~1M tokens = ~US$ 5 por sessão. Se 100 usuários simultaneamente = US$ 500/hora. Loops acontecem — os guardrails são obrigatórios.

Estimativa de custo de agentes

CenárioStepsTokens/stepModeloCusto/run
Agente simples (suporte)3-52kGPT-4o mini~US$ 0,003
Agente de pesquisa8-125kGPT-4o~US$ 0,75
Multi-agent (3 workers)15-208kGPT-4o~US$ 2,40
Agente em loop (sem guardrail)50+10kGPT-4o~US$ 12,50+

Preços aproximados GPT-4o: US$ 2,50/1M input tokens, US$ 10/1M output tokens (abril 2025).

Guardrails de terminação

1. Max iterations

from langchain.agents import AgentExecutor

executor = AgentExecutor(
    agent=agent,
    tools=tools,
    max_iterations=10,          # Máximo de steps
    max_execution_time=60,      # Segundos máximos
    early_stopping_method="generate"  # Gera resposta parcial ao atingir limite
)

2. Token budget

import tiktoken

class TokenBudgetTracker:
    def __init__(self, budget: int = 50_000):
        self.budget = budget
        self.used = 0
        self.enc = tiktoken.encoding_for_model("gpt-4o")
    
    def track(self, text: str) -> bool:
        tokens = len(self.enc.encode(text))
        self.used += tokens
        return self.used < self.budget  # False = orçamento esgotado
    
    def remaining_pct(self) -> float:
        return (self.budget - self.used) / self.budget * 100

# No loop do agente:
tracker = TokenBudgetTracker(budget=30_000)

while True:
    response = call_llm(messages)
    if not tracker.track(response.content):
        return graceful_degradation_response(partial_results)
    # ... continua loop

3. Graceful degradation

Quando o agente atinge um limite, não deve simplesmente falhar — deve retornar o melhor resultado possível com o que tem:

def graceful_degradation_response(
    partial_results: list,
    reason: str
) -> str:
    """Retorna resultado parcial com aviso claro ao usuário"""
    if not partial_results:
        return f"Não foi possível completar a tarefa ({reason}). Tente dividir em partes menores."
    
    summary = "\n".join(f"- {r}" for r in partial_results)
    return f"""⚠️ Resultado parcial ({reason}):
    
{summary}

Para resultado completo, divida a tarefa em etapas menores ou aumente o budget."""
graph TD A[Agente inicia] --> B{Step N} B --> C{Max iterations\nalcançado?} C -->|Sim| D[Graceful degradation] C -->|Não| E{Token budget\nesgotado?} E -->|Sim| D E -->|Não| F{Time limit\nexpirado?} F -->|Sim| D F -->|Não| G{Tarefa\nconcluída?} G -->|Sim| H[Resultado final] G -->|Não| B D --> I[Resultado parcial\n+ aviso ao usuário] style D fill:#7c2d12,color:#fff style H fill:#065f46,color:#fff style I fill:#374151,color:#fff

Monitoramento em produção

import time
import logging
from dataclasses import dataclass, field

@dataclass
class AgentRunMetrics:
    run_id: str
    start_time: float = field(default_factory=time.time)
    iterations: int = 0
    input_tokens: int = 0
    output_tokens: int = 0
    tool_calls: list = field(default_factory=list)
    
    @property
    def duration(self) -> float:
        return time.time() - self.start_time
    
    @property
    def estimated_cost_usd(self) -> float:
        # GPT-4o pricing
        return (self.input_tokens / 1_000_000 * 2.50 + 
                self.output_tokens / 1_000_000 * 10.00)
    
    def log(self):
        logging.info(f"""
        Run: {self.run_id}
        Duration: {self.duration:.1f}s
        Iterations: {self.iterations}
        Tokens: {self.input_tokens + self.output_tokens:,}
        Cost: US$ {self.estimated_cost_usd:.4f}
        Tools used: {[t['name'] for t in self.tool_calls]}
        """)
Azure Monitor + Application Insights: Para agentes em produção no Azure, integre o tracking de tokens e custos com o Azure Monitor. O Azure AI Foundry tem dashboards nativos de custo por run. Configure alertas quando o custo/hora exceder um threshold.
Regra dos 3 guardrails: Todo agente em produção deve ter: (1) max_iterations, (2) token budget, (3) time limit. Os 3 cobrem diferentes tipos de falha. Um não é suficiente — um loop com respostas curtas pode passar pelo token budget mas explodir em iterações.

Como isso se conecta

  • 05-02-01 — ReAct sem max_iterations é o caso mais comum de loop infinito.
  • 05-04-03 — Anthropic recomenda agentes com human-in-the-loop como guardrail adicional.
  • 05-01-02 — Quando o custo de agentes não justifica o benefício, use pipeline ou workflow.

Fontes

  1. OpenAI — Pricing (atualizado) — preços atuais dos modelos para cálculo de custo.
  2. LangChain — AgentExecutor docs — max_iterations, max_execution_time e early_stopping.
  3. Microsoft — Azure AI Foundry costs and budgets — gestão de custos no Azure AI.
  4. Anthropic — Building Effective Agents (seção de riscos) — boas práticas de guardrails.