Source: https://aiprimetech.io/fr/blog/prompt-caching-explained/ Juin 17, 2026 · 6 min · API # Comprendre la mise en cache des prompts : quand elle permet des économies et quand ce n’est pas le cas A Par [AI Prime Tech](https://aiprimetech.io/fr/) · Avec l’aide de l’IA Un lundi à 9:12 du matin, l’un de nos agents d’assistance a commencé à coûter 4x de plus que prévu. Le modèle n’hallucinait pas, le graphique du trafic était correct et personne n’avait accidentellement remplacé Haiku par Opus. Le problème était plus simple : chaque requête incluait le même manuel de procédures de 42,000 tokens, mais notre taux de succès du cache de prompts était pratiquement nul, car nous ajoutions un nouvel horodatage et des métadonnées propres à l’utilisateur avant le manuel. Même contenu. Même modèle. Même application. Aucune économie grâce au cache. La mise en cache des prompts fait partie de ces fonctionnalités qui semblent automatiques jusqu’à ce que l’on essaie de faire baisser la facture. En pratique, elle favorise une structure de prompt très précise : un long préfixe stable, réutilisé dans de nombreuses requêtes. Si vous comprenez cette phrase, vous pouvez généralement prévoir si la mise en cache vous fera économiser ou si elle n’aura discrètement aucun effet. ## Ce que la mise en cache des prompts met réellement en cache La mise en cache des prompts n’est pas une mémoire sémantique. Le fournisseur ne dit pas : « Cela ressemble à quelque chose que vous avez envoyé auparavant. » Son fonctionnement est plutôt le suivant : « Le début de cette requête correspond suffisamment à une séquence de tokens précédente, pour ce modèle et cette politique de cache, pour que nous puissions réutiliser les calculs internes associés à ce préfixe. » Cette distinction est importante. La mise en cache des prompts est généralement utile lorsque vous envoyez à plusieurs reprises le même long préfixe : - Instructions système - Schémas des outils - Longs ensembles de documents - Catalogues de produits - Contexte de la base de code - Manuels juridiques ou de procédures - Exemples few-shot - Résultats de recherche statiques réutilisés dans de nombreuses requêtes Elle est généralement peu utile lorsque chaque requête commence différemment : - Horodatages dynamiques en tête - Données propres à l’utilisateur avant le contenu partagé - Ordre des exemples aléatoire - UUID propres à chaque requête dans la section pouvant être mise en cache - Fragments récupérés dont l’ordre ou le format change - Historique de conversation placé avant les instructions stables Le principe technique essentiel consiste à placer d’abord le contexte stable et coûteux, puis le contexte variable. ## Anthropic et OpenAI : un objectif similaire, des contrôles différents Anthropic et OpenAI prennent tous deux en charge la mise en cache des prompts, mais l’ergonomie pour les développeurs diffère. Anthropic expose la mise en cache des prompts de manière plus explicite. Vous pouvez associer des contrôles de cache aux blocs de contenu, puis examiner des champs d’utilisation tels que cache_creation_input_tokens et cache_read_input_tokens. Cela permet de déterminer plus facilement si vous créez des entrées de cache ou si vous lisez des entrées existantes. La mise en cache des prompts d’OpenAI est plus automatique sur les modèles compatibles. Lorsqu’un préfixe de prompt est réutilisé, les tokens d’entrée en cache peuvent être facturés différemment et apparaître dans les métadonnées d’utilisation. En général, vous ne placez pas de points de délimitation explicites du cache de la même manière ; vous structurez plutôt les requêtes pour que le préfixe réutilisable reste identique au niveau des octets et des tokens. La différence pratique se situe entre contrôle et simplicité. | Dimension | Mise en cache explicite de type Anthropic | Mise en cache automatique de type OpenAI | Contrôle du développeur | Plus élevé ; vous pouvez désigner les blocs à mettre en cache | Plus faible ; le fournisseur détecte les préfixes réutilisables | Facilité de débogage | Généralement meilleure grâce aux compteurs de création et de lecture du cache | Dépend des métadonnées d’utilisation exposées par le modèle ou l’API | Importance de la structure du prompt | Très élevée | Très élevée | Usage le plus adapté | Grands blocs statiques, outils, documents, exemples | Longs préfixes réutilisés lors d’appels répétés | Cause fréquente d’échec | Point de délimitation du cache placé après du contenu dynamique | Le préfixe change avant qu’une correspondance avec le cache puisse être établie | Modèle mental | « J’écris et je lis un préfixe plus ou moins nommé » | « Le fournisseur reconnaît ce préfixe répété » Les détails de mise en œuvre varient selon le modèle et le fournisseur, et continuent d’évoluer. Mais la règle d’architecture reste stable : la mise en cache repose sur des préfixes répétés, pas sur des prompts similaires. ## Le modèle de tarification : création et lecture Pour comprendre la mise en cache des prompts, il est utile de répartir les tokens d’entrée en trois catégories : - Tokens d’entrée normaux : facturés au tarif habituel des tokens d’entrée. - Tokens de création du cache : tokens utilisés pour créer une entrée de cache, souvent facturés à un tarif majoré ou à un tarif d’écriture spécifique. - Tokens de lecture du cache : tokens lus depuis une entrée de cache existante, généralement facturés à un tarif réduit. Anthropic expose directement cette distinction au moyen de champs d’utilisation tels que : ``` { "usage": { "input_tokens": 812, "cache_creation_input_tokens": 42000, "cache_read_input_tokens": 0, "output_tokens": 684 } } ``` Lors d’une requête ultérieure, si le préfixe est trouvé dans le cache, vous devriez obtenir quelque chose de plus proche de ceci : ``` { "usage": { "input_tokens": 936, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 42000, "output_tokens": 711 } } ``` Le premier appel crée le cache. Les appels suivants le lisent. L’intérêt économique dépend des tarifs actuels du fournisseur, de la durée de vie du cache et du modèle. Comme les prix changent, je préfère modéliser cela avec des variables dans le code plutôt que d’inscrire des chiffres en dur dans les documents de conception. Voici une petite fonction Python que j’utilise pour déterminer si la mise en cache mérite d’être implémentée pour une route : ``` def cache_savings( cached_tokens: int, normal_input_per_mtok: float, cache_write_per_mtok: float, cache_read_per_mtok: float, requests: int, ) -> dict: mtok = cached_tokens / 1_000_000 no_cache = requests * mtok * normal_input_per_mtok with_cache = ( mtok * cache_write_per_mtok + (requests - 1) * mtok * cache_read_per_mtok ) return { "no_cache": round(no_cache, 6), "with_cache": round(with_cache, 6), "savings": round(no_cache - with_cache, 6), "savings_pct": round((1 - with_cache / no_cache) * 100, 2), } print(cache_savings( cached_tokens=42_000, normal_input_per_mtok=3.00, cache_write_per_mtok=3.75, cache_read_per_mtok=0.30, requests=100, )) ``` Les tarifs utilisés ici sont purement illustratifs. C’est la structure qui compte. Avec un préfixe réutilisable de 42,000 tokens et 100 requêtes, la mise en cache est généralement très avantageuse. Avec le même préfixe et une seule requête, elle peut coûter plus cher si le tarif d’écriture est supérieur au tarif normal des tokens d’entrée. C’est le premier grand piège : la mise en cache des prompts repose sur l’amortissement. Si vous ne réutilisez pas le préfixe en cache, vous n’en tirez aucun bénéfice. ## La formule du seuil de rentabilité Vous pouvez estimer le seuil de rentabilité avec : ``` no_cache_cost = N * T * normal_price cache_cost = T * write_price + (N - 1) * T * read_price ``` Où : - N est le nombre de requêtes utilisant le même préfixe - T est le nombre de tokens pouvant être mis en cache - normal_price est le tarif normal des tokens d’entrée - write_price est le tarif de création du cache - read_price est le tarif de lecture du cache La mise en cache permet d’économiser lorsque : ``` T * write_price + (N - 1) * T * read_price < N * T * normal_price ``` Le T s’annule dans le calcul du seuil de rentabilité purement financier, ce qui signifie que le nombre de réutilisations et les tarifs relatifs déterminent la décision. Mais le nombre de tokens reste important sur le plan opérationnel : économiser 80 % sur 500 tokens est négligeable ; réaliser cette économie sur 80,000 tokens représente un poste budgétaire. Une approximation utile pour un calcul rapide : ``` break_even_requests = (write_price - read_price) / (normal_price - read_price) ``` Si les écritures dans le cache ne coûtent que légèrement plus cher que les tokens d’entrée normaux et que les lectures sont beaucoup moins chères, le seuil de rentabilité peut être très bas. Si les écritures sont coûteuses ou si votre préfixe se répète rarement, la rentabilité de la mise en cache est fragile. ## Comment structurer les prompts pour obtenir des préfixes stables La meilleure optimisation de la mise en cache des prompts ne repose pas sur un paramètre de l’API. Elle repose sur l’agencement du prompt. Mauvais agencement : ``` Request ID: req_8f19a Current time: 2026-02-14T09:12:33Z User: customer_4812 Locale: en-US SYSTEM INSTRUCTIONS: ... POLICY MANUAL: [42,000 tokens of stable text] USER QUESTION: Can I get a refund after 45 days? ``` Cela empêche la mise en cache du préfixe, car le prompt diverge dès le début. Meilleur agencement : ``` SYSTEM INSTRUCTIONS: ... POLICY MANUAL: [42,000 tokens of stable text] DYNAMIC REQUEST METADATA: Request ID: req_8f19a Current time: 2026-02-14T09:12:33Z User: customer_4812 Locale: en-US USER QUESTION: Can I get a refund after 45 days? ``` Le bloc stable vient en premier. Le bloc dynamique vient ensuite. Pour une mise en cache explicite de type Anthropic, la structure peut conceptuellement ressembler à ceci : ``` { "model": "claude-sonnet-4-6", "max_tokens": 800, "system": [ { "type": "text", "text": "You are a support policy assistant..." }, { "type": "text", "text": "Refund policy manual v2026-02-01:\n\n...", "cache_control": { "type": "ephemeral" } } ], "messages": [ { "role": "user", "content": "Can I get a refund after 45 days?" } ] } ``` Le schéma exact de la requête varie selon la version de l’API et le SDK ; considérez donc ceci comme une structure plutôt que comme du code à copier-coller. L’essentiel est que le grand bloc stable soit explicitement défini comme pouvant être mis en cache et reste inchangé entre les appels. Pour une mise en cache automatique de type OpenAI, la structure du prompt compte tout autant, même si vous ne désignez pas manuellement un bloc : ``` { "model": "gpt-5.5", "messages": [ { "role": "system", "content": "You are a support policy assistant...\n\nRefund policy manual v2026-02-01:\n\n..." }, { "role": "user", "content": "Can I get a refund after 45 days?" } ] } ``` Si le message système change à chaque requête, ne vous attendez pas à des lectures régulières depuis le cache. ## Un modèle d’architecture pratique Pour les systèmes en production, j’aime rendre les préfixes de prompts en cache explicites dans le code de l’application. Un modèle simple : ``` prompt_prefix/ support_policy_v17.txt tool_schema_v4.json examples_v9.md runtime_request/ user_question user_profile retrieved_recent_orders ``` Composez ensuite les requêtes de cette manière : ``` from pathlib import Path POLICY_PREFIX = Path("prompt_prefix/support_policy_v17.txt").read_text() TOOL_SCHEMA = Path("prompt_prefix/tool_schema_v4.json").read_text() EXAMPLES = Path("prompt_prefix/examples_v9.md").read_text() def build_prompt(user_question: str, user_profile: dict) -> str: stable_prefix = f""" You are a support policy assistant. TOOLS: {TOOL_SCHEMA} POLICY: {POLICY_PREFIX} EXAMPLES: {EXAMPLES} """.strip() dynamic_suffix = f""" USER PROFILE: {user_profile} USER QUESTION: {user_question} """.strip() return stable_prefix + "\n\n--- DYNAMIC REQUEST ---\n\n" + dynamic_suffix ``` En pratique, j’attribue aussi une version au préfixe. Si le manuel de procédures change, je veux que cela constitue un événement délibéré d’invalidation du cache : ``` sha256sum prompt_prefix/support_policy_v17.txt ``` Cette empreinte apparaît dans les journaux à côté du nom du modèle, des tokens de création du cache, des tokens de lecture du cache et de la route de la requête. Sans cette observabilité, les bugs de cache sont pénibles, car la réponse fonctionne toujours ; elle coûte simplement plus cher. Une ligne de journal utile ressemble à ceci : ``` { "route": "support.answer", "model": "claude-sonnet-4-6", "prefix_hash": "9d3a4a...", "input_tokens": 932, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 42000, "output_tokens": 688, "latency_ms": 1840 } ``` Ne vous appuyez pas uniquement sur la facturation pour optimiser. Consignez le comportement du cache pour chaque route. ## Latence : souvent améliorée, mais sans magie La mise en cache des prompts peut réduire la latence, car le fournisseur du modèle peut réutiliser les calculs associés au préfixe en cache. Mais je ne définirais pas un SLA en supposant une réduction fixe de la latence sans l’avoir mesurée sur ma propre charge de travail. Ce qui se passe réellement en production est plus complexe : - Les prompts courts peuvent ne présenter aucun changement significatif de latence. - Les longs préfixes mis en cache améliorent souvent le délai avant le premier token. - La longueur de la sortie reste le facteur dominant pour de nombreuses requêtes. - Les appels d’outils, la latence réseau et la mise en file d’attente peuvent masquer les avantages du cache. - Les défauts de cache provoquent des pics de latence extrême si les écritures sont plus lentes que les lectures. Un protocole de benchmark réaliste est simple : ``` # warm cache python run_eval.py --case support_refund --repeat 1 # measure cache reads python run_eval.py --case support_refund --repeat 50 --jsonl out.jsonl # inspect p50/p95 by cache_read_input_tokens > 0 python analyze_latency.py out.jsonl ``` Mesurez séparément les requêtes avec succès et avec défaut de cache. Les regrouper donne un chiffre qui n’explique ni les unes ni les autres. ## Les pièges que je rencontre dans les systèmes réels ### 1. Du contenu dynamique avant le contenu stable C’est l’erreur la plus courante. Un horodatage, un identifiant de requête, un export des indicateurs de fonctionnalité, les paramètres régionaux de l’utilisateur ou son affectation à une expérimentation sont placés en tête du prompt système. Déplacez ces éléments plus bas. ### 2. Un JSON « équivalent » n’est pas équivalent Ces deux extraits sont sémantiquement identiques, mais pas nécessairement identiques du point de vue du cache : ``` {"name":"refund_lookup","timeout":3,"strict":true} ``` ``` { "strict": true, "timeout": 3, "name": "refund_lookup" } ``` Si vous incluez des schémas d’outils ou une configuration dans le préfixe mis en cache, sérialisez-les de manière déterministe : ``` import json def stable_json(data: dict) -> str: return json.dumps(data, sort_keys=True, separators=(",", ":")) ``` Cela évite les défauts de cache accidentels dus à des changements dans l’ordre des clés ou dans les espaces. ### 3. La récupération documentaire peut empêcher la mise en cache Les systèmes RAG construisent souvent des prompts comme ceci : ``` Retrieved documents: [doc A] [doc B] [doc C] Instructions: ... ``` Si les résultats de récupération diffèrent selon la requête, le préfixe diffère lui aussi. C’est normal si le contexte récupéré est réellement dynamique, mais ne placez pas vos instructions stables après celui-ci. Mieux : ``` Instructions: ... Long-lived product documentation: [stable docs] Query-specific retrieved documents: [doc A] [doc B] [doc C] ``` Pour les systèmes à fort volume, envisagez de répartir le contexte en plusieurs couches : - Instructions stables à l’échelle globale - Documentation stable pour chaque tenant - Récupération propre à l’utilisateur ou à la requête Chaque couche présente un comportement différent vis-à-vis du cache. ### 4. Les durées de vie du cache comptent Certaines entrées de cache expirent. Si votre trafic arrive par pics, un préfixe peut être fortement réutilisé pendant dix minutes, puis ne plus être sollicité. Des durées de vie plus longues peuvent aider, mais leur tarification ou leur disponibilité peuvent varier selon le fournisseur et le modèle. C’est là que la répartition des requêtes compte. « Nous recevons 10,000 requêtes par jour » est moins utile que « nous recevons 200 requêtes par minute pour ce préfixe exact entre 9 heures et 10 heures du matin ». ### 5. Les changements de modèle invalident les hypothèses Il ne faut pas supposer qu’un préfixe mis en cache pour un modèle est réutilisable avec un autre. Si vous routez les requêtes entre Claude Opus 4.8, Sonnet 4.6, GPT-5.5, Gemini 3 ou des modèles ouverts comme Llama, Qwen, DeepSeek, MiniMax ou Kimi, suivez le comportement du cache pour chaque modèle. Le routage entre plusieurs modèles est utile, mais il complique l’amortissement. Si le trafic est réparti entre cinq modèles, chacun peut recevoir moins de préfixes répétés. ### 6. La personnalisation des prompts peut se retourner contre vous Les équipes personnalisent souvent les prompts système : ``` You are helping {{customer_name}}, who is on plan {{plan_name}}. ``` Cela semble anodin, mais si cette personnalisation apparaît avant le contenu mis en cache, chaque client obtient un préfixe différent. Placez-la plus loin, sauf si elle change réellement l’interprétation du bloc stable par le modèle. ## Quand la mise en cache des prompts permet d’économiser La mise en cache est généralement bien adaptée lorsque : - Le préfixe pouvant être mis en cache est volumineux, souvent de plusieurs milliers ou dizaines de milliers de tokens. - Le même préfixe exact est réutilisé de nombreuses fois. - Le préfixe reste stable d’une requête à l’autre. - Le trafic arrive pendant la durée de vie du cache. - Vous pouvez observer les tokens de création et de lecture du cache. - La composition des prompts est prévisible pour la route. Exemples concrets : - Un assistant de programmation inclut à répétition la même cartographie du dépôt et le même guide de style. - Un bot d’assistance inclut le même manuel de politiques pour chaque question sur un remboursement. - Un agent utilise un schéma d’outils statique volumineux à chaque requête. - Un assistant de recherche interne inclut la même vue d’ensemble du corpus pour une équipe. Pour ces charges de travail, la mise en cache des prompts peut être l’une des optimisations de coûts les plus efficaces, car elle ne nécessite pas de réduire la qualité du contexte. Vous conservez le prompt long ; vous cessez simplement de payer le plein tarif d’entrée à chaque fois. ## Quand la mise en cache des prompts n’apporte rien La mise en cache présente peu d’intérêt, voire un effet négatif, lorsque : - Le prompt est court. - Les préfixes sont rarement réutilisés. - L’essentiel du contexte provient d’une récupération propre à la requête. - Les données dynamiques apparaissent avant les données stables. - Vous modifiez constamment les instructions pendant les expérimentations. - Le trafic est dispersé entre de nombreux modèles, tenants ou variantes de prompts. - Les écritures en cache coûtent plus cher et les lectures sont trop rares pour les amortir. Un piège courant pendant l’évaluation : la mise en cache des prompts semble peu avantageuse dans un notebook parce que vous n’exécutez chaque cas qu’une fois. Elle paraît ensuite excellente en production, car des milliers d’utilisateurs partagent le même préfixe stable. L’inverse se produit aussi : une démonstration exécute le même prompt 100 fois en boucle et affiche de fortes économies, mais la production comporte une personnalisation par tenant qui empêche la réutilisation. Testez avec la répartition réelle des requêtes. ## Une liste de vérification simple pour préparer la mise en cache Avant d’activer la mise en cache des prompts ou de m’appuyer dessus, je vérifie les points suivants : - Existe-t-il au moins un préfixe stable de plus de quelques milliers de tokens ? - Apparaît-il avant tout le contenu dynamique ? - La sérialisation est-elle déterministe ? - Le préfixe est-il versionné et haché ? - Puis-je journaliser les tokens de création et de lecture du cache ? - Est-ce que je connais le nombre de réutilisations attendu pendant la durée de vie du cache ? - Ai-je mesuré séparément la latence des succès et des défauts de cache ? Si la réponse est « non » à trois questions ou plus, la mise en cache peut quand même fonctionner, mais vous avancez à l’aveugle. ## Conseils pratiques La mise en cache des prompts n’est pas une compression magique. Elle consiste à réutiliser un préfixe stable de tokens, et son intérêt économique vient du paiement d’un coût de création unique, puis d’un coût de lecture inférieur à chaque réutilisation. La démarche technique est simple : - Placez d’abord le contenu stable volumineux : instructions, outils, documentation, exemples. - Déplacez les horodatages, les métadonnées utilisateur, les résultats de récupération et les identifiants de requête après le préfixe pouvant être mis en cache. - Suivez cache_creation par rapport à cache_read tokens par route et par modèle. - Utilisez une sérialisation déterministe pour les schémas d’outils et la configuration en JSON. - Modélisez le seuil de rentabilité à partir des tarifs réels de votre fournisseur et de la répartition de votre trafic. - Soyez prudent avec le routage entre plusieurs modèles, la personnalisation par tenant et les prompts courts. - Mesurez séparément la latence des succès et des défauts de cache au lieu de vous fier aux moyennes. La meilleure optimisation du cache de prompts que j’aie vue n’avait rien d’astucieux : nous avons déplacé 42,000 tokens stables avant 12 tokens dynamiques. Le comportement du modèle n’a pas changé. La facture, si. [Inférence](/fr/blog/tag/inference/)[Prompts](/fr/blog/tag/prompts/)[RAG](/fr/blog/tag/rag/)[API](/fr/blog/tag/api/) A [AI Prime Tech](https://aiprimetech.io/fr/) Ce blog est publié par AI Prime Tech. Les articles sont rédigés avec l’aide de l’IA ; vérifiez les détails propres à chaque version, tels que les identifiants de modèles, les prix et les limites, dans la documentation officielle avant de vous y fier. Accédez à l’API Claude à moindre coût Une seule clé API pour Claude Opus 5.5, Sonnet 5, Haiku 4.5 et Fable 5.1, ainsi que GPT-6 modèles. Paiement à l’usage, sans abonnement. [Obtenir votre clé API →](/register) AI Prime Tech est une passerelle API tierce indépendante. Claude™ et Anthropic® sont des marques d’Anthropic, PBC. Aucune affiliation ni approbation n’est sous-entendue.