Almacenamiento en caché rápido con la API OpenAI: un tutorial práctico completo de Python

En mi publicación anterior, Prompt Caching: qué es, cómo funciona y cómo puede ahorrarle mucho dinero y tiempo al ejecutar aplicaciones impulsadas por IA con mucho tráfico. En la publicación de hoy, lo guío en la implementación de Prompt Caching específicamente usando la API de OpenAI y analizamos algunos errores comunes.

Un breve recordatorio sobre el almacenamiento en caché rápido

Antes de ensuciarnos las manos, revisemos brevemente cuál es exactamente el concepto de Prompt Caching. Prompt Caching es una funcionalidad proporcionada en servicios API de modelo fronterizo como OpenAI API o Claude’s API, que permite almacenar en caché y reutilizar partes de la entrada del LLM que se repiten con frecuencia. Estas partes repetidas pueden ser indicaciones del sistema o instrucciones que se pasan al modelo cada vez que se ejecuta una aplicación de IA, junto con cualquier otro contenido variable, como la consulta del usuario o la información recuperada de una base de conocimiento. Para poder acceder al caché con el almacenamiento en caché del mensaje, las partes repetidas del mensaje deben estar al principio, es decir, un prefijo del mensaje. Además, para que se active el almacenamiento en caché rápido, este prefijo debe exceder un cierto umbral (por ejemplo, para OpenAI el prefijo debe ser más de 1024 tokens, mientras que Claude tiene diferentes longitudes mínimas de caché para diferentes modelos). En la medida en que se cumplan esas dos condiciones (tokens repetidos como prefijo que exceden el umbral de tamaño definido por el servicio y modelo API), el almacenamiento en caché se puede activar para lograr economías de escala al ejecutar aplicaciones de IA.

A diferencia del almacenamiento en caché en otros componentes de un RAG u otra aplicación de IA, el almacenamiento en caché rápido opera a nivel de token, en los procedimientos internos del LLM. En particular, la inferencia LLM se lleva a cabo en dos pasos:

Precompletar, es decir, el LLM tiene en cuenta la solicitud del usuario para generar el primer token, y Decodificación, es decir, el LLM genera recursivamente los tokens de salida uno por uno.

En resumen, el almacenamiento en caché rápido almacena los cálculos que tienen lugar en la etapa de prellenado, por lo que el modelo no necesita volver a calcularlo cuando reaparece el mismo prefijo. Cualquier cálculo que se realice en la fase de iteraciones de decodificación, incluso si se repite, no se almacenará en caché.

Durante el resto de la publicación, me centraré únicamente en el uso del almacenamiento en caché de avisos en la API de OpenAI.

¿Qué pasa con la API OpenAI?

En la API de OpenAI, el almacenamiento en caché rápido se introdujo inicialmente el 1 de octubre de 2024. Originalmente, ofrecía un descuento del 50% en los tokens almacenados en caché, pero hoy en día, este descuento sube al 90%. Además de esto, al acceder a su caché de avisos, se pueden lograr ahorros adicionales en latencia de hasta un 80%.

Cuando se activa el almacenamiento en caché de mensajes, el servicio API intenta acceder al caché para una solicitud enviada enrutando el mensaje enviado a una máquina adecuada, donde se espera que exista el caché respectivo. Esto se denomina enrutamiento de caché y, para ello, el servicio API normalmente utiliza un hash de los primeros 256 tokens del mensaje.

Más allá de esto, su API también permite definir explícitamente el parámetro Prompt_cache_key en la solicitud de API al modelo. Se trata de una clave única que define a qué caché nos referimos, con el objetivo de aumentar aún más las posibilidades de que nuestro mensaje se dirija a la máquina correcta y acceda al caché.

Además, la API de OpenAI proporciona dos tipos distintos de almacenamiento en caché con respecto a la duración, definidos a través del parámetro Prompt_cache_retention. Esos son:

Retención de caché de avisos en memoria: este es esencialmente el tipo de almacenamiento en caché predeterminado, disponible para todos los modelos para los cuales el almacenamiento en caché de avisos está disponible. Con la caché en memoria, los datos almacenados en caché permanecen activos durante un período de 5 a 10 minutos entre solicitudes. Retención de caché de aviso extendida: está disponible para modelos específicos. La caché extendida permite mantener los datos en la caché durante más tiempo y hasta un máximo de 24 horas.

