· 6 min · API

Cache de prompts explicado: quando economiza dinheiro e quando não

Cache de prompts explicado: quando economiza dinheiro e quando não

Às 9:12 da manhã de uma segunda-feira, um dos nossos agentes de suporte começou a custar 4x a mais do que o esperado.

O modelo não estava alucinando, o gráfico de tráfego não estava errado e ninguém havia trocado acidentalmente de Haiku para Opus. O problema era mais simples: cada requisição incluía o mesmo manual de políticas de 42,000 tokens, mas nossa taxa de acertos no cache de prompts era praticamente zero porque estávamos inserindo um novo registro de data e hora e metadados específicos do usuário antes do manual.

Mesmo conteúdo. Mesmo modelo. Mesma aplicação. Nenhuma economia com cache.

O cache de prompts é um daqueles recursos que parecem automáticos até você tentar reduzir a conta. Na prática, ele favorece uma estrutura de prompt muito específica: um prefixo grande e estável, reutilizado em muitas requisições. Se você entender essa frase, geralmente conseguirá prever se o cache vai economizar dinheiro ou, silenciosamente, não fazer diferença.

O que o cache de prompts realmente armazena

O cache de prompts não é memória semântica. O provedor não está dizendo: “Isso parece semelhante a algo que você enviou antes.” É mais próximo de:

“O início desta requisição corresponde suficientemente a uma sequência anterior de tokens, considerando este modelo e esta política de cache, então podemos reutilizar o processamento interno desse prefixo.”

Essa distinção importa.

O cache de prompts geralmente ajuda quando você envia repetidamente o mesmo prefixo longo:

  • Instruções de sistema
  • Esquemas de ferramentas
  • Conjuntos extensos de documentação
  • Catálogos de produtos
  • Contexto da base de código
  • Manuais jurídicos ou de políticas
  • Exemplos de few-shot
  • Resultados estáticos de recuperação reutilizados em muitas requisições

Geralmente, ele não ajuda muito quando cada requisição começa de forma diferente:

  • Registros dinâmicos de data e hora no início
  • Dados específicos do usuário antes do conteúdo compartilhado
  • Ordem aleatória dos exemplos
  • UUIDs por requisição dentro da seção que pode ser armazenada em cache
  • Trechos recuperados cuja ordem ou formatação muda
  • Histórico de conversa colocado antes das instruções estáveis

A principal medida de engenharia é colocar primeiro o contexto estável e de alto custo, deixando o contexto variável para depois.

Anthropic vs OpenAI: objetivo semelhante, controles diferentes

Anthropic e OpenAI oferecem suporte a cache de prompts, mas a experiência de desenvolvimento é diferente.

A Anthropic disponibiliza o cache de prompts de forma mais explícita. Você pode marcar blocos de conteúdo com controles de cache e depois inspecionar campos de uso como cache_creation_input_tokens e cache_read_input_tokens. Isso facilita entender se você está criando entradas de cache ou lendo delas.

O cache de prompts da OpenAI é mais automático nos modelos compatíveis. Quando um prefixo de prompt é reutilizado, os tokens de entrada em cache podem ser cobrados de forma diferente e aparecer nos metadados de uso. Normalmente, você não define pontos de delimitação explícitos de cache da mesma maneira; em vez disso, estrutura as requisições para que o prefixo reutilizável seja estável em bytes e tokens.

A diferença prática é controle versus conveniência.

DimensãoCache explícito no estilo da AnthropicCache automático no estilo da OpenAI
Controle do desenvolvedorMaior; você pode marcar blocos que podem ser armazenados em cacheMenor; o provedor detecta prefixos reutilizáveis
Facilidade de depuraçãoGeralmente mais clara por meio de contadores de criação e leitura de cacheDepende dos metadados de uso disponibilizados pelo modelo ou pela API
Importância da estrutura do promptMuito altaMuito alta
Mais indicado paraGrandes blocos estáticos, ferramentas, documentação e exemplosPrefixos longos reutilizados em chamadas repetidas
Falha comumPonto de delimitação de cache colocado após conteúdo dinâmicoO prefixo muda antes que o cache possa encontrar uma correspondência
Modelo mental“Estou gravando e lendo um prefixo com uma espécie de nome”“O provedor reconhece este prefixo repetido”

Os detalhes de implementação variam conforme o modelo e o provedor, e continuam evoluindo. Mas a regra arquitetural é estável: o cache depende de prefixos repetidos, não de prompts semelhantes.

