Phase 11 - Lesson 15

Caching de Prompt e Caching de Contexto

Seu prompt de sistema tem 4.000 tokens. Seu contexto RAG tem 20.000 tokens. Você envia ambos a cada requisição. Você também paga por ambos — todas as vezes. O caching de prompt permite que o provedor mantenha esse prefixo quente do lado dele e cobre de você 10% da taxa normal no reuso. Usado corretamente, ele reduz o custo de inferência em 50–90% e a latência do primeiro token em 40–85%.

Tipo: Build Linguagens: Python Pré-requisitos: Fase 11 · 01 (Engenharia de Prompt), Fase 11 · 05 (Engenharia de Contexto), Fase 11 · 11 (Caching e Custo) Tempo: ~60 minutos

O Problema

Um agente de codificação envia o mesmo prompt de sistema de 15.000 tokens para o Claude a cada turno de uma conversa. Vinte turnos a $3/M tokens de entrada custam $0,90 apenas em custo de entrada — antes de qualquer mensagem real do usuário. Multiplique por 10.000 conversas diárias e a conta chega a $9.000/dia para um texto que nunca muda.

Você não pode reduzir o prompt sem prejudicar a qualidade. Você não pode evitar enviá-lo — o modelo precisa dele a cada turno. A única alternativa é parar de pagar o preço total por um prefixo que o provedor já viu.

Essa alternativa é o caching de prompt. A Anthropic lançou essa funcionalidade em agosto de 2024 (com uma variante de TTL estendido de 1 hora em 2025), a OpenAI a automatizou no final daquele ano, a Google lançou o caching de contexto explícito junto com o Gemini 1.5, e todas as três agora oferecem isso como um recurso de primeira classe em seus modelos de fronteira.

O Conceito

Caching de prompt: escrita única, leitura barata

O funcionamento. Quando o prefixo de uma requisição corresponde ao de uma requisição recente, o provedor serve o KV-cache da execução anterior em vez de codificar novamente os tokens. Você paga uma pequena taxa extra de escrita na primeira vez e um grande desconto de leitura em todas as vezes seguintes.

Três variantes de provedores em 2026.

Provedor Estilo da API Desconto no hit Adicional de escrita TTL padrão Mínimo cacheável
Anthropic Marcadores cache_control explícitos em blocos de conteúdo 90% de desconto na entrada Sobretaxa de 25% 5 min (estendível para 1 hora) 1.024 tokens (Sonnet/Opus), 2.048 (Haiku)
OpenAI Detecção automática de prefixo 50% de desconto na entrada nenhuma Até 1 hora (melhor esforço) 1.024 tokens
Google (Gemini) API CachedContent explícita Cobrado por armazenamento; leitura a ~25% do normal Taxa de armazenamento por token·hora Definido pelo usuário (padrão 1 hora) 4.096 tokens (Flash), 32.768 (Pro)

A invariante. Todos os três realizam cache apenas de prefixos. Se qualquer token for diferente entre as requisições, tudo após o primeiro token diferente resultará em uma falha de cache (miss). Coloque as partes estáveis no topo, e as partes variáveis na parte inferior.

O layout favorável ao cache

[system prompt]          <-- cache this
[tool definitions]       <-- cache this
[few-shot examples]      <-- cache this
[retrieved documents]    <-- cache if reused, else don't
[conversation history]   <-- cache up to last turn
[current user message]   <-- never cache (different every time)

Violou a ordem — colocou a mensagem do usuário acima do prompt de sistema, intercalou recuperações dinâmicas entre os exemplos few-shot — e o cache nunca será acionado.

O cálculo de ponto de equilíbrio

A taxa extra de escrita de 25% da Anthropic significa que um bloco em cache precisa ser lido pelo menos duas vezes para gerar economia real. 1 escrita + 1 leitura resulta em uma média de 0,675x do custo por requisição (economiza 32%); 1 escrita + 10 leituras resulta em uma média de 0,205x (economiza 80%). Regra geral: faça cache de qualquer coisa que você espera reusar pelo menos 3 vezes dentro do TTL.

Construa

Passo 1: Caching de prompt da Anthropic com marcadores explícitos

import anthropic

client = anthropic.Anthropic()

SYSTEM = [
    {
        "type": "text",
        "text": "You are a senior Python reviewer. Follow the rubric exactly.\n\n" + RUBRIC_15K_TOKENS,
        "cache_control": {"type": "ephemeral"},
    }
]

