Saltar a contenido

Prompt caching — la palanca económica

Caching reduce input cost hasta 90% y latencia en hits. Es la herramienta más infrautilizada de la API.

Mecánica

client.messages.create(
    model="claude-sonnet-4-6",
    system=[
        {
            "type": "text",
            "text": <contenido del CLAUDE.md + design system + tokens>,
            "cache_control": {"type": "ephemeral", "ttl": "1h"}
        }
    ],
    messages=[{"role": "user", "content": prompt}]
)
  • TTL options: "5m" (1.25× write cost) o "1h" (2× write cost).
  • Cache HIT: cuesta 0.1× input price (90% off).
  • Cache MISS / WRITE: cuesta 1.25× (5min) o (1h) del input price.
  • Break-even:
  • 5m TTL: paga tras 1 read (1.25 write + 0.1 read = 1.35 < 2.0 sin cache).
  • 1h TTL: paga tras 2 reads (2.0 write + 0.1×2 = 2.2 < 3.0).
  • Hasta 4 breakpoints por request. Jerarquía de invalidación: tools → system → messages.

Estrategia para diseño

Tier 1: prefijo system con TTL 1h

Cachea SIEMPRE este bundle como prefijo system:

  1. CLAUDE.md completo (~3k tokens).
  2. references/brand-tokens.json (~500 tokens).
  3. Design system / Storybook export si existe (~5-30k tokens).
  4. Skill activations frecuentes (frontend-design, brand-guidelines) (~2k tokens cada).

Total típico: 10-40k tokens cacheados.

Tier 2: contexto de tarea con TTL 5m

Si dentro de una conversación hay un documento grande de referencia (mockup descrito, brief largo, transcripción de reunión), cachealo con TTL 5m. Si la sesión dura más de 5 min con interacciones cada <5min, sigue siendo hit.

Tier 3: sin cache

El user prompt mismo, los tool results variables.

Patrón TypeScript

import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic();
const DESIGN_SYSTEM = readFileSync('CLAUDE.md', 'utf-8')
  + '\n\n'
  + readFileSync('references/brand-tokens.json', 'utf-8');

async function generateComponent(prompt: string) {
  const res = await client.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 4000,
    system: [
      {
        type: 'text',
        text: DESIGN_SYSTEM,
        cache_control: { type: 'ephemeral', ttl: '1h' }
      }
    ],
    messages: [{ role: 'user', content: prompt }]
  });

  console.log('cache stats:', {
    write: res.usage.cache_creation_input_tokens,
    read: res.usage.cache_read_input_tokens,
    fresh_input: res.usage.input_tokens
  });

  return res.content;
}

Medición

usage.cache_read_input_tokens vs usage.cache_creation_input_tokens:

  • Hit rate = cache_read / (cache_read + cache_creation) debería ser >80% en sesiones de >5 turnos.
  • Si hit rate <50%, algo está cambiando el prefijo (timestamps, datos dinámicos, orden de mensajes).

Trampas comunes

1. Timestamps en el contexto cacheado

# MAL — el timestamp cambia cada request, invalida cache
system = f"Today is {datetime.now().isoformat()}. ..."

# BIEN — timestamp en user message
system = "..."
messages = [{"role": "user", "content": f"[{datetime.now()}] {prompt}"}]

2. Mensajes en orden inconsistente

El cache hash incluye la concatenación EXACTA. Reordenar tools o system blocks invalida.

3. Anidación incorrecta de cache_control

cache_control va en el bloque, no en el mensaje:

# MAL
{"role": "user", "content": "...", "cache_control": {...}}

# BIEN
{"role": "user", "content": [{"type": "text", "text": "...", "cache_control": {...}}]}

4. Cachear cosas pequeñas

Bajo ~1024 tokens (Sonnet) el overhead no compensa. Cachea bloques >2k tokens.

Batch API + caching

Para procesar lotes (e.g. 100 componentes con el mismo design system):

client.messages.batches.create(
    requests=[
        {
            "custom_id": f"comp-{i}",
            "params": {
                "model": "claude-sonnet-4-6",
                "max_tokens": 2000,
                "system": [{
                    "type": "text",
                    "text": DESIGN_SYSTEM,
                    "cache_control": {"type": "ephemeral", "ttl": "1h"}
                }],
                "messages": [{"role": "user", "content": prompts[i]}]
            }
        }
        for i in range(100)
    ]
)

Batch API ya da 50% off, combinable con caching → coste efectivo ~5% del input price.

Para Claude Code

Claude Code aplica caching automáticamente en CLAUDE.md y archivos abiertos. No necesitas configurarlo. Verifica en la barra de status que ves cached en el budget breakdown.

Para artifacts (Claudeception)

El proxy de Anthropic NO expone cache_control al cliente. No puedes cachear desde dentro del artifact. Diseña los prompts internos para ser cortos y autocontenidos.