O modelo de preços: criação vs leitura

Uma forma útil de pensar no cache de prompts é dividir os tokens de entrada em três categorias:

  1. Tokens de entrada normais: cobrados pelo preço usual de entrada.
  2. Tokens de criação de cache: tokens usados para criar uma entrada de cache, frequentemente cobrados com um acréscimo ou uma tarifa especial de gravação.
  3. Tokens de leitura de cache: tokens lidos de uma entrada de cache existente, geralmente cobrados com desconto.

A Anthropic disponibiliza essa distinção diretamente em campos de uso como:

{
  "usage": {
    "input_tokens": 812,
    "cache_creation_input_tokens": 42000,
    "cache_read_input_tokens": 0,
    "output_tokens": 684
  }
}

Em uma requisição posterior, se houver um acerto de cache para o prefixo, você deve esperar algo mais próximo de:

{
  "usage": {
    "input_tokens": 936,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 42000,
    "output_tokens": 711
  }
}

A primeira chamada cria o cache. As chamadas seguintes leem dele.

A viabilidade econômica depende dos preços atuais do provedor, do TTL do cache e do modelo. Como os preços mudam, prefiro modelar isso com variáveis no código em vez de fixar valores em documentos de projeto.

Aqui está uma pequena função em Python que uso para decidir se vale a pena implementar cache em uma rota:

def cache_savings(
    cached_tokens: int,
    normal_input_per_mtok: float,
    cache_write_per_mtok: float,
    cache_read_per_mtok: float,
    requests: int,
) -> dict:
    mtok = cached_tokens / 1_000_000

    no_cache = requests * mtok * normal_input_per_mtok
    with_cache = (
        mtok * cache_write_per_mtok +
        (requests - 1) * mtok * cache_read_per_mtok
    )

    return {
        "no_cache": round(no_cache, 6),
        "with_cache": round(with_cache, 6),
        "savings": round(no_cache - with_cache, 6),
        "savings_pct": round((1 - with_cache / no_cache) * 100, 2),
    }


print(cache_savings(
    cached_tokens=42_000,
    normal_input_per_mtok=3.00,
    cache_write_per_mtok=3.75,
    cache_read_per_mtok=0.30,
    requests=100,
))

Este exemplo usa apenas preços ilustrativos. O que importa é a estrutura.

Com um prefixo reutilizável de 42,000 tokens e 100 requisições, o cache geralmente é excelente. Com o mesmo prefixo e apenas uma requisição, o cache pode sair mais caro se o preço de gravação for maior que o preço normal de entrada.

Essa é a primeira grande armadilha: o cache de prompts é uma forma de amortização. Se você não reutilizar o prefixo em cache, não terá o benefício.

A fórmula do ponto de equilíbrio

Você pode estimar o ponto de equilíbrio com:

no_cache_cost = N * T * normal_price

cache_cost = T * write_price + (N - 1) * T * read_price

Onde:

  • N é o número de requisições que usam o mesmo prefixo
  • T é a quantidade de tokens que podem ser armazenados em cache
  • normal_price é o preço normal dos tokens de entrada
  • write_price é o preço de criação do cache
  • read_price é o preço de leitura do cache

O cache economiza dinheiro quando:

T * write_price + (N - 1) * T * read_price
  <
N * T * normal_price

O T se cancela no cálculo do ponto de equilíbrio puramente financeiro, o que significa que o número de reutilizações e os preços relativos determinam a decisão. Mas a quantidade de tokens ainda importa operacionalmente: economizar 80% em 500 tokens é insignificante; economizar essa mesma porcentagem em 80,000 tokens é um valor que merece uma linha no orçamento.

Uma versão útil para um cálculo aproximado:

break_even_requests =
  (write_price - read_price) / (normal_price - read_price)

Se as gravações em cache forem apenas um pouco mais caras que a entrada normal e as leituras forem muito mais baratas, o ponto de equilíbrio pode ser muito baixo. Se as gravações em cache forem caras ou seu prefixo raramente se repetir, a economia com cache será frágil.

Como estruturar prompts para ter prefixos estáveis

A melhor otimização para cache de prompts não é uma opção da API. É a organização do prompt.

Organização ruim:

Request ID: req_8f19a
Current time: 2026-02-14T09:12:33Z
User: customer_4812
Locale: en-US