def review(code: str):
    return client.messages.create(
        model="claude-opus-4-7",
        max_tokens=1024,
        system=SYSTEM,
        messages=[{"role": "user", "content": code}],
    )

O marcador cache_control instrui a Anthropic a armazenar o bloco por 5 minutos. O reuso dentro dessa janela resulta em hit; o reuso após esse período expira e realiza a escrita novamente.

Campos de uso da resposta:

response = review(code_a)
response.usage
# InputTokensUsage(
#     input_tokens=120,
#     cache_creation_input_tokens=15023,   # paid at 1.25x
#     cache_read_input_tokens=0,
#     output_tokens=340,
# )

response_b = review(code_b)
response_b.usage
# cache_creation_input_tokens=0
# cache_read_input_tokens=15023           # paid at 0.1x

Verifique ambos os campos no CI — se cache_read_input_tokens permanecer em zero em várias requisições, suas chaves de cache estão sofrendo desvio (drifting).

Passo 2: TTL estendido de uma hora

Para jobs em lote (batch jobs) de longa duração, o padrão de 5 minutos expira entre as execuções. Defina o ttl:

{"type": "text", "text": RUBRIC, "cache_control": {"type": "ephemeral", "ttl": "1h"}}

O TTL de 1 hora custa o dobro da taxa extra de escrita (50% acima da linha de base em vez de 25%), mas se paga rapidamente em qualquer lote que reuse o prefixo mais de 5 vezes.

Passo 3: Caching automático da OpenAI

A OpenAI não oferece nenhuma configuração. Qualquer prefixo com mais de 1.024 tokens que corresponda a uma requisição recente recebe automaticamente um desconto de 50%.

from openai import OpenAI
client = OpenAI()

resp = client.chat.completions.create(
    model="gpt-5",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},   # long and stable
        {"role": "user", "content": user_msg},
    ],
)
resp.usage.prompt_tokens_details.cached_tokens  # the discounted portion

A mesma regra de layout favorável ao cache se aplica. Duas coisas invalidam o cache da OpenAI que não invalidam o da Anthropic: alterar o campo user (usado como componente da chave de cache) e reordenar as ferramentas.

Passo 4: Caching de contexto explícito do Gemini

O Gemini trata o cache como um objeto de primeira classe que você cria e nomeia:

from google import genai
from google.genai import types

client = genai.Client()

cache = client.caches.create(
    model="gemini-3-pro",
    config=types.CreateCachedContentConfig(
        display_name="rubric-v3",
        system_instruction=RUBRIC,
        contents=[FEW_SHOT_EXAMPLES],
        ttl="3600s",
    ),
)

resp = client.models.generate_content(
    model="gemini-3-pro",
    contents=["Review this code:\n" + code],
    config=types.GenerateContentConfig(cached_content=cache.name),
)

O Gemini cobra pelo armazenamento por token·hora enquanto o cache estiver ativo, e as leituras custam ~25% da taxa de entrada normal. Esse é o formato ideal quando você reutiliza o mesmo prompt gigante em muitas sessões ao longo de vários dias.

Passo 5: Medindo a taxa de acerto (hit rate) em produção

Consulte code/main.py para ver um contabilizador simulado de três provedores que monitora contagens de escrita/leitura/falha e calcula o custo composto por 1K requisições. Condicione os deploys a uma meta de taxa de acerto — a maioria das configurações de produção da Anthropic deve apresentar uma fração de leitura >80% após o aquecimento (warmup).

Armadilhas que ainda ocorrem em 2026

  • Timestamps dinâmicos no topo. "Current time: 2026-04-22 15:30:02" no topo do prompt de sistema. Cada requisição resulta em falha de cache (miss). Mova os timestamps para baixo do ponto de quebra do cache.
  • Reordenação de ferramentas. Serialize as ferramentas em uma ordem estável — uma reorganização de dicionário entre deploys quebra todos os acertos.
  • Quase-duplicatas de texto livre. "You are helpful." vs "You are a helpful assistant." — diferença de um único byte = falha total de cache.
  • Blocos pequenos demais. A Anthropic exige um limite mínimo de 1.024 tokens (2.048 para o Haiku). Blocos menores silenciosamente não são cacheados.
  • Dashboards de custos cegos. Separe os "tokens de entrada" em cacheados vs não-cacheados. Caso contrário, uma queda no tráfego parecerá um ganho de cache.

