Memória e Contexto
Janela de Contexto
Resumo automático, compressão de histórico e limpeza para reduzir tokens sem perder intenção.
Nesta aula você vai
- Detectar quando histórico aproxima limite de tokens
- Resumir conversa antiga com segunda chamada LLM
- Aplicar estratégia sliding window + summary
Janela de Contexto
Objetivos
- Reduzir custos quando conversa cresce
- Manter coerência sem enviar 200 mensagens brutas
O chat que ficou caro
O bot lembra tudo — ótimo para o usuário, desastroso para a fatura.
Na mensagem 5, você envia 800 tokens de histórico. Na mensagem 40, são 6.000. Cada novo turno paga de novo todo o passado. E ainda corre risco de bater no limite do modelo.
Memória infinita não existe em produção. Existe memória gerenciada.
Estratégia 1: Sliding window
Mantenha só últimas K mensagens (ex: 10 turnos = 20 entries).
Prós: simples, previsível. Contras: esquece início da conversa.
Quando serve: suporte rápido, FAQ, conversas curtas.
Cenário:
Nos primeiros 5 minutos o usuário explicou problema complexo. Na mensagem 15, com window de 6, o bot "esquece" o detalhe do pedido 5521.
Para isso entra resumo — estratégia 2.
Estratégia 2: Resumo periódico
Quando histórico > 15 mensagens, comprima o passado:
async function summarizeHistory(oldMessages) {
const transcript = oldMessages.map((m) => `${m.role}: ${m.content}`).join('\n');
return chat(
[
{ role: 'system', content: 'Resuma a conversa em 5 bullet points objetivos. Português.' },
{ role: 'user', content: transcript },
],
{ temperature: 0, max_tokens: 300 },
);
}
Nova estrutura enviada ao modelo:
system: {SYSTEM_PROMPT}
system: Resumo da conversa anterior: {summary}
user/assistant: {últimas 6 mensagens brutas}
Custo: 1 chamada extra ocasional — ainda mais barato que 100 mensagens completas a cada turno.
Analogia: em vez de reler 50 páginas de ata, você lê um resumo de uma página + as últimas notas.
Estratégia 3: Limpeza por tópico
Detecte mudança de assunto (classificador simples ou palavras-chave) → reset histórico, mantenha só summary:
Usuário mudou de "pedido" para "vaga de emprego" → descarte histórico de pedidos
Diálogo simulado:
Usuário: "Status do pedido 8842." [resolvido]
Usuário: "Vocês estão contratando dev?"
Sistema: detecta troca de tópico → novo contexto, sem arrastar logística na pergunta de RH.
Estimar tokens antes de enviar
function estimateTokens(text) {
return Math.ceil(text.length / 4); // aproximação
}
const total = messages.reduce((s, m) => s + estimateTokens(m.content), 0);
if (total > 6000) await compress(sessionId);
Compressão proativa evita erro 400 de context length no pior momento — no meio do atendimento.
O que NUNCA resumir sem cuidado
- Números de pedido confirmados
- Dados que o usuário corrigiu ("não, o pedido é 5521")
- Instruções de formato acordadas
Inclua no prompt de resumo: "Preserve IDs, valores e correções do usuário."
Resumo agressivo que apaga o número do pedido é pior que esquecer o nome do usuário.
Comparação de custo
| Abordagem | Tokens/turno (conv. longa) |
|---|---|
| Histórico completo (50 msgs) | ~8.000+ |
| Window 10 msgs | ~1.500 |
| Summary + window 6 | ~1.800 (+ amortizado) |
Resumo
- Conversa longa estoura contexto e orçamento
- Sliding window = MVP; summary = produção madura
- Resumo é chamada LLM — trate como pipeline, não hack
- Preserve fatos críticos no prompt de compressão
Com API, prompt, chatbot e memória no lugar, chegamos ao coração deste módulo: agentes — sistemas que não só conversam, mas agem. A próxima matéria define o que isso significa sem buzzword.