Se você envia um prompt de sistema longo — contexto RAG, catálogo de ferramentas, regras do agente, exemplos — provavelmente está pagando o preço integral de entrada em cada chamada. O cache de prompts da Anthropic reduz isso a 10% da tarifa na parte armazenada em cache. A OpenAI faz o mesmo implicitamente. A maioria das equipes considera que os 30 minutos de trabalho valem a pena, porque isso reduz de forma confiável em 60–90% o custo de entrada.
O Kunavo lida com ambos. Seus próprios pontos de interrupção cache_control passam pela Messages API sem alterações; nas APIs Chat Completions e Responses — cujo formato não tem um campo correspondente para enviar — o Kunavo os define por você e preenche ao redor do que você enviou, sem nunca exceder o limite de 4. Este artigo explica os dois casos, as armadilhas que invalidam silenciosamente os caches e como verificar sua taxa de acerto.
Antes e depois
Um loop ingênuo que envia o mesmo prompt de sistema de 18 mil tokens dez vezes:
# What most people start with: every call re-pays for the whole prompt.
import anthropic
client = anthropic.Anthropic(
api_key="sk-kn-...",
base_url="https://api.kunavo.com",
)
SYSTEM = open("system-prompt.md").read() # 18,000 tokens of rules + examples
# 10 user questions in a session. Every call sends the 18K-token system block.
for question in questions:
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=600,
system=SYSTEM,
messages=[{"role": "user", "content": question}],
)
# Cost per call (input only): 18,000 × $3 / 1M = $0.054
# 10 calls: $0.54 in input alone.Agora marque o bloco do sistema como armazenável em cache — um campo adicional:
# The fix: mark the static prefix as cacheable. After the first call,
# subsequent calls within ~5 minutes pay 10% the input rate on the cached
# portion. Same answer, 89% cheaper.
resp = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=600,
system=[
{
"type": "text",
"text": SYSTEM,
"cache_control": {"type": "ephemeral"}, # mark cacheable
}
],
messages=[{"role": "user", "content": question}],
)
# First call (cache write): 18,000 × $3.75 / 1M = $0.0675 (1.25× input)
# Calls 2–10 (cache hit): 18,000 × $0.30 / 1M = $0.0054 each
# Total: $0.0675 + 9 × $0.0054 = $0.116 (was $0.54 — 78.5% saved)Você acabou de economizar 78,5% do custo de entrada nesta sessão. A primeira chamada é, na verdade, um pouco mais cara que a versão ingênua (~1,25× a tarifa de entrada para gravar o cache). As chamadas 2 a 10 pagam 10% da tarifa. O ponto de virada ocorre na chamada 2; na chamada 3 você já está economizando. Na chamada 10, a diferença é enorme.
Estilo OpenAI: não há nada a fazer
O formato Chat Completions da OpenAI não tem o campo cache_control, pois a OpenAI faz cache implicitamente em seus próprios servidores. O Claude não faz isso: ele armazena em cache apenas o que um ponto de interrupção marca. Portanto, quando você acessa um modelo Claude por /v1/chat/completions ou /v1/responses, o Kunavo define os pontos de interrupção por você: um ponto móvel na última mensagem quando a conversa já tem pelo menos uma resposta do assistente, depois um após system e outro após tools. Tudo o que você definir permanece exatamente onde foi colocado — o Kunavo apenas preenche as posições vazias, até o limite de 4. Não há nada para configurar, e o mesmo modelo custa o mesmo, quer você entre pela rota Anthropic ou pela rota OpenAI:
# OpenAI Chat Completions style — Kunavo sets the breakpoints for you.
# No flag to set. The "usage" object tells you what was cached.
from openai import OpenAI
client = OpenAI(
api_key="sk-kn-...",
base_url="https://api.kunavo.com/v1",
)
resp = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[
{"role": "system", "content": LONG_SYSTEM_PROMPT}, # >1024 tokens
{"role": "user", "content": "Latest question…"},
],
)
# In the response:
# resp.usage.prompt_tokens_details.cached_tokens → 17,800
# resp.usage.prompt_tokens → 18,200
# 17.8K/18.2K = 98% of input came from cache. Bill reflects that automatically.Leia usage.prompt_tokens_details.cached_tokens para ver quanto foi servido do cache. Quanto maior o prefixo fixo, maior a economia. Regra geral: se o prompt do sistema for menor que o conteúdo variável do usuário, o cache não está ajudando muito. Reestruture o prompt para que as partes estáticas sejam grandes e fiquem no início.
Cache em várias camadas — até 4 pontos de interrupção
Para loops de agentes em que algumas camadas mudam mais rapidamente que outras, defina vários pontos de interrupção cache_control. Cada um é uma fotografia de tudo até aquele ponto:
# Anthropic supports up to 4 cache breakpoints per request — use them
# to keep the cache hot even as later layers change.
client.messages.create(
model="claude-sonnet-4-6",
max_tokens=600,
system=[
{"type": "text",
"text": ROLE_AND_RULES, # ~3,000 tokens
"cache_control": {"type": "ephemeral"}}, # breakpoint 1
{"type": "text",
"text": LARGE_KNOWLEDGE_BASE, # ~15,000 tokens, rarely changes
"cache_control": {"type": "ephemeral"}}, # breakpoint 2
],
messages=[
{"role": "user",
"content": [
{"type": "text",
"text": CONVERSATION_HISTORY, # grows each turn
"cache_control": {"type": "ephemeral"}}, # breakpoint 3
{"type": "text", "text": new_question},
]},
],
)
# When CONVERSATION_HISTORY changes, breakpoints 1+2 still hit cache.
# Only breakpoint 3 + the new question pay full input rate.A chave do cache é o prefixo inteiro. Adicionar um token na posição N invalida todos os pontos de interrupção na posição N ou depois dela. A ordem importa: conteúdo mais estável primeiro. A camada de regras raramente deve mudar; a base de conhecimento é atualizada semanalmente; a conversa cresce a cada turno.
Formas comuns de quebrar o cache silenciosamente
- Colocar a data atual ou um request_id no prompt. Cada chamada se torna um novo prefixo e a taxa de acerto do cache fica em 0%. Faça hash das entradas do prompt e compare-as entre as chamadas.
- Montagem não determinística do prompt de sistema. Se você montar o sistema a partir de um dict, a ordem de iteração do dict importa em algumas versões do Python. Ordene as chaves explicitamente.
- A vida útil do cache é de ~5 minutos. Padrões de tráfego esparsos (uma chamada a cada 10 minutos) não obtêm nenhum acerto. Faça chamadas em lote ou aceite a perda.
- O mínimo de 1.024 tokens. Abaixo de 1 mil tokens, o cache no estilo OpenAI não é ativado. Combine fragmentos estáticos pequenos em um único prefixo mais longo.
- Ferramentas / definições de funções fazem parte do prefixo. Adicionar uma nova ferramenta ao catálogo invalida o cache para todos. Mantenha o catálogo de ferramentas estável e versione-o.
Verificar a taxa de acerto
Cache que você não consegue observar não é engenharia — é esperança. Registre usage em todas as chamadas:
# Always read usage. If cached_tokens is 0 when you expected a hit,
# something's wrong — usually a non-deterministic prefix.
resp = client.messages.create(...)
u = resp.usage
print({
"input_uncached": u.input_tokens,
"input_cache_read": u.cache_read_input_tokens,
"input_cache_write": u.cache_creation_input_tokens,
"output": u.output_tokens,
})
# A common gotcha: putting today's date or a request_id in the system prompt
# silently invalidates the cache. Hash your inputs; verify cache_read_input_tokens
# is non-zero on the 2nd identical call.No painel do Kunavo, a página de uso mostra a divisão do cache por modelo e por dia. Se você vir cache_read_input_tokens crescendo como porcentagem da entrada total, o cache está funcionando. Se permanecer em 0 ou oscilar muito, percorra a lista de armadilhas acima.
O custo real no Kunavo
A taxa de cache de cada modelo é publicada na página de preços:
- Modelos Anthropic: leituras do cache custam 10% da tarifa de entrada — 2.5% on Claude Fable 5.1, 5% on Claude Opus 5.5. Gravações no cache custam 1,25× a tarifa de entrada — o multiplicador de cinco minutos da Anthropic — e o Kunavo cobra as gravações de uma hora pelo mesmo 1,25×, abaixo dos 2× da Anthropic.
- Modelos OpenAI / Gemini: leituras do cache custam 10% da tarifa de entrada (a proporção publicada pelos fornecedores). Gravações no cache custam 1,25× no GPT-5.6 e no GPT-6 Astra, e a tarifa de entrada normal em todos os outros modelos.
- Todos os preços com cache já incluem o desconto de modelo do Kunavo (abaixo do preço de tabela do upstream por modelo). Portanto, uma leitura do cache do Sonnet 4.6 no Kunavo custa
$3 × 0.40 × 0.10 = $0.12 per 1M tokens. Cerca de 25× menos que a tarifa upstream sem cache.
Quando o cache não é a resposta
Alguns casos em que o trabalho não compensa:
- Prompts curtos (<1K tokens no total). A sobrecarga domina; simplesmente não vale a pena.
- Tarefas de uma única execução sem tráfego repetido. A primeira chamada é um pouco mais cara; o cache só se paga a partir da chamada 2.
- Tarefas com muita saída e pouca entrada (escrita criativa, geração de código). A entrada já representa uma pequena parte da cobrança. Concentre-se nos limites do orçamento de saída.
Para todo o resto — chatbots RAG, agentes com catálogo fixo de ferramentas, classificadores que usam uma rubrica estática, pipelines de extração estruturada com few-shots consistentes — o cache é a otimização de maior retorno que você pode colocar em produção em uma única tarde. Combine-o com as outras quatro técnicas do nosso guia de otimização de custos e uma redução de 70% é realista sem qualquer concessão na qualidade da saída.
Já usa o Kunavo? Abra /app/usage e verifique a coluna de cache do seu maior modelo. Se estiver em zero, você está deixando dinheiro na mesa. Guia completo: /docs/caching.