Ahora, con respecto a cuánto cuestan todos estos, OpenAI cobra lo mismo por token de entrada (no almacenado en caché), ya sea que tengamos el almacenamiento en caché activado o no. Si logramos acceder al caché con éxito, se nos facturarán los tokens almacenados en caché a un precio muy reducido, con un descuento de hasta el 90%. Además, el precio por token de entrada sigue siendo el mismo tanto para la retención en memoria como para la retención de caché extendida.

Almacenamiento en caché rápido en la práctica

Entonces, veamos cómo funciona realmente el almacenamiento en caché de avisos con un ejemplo simple de Python que utiliza el servicio API de OpenAI. Más específicamente, vamos a crear un escenario realista en el que se reutiliza un mensaje de sistema largo (prefijo) en múltiples solicitudes. Si está aquí, supongo que ya tiene su clave API de OpenAI y ha instalado las bibliotecas necesarias. Entonces, lo primero que debemos hacer sería importar la biblioteca OpenAI, así como el tiempo para capturar la latencia, e inicializar una instancia del cliente OpenAI:

desde openai import OpenAI tiempo de importación cliente = OpenAI(api_key=”your_api_key_here”)

luego podemos definir nuestro prefijo (los tokens que se van a repetir y que pretendemos almacenar en caché):

long_prefix = “”” Eres un asistente altamente capacitado y especializado en aprendizaje automático. Responde preguntas con explicaciones detalladas y estructuradas, incluidos ejemplos cuando sea relevante. “”” * 200

Observe cómo aumentamos artificialmente la longitud (multiplicada por 200) para asegurarnos de que se cumpla el umbral de almacenamiento en caché de 1024 tokens. Luego también configuramos un temporizador para medir nuestro ahorro de latencia y finalmente estamos listos para realizar nuestra llamada:

inicio = time.time() respuesta1 = client.responses.create( model=”gpt-4.1-mini”, input=long_prefix + “¿Qué es el sobreajuste en el aprendizaje automático?” ) end = time.time() print(“Primer tiempo de respuesta:”, round(end – start, 2), “segundos”) print(response1.output[0].contenido[0].texto)

Entonces, ¿qué esperamos que suceda a partir de ahora? Para los modelos gpt-4o y posteriores, el almacenamiento en caché rápido está activado de forma predeterminada y, dado que nuestros 4616 tokens de entrada están muy por encima del umbral de 1024 tokens de prefijo, estamos listos para comenzar. Por lo tanto, lo que hace esta solicitud es que inicialmente verifica si la entrada es un acierto de caché (no lo es, ya que es la primera vez que hacemos una solicitud con este prefijo) y, como no lo es, procesa toda la entrada y luego la almacena en caché. La próxima vez que enviemos una entrada que coincida hasta cierto punto con los tokens iniciales de la entrada almacenada en caché, obtendremos un acierto de caché. Comprobemos esto en la práctica haciendo una segunda solicitud con el mismo prefijo:

inicio = time.time() respuesta2 = client.responses.create( model=”gpt-4.1-mini”, input=long_prefix + “¿Qué es la regularización?” ) end = time.time() print(“Tiempo de segunda respuesta:”, round(end – start, 2), “segundos”) print(response2.output[0].contenido[0].texto)

¡En efecto! La segunda solicitud se ejecuta significativamente más rápido (23,31 frente a 15,37 segundos). Esto se debe a que el modelo ya realizó los cálculos para el prefijo almacenado en caché y solo necesita procesar desde cero la nueva parte, “¿Qué es la regularización?”. Como resultado, al utilizar el almacenamiento en caché rápido, obtenemos una latencia significativamente menor y un costo reducido, ya que los tokens almacenados en caché tienen descuento.

Otra cosa mencionada en la documentación de OpenAI de la que ya hemos hablado es el parámetro Prompt_cache_key. En particular, según la documentación, podemos definir explícitamente una clave de caché de solicitud al realizar una solicitud y, de esta manera, definir las solicitudes que deben usar el mismo caché. No obstante, intenté incluirlo en mi ejemplo ajustando adecuadamente los parámetros de la solicitud, pero no tuve mucha suerte:

