05-04-02 — Loops, terminação e controle de custo
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ário | Steps | Tokens/step | Modelo | Custo/run |
|---|---|---|---|---|
| Agente simples (suporte) | 3-5 | 2k | GPT-4o mini | ~US$ 0,003 |
| Agente de pesquisa | 8-12 | 5k | GPT-4o | ~US$ 0,75 |
| Multi-agent (3 workers) | 15-20 | 8k | GPT-4o | ~US$ 2,40 |
| Agente em loop (sem guardrail) | 50+ | 10k | GPT-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
Fontes
- OpenAI — Pricing (atualizado) — preços atuais dos modelos para cálculo de custo.
- LangChain — AgentExecutor docs — max_iterations, max_execution_time e early_stopping.
- Microsoft — Azure AI Foundry costs and budgets — gestão de custos no Azure AI.
- Anthropic — Building Effective Agents (seção de riscos) — boas práticas de guardrails.