SYSTEM INSTRUCTIONS:
...

POLICY MANUAL:
[42,000 tokens of stable text]

USER QUESTION:
Can I get a refund after 45 days?

Isso impede o cache de prefixos porque o prompt diverge logo no início.

Organização melhor:

SYSTEM INSTRUCTIONS:
...

POLICY MANUAL:
[42,000 tokens of stable text]

DYNAMIC REQUEST METADATA:
Request ID: req_8f19a
Current time: 2026-02-14T09:12:33Z
User: customer_4812
Locale: en-US

USER QUESTION:
Can I get a refund after 45 days?

O bloco estável vem primeiro. O bloco dinâmico vem depois.

Para cache explícito no estilo da Anthropic, a estrutura conceitual pode ser assim:

{
  "model": "claude-sonnet-4-6",
  "max_tokens": 800,
  "system": [
    {
      "type": "text",
      "text": "You are a support policy assistant..."
    },
    {
      "type": "text",
      "text": "Refund policy manual v2026-02-01:\n\n...",
      "cache_control": {
        "type": "ephemeral"
      }
    }
  ],
  "messages": [
    {
      "role": "user",
      "content": "Can I get a refund after 45 days?"
    }
  ]
}

O esquema exato da requisição varia conforme a versão da API e o SDK, então trate isso como uma estrutura, e não como código pronto para copiar e colar. O importante é que o grande bloco estável seja explicitamente elegível para cache e permaneça inalterado entre as chamadas.

Para cache automático no estilo da OpenAI, a estrutura do prompt importa tanto quanto, mesmo que você não marque um bloco manualmente:

{
  "model": "gpt-5.5",
  "messages": [
    {
      "role": "system",
      "content": "You are a support policy assistant...\n\nRefund policy manual v2026-02-01:\n\n..."
    },
    {
      "role": "user",
      "content": "Can I get a refund after 45 days?"
    }
  ]
}

Se a mensagem de sistema mudar a cada requisição, você não deve esperar leituras consistentes do cache.

Um padrão prático de arquitetura

Para sistemas em produção, gosto de tornar os prefixos de prompt em cache explícitos no código da aplicação.

Um padrão simples:

prompt_prefix/
  support_policy_v17.txt
  tool_schema_v4.json
  examples_v9.md

runtime_request/
  user_question
  user_profile
  retrieved_recent_orders

Depois, componha as requisições assim:

from pathlib import Path

POLICY_PREFIX = Path("prompt_prefix/support_policy_v17.txt").read_text()
TOOL_SCHEMA = Path("prompt_prefix/tool_schema_v4.json").read_text()
EXAMPLES = Path("prompt_prefix/examples_v9.md").read_text()

def build_prompt(user_question: str, user_profile: dict) -> str:
    stable_prefix = f"""
You are a support policy assistant.

TOOLS:
{TOOL_SCHEMA}

POLICY:
{POLICY_PREFIX}

EXAMPLES:
{EXAMPLES}
""".strip()

    dynamic_suffix = f"""
USER PROFILE:
{user_profile}

USER QUESTION:
{user_question}
""".strip()

    return stable_prefix + "\n\n--- DYNAMIC REQUEST ---\n\n" + dynamic_suffix

Na prática, também versiono o prefixo. Se o manual de políticas mudar, quero que isso seja um evento deliberado de invalidação do cache:

sha256sum prompt_prefix/support_policy_v17.txt

Esse hash aparece nos logs junto com o nome do modelo, os tokens de criação de cache, os tokens de leitura de cache e a rota da requisição. Sem essa observabilidade, os problemas de cache são difíceis de diagnosticar porque a resposta continua funcionando; ela só custa mais.

Uma linha de log útil se parece com:

{
  "route": "support.answer",
  "model": "claude-sonnet-4-6",
  "prefix_hash": "9d3a4a...",
  "input_tokens": 932,
  "cache_creation_input_tokens": 0,
  "cache_read_input_tokens": 42000,
  "output_tokens": 688,
  "latency_ms": 1840
}

Não otimize apenas com base na cobrança. Registre o comportamento do cache por rota.

Latência: geralmente melhora, mas não faz mágica

O cache de prompts pode reduzir a latência porque o provedor do modelo pode reutilizar o processamento do prefixo em cache. Mas eu não definiria um SLA supondo uma redução fixa de latência sem antes medi-la na minha própria carga de trabalho.

