Prompt caching: la técnica que baja tu factura de IA a la mitad

By Carlos Montiel | Especialista en IA Empresarial
Publicado: 2026-07-28 | Por: Carlos Montiel | Lectura: ~7 minutos

Prompt caching no es un flag mágico que activas y ya. Es una técnica con una mecánica muy específica — y si no entiendes esa mecánica, vas a implementarlo y seguir pagando precio completo sin saber por qué.

La regla que lo explica todo: es un prefix match

El caching de prompts funciona sobre coincidencia de prefijo exacto. Esto significa que el sistema toma los bytes exactos del prompt renderizado hasta un punto de corte (`cache_control`) y los compara con la ejecución anterior. Si un solo byte cambia en cualquier parte de ese prefijo, todo lo que viene después de ese punto se invalida — no solo la parte que cambió.

El orden de renderizado es siempre: herramientas (`tools`) → prompt de sistema (`system`) → mensajes (`messages`). Un breakpoint puesto al final del bloque de sistema cachea tools + system juntos.

Esto tiene una implicación práctica enorme: el contenido estable debe ir *físicamente antes* que el contenido volátil en tu prompt renderizado. Si metes la fecha actual o un UUID al principio del system prompt, invalidas el caché en cada request sin importar cuántos `cache_control` pongas después.

Cómo se ve en código

response = client.messages.create( model="claude-opus-4-8", max_tokens=1024, system=[{ "type": "text", "text": prompt_de_sistema_grande, # instrucciones, ejemplos, políticas "cache_control": {"type": "ephemeral"}, # TTL por defecto: 5 minutos }], messages=[{"role": "user", "content": pregunta_del_usuario}], ) # Verifica que realmente esté funcionando print(response.usage.cache_creation_input_tokens) # se escribió al caché print(response.usage.cache_read_input_tokens) # se leyó del caché (barato) print(response.usage.input_tokens) # no cacheado (precio completo)

Para TTL de una hora en vez de cinco minutos: `{"type": "ephemeral", "ttl": "1h"}`. El máximo son 4 breakpoints por request, y se pueden poner en cualquier bloque de contenido: texto del sistema, definiciones de herramientas, o bloques dentro de los mensajes.

La economía real, no la intuición

Un cache read cuesta aproximadamente 10% del precio de input normal. Pero un cache write no es gratis: cuesta 1.25x el precio normal con TTL de 5 minutos, y 2x con TTL de 1 hora. Esto significa que el punto de equilibrio depende de cuántas veces vas a reutilizar ese prefijo:

- Con TTL de 5 minutos: necesitas al menos 2 requests para salir ganando (1.25x + 0.10x = 1.35x, contra 2x sin cachear). - Con TTL de 1 hora: necesitas al menos 3 requests (2x + 0.20x = 2.2x, contra 3x sin cachear).

Si tu prefijo compartido solo se usa una vez, cachearlo te cuesta más, no menos. La técnica solo paga cuando hay reutilización real — sesiones de chat multi-turno, el mismo documento de contexto consultado repetidamente, o el mismo set de herramientas en un agente que hace muchas llamadas.

Dónde poner el breakpoint según el patrón de uso

**System prompt compartido entre muchas requests.** Un breakpoint en el último bloque de texto del system prompt cachea tools + system juntos — el patrón más simple y el de mayor impacto en la mayoría de las apps.

**Conversaciones multi-turno.** Pon el breakpoint en el último bloque de contenido del turno más reciente. Cada request subsecuente reutiliza todo el prefijo previo de la conversación; los breakpoints anteriores siguen siendo puntos de lectura válidos, así que los hits se acumulan de forma incremental conforme crece la conversación.

**Prefijo compartido con sufijo variable** (few-shot examples + pregunta distinta cada vez, o contexto recuperado + pregunta del usuario): el breakpoint va al final de la parte *compartida*, no al final del prompt completo.

messages = [{"role": "user", "content": [ {"type": "text", "text": contexto_compartido, "cache_control": {"type": "ephemeral"}}, {"type": "text", "text": pregunta_variable} # sin marcador — cambia siempre ]}]

El checklist de invalidadores silenciosos

Cuando el caching "no funciona" (`cache_read_input_tokens` en cero request tras request), casi siempre es uno de estos:

| Patrón | Por qué rompe el caché | |---|---| | `datetime.now()` en el system prompt | El prefijo cambia en cada request | | UUIDs o IDs de request al inicio del contenido | Mismo problema — cada request es única | | `json.dumps(d)` sin `sort_keys=True`, o iterar un `set` | Serialización no determinista → los bytes difieren aunque el contenido sea "el mismo" | | Secciones condicionales de sistema (`if flag: system += ...`) | Cada combinación de flags es un prefijo distinto | | Set de herramientas que varía por usuario | Las herramientas se renderizan en la posición 0 — nada cachea entre usuarios distintos |

La forma de diagnosticar esto es simple: compara byte a byte el prompt renderizado entre dos requests que "deberían" ser idénticas. En el 90% de los casos el problema salta a la vista en los primeros 500 caracteres.

Jerarquía de invalidación — no todo rompe todo

No todos los cambios invalidan el caché completo. Hay tres niveles: caché de herramientas, de sistema, y de mensajes. Cambiar `tool_choice`, activar/desactivar `thinking`, o agregar imágenes invalida sistema y mensajes pero no herramientas. Cambiar el modelo o la definición de una herramienta sí invalida todo. Saber esto evita el error de asumir que cualquier ajuste menor te obliga a reconstruir el caché desde cero.

Pre-calentar el caché antes de que llegue tráfico real

Si la latencia del primer request es visible para el usuario (chat interactivo, no un job en batch), puedes eliminar el costo de ese primer cache-miss enviando una request con `max_tokens: 0` al arrancar tu servicio. El sistema ejecuta el prefill — escribe el caché en tu breakpoint — y regresa de inmediato sin cobrar tokens de salida.

client.messages.create( model="claude-opus-4-8", max_tokens=0, system=[{ "type": "text", "text": system_prompt, "cache_control": {"type": "ephemeral"}, }], messages=[{"role": "user", "content": "warmup"}], )

Solo vale la pena si tu tráfico tiene huecos más largos que el TTL del caché — si las requests reales llegan cada menos de 5 minutos, ya se mantienen calientes solas y un pre-calentamiento adicional es puro gasto extra.

Bien implementado, el prompt caching es la optimización de costo con mayor retorno por hora de trabajo en cualquier arquitectura de LLM en producción — pero solo si entiendes la mecánica de prefijo lo suficiente para no romperla sin darte cuenta.

Carlos Montiel
Arquitecto de Soluciones IA Empresarial
Especialista en LLMs, Agentes y Orquestación
guatemalia.com/#contacto · info@guatemalia.com

¿Necesitas implementar IA en tu empresa?

Carlos Montiel es arquitecto de soluciones IA empresarial. Implementa LLMs, Agentes, RAG y orquestadores en empresas de Guatemala y Latinoamérica. Contáctalo para una consultoría.

Contactar a Carlos Montiel

info@guatemalia.com