respuesta1 = client.responses.create( Prompt_cache_key = ‘prompt_cache_test1’, model=”gpt-5.1″, input=long_prefix + “¿Qué es el sobreajuste en el aprendizaje automático?”)

🤔

Parece que si bien Prompt_cache_key existe en las capacidades de la API, aún no está expuesto en el SDK de Python. En otras palabras, todavía no podemos controlar explícitamente la reutilización de la caché, pero es más bien automática y de mejor esfuerzo.

Entonces, ¿qué puede salir mal?

Activar el almacenamiento en caché de aviso y acceder al caché parece ser bastante sencillo por lo que hemos dicho hasta ahora. Entonces, ¿qué puede salir mal y hacer que nos perdamos el caché? Desgraciadamente, muchas cosas. Por muy sencillo que sea, el almacenamiento en caché rápido requiere que se cumplan muchas suposiciones diferentes. Si falta incluso uno de esos requisitos previos, se producirá una pérdida de caché. ¡Pero echemos un vistazo mejor!

Un error obvio es tener un prefijo menor que el umbral para activar el almacenamiento en caché de avisos, es decir, menos de 1024 tokens. No obstante, esto se puede resolver muy fácilmente: siempre podemos aumentar artificialmente el recuento de tokens de prefijo simplemente multiplicándolo por un valor apropiado, como se muestra en el ejemplo anterior.

Otra cosa sería romper silenciosamente el prefijo. En particular, incluso cuando usamos instrucciones persistentes y mensajes del sistema de tamaño apropiado en todas las solicitudes, debemos tener mucho cuidado de no romper los prefijos agregando contenido variable al comienzo de la entrada del modelo, antes del prefijo. Esa es una forma garantizada de romper el caché, sin importar cuán largo y repetido sea el siguiente prefijo. Los sospechosos habituales de caer en este error son los datos dinámicos, por ejemplo, añadir el ID de usuario o las marcas de tiempo al principio del mensaje. Por lo tanto, una de las mejores prácticas a seguir en todo el desarrollo de aplicaciones de IA es que cualquier contenido dinámico siempre debe agregarse al final del mensaje, nunca al principio.

En última instancia, vale la pena resaltar que el almacenamiento en caché de avisos solo se refiere a la fase de precarga: la decodificación nunca se almacena en caché. Esto significa que incluso si imponemos al modelo que genere respuestas siguiendo una plantilla específica, que comienza con ciertos tokens fijos, esos tokens no se almacenarán en caché y se nos facturará por su procesamiento como de costumbre.

Por el contrario, para casos de uso específicos, realmente no tiene sentido utilizar el almacenamiento en caché de avisos. Estos casos serían mensajes muy dinámicos, como chatbots con poca repetición, solicitudes únicas o sistemas personalizados en tiempo real.

. . .

en mi mente

El almacenamiento en caché rápido puede mejorar significativamente el rendimiento de las aplicaciones de IA tanto en términos de costo como de tiempo. En particular, cuando se busca escalar aplicaciones de IA, el almacenamiento en caché de avisos resulta extremadamente útil para mantener el costo y la latencia en niveles aceptables.

Para la API de OpenAI, el almacenamiento en caché de avisos se activa de forma predeterminada y los costos de entrada, los tokens no almacenados en caché son los mismos, ya sea que activemos el almacenamiento en caché de avisos o no. Por lo tanto, sólo se puede ganar activando el almacenamiento en caché rápido y apuntando a alcanzarlo en cada solicitud, incluso si no se logra.

Claude también proporciona una amplia funcionalidad sobre el almacenamiento en caché de avisos a través de su API, que exploraremos en detalle en una publicación futura.

¡Gracias por leer! 🙂

. . .

¿Te encantó esta publicación? ¡Seamos amigos! Únase a mí en:

📰Substack 💌 Medio 💼LinkedIn ☕¡Cómprame un café!

Todas las imágenes del autor, salvo que se indique lo contrario.