A tese desta página: o cache de prompt é casamento de prefixo. Ele vale do primeiro byte até o primeiro byte diferente, e nem um caractere além. Não existe casamento de pedaço no meio, não existe reaproveitamento parcial e não existe aviso quando você quebra o casamento. É a otimização de maior retorno e menor esforço que existe em cima de um LLM e a mais fácil de perder por acidente, porque perdê-la não gera erro nenhum.
O que o cache NÃO é
não é cache de resposta: a mesma pergunta duas vezes gera duas gerações diferentes
não é busca por semelhança: prompts "parecidos" não casam, só prefixos idênticos
não casa por pedaço: um trecho igual no meio do prompt não vale nada
não avisa quando quebra: a conta sobe e o log fica idêntico
O que ele é
é o KV-cache da página anterior, congelado e reusado entre requisições
é a decisão de onde cortar: até que ponto do prompt vale guardar
é uma conta de escrita cara, leitura barata, com ponto de equilíbrio conhecido
é, sobretudo, uma decisão de arquitetura tomada antes da primeira linha
Explore cada etapa →
A matemática, num só lugar
As 4 contas que decidem se o cache vale a pena. Clique em qualquer uma para pular direto para a etapa que a explica.
Honestidade, antes de começar: tudo que envolve posição nesta página é exato o prefixo comum é calculado caractere a caractere, no seu navegador, sobre o texto que você digitar. Duas coisas são aproximadas e ficam editáveis de propósito: a contagem de tokens (o tokenizador real é BPE e depende do modelo; a regra de bolso daqui erra na casa de 10–15% em texto corrido e mais em código) e os preços e multiplicadores, que variam por provedor, por modelo e por contrato. Os valores padrão seguem a tabela pública da Anthropic escrita a 1,25× do preço de entrada com validade de 5 minutos, 2× com validade de 1 hora, leitura a 0,1× nos dois casos. Confira os do seu provedor antes de levar qualquer número daqui para uma planilha.
A página anterior terminou com o KV-cache: as chaves e valores dos tokens já lidos, guardados para não recalcular a matriz de atenção a cada token novo. Aquele cache vive dentro de uma requisição. O cache de prompt é a mesma ideia esticada um nível: guardar o KV entre requisições diferentes, para que a segunda chamada não pague de novo pelo prefixo que a primeira já processou.
O mesmo prefixo, N chamadas
20 chamadas
escrita do prefixo (1,25× a 2× do preço base)leitura do prefixo (0,1× do preço base)parte variável (preço cheio, sempre)
Por que isso é possível
Porque a máscara causal garante que o K e o V de um token dependem apenas do que veio antes dele nunca do que vem depois. Então se duas requisições começam com os mesmos 10 mil tokens, os K e V desses 10 mil são bit a bit os mesmos nas duas, independentemente do que venha em seguida. É a mesma propriedade da etapa 3 da página anterior, agora valendo dinheiro.
E também por que é tão frágil
A mesma propriedade explica a fragilidade. Se o token na posição 12 muda, o K e o V dele mudam e como todo token depois dele olhou para ele, os K e V de todos os seguintes mudam junto. Não é uma escolha de implementação conservadora: é aritmética. Não há como salvar a parte de baixo.
Detalhe operacional: o cache tem prazo de validade e um tamanho mínimo. O prazo padrão costuma ser curto (na casa dos 5 minutos, renovável a cada leitura) com uma opção mais longa e mais cara. O mínimo é uma quantidade de tokens abaixo da qual nada é cacheado e esse é um dos pontos mais escorregadores da coisa toda: o mínimo varia por modelo e não é monotônico entre gerações. Um prompt de 3 mil tokens é cacheado num modelo e silenciosamente não é no anterior. A tabela está na etapa 2.
Edite os dois prompts abaixo. A página calcula o prefixo comum exato, caractere a caractere, e pinta o resto de vermelho: é tudo que vai ser recalculado do zero na segunda requisição.
O prefixo comum
Caracteres
Tokens (aprox.)
Proporção
verde = prefixo comum, cacheável · vermelho = a partir daqui tudo é recalculado
Fórmula · a condição de acerto
acerto(k) ⟺ bytes(P₁[0…k]) = bytes(P₂[0…k])
Leia assim: o cache acerta até a posição k se, e somente se, os bytes das duas requisições forem idênticos até ali. Repare em três palavras. Bytes, não caracteres: um acento codificado diferente já é outro prompt. Se e somente se: não existe acerto parcial nem aproximado. E o 0…k: sempre a partir do começo nunca de um ponto do meio.
O mínimo cacheável, por modelo
Repare que não é monotônico: o mínimo cai de 4096 para 512 ao longo das gerações, mas não em linha reta. Abaixo do mínimo, o prefixo simplesmente não é cacheado sem erro, sem aviso, com a marcação de corte presente e ignorada.
A hierarquia de invalidação
Nem toda mudança derruba tudo. Há três camadas, e uma mudança só invalida a sua camada e as de baixo. É por isso que dá para alternar parâmetros de amostragem por requisição sem perder o cache de ferramentas e sistema e por isso que trocar uma ferramenta custa o prompt inteiro.
O prompt que chega ao modelo é montado numa ordem fixa: ferramentas → sistema → mensagens. Isso não é detalhe de implementação é a informação mais acionável da página inteira. O prefixo estável termina no primeiro bloco volátil, e tudo que vem depois dele é recalculado a cada chamada, ainda que nunca mude.
A consequência prática
Mova a pergunta atual para o topo e observe: 16 mil tokens perfeitamente estáveis passam a ser recalculados a cada chamada por causa de 90 tokens que mudam. Nenhum erro, nenhuma diferença de resultado, quatro vezes o custo. Esse é o formato de praticamente todo desperdício de cache que existe em produção.
A armadilha da janela de 20 blocos
Um ponto de corte procura o cache anterior olhando no máximo 20 blocos de conteúdo para trás. Num laço agêntico, um único turno pode acrescentar bem mais que isso em pares de chamada e resultado de ferramenta e aí o corte seguinte não encontra o anterior e erra silenciosamente. A correção é pôr um ponto de corte intermediário a cada ~15 blocos em turnos longos.
a mesma funcionalidade, 90% mais barata
# ANTES tudo isto invalida o cache a cada chamada
system = f"""Hoje é {datetime.now().isoformat()}.
Usuário: {user.name} (plano {user.plan})
Requisição: {uuid4()}
{POLITICA_COMPLETA}
{BASE_DE_CONHECIMENTO}"""# e as ferramentas variam por usuário posição zero!
tools = build_tools(user)
resp = client.messages.create(
model="claude-opus-5",
system=system,
tools=tools,
messages=[{"role": "user", "content": pergunta}],
)
# resp.usage.cache_read_input_tokens == 0, sempre.# Nenhum erro. Nenhum log diferente. Só a fatura.
# DEPOIS o estável na frente, congelado e marcado
TOOLS = sorted(TODAS_AS_FERRAMENTAS, key=lambda t: t["name"]) # determinístico
resp = client.messages.create(
model="claude-opus-5",
tools=TOOLS, # igual para todo mundo
system=[{
"type": "text",
"text": POLITICA_COMPLETA + BASE_DE_CONHECIMENTO,
"cache_control": {"type": "ephemeral"}, ← o corte
}],
messages=[{
"role": "user",
# o volátil desce para DEPOIS do corte, onde não custa nada"content": f"[contexto] hoje: {hoje}, plano: {user.plan}\n\n{pergunta}",
}],
)
# A verificação que importa se der zero, existe um invalidador solto:print(resp.usage.cache_read_input_tokens)
Cada um destes é uma linha de código que ninguém escreveu de má-fé, e que custa a maior parte do dinheiro. Ligue um e veja o prefixo cacheável desabar. O detalhe importante não é o quanto ele cai: é que nada nesta operação gera erro.
prefixo que sobreviverecalculado a cada chamada
Como se descobre: a resposta da API traz quantos tokens foram lidos do cache e quantos foram escritos nele. Se em chamadas repetidas com o mesmo prefixo os tokens lidos vêm zero, existe um invalidador solto sempre. Essa é a única evidência que você vai ter, e ela não aparece em nenhum lugar a menos que você a registre de propósito. Coloque esse número num painel antes de otimizar qualquer coisa: sem ele, você não sabe se está economizando ou se só acha que está.
a instrumentação mínima
u = resp.usage
# O tamanho do prompt é a SOMA dos três. Olhar só input_tokens# num agente com cache dá a impressão de um prompt minúsculo.
total = u.input_tokens + u.cache_creation_input_tokens + u.cache_read_input_tokens
metrics.gauge("llm.cache.read", u.cache_read_input_tokens)
metrics.gauge("llm.cache.write", u.cache_creation_input_tokens)
metrics.gauge("llm.cache.miss", u.input_tokens)
metrics.gauge("llm.cache.ratio", u.cache_read_input_tokens / max(total, 1))
# O alarme que vale a pena ter: taxa de leitura despencando# num endpoint que não mudou. É sempre um invalidador novo.
# A varredura de 30 segundos que encontra a maioria dos casos.# Rode sobre TUDO que alimenta o prefixo do prompt:
rg -n 'datetime\.now|Date\.now|time\.time|utcnow' --glob '*prompt*'
rg -n 'uuid4|randomUUID|secrets\.token' --glob '*prompt*'# json.dumps sem sort_keys: mesmo conteúdo, bytes diferentes
rg -n 'json\.dumps\((?!.*sort_keys)' -P
# conjunto de ferramentas montado por usuário: posição zero
rg -n 'tools\s*=\s*\w*build|tools\s*=\s*\[' -A3
# iterar sobre set() não tem ordem garantida entre execuções
rg -n 'for .* in set\(|\.join\(set\('
Armadilha de produção: as operações derivadas. Sumarização, compactação de histórico e subagentes normalmente abrem uma chamada separada. Se essa chamada remontar o sistema, as ferramentas ou o modelo com qualquer diferença uma linha a mais, um modelo mais barato, uma ferramenta a menos ela perde o cache do processo pai inteiro e paga tudo do zero. Copie system, tools e model verbatim do pai e acrescente o que é específico só no fim.
Cachear não é de graça. A primeira chamada paga um prêmio de escrita mais caro do que se você não tivesse cacheado nada. As seguintes pagam uma leitura, que custa quase nada. A pergunta operacional é uma só: a partir de quantos reusos você sai no lucro?
Os parâmetros
A fatura
Fórmula · ponto de equilíbrio
n* = 1 + (w − 1) / (1 − r)
w é o multiplicador de escrita e r o de leitura, ambos relativos ao preço base de entrada. A leitura acima do necessário é o ponto: você paga (w − 1) a mais uma vez, e recupera (1 − r) a cada reuso. Com w = 1,25 e r = 0,1, o prêmio se paga já na segunda chamada. Com o cache de uma hora (w = 2), na terceira. No regime permanente a economia tende a (1 − r) · c / (c + t) perto de 90% quando o prefixo domina.
Quando o TTL longo compensa: quase nunca por padrão, e claramente em um caso. O cache de 5 minutos se renova a cada leitura, então tráfego contínuo mantém o cache vivo sozinho pagar 2× pela escrita ali é desperdício. O TTL de uma hora existe para tráfego em rajadas com intervalos longos: um agente que roda de hora em hora, um lote noturno, um assistente com sessões esparsas. A pergunta certa não é "quanto tempo quero guardar" e sim "meus intervalos entre chamadas passam de 5 minutos com frequência?".
Nada nesta página é difícil. É por isso que a maior parte do dinheiro perdido com cache se perde por ordem de montagem, não por falta de conhecimento a decisão é tomada no dia em que o prompt é escrito, geralmente sem que ninguém perceba que está tomando uma.
A lista de verificação
Um caso real
377K → 28K tokens por requisição
O número que abre este bloco veio de um sistema em produção: 377 mil tokens cobrados por requisição caíram para 28 mil uma redução de 92,6% sem trocar de modelo, sem cortar contexto e sem mudar uma linha do que o sistema fazia. A mudança foi de montagem: separar o que era estável do que era volátil, congelar o primeiro, empurrar o segundo para depois do ponto de corte.
A forma dessa conta é reproduzível, e você pode conferi-la na etapa anterior: com um prefixo de ~350 mil tokens estáveis, uma cauda de alguns milhares e leitura a 0,1×, a fatura por requisição no regime permanente cai justamente para a casa dos 7–8% da original. Não há truque é a mesma aritmética que você acabou de arrastar.
A ordem de ataque
1. Instrumente registre os tokens lidos do cache; sem isso nada mais é mensurável. 2. Congele o sistema e as ferramentas; é aqui que mora quase todo o ganho. 3. Reordene para pôr o volátil no fim. 4. Só então mexa em pontos de corte e TTL. A ordem importa: começar pelo passo 4 é o erro mais comum, e é o passo que menos rende.
Duas notas de concorrência
Uma entrada de cache só fica legível depois que a primeira resposta começa a sair. Disparar N requisições idênticas em paralelo faz as N pagarem preço cheio: nenhuma consegue ler o que as outras ainda estão escrevendo. Em leque, mande uma, espere o primeiro token, e só então dispare as outras. E cuidado com o mínimo: um prompt curto demais não é cacheado, e a marcação de corte é silenciosamente ignorada.
O caminho inteiro
No fim: o cache de prompt é a rara otimização em que a decisão certa é gratuita e a errada é invisível. Não há trade-off de qualidade, não há risco de resposta pior, não há complexidade nova para manter há uma ordem de montagem que você escolhe uma vez. O que torna o assunto perigoso é justamente isso: errar não dói. Nada quebra, nada alerta, nenhum teste falha. A fatura chega quatro vezes maior no fim do mês e a causa está numa linha de f-string escrita seis meses atrás.