O que realmente acontece em produção é mais complicado:

  • Prompts curtos podem não apresentar mudanças significativas na latência.
  • Prefixos longos em cache costumam melhorar o tempo até o primeiro token.
  • O comprimento da saída ainda é o fator dominante em muitas requisições.
  • Chamadas de ferramentas, latência de rede e filas podem ocultar os benefícios do cache.
  • Falhas de cache geram picos na latência de cauda se as gravações forem mais lentas que as leituras.

Uma configuração realista de benchmark é simples:

# warm cache
python run_eval.py --case support_refund --repeat 1

# measure cache reads
python run_eval.py --case support_refund --repeat 50 --jsonl out.jsonl

# inspect p50/p95 by cache_read_input_tokens > 0
python analyze_latency.py out.jsonl

Meça separadamente as requisições com acerto e com falha de cache. Misturá-las produz um número que não explica nenhuma das duas.

Armadilhas que vejo em sistemas reais

1. Conteúdo dinâmico antes do conteúdo estável

Esta é a falha mais comum. Um registro de data e hora, ID de requisição, lista de flags de funcionalidades, configuração regional do usuário ou atribuição a um experimento é colocado no início do prompt de sistema.

Mova isso para baixo.

2. JSON “equivalente” não é equivalente

Estes dois trechos são semanticamente idênticos, mas não necessariamente idênticos para o cache:

{"name":"refund_lookup","timeout":3,"strict":true}
{
  "strict": true,
  "timeout": 3,
  "name": "refund_lookup"
}

Se você incluir esquemas de ferramentas ou configurações no prefixo em cache, serialize-os de forma determinística:

import json

def stable_json(data: dict) -> str:
    return json.dumps(data, sort_keys=True, separators=(",", ":"))

Isso evita falhas de cache acidentais causadas por mudanças na ordem das chaves ou nos espaços em branco.

3. A recuperação pode inviabilizar o uso de cache

Sistemas RAG costumam montar prompts assim:

Retrieved documents:
[doc A]
[doc B]
[doc C]

Instructions:
...

Se os resultados da recuperação variarem por consulta, o prefixo também variará. Isso é aceitável se o contexto recuperado for de fato dinâmico, mas não coloque suas instruções estáveis depois dele.

Melhor:

Instructions:
...

Long-lived product documentation:
[stable docs]

Query-specific retrieved documents:
[doc A]
[doc B]
[doc C]

Para sistemas de alto volume, considere dividir o contexto em:

  • Instruções globalmente estáveis
  • Documentação estável por tenant
  • Recuperação específica do usuário ou da consulta

Cada camada tem um comportamento de cache diferente.

4. Os TTLs do cache importam

Algumas entradas de cache expiram. Se seu tráfego ocorre em rajadas, um prefixo pode ser muito reutilizado por dez minutos e depois deixar de ser acessado. Tempos de vida mais longos para o cache podem ajudar, mas podem ter preços ou disponibilidade diferentes dependendo do provedor e do modelo.

É aqui que a distribuição das requisições importa. “Recebemos 10,000 requisições por dia” é menos útil do que “recebemos 200 requisições por minuto para este prefixo exato entre 9 e 10 da manhã”.

5. Mudanças de modelo invalidam premissas

Não se deve presumir que um prefixo armazenado em cache para um modelo possa ser reutilizado em outro. Se você rotear entre Claude Opus 4.8, Sonnet 4.6, GPT-5.5, Gemini 3 ou modelos abertos como Llama, Qwen, DeepSeek, MiniMax ou Kimi, acompanhe o comportamento do cache por modelo.

O roteamento entre vários modelos é útil, mas complica a amortização. Se o tráfego for dividido de cinco formas, cada modelo poderá receber menos prefixos repetidos.

6. A personalização de prompts pode ter o efeito contrário

As equipes costumam personalizar prompts de sistema:

You are helping {{customer_name}}, who is on plan {{plan_name}}.

Isso parece inofensivo, mas, se aparecer antes do conteúdo em cache, cada cliente receberá um prefixo diferente. Coloque a personalização mais adiante, a menos que ela realmente altere a interpretação do bloco estável pelo modelo.

Quando o cache de prompts economiza dinheiro

