
Mise en cache des invites avec l’API OpenAI : un didacticiel Python pratique et complet
Dans mon article précédent, Prompt Caching – qu’est-ce que c’est, comment cela fonctionne et comment cela peut vous faire économiser beaucoup d’argent et de temps lors de l’exécution d’applications basées sur l’IA avec un trafic élevé. Dans l’article d’aujourd’hui, je vous explique comment implémenter Prompt Caching spécifiquement à l’aide de l’API d’OpenAI, et nous discutons de certains pièges courants.
Un bref rappel sur la mise en cache des invites
Avant de nous salir les mains, revenons brièvement sur le concept exact de Prompt Caching. La mise en cache des invites est une fonctionnalité fournie dans les services API du modèle frontière comme API OpenAI ou L’API de Claude, qui permet de mettre en cache et de réutiliser des parties de l’entrée du LLM qui sont fréquemment répétées. Ces parties répétées peuvent être des invites système ou des instructions transmises au modèle à chaque fois lors de l’exécution d’une application d’IA, ainsi que tout autre contenu variable, comme la requête de l’utilisateur ou les informations extraites d’une base de connaissances. Pour pouvoir accéder au cache avec la mise en cache des invites, les parties répétées de l’invite doivent se trouver au début de celle-ci, à savoir un préfixe d’invite. De plus, pour que la mise en cache rapide soit activée, ce préfixe doit dépasser un certain seuil (par exemple, pour OpenAI, le préfixe doit être supérieur à 1 024 jetons, tandis que Claude a différentes longueurs de cache minimales pour différents modèles). Dans la mesure où ces deux conditions sont remplies (jetons répétés comme préfixe dépassant le seuil de taille défini par le service et le modèle API), la mise en cache peut être activée pour réaliser des économies d’échelle lors de l’exécution d’applications d’IA.
Contrairement à la mise en cache dans d’autres composants d’un RAG ou d’une autre application d’IA, la mise en cache des invites fonctionne au niveau du jeton, dans les procédures internes du LLM. En particulier, l’inférence LLM se déroule en deux étapes :
- Pré-remplirc’est-à-dire que le LLM prend en compte l’invite de l’utilisateur pour générer le premier jeton, et
- Décodagec’est-à-dire que le LLM génère de manière récursive les jetons de la sortie un par un
En bref, la mise en cache des invites stocke les calculs effectués lors de l’étape de pré-remplissage, de sorte que le modèle n’a pas besoin de les recalculer lorsque le même préfixe réapparaît. Tous les calculs effectués lors de la phase d’itérations de décodage, même s’ils sont répétés, ne seront pas mis en cache.
Pour le reste de l’article, je me concentrerai uniquement sur l’utilisation de la mise en cache des invites dans l’API OpenAI.
Qu’en est-il de l’API OpenAI ?
Dans l’API d’OpenAI, la mise en cache des invites a été initialement introduite sur le 1er octobre 2024. À l’origine, il offrait une réduction de 50 % sur les jetons mis en cache, mais aujourd’hui, cette réduction monte jusqu’à 90 %. De plus, en accédant à leur cache d’invites, des économies supplémentaires sur la latence peuvent être réalisées jusqu’à 80 %.
Lorsque la mise en cache des invites est activée, le service API tente d’accéder au cache pour une demande soumise en acheminant l’invite soumise vers une machine appropriée, où le cache correspondant est censé exister. C’est ce qu’on appelle le routage du cache et, pour ce faire, le service API utilise généralement un hachage des 256 premiers jetons de l’invite.
Au-delà de cela, leur API permet également de définir explicitement un prompt_cache_key paramètre dans la requête API au modèle. Il s’agit d’une clé unique définissant le cache auquel nous faisons référence, dans le but d’augmenter encore les chances que notre invite soit acheminée vers la bonne machine et atteigne le cache.
De plus, l’API OpenAI fournit deux types distincts de mise en cache en termes de durée, définis via le prompt_cache_retention paramètre. Ce sont :
- Rétention du cache des invites en mémoire: Il s’agit essentiellement du type de mise en cache par défaut, disponible pour tous les modèles pour lesquels la mise en cache rapide est disponible. Avec le cache en mémoire, les données mises en cache restent actives pendant une période de 5 à 10 minutes entre les requêtes.
- Rétention étendue du cache des invites: Ceci est disponible pour modèles spécifiques. Le cache étendu permet de conserver les données en cache pour l’enregistreur et jusqu’à un maximum de 24 heures.
Maintenant, en ce qui concerne le coût de tout cela, OpenAI facture le même jeton par entrée (non mis en cache), que la mise en cache rapide soit activée ou non. Si nous parvenons à accéder au cache avec succès, nous sommes facturés pour les jetons mis en cache à un prix considérablement réduit, avec une remise allant jusqu’à 90 %. De plus, le prix par jeton d’entrée reste le même pour la rétention en mémoire et le cache étendu.
Mise en cache rapide en pratique
Voyons donc comment la mise en cache des invites fonctionne réellement avec un simple exemple Python utilisant le service API d’OpenAI. Plus précisément, nous allons faire un scénario réaliste où un longue invite système (préfixe) est réutilisé sur plusieurs requêtes. Si vous êtes ici, je suppose que vous avez déjà votre OpenAI Clé API en place et avoir installé les bibliothèques requises. La première chose à faire serait donc d’importer le OpenAI bibliothèque, ainsi que time pour capturer la latence et initialiser une instance du client OpenAI :
from openai import OpenAI
import time
client = OpenAI(api_key="your_api_key_here")
alors nous pouvons définir notre préfixe (les jetons qui vont être répétés et que nous visons à mettre en cache) :
long_prefix = """
You are a highly knowledgeable assistant specialized in machine learning.
Answer questions with detailed, structured explanations, including examples when relevant.
""" * 200
Remarquez comment nous augmentons artificiellement la longueur (multipliez par 200) pour nous assurer que le seuil de mise en cache de 1 024 jetons est atteint. Ensuite, nous mettons également en place un timer afin de mesurer nos gains de latence, et nous sommes enfin prêts à passer notre appel :
start = time.time()
response1 = client.responses.create(
model="gpt-4.1-mini",
input=long_prefix + "What is overfitting in machine learning?"
)
end = time.time()
print("First response time:", round(end - start, 2), "seconds")
print(response1.output[0].content[0].text)

