Por que essa pergunta apareceu agora

Janela de contexto de modelo cresceu rápido nos últimos dois anos. Cabe hoje, sem esforço, uma base de conhecimento inteira de uma empresa pequena dentro de um único prompt. Isso trouxe uma pergunta que eu comecei a ouvir com frequência: se o modelo aceita tanto texto de uma vez, ainda faz sentido montar um pipeline de retrieval, com banco vetorial, embeddings e reranking, ou dá pra simplesmente colar tudo no prompt e deixar o modelo se virar.

Essa pergunta apareceu de verdade pra mim enquanto eu decidia a arquitetura do Arms Context System, o sistema de RAG multi-fonte que venho construindo. Fui atrás de literatura séria sobre o assunto e encontrei um paper específico propondo abandonar RAG em favor de uma técnica chamada CAG, cache-augmented generation. Vale a pena entender o que ele realmente propõe, o que os números dele mostram e onde a proposta para de fazer sentido.

RAG por dentro: onde funciona e onde quebra

RAG separa a base de conhecimento do modelo. Um índice (vetorial, lexical ou os dois) guarda pedaços de documento, os chunks. Na hora da pergunta, o sistema recupera os k pedaços mais relevantes e injeta só eles no prompt. O modelo nunca vê a base inteira, vê uma fatia escolhida em tempo real.

Isso resolve bem um problema específico: bases que não cabem em contexto nenhum, por maior que ele seja, e bases que mudam o tempo todo. Adicionar um documento novo custa processar só aquele documento. Remover um, custa remover uma entrada do índice. Nada mais precisa ser reprocessado.

O preço dessa flexibilidade é conhecido e bem documentado: a qualidade da resposta depende inteiramente da qualidade do chunking e do embedding. Eu já vi de perto como a escolha de fronteira de token muda resultado, no artigo sobre os quatro algoritmos de tokenização em Rust. Com chunking o problema é parecido: cortar no lugar errado separa uma pergunta da resposta que estava duas frases à frente, e o retrieval nunca vai buscar o pedaço certo porque ele não existe como unidade recuperável.

Some a isso a latência do lookup vetorial antes de qualquer geração começar, o custo de manter um índice como mais um serviço de infraestrutura, e a falha silenciosa mais chata do modelo: quando o retrieval traz contexto irrelevante, o modelo às vezes responde com ele mesmo assim, com convicção.

CAG: jogar a base inteira no contexto e cachear

O paper “Don't Do RAG: When Cache-Augmented Generation is All You Need for Knowledge Tasks” (Chan et al., 2024) propõe eliminar o retrieval por completo quando a base cabe na janela de contexto. A ideia central roda em três fases.

  • Pré-carregamento: os documentos relevantes são processados uma única vez pelo modelo, gerando um cache de chave-valor (KV-cache) que representa o estado interno de inferência sobre aquele texto.
  • Inferência: cada pergunta reusa o KV-cache pronto. O modelo responde direto sobre o estado pré-computado, sem nenhuma etapa de recuperação no meio do caminho.
  • Reset: como o cache cresce a cada pergunta respondida, o reset trunca só os tokens novos adicionados durante a conversa, sem precisar recarregar a base inteira do zero.

O argumento dos autores é direto: processar a base uma vez custa caro, mas esse custo se paga sozinho conforme cresce o número de perguntas respondidas sobre o mesmo material, porque cada pergunta deixa de pagar retrieval.

CAG é mesmo uma técnica nova?

Descrito assim, “pré-carregar recursos no contexto estendido e cachear o estado de execução do modelo” é exatamente a descrição de prompt caching, técnica que Anthropic e OpenAI já ofereciam antes desse paper ser publicado. A crítica já apareceu em discussões técnicas públicas: CAG não é um mecanismo novo, é prompt caching aplicado a uma base de conhecimento inteira em vez de a um system prompt ou a um conjunto de ferramentas.

Acho a crítica correta no nível de mecanismo e ainda assim acho o paper útil, pelo mesmo motivo que achei útil descobrir que o critério de merge do WordPiece é PMI com outro nome: dar nome a um padrão ajuda a reconhecer quando ele se aplica. CAG não é uma primitiva nova de engenharia, é uma categoria de decisão: colocar o conhecimento inteiro no contexto e cachear, em vez de recuperar pedaço por pedaço. A pergunta interessante não é se o nome é novo, é quando essa categoria vence a outra.

Os números do paper

Os autores testaram em HotPotQA e SQuAD, em três tamanhos de base (pequeno, médio, grande, de 21 mil a 85 mil tokens), rodando Llama 3.1 8B com contexto efetivo de 32 a 64 mil tokens. Compararam CAG contra RAG esparso (BM25, top 3) e RAG denso (embeddings, top 3), medindo qualidade por BERTScore.

Sistema HotPotQA pequeno HotPotQA grande SQuAD pequeno
Sparse RAG (top 3) 0,7626 0,7463 0,7616
Dense RAG (top 3) 0,7582 0,7409 0,7106
CAG 0,7951 0,7407 0,7695

CAG ganha nas duas bases pequenas e empata (por baixo) na base grande de HotPotQA. A vantagem de qualidade encolhe conforme a base cresce, o que os próprios autores atribuem a um efeito já documentado em outros trabalhos: modelos de contexto longo perdem precisão quando o contexto fica muito extenso.

Na latência, o quadro é mais interessante ainda. Tempos em segundos, para HotPotQA:

Tamanho Sistema Retrieval Geração Total
Pequeno Sparse RAG (top 3) 0,0008 s 0,7406 s 0,7414 s
Pequeno Dense RAG (top 3) 0,4849 s 1,0093 s 1,4942 s
Pequeno CAG n/a 0,8512 s 0,8512 s
Grande Sparse RAG (top 3) 0,0008 s 0,6667 s 0,6675 s
Grande Dense RAG (top 3) 0,4123 s 0,9331 s 1,3454 s
Grande CAG n/a 2,2631 s 2,2631 s

CAG elimina os 0,48 segundos de retrieval denso na base pequena e sai na frente no total. Na base grande a vantagem desaparece: o tempo de geração do CAG salta para 2,26 segundos, mais lento que as duas versões de RAG somadas. Atenção não é de graça, custa mais processar um contexto maior a cada pergunta, e isso cresce mais rápido que o benefício de não fazer retrieval.

A conta que decide entre CAG e RAG

A decisão é se o seu prefixo cabe na janela de contexto e fica parado o suficiente pra valer a pena cachear. Isso vira uma conta simples de fazer, usando os números reais de prompt caching que a Anthropic documenta hoje: escrever um prefixo no cache custa cerca de 1,25 vez o preço normal de entrada, e ler desse cache depois custa cerca de 0,1 vez, um desconto de 90%. O cache expira por padrão em 5 minutos, com opção de estender pra 1 hora.

Chamando de c o custo normal (sem cache) de processar aquele prefixo, o custo de N chamadas sem cache é N·c. Com cache, a primeira chamada paga a escrita e as demais pagam leitura:

N⋅c  =  1,25c+(N−1)⋅0,1c⟹N∗≈1,28N\cdot c \;=\; 1{,}25c + (N-1)\cdot 0{,}1c \quad\Longrightarrow\quad N^{*} \approx 1{,}28

A partir da segunda chamada sobre o mesmo prefixo, cachear já compensa. Isso vale independente de você estar fazendo CAG (cache da base inteira) ou só cacheando o system prompt e a definição de ferramentas de um agente RAG comum. O que separa CAG de RAG é outra coisa: o que cabe e permanece estável dentro da janela.

Uma base de 50 mil tokens que muda uma vez por semana é candidata natural a CAG. Uma base de alguns milhões de tokens que muda a cada hora não cabe hoje em nenhuma janela de contexto disponível e, mesmo que coubesse, pagaria a taxa de escrita de cache a cada atualização, o que destrói a economia. O TTL padrão de 5 minutos importa aqui também: se o tráfego sobre aquele prefixo não é constante o bastante pra manter o cache quente, cada rajada de uso paga a reescrita de novo.

Arquitetura híbrida na prática

O padrão que faz sentido em produção é rotear. Consultas que caem dentro do que está cacheado seguem um caminho quente, sem retrieval. Consultas fora desse escopo caem num caminho frio, com retrieval completo. A parte difícil não é a ideia, é decidir o que fica no caminho quente e manter essa decisão coerente conforme a base muda.

Existe uma variação dessa ideia com evidência experimental melhor documentada que o CAG puro: cachear não a base inteira, mas os resultados do retrieval. O paper sobre caching aproximado pra RAG usa locality-sensitive hashing pra identificar quando uma pergunta nova é parecida o suficiente com uma pergunta antiga pra reaproveitar os documentos já recuperados, sem consultar o banco vetorial de novo. Nos benchmarks MMLU e MedRAG isso reduziu em 77,2% as chamadas ao banco vetorial, mantendo a acurácia, com latência de cache na casa dos microssegundos.

São duas coisas diferentes: CAG elimina o retrieval, cache de resultado de retrieval só evita repetir um retrieval que já foi feito antes para uma pergunta parecida. As duas cabem na mesma arquitetura híbrida ao mesmo tempo, uma cuidando do prefixo estável, outra cuidando da cauda longa de perguntas repetidas.

Onde eu aplicaria isso

No Arms Context System o perfil de dado é o oposto do caso ideal pra CAG puro: multi-tenant, cada cliente com sua fatia de contexto, alimentado por múltiplas fontes (calls, WhatsApp, GitHub, board) que chegam o tempo todo por flows de ingestão contínuos. Colocar a base inteira de um tenant no contexto e cachear pagaria a taxa de escrita a cada ingestão nova, para um corpus que só tende a crescer. RAG com filtro por cliente, peso temporal e citação de fonte é a escolha certa aqui, porque o perfil dos dados é grande, por tenant e mudando o tempo todo, exatamente os três fatores que tiram CAG da mesa.

Isso não significa abrir mão de cache. O system prompt do agente, o esquema de ferramentas do MCP server e qualquer trecho de instrução fixa continuam sendo candidatos óbvios a prompt caching comum, pela mesma conta da seção anterior. A decisão entre CAG e RAG é sobre o corpus de conhecimento; cachear o que é estável no prompt vale sempre que existe mais de uma chamada reutilizando o mesmo prefixo.

O que eu tiro disso

Toda vez que uma técnica chega com nome novo vale desmontar o mecanismo antes de comprar a categoria. CAG não é mágica nem substitui RAG de forma geral, é uma aplicação específica de cache de contexto que só funciona quando a base cabe na janela do modelo e fica parada tempo suficiente pra amortizar o custo de escrever o cache. Fora dessa faixa, RAG continua sendo a escolha certa, porque resolve um problema que CAG estruturalmente não resolve: base grande, dinâmica e por tenant.

O recado maior é o mesmo do artigo sobre tokenização: antes de adotar uma técnica porque ela tem nome bonito ou porque virou tendência, vale fazer a conta com os números reais do seu caso. Às vezes a conta confirma a moda. Às vezes mostra que você já estava fazendo a coisa certa com outro nome.