Imagine que você contrata um consultor brilhante. Tem dois doutorados, fala sete idiomas, e resolve problemas que você nem sabia que tinha. Você o senta numa sala e diz: “preciso que você refatore a autenticação do projeto”.

O consultor te olha, concorda, e pergunta: “Que projeto?”

Você não deu acesso ao código. Não explicou a arquitetura. Ele não sabe se vocês usam tokens JWT ou cookies de sessão. Não sabe que linguagem vocês usam, nem quantos microsserviços há, nem por que a última tentativa de migração acabou em desastre.

Esse consultor é seu LLM. E você acabou de cometer o erro que 90% das pessoas que trabalham com agentes de IA cometem: se preocupar com o cérebro em vez de se preocupar com o que o cérebro vê.

Prompt engineering está morto. Vida longa ao context engineering.

Há meses vejo a mesma conversa em cada fórum, em cada thread do Twitter, em cada reunião de equipe: “GPT-5 ou Claude Opus?”, “qual modelo é melhor para código?”, “qual raciocina melhor?”.

E a resposta, toda vez que faço as contas, é a mesma: tanto faz. Bem, não faz exatamente tanto faz. Mas a diferença entre um modelo top e outro modelo top é marginal comparada com a diferença entre dar bom contexto ou dar lixo.

Um modelo medíocre com contexto perfeito ganha de um modelo top com contexto ruim. Sempre. Sem exceções.

Isso tem um nome: context engineering. E não, não é a mesma coisa que prompt engineering.

Prompt engineering é escrever um bom prompt. É escolher as palavras corretas, estruturar a solicitação, adicionar exemplos. É importante, mas é apenas uma peça.

Context engineering é projetar tudo o que o modelo vê: que informação entra, em que ordem, o que é descartado quando não cabe, o que é comprimido, o que é preservado a todo custo. É arquitetura da informação para LLMs.

Em outras palavras: prompt engineering é redigir uma boa pergunta. Context engineering é decidir que livros o aluno tem na mesa antes de começar a prova.

As quatro fases da memória: um ciclo de vida que você não vê

A OpenAI publicou recentemente dois artigos de Cookbook que desmontam como funciona a gestão de contexto em agentes com memória de longo prazo. Não é RAG. Não é um banco de dados vetorial. É um sistema de estados que funciona como um caderno de campo com regras rígidas.

O padrão é local-first e state-based: um objeto de estado estruturado que viaja com o agente e é atualizado em cada fase.

flowchart TD
    A["1. INJECTION\n(início de sessão)"] --> B["2. DISTILLATION\n(durante conversação)"]
    B --> C["3. CONSOLIDATION\n(pós-sessão)"]
    C --> D["4. TRIMMING\n(preservação)"]
    D -->|"Nova sessão"| A

    A1["Renderiza estado como YAML\n+ memórias globais (máx 6)\n+ regras de precedência"] -.-> A
    B1["save_memory_note()\nValida durabilidade\nExige acionabilidade\nRejeita PII e especulação"] -.-> B
    C1["Job assíncrono\nMergea session → global\nDesduplicação com LLM\nFiltra notas efêmeras"] -.-> C
    D1["TrimmingSession: últimas N\nReinjeita notas recortadas\nem system prompt"] -.-> D

    style A fill:#2d3748,stroke:#4a9eed,color:#fff
    style B fill:#2d3748,stroke:#ed9a4a,color:#fff
    style C fill:#2d3748,stroke:#9a4eed,color:#fff
    style D fill:#2d3748,stroke:#4aed5c,color:#fff

Fase 1: Injection — a mesa da prova

Quando uma sessão inicia, o agente monta seu contexto inicial. Não é aleatório. É uma estrutura concreta:

  • YAML frontmatter com o estado do usuário (preferências, configuração).
  • Lista de memórias globais: máximo 6, ordenadas por recenticidade. Por que 6? Porque mais de 6 competem entre si pela atenção do modelo e começam a se diluir. Menos é mais.
  • Bloco <memory_policy> com regras de precedência explícitas.

As regras de precedência são fundamentais: Input atual > Memória de sessão > Memória global > Recenticidade dentro do mesmo escopo. Se o usuário te diz “agora uso Vim” mas sua memória global diz “usa VS Code”, ganha o que acabou de dizer. Parece óbvio, mas sem regras explícitas o modelo às vezes se apega ao que “lembra” acima do que você está dizendo.

Fase 2: Distillation — capturar sem contaminar

Durante a conversa, o agente pode capturar memórias em tempo real com uma ferramenta tipo save_memory_note(). Mas nem tudo vale. A ferramenta tem guardrails rigorosos:

  • Valida durabilidade: “o usuário quer pizza hoje à noite” não é uma memória durável. É rejeitada.
  • Exige acionabilidade: a memória tem que servir para algo em sessões futuras.
  • Rejeita PII: nomes completos, endereços, números de cartão. Fora.
  • Rejeita especulação: “acho que o usuário prefere Python” não é um fato. É uma suposição.
  • Requer confirmação do usuário: antes de salvar, pergunta.