Alors, qu’attendons-nous d’ici ? Pour les modèles à partir de gpt-4o et plus récents, la mise en cache des invites est activée par défaut, et comme nos 4 616 jetons d’entrée sont bien au-dessus du seuil de 1 024 jetons de préfixe, nous sommes prêts à partir. Ainsi, ce que fait cette requête, c’est qu’elle vérifie d’abord si l’entrée est une réussite dans le cache (ce n’est pas le cas, puisque c’est la première fois que nous faisons une requête avec ce préfixe), et comme ce n’est pas le cas, elle traite l’intégralité de l’entrée puis la met en cache. La prochaine fois que nous enverrons une entrée qui correspond dans une certaine mesure aux jetons initiaux de l’entrée mise en cache, nous obtiendrons un accès au cache. Vérifions cela en pratique en faisant une deuxième requête avec le même préfixe :
start = time.time()
response2 = client.responses.create(
model="gpt-4.1-mini",
input=long_prefix + "What is regularization?"
)
end = time.time()
print("Second response time:", round(end - start, 2), "seconds")
print(response2.output[0].content[0].text)

En effet! La deuxième requête s’exécute beaucoup plus rapidement (23,31 contre 15,37 secondes). En effet, le modèle a déjà effectué les calculs pour le préfixe mis en cache et n’a plus qu’à traiter à partir de zéro la nouvelle partie « Qu’est-ce que la régularisation ? ». En conséquence, en utilisant la mise en cache rapide, nous obtenons une latence et un coût considérablement réduits, puisque les jetons mis en cache sont réduits.
Une autre chose mentionnée dans la documentation OpenAI dont nous avons déjà parlé est le prompt_cache_key paramètre. En particulier, selon la documentation, nous pouvons définir explicitement une clé de cache d’invite lors d’une requête, et ainsi définir les requêtes qui doivent utiliser le même cache. Néanmoins, j’ai essayé de l’inclure dans mon exemple en ajustant de manière appropriée les paramètres de la requête, mais je n’ai pas eu beaucoup de chance :
response1 = client.responses.create(
prompt_cache_key = 'prompt_cache_test1',
model="gpt-5.1",
input=long_prefix + "What is overfitting in machine learning?"
)

