📝 Buffer de conversa
O buffer de conversa é a forma mais simples de memória em agentes: uma lista de mensagens (user + assistant) que é passada para o LLM a cada nova chamada. Sem ele, cada interação começa do zero — o agente não sabe o que aconteceu antes.
📋 Estrutura do buffer
# Estrutura de mensagens (padrão OpenAI/Anthropic)
messages = [
{"role": "system", "content": "Você é um assistente..."},
{"role": "user", "content": "Qual é a capital do Brasil?"},
{"role": "assistant", "content": "A capital é Brasília."},
{"role": "user", "content": "E qual é a maior cidade?"},
]
# O LLM vê TODAS as mensagens e responde com contexto
Vantagens do buffer simples
- ✓Implementação trivial — uma lista Python
- ✓Nenhuma perda de informação
- ✓O LLM tem acesso a toda a conversa
- ✓Fácil de debugar — você vê exatamente o que o LLM vê
Desvantagens
- ✗Cresce indefinidamente — sem limite natural
- ✗Custo cresce linearmente com a conversa
- ✗Eventualmente estoura o context window
- ✗Não persiste entre sessões por padrão
💡Quando usar buffer simples
Ideal para conversas curtas (menos de 20 turnos) ou protótipos. Em produção com conversas longas, você precisa de uma estratégia de gerenciamento. O buffer simples é o ponto de partida — não o destino.
🪟 Sliding Window
A sliding window (janela deslizante) mantém apenas as N mensagens mais recentes no buffer. Quando a conversa atinge o limite, as mensagens mais antigas são descartadas (FIFO). O contexto fica estável e o custo previsível.
🖼️ Visualizando a janela deslizante
📊 Tamanhos de janela por caso de uso
5-10 mensagens
Chatbots simples, FAQ. Conversas que não acumulam contexto complexo.
20-50 mensagens
Assistentes de trabalho. Conversas longas onde histórico recente importa.
100+ mensagens
Agentes de pesquisa ou projetos longos. Combine com compressão.
⚠️ O problema da janela pura
Sliding window descarta informações potencialmente críticas. Se o usuário mencionou seu nome no início da conversa e isso foi descartado, o agente "esquece" e pode tratá-lo como desconhecido. Para contexto crítico, use compressão ou memória longo prazo.
📋 Resumo automático
Em vez de descartar mensagens antigas, o resumo automático usa um LLM para comprimir o histórico antigo em texto denso. O sumário substitui as mensagens originais, preservando a essência sem perder informações críticas.
Trigger: contexto quase cheio
Quando o buffer ultrapassa N tokens (ex: 80% do context window), o sistema detecta e ativa a sumarização antes de fazer a próxima chamada ao agente.
Chamada de sumarização
Um LLM pequeno (Claude Haiku, GPT-4o-mini) recebe as mensagens antigas e o prompt: "Sumarize esta conversa preservando fatos importantes, decisões tomadas e contexto relevante."
Substituição no buffer
As mensagens antigas são substituídas por uma única mensagem "system" ou "assistant" com o sumário. As mensagens recentes são mantidas intactas.
ConversationSummaryMemory em LangChain
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
# LLM pequeno para sumarizar (economiza custo)
summary_llm = ChatOpenAI(model="gpt-4o-mini")
memory = ConversationSummaryMemory(
llm=summary_llm,
max_token_limit=1000 # Sumariza quando passa 1k tokens
)
💥 O problema do contexto longo: Lost in the Middle
Pesquisas mostram que LLMs têm dificuldade em usar informações do meio do contexto. Informações no início e no final são processadas melhor do que as no centro de um contexto muito longo — o fenômeno "lost in the middle".
📊 Evidências do problema
- •LLMs com contexto de 100k tokens têm desempenho pior no centro vs. início/fim do contexto (Stanford, 2024)
- •Para recuperação de informação, modelos com contexto menor e mais relevante superam modelos com contexto enorme e com ruído
- •O efeito é mais pronunciado em modelos menores e em tarefas que exigem integração de múltiplas informações
Implicações para design
- →Coloque informações críticas no início ou no final do contexto
- →System prompt detalhado no início é sempre bem processado
- →Instruções finais ("responda em JSON") têm peso alto
- →Não confie que o LLM "vai achar" informação no meio de um documento longo
Soluções práticas
- ✓RAG com retrieval focado: menos chunks, mais relevantes
- ✓Reranking para colocar chunks mais relevantes primeiro
- ✓Sumarização de histórico antes de injetar novos documentos
- ✓Teste com contextos de tamanho variado antes de produção
🗜️ Estratégias avançadas de compressão
Além da sumarização geral, existem estratégias mais precisas de compressão: extração de fatos-chave, memória de entidades e compressão por importância. Cada uma preserva um tipo diferente de informação.
Entity Memory
Mantém um dicionário de entidades mencionadas na conversa com seus atributos. "João é desenvolvedor Python sênior na empresa X".
"João": "Dev Python sênior, Empresa X",
"Projeto": "API de pagamentos, prazo Q2"
}
Fact List Compression
Extrai afirmações factuais da conversa em lista estruturada. Mais densa que sumário narrativo — menos tokens para a mesma informação.
"Usuário prefere Python a JavaScript",
"Budget do projeto: R$ 50k",
"Deploy em AWS, não Azure"
]
💡Hybrid Memory: o melhor dos dois mundos
A estratégia mais robusta combina: Entity Memory (fatos sobre pessoas/entidades), Fact List (decisões e preferências) + Sliding Window (N mensagens recentes integrais). O LLM recebe o dict de entidades + lista de fatos + mensagens recentes. Contexto eficiente sem perda de informação crítica.
🔴 Quando a memória curta falha
Bugs de memória curta são difíceis de diagnosticar porque o agente parece funcionar mas produz resultados inconsistentes ao longo do tempo. Conhecer os padrões de falha acelera o diagnóstico.
Sintoma: "Agente contradiz resposta anterior"
Causa: Sliding window descartou a mensagem onde o agente afirmou algo. Agora, sem ver o que disse antes, ele afirma o oposto.
Solução: Aumentar janela ou usar Entity Memory para fatos que não podem ser descartados.
Sintoma: "Agente repete pergunta já feita"
Causa: Buffer truncado silenciosamente pelo framework (sem erro!). O LLM não vê a resposta que o usuário já deu.
Solução: Logar o tamanho do buffer em cada chamada. Detectar truncação e tratar explicitamente.
Sintoma: "Agente ignora instrução do system prompt após muitas trocas"
Causa: Lost in the middle — o system prompt ficou enterrado no meio do contexto enorme e o LLM não o está seguindo.
Solução: Reinjetar as instruções críticas periodicamente. Mover instruções de formatação para o final do contexto.
🧪 Como testar memória do seu agente
- Mencione uma informação específica na mensagem 1 (ex: "meu nome é Carlos")
- Faça 15+ trocas sobre outro assunto
- Pergunte: "Como você me chama?"
- Se o agente não souber, a memória foi perdida no meio da conversa
- Repita com diferentes tamanhos de janela para encontrar o limiar
✅ Resumo do Módulo 2.2
Próximo Módulo:
2.3 — Memória Longo Prazo e RAG: como dar ao agente memória entre sessões com embeddings, bancos vetoriais e o pipeline RAG completo.