Este filtro é brutal, e com razão. Uma memória contaminada envenena todas as sessões futuras. É como se seu caderno de campo tivesse uma anotação falsa: toda vez que você consulta, toma decisões baseadas em informação incorreta.

Fase 3: Consolidation — a limpeza noturna

Após cada sessão, um job assíncrono coleta as notas de sessão e as fusiona com a memória global. Não é um append. É uma consolidação inteligente:

  • Desduplicação assistida por LLM: se duas notas dizem a mesma coisa com palavras diferentes, são fusionadas.
  • Filtragem de notas efêmeras: qualquer coisa com “desta vez”, “hoje”, “agora mesmo” é descartada.
  • Resolução de conflitos por recenticidade: se uma nota nova contradiz uma velha, ganha a nova.

Pense nisso como a pessoa que limpa sua mesa no final do dia. Não joga tudo fora — guarda o importante, consolida os post-its que dizem a mesma coisa, e joga fora os que não se aplicam mais.

Fase 4: Trimming — cortar sem perder

Quando o histórico cresce demais, é preciso recortar. TrimmingSession conserva apenas as últimas N intervenções. Mas — atenção — as notas de memória que viviam nos turnos recortados não se perdem. São reinjetadas no system prompt do próximo turno.

É como arrancar as folhas velhas de um caderno mas copiar as anotações importantes para a primeira página antes de jogá-las fora.

Trimming vs Summarization: duas filosofias, um dilema

Para gerenciar a memória de curto prazo (o histórico de conversa dentro de uma sessão), há duas técnicas fundamentais. Cada uma com vantagens e armadilhas.

flowchart LR
    subgraph Trimming["Trimming (Last-N Turns)"]
        direction TB
        T1["Histórico completo\n(40 turnos)"]
        T2["Cortar turnos 1-30"]
        T3["Conservar turnos 31-40\n(intactos, sem alterar)"]
        T1 --> T2 --> T3
    end

    subgraph Summarization["Summarization (Compression)"]
        direction TB
        S1["Histórico completo\n(40 turnos)"]
        S2["LLM resume turnos 1-30\nem ~400 tokens"]
        S3["Injetar resumo sintético\n+ turnos 31-40"]
        S1 --> S2 --> S3
    end

    style Trimming fill:#1a2332,stroke:#4a9eed,color:#fff
    style Summarization fill:#2a1a32,stroke:#9a4eed,color:#fff

Trimming: a guilhotina determinística

Escaneia o histórico para trás, conserva as últimas N intervenções completas, e tudo anterior desaparece.

Vantagem: fidelidade total do contexto recente. O que resta não foi alterado, resumido nem interpretado. São as mensagens originais, como eram.

Desvantagem: amnésia abrupta. O turno N-1 existe com todo detalhe. O turno N-2 não existe absolutamente. Não há degradação gradual — há um corte binário entre “lembro tudo” e “não lembro nada”.

É como a memória de um peixinho dourado com um HD externo: os últimos 10 segundos ele tem perfeitos, tudo anterior simplesmente não existe.

Summarization: a compressão com risco

Quando o histórico supera um limite, um LLM comprime o antigo e injeta como um par sintético user/assistant no início da conversa. O prompt de resumo tem princípios rígidos:

  • Preservar marcos (decisões tomadas, acordos).
  • Manter ordem temporal.
  • Detectar contradições e marcá-las.
  • Fatos incertos marcados como “UNVERIFIED”.
  • Máximo 400 tokens por resumo.

Vantagem: você conserva a essência de toda a conversa. Não há amnésia abrupta. O modelo “sabe” que há 30 turnos vocês decidiram usar PostgreSQL em vez de MongoDB, mesmo que não tenha mais as mensagens originais.

Desvantagem: erros compostos. Se um fato errado entra no resumo, envenena todo o comportamento futuro. E como o resumo é gerado com um LLM, não é imune a alucinações. Um modelo que resume mal gera um resumo incorreto que o próximo turno trata como verdade absoluta.

É de uma audácia incrível: você usa um LLM para resumir o histórico de outro LLM, e se o primeiro erra, o segundo herda o erro sem saber.

Para distinguir o real do sintético, cada registro carrega metadata de observabilidade: {"synthetic": bool, "kind": "...", "summary_for_turns": "..."}. Assim pelo menos você pode auditar que parte do contexto é original e que parte é um resumo.

Você já está fazendo isso (e não sabia)

Se usa Claude Code, já tem um sistema de context engineering funcionando. Só que você não o projetou — a Anthropic projetou. Mas se parar para olhar, as peças se encaixam:

