Consumindo Modelos de IA

Tratamento de Erros

Timeout, rate limits, falhas de rede, retry com backoff e respostas seguras ao usuário.

Intermediário 25 min 25 pontos Leitura 0%

Nesta aula você vai

  • Identificar erros comuns das APIs de LLM
  • Implementar retry idempotente com exponential backoff
  • Retornar mensagens amigáveis sem vazar detalhes internos

Tratamento de Erros

Objetivos

  • Criar integrações robustas — demo quebra, produção aguenta
  • Saber quando repetir chamada e quando desistir

Erros frequentes

HTTP Código típico Causa Ação
401 invalid_api_key Key errada/revogada Alerta ops, não retry
429 rate_limit_exceeded Muitas req/min Retry com backoff
500 server_error Instabilidade provedor Retry limitado
503 overloaded Pico de demanda Retry + fallback message
Timeout Rede lenta / resposta longa Retry ou reduzir max_tokens

Context length exceeded (400): prompt + histórico > limite — não adianta retry; resuma ou truncue histórico.

Retry com exponential backoff

Regra: retry só em 429, 500, 503 e timeouts — nunca em 400/401.

async function chatWithRetry(messages, maxAttempts = 3) {
  let delay = 1000;

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      return await chat(messages);
    } catch (err) {
      const retryable = err.status === 429 || err.status >= 500;
      if (!retryable || attempt === maxAttempts) throw err;
      await sleep(delay);
      delay *= 2; // 1s → 2s → 4s
    }
  }
}

Use jitter (delay + random(0, 500)) se muitas instâncias retry juntas.

Circuit breaker (conceito)

Se 5 falhas seguidas em 1 minuto → pare de chamar LLM por 30s, retorne:

"Assistente temporariamente indisponível. Tente em instantes."

Evita cascata de custo e timeout no seu servidor.

Resposta ao usuário vs log interno

// ❌ Não exponha ao frontend
res.status(500).json({ error: err.stack, openai: err.raw });

// ✅ Mensagem genérica + correlation id
const requestId = crypto.randomUUID();
logger.error({ requestId, err });
res.status(503).json({
  error: 'Não foi possível processar sua mensagem agora.',
  requestId, // suporte pode rastrear
});

Timeout em camadas

  1. HTTP client: 45–60s para LLM
  2. Seu endpoint: 55s (menor que load balancer)
  3. Frontend: loading state + cancel após 60s

Idempotência

Retry pode gerar duas respostas cobradas. Para operações críticas:

  • Gere idempotencyKey por mensagem do usuário
  • Armazene hash(prompt) → resposta em cache curto (5 min)

Checklist produção

  • Try/catch em toda chamada externa
  • Log estruturado: latência, tokens, status, model
  • Retry máximo 3× com backoff
  • Mensagem amigável ao usuário
  • Alertas se taxa de 429 > 5% por hora

Resumo

  • Nem todo erro merece retry — 401 e context overflow são fix no código/dados
  • Backoff exponencial para 429/5xx
  • Usuário vê mensagem simples; você loga detalhe
  • Timeout explícito evita thread/worker preso