Quando Usar

Situação Escolha
Agente com prompt de sistema estável de 10k+ tokens, muitos turnos Anthropic cache_control com TTL de 5 min
Job em lote reutilizando um prefixo por mais de 30 minutos Anthropic com ttl: "1h"
Endpoints serverless no GPT-5, sem infraestrutura personalizada OpenAI automático (apenas torne seu prefixo estável e longo)
Reutilização por vários dias de um corpus gigante de código/documentos Gemini explícito CachedContent
Fallback entre provedores Mantenha o layout do prefixo cacheável idêntico entre os provedores para que qualquer acerto funcione

Combine com caching semântico (Fase 11 · 11) para a camada de mensagens do usuário: o caching de prompt lida com o reuso de tokens idênticos, enquanto o caching semântico lida com o reuso de significados idênticos.

Entregue

Salve outputs/skill-prompt-caching-planner.md:

---
name: prompt-caching-planner
description: Design a cache-friendly prompt layout and pick the right provider caching mode.
version: 1.0.0
phase: 11
lesson: 15
tags: [llm-engineering, caching, cost]
---

Given a prompt (system + tools + few-shot + retrieval + history + user) and a usage profile (requests per hour, TTL needed, provider), output:

1. Layout. Reordered sections with a single cache breakpoint marked; explain which sections are stable, which are volatile.
2. Provider mode. Anthropic cache_control, OpenAI automatic, or Gemini CachedContent. Justify from TTL and reuse pattern.
3. Break-even. Expected reads per write within TTL; net cost vs no-cache with math.
4. Verification plan. CI assertion that cache_read_input_tokens > 0 on the second identical request; dashboard split by cached vs uncached tokens.
5. Failure modes. List the three most likely reasons the cache will miss in this setup (dynamic timestamp, tool reorder, near-duplicate text) and how you will prevent each.

Refuse to ship a cache plan that places a dynamic field above the breakpoint. Refuse to enable 1h TTL without a reuse count that makes the 2x write premium pay back.

Exercícios

  1. Fácil. Realize uma conversa de 10 turnos com um prompt de sistema de 5.000 tokens contra o Claude. Execute-a sem cache_control e depois com ele. Relate a cobrança de tokens de entrada para cada caso.
  2. Médio. Escreva um ambiente de testes (test harness) que, dado um modelo de prompt e um log de requisições, calcule a taxa de acerto (hit rate) esperada e a economia em dólares por provedor (Anthropic 5m, Anthropic 1h, OpenAI automático, Gemini explícito).
  3. Difícil. Construa um otimizador de layout: dado um prompt e uma lista de campos marcados como stable=True/False, reescreva o prompt para colocar um único ponto de quebra de cache na posição máxima favorável ao cache, sem perder informações. Verifique em um endpoint real da Anthropic.

Termos-Chave

Termo O que as pessoas dizem O que realmente significa
Prompt caching "Torna prompts longos baratos" Reutilização de um KV-cache no lado do provedor para prefixos correspondentes; 50-90% de desconto em tokens de entrada repetidos.
cache_control "O marcador da Anthropic" Atributo do bloco de conteúdo que declara "tudo até aqui é cacheável"; {"type": "ephemeral"}.
Escrita no cache "Pagando a taxa extra" A primeira requisição que preenche o cache; cobrada a ~1,25x da taxa de entrada na Anthropic, gratuita na OpenAI.
Leitura do cache "O desconto" Requisições subsequentes que correspondem ao prefixo; cobradas a 10% (Anthropic), 50% (OpenAI), ~25% (Gemini).
TTL "Quanto tempo ele vive" Segundos que o cache permanece quente; padrão de 5m na Anthropic (estendível para 1h), melhor esforço de até 1h na OpenAI, definido pelo usuário no Gemini.
TTL Estendido "Cache de 1 hora da Anthropic" {"type": "ephemeral", "ttl": "1h"}; o dobro da taxa extra de escrita, mas vale a pena para reuso em lote.
Correspondência de prefixo "Por que meu cache falhou" Os acertos de cache ocorrem apenas quando cada token desde o início até o ponto de quebra é idêntico em nível de bytes.
Caching de contexto (Gemini) "O explícito" Objeto de cache nomeado do Google e cobrado por armazenamento; melhor para reuso de grandes volumes de texto (corpora) ao longo de vários dias.

Leituras Adicionais

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).