🤔
Il semble que pendant que prompt_cache_key existe dans les fonctionnalités de l’API, il n’est pas encore exposé dans le SDK Python. En d’autres termes, nous ne pouvons pas encore contrôler explicitement la réutilisation du cache, mais c’est plutôt automatique et au mieux.
Alors, qu’est-ce qui peut mal se passer ?
Activer la mise en cache des invites et accéder au cache semble être assez simple d’après ce que nous avons dit jusqu’à présent. Alors, qu’est-ce qui pourrait mal se passer, ce qui nous ferait manquer le cache ? Malheureusement, beaucoup de choses. Aussi simple soit-elle, la mise en cache rapide nécessite la mise en place de nombreuses hypothèses différentes. Manquer ne serait-ce qu’une de ces conditions préalables entraînera un échec du cache. Mais regardons de plus près !
Un échec évident est d’avoir un préfixe inférieur au seuil d’activation de la mise en cache des invites, à savoir moins de 1 024 jetons. Néanmoins, ce problème peut être très facilement résolu : nous pouvons toujours augmenter artificiellement le nombre de jetons de préfixe en le multipliant simplement par une valeur appropriée, comme le montre l’exemple ci-dessus.
Une autre chose serait de briser silencieusement le préfixe. En particulier, même lorsque nous utilisons des instructions persistantes et des invites système de taille appropriée pour toutes les requêtes, nous devons faire extrêmement attention à ne pas casser les préfixes en ajoutant un contenu variable au début de l’entrée du modèle, avant le préfixe. C’est un moyen garanti de briser le cache, quelle que soit la durée et la répétition du préfixe suivant. Les données dynamiques, par exemple l’ajout de l’ID utilisateur ou d’un horodatage au début de l’invite, sont généralement suspectes de tomber dans ce piège. Ainsi, une bonne pratique à suivre dans tout le développement d’applications d’IA est que tout contenu dynamique doit toujours être ajouté à la fin de l’invite, jamais au début.
En fin de compte, il convient de souligner que la mise en cache des invites ne concerne que la phase de pré-remplissage : le décodage n’est jamais mis en cache. Cela signifie que même si nous imposons au modèle de générer des réponses selon un modèle spécifique, qui commence avec certains jetons fixes, ces jetons ne seront pas mis en cache et nous serons facturés pour leur traitement comme d’habitude.
À l’inverse, pour des cas d’utilisation spécifiques, cela n’a pas vraiment de sens d’utiliser la mise en cache des invites. De tels cas seraient des invites très dynamiques, comme des chatbots peu répétitifs, des demandes ponctuelles ou des systèmes personnalisés en temps réel.
. . .
Dans mon esprit
La mise en cache rapide peut améliorer considérablement les performances des applications d’IA, tant en termes de coût que de temps. En particulier lorsque l’on cherche à faire évoluer les applications d’IA, la mise en cache rapide s’avère extrêmement pratique, pour maintenir les coûts et la latence à des niveaux acceptables.
Pour l’API d’OpenAI, la mise en cache des invites est activée par défaut et les coûts de saisie, les jetons non mis en cache sont les mêmes, que nous activions ou non la mise en cache des invites. Ainsi, on ne peut gagner qu’en activant la mise en cache des invites et en visant à l’atteindre à chaque requête, même si elle échoue.
Claude fournit également des fonctionnalités étendues de mise en cache des invites via leur API, que nous allons explorer en détail dans un prochain article.
Merci d’avoir lu! 🙂
. . .
Vous avez adoré cet article ? Soyons amis ! Rejoignez-moi sur :
📰Sous-pile 💌 Moyen 💼LinkedIn ☕Achetez-moi un café!
Toutes les images sont de l’auteur, sauf mention contraire.