O cache costuma ser uma boa opção quando:

  • O prefixo que pode ser armazenado em cache é grande, muitas vezes com milhares ou dezenas de milhares de tokens.
  • Exatamente o mesmo prefixo é reutilizado muitas vezes.
  • O prefixo permanece estável entre as requisições.
  • O tráfego chega dentro do tempo de vida do cache.
  • Você consegue observar os tokens de criação e de leitura do cache.
  • A rota tem uma composição de prompt previsível.

Exemplos concretos:

  • Um assistente de programação inclui repetidamente o mesmo mapa do repositório e guia de estilo.
  • Um bot de suporte inclui o mesmo manual de políticas em todas as perguntas sobre reembolso.
  • Um agente usa um grande esquema estático de ferramentas em todas as requisições.
  • Um assistente interno de pesquisa inclui a mesma visão geral do corpus para uma equipe.

Para essas cargas de trabalho, o cache de prompts pode ser uma das otimizações de custo de maior impacto, pois não exige reduzir a qualidade do contexto. Você mantém o prompt longo; apenas deixa de pagar o preço integral de entrada a cada vez.

Quando o cache de prompts não ajuda

O cache oferece pouco benefício ou tem impacto negativo quando:

  • O prompt é curto.
  • Os prefixos raramente são reutilizados.
  • A maior parte do contexto é obtida por recuperação específica da consulta.
  • Dados dinâmicos aparecem antes dos dados estáveis.
  • Você modifica constantemente as instruções durante os experimentos.
  • O tráfego fica muito disperso entre diversos modelos, tenants ou variantes de prompt.
  • As gravações no cache custam mais e as leituras são raras demais para amortizá-las.

Uma armadilha comum durante a avaliação: o cache de prompts parece ruim em um notebook porque você executa cada caso uma única vez. Depois, ele parece excelente em produção porque milhares de usuários compartilham o mesmo prefixo estável. O inverso também acontece: uma demonstração repete o mesmo prompt 100 vezes e mostra uma grande economia, mas a produção tem personalização por tenant que impede a reutilização.

Teste com a distribuição real das requisições.

Uma lista simples para verificar a prontidão para o cache

Antes de habilitar o cache de prompts ou depender dele, verifico:

  • Existe pelo menos um prefixo estável com mais de alguns milhares de tokens?
  • Ele aparece antes de todo o conteúdo dinâmico?
  • A serialização é determinística?
  • O prefixo tem versionamento e um hash calculado?
  • Consigo registrar os tokens de criação e de leitura do cache?
  • Sei o número esperado de reutilizações dentro do tempo de vida do cache?
  • Medi a latência separadamente para acertos e falhas de cache?

Se a resposta a três ou mais perguntas for “não”, o cache ainda pode funcionar, mas você está apenas supondo.

Recomendações Práticas

O cache de prompts não é uma compressão mágica. É a reutilização de um prefixo estável de tokens, e a economia vem de pagar um custo de criação uma vez e um custo de leitura menor muitas vezes.

O roteiro de engenharia é simples:

  • Coloque primeiro o conteúdo grande e estável: instruções, ferramentas, documentação e exemplos.
  • Mova registros de data e hora, metadados do usuário, resultados de recuperação e IDs de requisição para depois do prefixo que pode ser armazenado em cache.
  • Acompanhe cache_creation versus cache_read tokens por rota e modelo.
  • Use serialização determinística para esquemas de ferramentas e configurações em JSON.
  • Modele o ponto de equilíbrio com os preços reais do seu provedor e a distribuição do tráfego.
  • Tenha cuidado com o roteamento entre vários modelos, a personalização por tenant e os prompts curtos.
  • Meça a latência de acertos e falhas separadamente em vez de confiar nas médias.

A melhor otimização de cache de prompts que já vi não tinha nada de engenhoso: movemos 42,000 tokens estáveis para antes de 12 tokens dinâmicos. O comportamento do modelo não mudou. A conta mudou.

A

A AI Prime Tech publica este blog. Os artigos são redigidos com assistência de IA; confira detalhes específicos de cada versão, como IDs de modelos, preços e limites, na documentação oficial antes de se basear neles.

Obtenha acesso mais barato à API do Claude

Uma única chave de API para Claude Opus 5.5, Sonnet 5, Haiku 4.5 e Fable 5.1, além de GPT-6 modelos. Pague conforme o uso, sem assinatura.

Obtenha Sua Chave de API →
A AI Prime Tech é um gateway de API independente de terceiros. Claude™ e Anthropic® são marcas comerciais da Anthropic, PBC. Não há afiliação nem endosso implícitos.