Seu CLAUDE.md global + CLAUDE.md por projeto + arquivos SKILL.md = injection manual. Você está decidindo que contexto o modelo vê ao iniciar cada sessão. É você quem escolhe que “livros vão para a mesa”.

O diretório ~/.claude/projects/*/memory/ onde Claude Code guarda notas entre sessões = implementação direta do padrão injection + distillation. O modelo captura fatos durante a sessão e os recupera na seguinte.

A compressão automática de contexto que Claude Code faz quando a conversa se alonga = trimming + summarization. Você não vê porque é transparente, mas toda vez que sua sessão supera certo limite, parte da conversa é comprimida.

Os skills (/blog, /commit, etc.) = injeção de contexto especializado sob demanda. Em vez de carregar todo o contexto possível no início, você carrega só o que precisa quando precisa.

E aqui vem o que acho mais interessante: a qualidade dos seus CLAUDE.md determina a qualidade do seu agente muito mais que o modelo que você usa. Um CLAUDE.md bem estruturado — com convenções claras, caminhos corretos, decisões de arquitetura documentadas — transforma qualquer modelo decente num assistente útil. Um CLAUDE.md vazio ou desarrumado transforma o melhor modelo do mundo num consultor brilhante trancado numa sala sem luz.

Prompt debt: a dívida técnica que você não vê

Conhece o conceito de dívida técnica? Código que funciona mas que acumula problemas futuros. Atalhos que você paga depois.

Context engineering tem sua própria dívida: prompt debt. São todos esses arquivos de configuração, instruções, memórias e anotações que se acumulam e que ninguém mantém.

Um CLAUDE.md com instruções contraditórias. Memórias globais que não se aplicam mais. Skills com caminhos que mudaram há três meses. Regras de precedência implícitas que ninguém documentou.

Cada peça de contexto obsoleto é ruído. E o ruído compete com o sinal pela atenção do modelo. Mais ruído → piores resultados. Não porque o modelo seja pior, mas porque você está dando lixo misturado com informação útil e esperando que ele saiba distinguir.

A higiene da sua camada de context engineering é tão importante quanto a higiene do seu código. Talvez mais, porque um bug no código falha ruidosamente. Um bug no contexto falha silenciosamente — o modelo simplesmente toma decisões piores sem que ninguém perceba.

O acionável: o que você pode fazer hoje

Toda essa teoria está muito bem, mas o que você faz com ela numa terça-feira de manhã?

1. Audite seu CLAUDE.md (ou equivalente). Tem instruções contraditórias? Caminhos que não existem mais? Regras que não se aplicam mais? Limpe. Cada linha que sobra é ruído.

2. Ordene seu contexto por estabilidade. O que nunca muda vai primeiro (convenções, stack). O que muda frequentemente vai por último (tarefa atual). Isso maximiza cache hits e reduz custos. Não é cosmético — é econômico.

3. Estabeleça regras de precedência explícitas. Se o usuário diz uma coisa e a memória diz outra, quem ganha? Se você não definir, o modelo decide por você. E aí você está arriscando.

4. Filtre agressivamente. Nem tudo merece ser lembrado. Uma decisão de arquitetura, sim. Que o usuário prefere tabs a spaces, talvez. Que hoje estava chovendo quando começou a sessão, não.

5. Distinga contexto real de sintético. Se usa summarization, marque os resumos como tais. Quando algo falhar, você precisa saber se o modelo estava trabalhando com dados reais ou com um resumo potencialmente incorreto.

6. Trate a manutenção do contexto como dívida técnica. Ponha no backlog. Revise periodicamente. Não é glamouroso, mas é o que separa um agente que funciona de um que alucina.

A habilidade que ninguém põe no CV

Context engineering é a habilidade invisível. Não aparece nas ofertas de trabalho. Não tem certificação. Não há um curso de 40 horas no Udemy com diploma no final.

Mas é o que separa pessoas que “usam ChatGPT” de pessoas que constroem agentes que funcionam. É a diferença entre perguntar algo a um LLM e projetar um sistema onde o LLM tem tudo que precisa para te dar a resposta correta.

Na próxima vez que seu agente fizer algo estúpido, antes de culpar o modelo, olhe que contexto você estava dando. Há muitas probabilidades de que o problema não seja o cérebro — seja o que o cérebro estava vendo.

E isso, diferentemente do modelo, você controla.


Fontes: Os dois artigos do OpenAI Cookbook sobre Context Engineering for Long-Term Personalization e Short-Term Memory Management with Sessions. Se te interessa como funciona o loop interno de um coding agent, leia Seu AI coding agent é um while loop com delírios de grandeza. E se quer entender por que a ordem do prompt afeta o custo, Por que 99% do que você envia ao Claude ele já tem em cache.

Este artigo foi escrito originalmente em espanhol e traduzido com a ajuda de IA.