Capítulo 6: Tokens, contexto y caché de prompts
Recorta el contexto que una petición no usa y mantén un prefijo estable que la caché pueda reutilizar.
Publicada el
Leer hasta 6 min completo
Visión general#
Los prompts crecen por motivos comprensibles: un ejemplo nuevo arregla un caso límite, otra instrucción mejora la consistencia y, en algún momento, la aplicación empieza a incluir la conversación entera para mantener la continuidad. Al final, cada petición lleva material que nadie sabe justificar con claridad.
Empieza por preguntarte por qué está ahí cada pieza de información. Una parte define la tarea, otra es evidencia y otra se repite porque la aplicación nunca aprendió a omitirla. Recortar el contexto irrelevante puede bajar el coste y dejar más claro el trabajo del modelo, siempre que se mantenga la evidencia de la que depende la respuesta.
La salida también cuenta. Si el producto necesita una categoría y una prioridad, un ensayo que explique la elección puede ser desperdicio. Especifica el formato exacto de salida, porque “sé conciso” es demasiado vago.
Práctica#
Inspecciona la petición real que se envía al modelo: instrucciones de sistema, ejemplos, definiciones de herramientas, pasajes recuperados e historial de la conversación, no solo el mensaje visible del usuario.
Para un asistente de soporte, puede bastar con la pregunta actual, la política aplicable y los datos relevantes de la cuenta, sin años de historial. Para la extracción, mejor un esquema explícito que explicaciones libres que el producto descarta. Conserva las excepciones, los identificadores originales y cualquier evidencia necesaria para que el resultado sea correcto.
Un ejemplo de coste con precios hipotéticos de 1 $ por millón de tokens de entrada y 4 $ por millón de tokens de salida:
| Antes | Después | |
|---|---|---|
| Tokens de entrada | 10.000 | 6.000 |
| Tokens de salida | 1.000 | 400 |
| Coste por llamada | 0,0140 $ | 0,0076 $ |
Es una reducción modelada del 45,7 % para la llamada, suponiendo que ambos resultados son igual de aceptables y que toda la entrada se cobra a precio sin caché.
La caché de prompts lo complica. Cuando muchas peticiones comparten un prefijo estable largo, un proveedor puede procesar y cobrar esa parte de otra forma, y un prompt más corto con datos dinámicos cerca del principio puede perder esa ventaja. Pon las instrucciones reutilizables y el material de referencia antes del contenido específico de cada petición cuando eso encaje con el comportamiento de caché del proveedor.
Imágenes, audio y documentos#
La entrada que no es texto sigue sus propias reglas de facturación. Las imágenes suelen convertirse en tokens según su resolución, a menudo dividiéndolas en teselas de tamaño fijo, así que una imagen más grande cuesta más aunque el detalle extra no ayude a la tarea. El audio se cuenta normalmente por duración o se convierte en tokens. Los PDF y otros documentos se procesan a menudo página a página, a veces como texto extraído y como imagen renderizada de cada página a la vez.
Unos cuantos hábitos mantienen estas entradas bajo control:
- Envía la resolución que necesita la tarea. Reduce las capturas de pantalla y las fotos, y recorta la zona que importa, como una tabla o un campo de un formulario.
- Evita enviar la misma imagen o página en cada turno. El historial de la conversación arrastra los adjuntos, así que guarda el primer resultado (una descripción, los campos extraídos o una transcripción) y haz referencia a él en los turnos siguientes.
- Cuando la tarea solo necesita el texto, extráelo con una herramienta de OCR barata o un parser de documentos y envía ese texto al modelo.
- Comprueba cómo cuenta el proveedor cada modalidad antes de estimar. Los tokens por imagen o por página varían según el proveedor y el modelo, y una estimación basada solo en texto puede desviarse mucho.
Ledgerline. Cada petición de soporte de Ledgerline llevaba un bloque de 6.000 tokens de texto de políticas, con el nombre del cliente y una marca de tiempo al principio. Mover los campos específicos de la petición al final convirtió el bloque de políticas en un prefijo estable que el proveedor guarda en caché, y el formato de respuesta pasó de prosa libre a una respuesta estructurada breve. Soporte baja de 420 $ a 330 $ al mes.
En profundidad#
Hay tres mecanismos fáciles de confundir:
| Mecanismo | Reutiliza | Qué ahorra |
|---|---|---|
| Caché de prompts del proveedor | Prefijo de entrada repetido | Cargos de entrada elegibles y/o procesamiento |
| Caché de prefijos del motor de servicio | KV cache almacenada de un prefijo compartido | Parte del cómputo de prefill |
| Caché de respuestas | Una salida anterior válida | Potencialmente la llamada de inferencia entera |
Con la caché de prompts o de prefijos, el modelo en general sigue teniendo que generar una respuesta nueva. Ayuda sobre todo cuando entradas compartidas largas se repiten a menudo. No hay un descuento universal. Las escrituras y lecturas de caché, los TTL, los tamaños mínimos y la elegibilidad varían según el proveedor y el modelo.
A modo de ejemplo: 10.000 tokens de entrada en caché a 0,10 $/M más 2.000 sin caché a 1 $/M cuestan 0,003 $, mientras que un prompt reescrito de 8.000 tokens sin caché cuesta 0,008 $. En este escenario, el prompt más corto cuesta más.
La caché de prefijos del motor de servicio funciona una capa por debajo. Cada petición construye una KV cache, el estado de atención de los tokens procesados hasta ese momento, y cada paso de decodificación la lee. La caché de prefijos, como la de vLLM, conserva la KV cache de un prefijo compartido y la reutiliza en peticiones posteriores que empiezan con los mismos tokens. Eso ahorra trabajo de prefill para el prefijo, pero el modelo sigue generando cada token de salida. En capacidad dedicada, el beneficio puede ser más rendimiento (throughput) y no una factura mensual menor.
Un límite de prompt estable en la práctica#
El patrón simplificado en Python de abajo está pensado para una API que admite mensajes normales de sistema y de usuario. El material compartido se mantiene estable y el contenido específico de la petición va al final. El código no garantiza un acierto de caché, que depende del proveedor que sirve el modelo, del modelo, de la longitud mínima elegible y de las peticiones anteriores.
SYSTEM = (
"You answer questions about our public API. "
"Use only the supplied reference material. "
"If the source does not answer the question, say what is missing."
)
# Versioned and stable across requests until the documentation changes.
DOCS_VERSION = "api-docs-v17"
REFERENCE = load_documentation(DOCS_VERSION)
def messages_for(question: str) -> list[dict[str, str]]:
return [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": f"Reference ({DOCS_VERSION}):\n{REFERENCE}"},
{"role": "user", "content": f"Question:\n{question}"},
]En una aplicación real, load_documentation representa tu propio cargador de documentos versionado. No insertes una marca de tiempo ni un ID de petición aleatorio antes del material de referencia, porque cambia el principio de la petición cada vez. Mantén estables también las definiciones de herramientas y su orden cuando el proveedor las incluya en el prefijo cacheable.
Comprueba los campos de tokens en caché que devuelve la API antes de dar por hecho el ahorro. Cuando un servicio cobra por las escrituras o el almacenamiento en caché, calcula el coste efectivo del ciclo completo de reutilización en lugar de multiplicar el descuento de caché anunciado por todos los tokens de entrada. Un prefijo estable merece la pena incluso sin caché, porque hace que los cambios en el prompt sean deliberados y revisables.
Referencias: Caché de prompts de OpenAI, Caché de Gemini, Caché de prefijos de vLLM, Caché de prompts de Anthropic, Entradas de imagen de OpenAI, Recuento de tokens multimedia de Gemini, Soporte de PDF de Anthropic.