Retour aux articles
11 MIN READ

Prompt Caching Claude : Optimiser Coûts et Performance API

By Dorian Laurenceau

📅 Dernière révision : 24 avril 2026. Mise à jour avec les retours et observations d'avril 2026.

🔗 Article pilier : API Claude : Guide Complet


Qu'est-ce que le Prompt Caching ?

Le prompt caching permet de stocker en mémoire des portions de votre prompt qui ne changent pas entre les requêtes. Au lieu de retraiter les mêmes tokens à chaque appel, Claude les lit directement depuis le cache.

Sans Cache vs Avec Cache

AspectSans cacheAvec cache
TraitementTous les tokens à chaque appelSeuls les nouveaux tokens sont traités
Coût tokens d'entréePrix standard90% de réduction sur les tokens cachés
LatenceProportionnelle au prompt totalRéduite de ~85% pour les tokens cachés
Premier appelStandardLégèrement plus cher (+25% cache write)
Appels suivantsStandardBeaucoup moins chers (cache read)

Le Flux de Caching

Appel 1 (cache miss) :
  [System prompt 10K tokens] → Cache Write → Coût: 1.25x (surcoût écriture)
  [Question utilisateur 100 tokens] → Normal

Appel 2+ (cache hit) :
  [System prompt 10K tokens] → Cache Read → Coût: 0.10x (90% économie)
  [Question utilisateur 100 tokens] → Normal

La lecture honnête du prompt caching par les ingénieurs qui le font tourner en prod, remontée sur r/LocalLLaMA, r/MachineLearning, et le Discord Anthropic : le chiffre des 90 % d'économie est réel et atteint couramment, mais uniquement si votre workload ressemble vraiment à des cache hits. Un appel qui réutilise le même system prompt de 10K tokens à travers des milliers de requêtes user économise ; un appel où la section « cachée » change à chaque fois paie la pénalité d'écriture de 1.25x et ne récupère rien. La documentation Anthropic sur le prompt caching est explicite sur ce point — le TTL de 5 minutes signifie qu'un endpoint à faible trafic touche rarement un cache chaud en pratique.

Là où la communauté nuance à juste titre les benchmarks naïfs : le headline des économies suppose un taux de hit au-dessus d'environ 50 %. En dessous, le surcoût d'écriture sur les miss mange les gains. Les équipes qui l'ont mesuré proprement — voir les benchmarks caching d'OpenRouter et les posts observability de LangSmith — obtiennent des économies effectives différentes selon que le workload est un chatbot support (hit rate élevé), un RAG à contexte dynamique (hit rate bas), ou une eval batch (hit rate proche de 100 % une fois chaud).

Règle pragmatique des gens qui l'ont vraiment shipé : instrumentez les champs cache_read_input_tokens et cache_creation_input_tokens à chaque appel, calculez le hit rate par endpoint, et désactivez le caching sur tout endpoint qui stagne sous 30 %. La feature ne se rembourse que sur les workloads qui collent à sa forme.

Implémentation

Python

import anthropic

client = anthropic.Anthropic()

# System prompt long avec cache_control
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": """Tu es un assistant juridique expert en droit français.

Voici le Code du travail complet que tu dois utiliser comme référence :

Article L1221-1 : Le contrat de travail est soumis aux règles du droit commun...
[... 10 000 tokens de contenu juridique ...]
Article L8291-1 : Les dispositions du présent code sont applicables...
""",
            "cache_control": {"type": "ephemeral"}
        }
    ],
    messages=[
        {"role": "user", "content": "Quels sont les droits d'un salarié en cas de licenciement économique ?"}
    ]
)

# Vérifier les statistiques de cache
print(f"Cache write: {response.usage.cache_creation_input_tokens} tokens")
print(f"Cache read: {response.usage.cache_read_input_tokens} tokens")
print(f"Input normal: {response.usage.input_tokens} tokens")

TypeScript

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const response = await client.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  system: [
    {
      type: "text",
      text: `Tu es un assistant technique. Voici la documentation de l'API :
      
      [... documentationdétaillée ...]`,
      cache_control: { type: "ephemeral" },
    },
  ],
  messages: [
    { role: "user", content: "Comment créer un endpoint REST ?" },
  ],
});

console.log(`Cache write: ${response.usage.cache_creation_input_tokens}`);
console.log(`Cache read: ${response.usage.cache_read_input_tokens}`);

Stratégies de Caching

1. System Prompt Fixe

Le cas d'usage le plus courant : un system prompt qui ne change jamais entre les requêtes.

# Le même system prompt est caché pour tous les utilisateurs
system = [{
    "type": "text",
    "text": "Tu es un assistant [rôle détaillé + instructions + contexte]...",
    "cache_control": {"type": "ephemeral"}
}]

# Utilisateur 1
client.messages.create(model=model, max_tokens=1024, system=system,
    messages=[{"role": "user", "content": "Question de l'utilisateur 1"}])

# Utilisateur 2 (bénéficie du cache)
client.messages.create(model=model, max_tokens=1024, system=system,
    messages=[{"role": "user", "content": "Question de l'utilisateur 2"}])

2. Documents de Référence

Incluez un document volumineux une fois, posez de nombreuses questions dessus.

# Cacher le document
system = [{
    "type": "text",
    "text": f"Document de référence :\n\n{long_document}",
    "cache_control": {"type": "ephemeral"}
}]

# 50 questions sur le même document → 49 cache hits
questions = ["Résume le chapitre 3", "Quels sont les risques mentionnés ?", ...]
for q in questions:
    response = client.messages.create(
        model=model, max_tokens=1024, system=system,
        messages=[{"role": "user", "content": q}]
    )

3. Exemples Few-Shot

Cachez un ensemble d'exemples réutilisés dans de nombreuses requêtes.

system = [{
    "type": "text",
    "text": """Classification de sentiment. Exemples :

Texte: "Ce produit est fantastique !" → Positif
Texte: "Livraison en retard, déçu." → Négatif
Texte: "Correct, rien d'exceptionnel." → Neutre
[... 50 exemples ...]
""",
    "cache_control": {"type": "ephemeral"}
}]

# Classifier des milliers de textes avec le cache des exemples
for text in texts_to_classify:
    response = client.messages.create(
        model=model, max_tokens=100, system=system,
        messages=[{"role": "user", "content": f"Classifie : \"{text}\""}]
    )

4. Cache dans les Messages (Conversation)

Vous pouvez aussi cacher des contenus dans les messages (pas seulement le system).

messages = [
    {
        "role": "user",
        "content": [
            {
                "type": "text",
                "text": f"Voici un rapport de 50 pages :\n\n{rapport}",
                "cache_control": {"type": "ephemeral"}
            },
            {
                "type": "text",
                "text": "Résume les conclusions principales."
            }
        ]
    }
]

TTL et Gestion du Cache

Fonctionnement du TTL

ÉvénementEffet sur le TTL
Cache write (premier appel)TTL initialisé à 5 minutes
Cache hit (appel suivant)TTL réinitialisé à 5 minutes
Pas d'appel pendant 5 minCache expiré, prochain appel = cache write

Optimiser le TTL

import time
import threading

def keep_cache_warm(client, model, system, interval=240):
    """Garde le cache actif en envoyant un ping périodique."""
    def ping():
        while True:
            client.messages.create(
                model=model,
                max_tokens=1,
                system=system,
                messages=[{"role": "user", "content": "ping"}]
            )
            time.sleep(interval)  # 4 minutes < TTL de 5 minutes
    
    thread = threading.Thread(target=ping, daemon=True)
    thread.start()

Calcul des Économies

Formule d'Économie

Économie par requête = (tokens_cachés × prix_normal) - (tokens_cachés × prix_cache_read)
                     = tokens_cachés × prix_normal × 0.90

Surcoût première requête = tokens_cachés × prix_normal × 0.25

Break-even = 1 + (surcoût / économie_par_requête)
           = 1 + (0.25 / 0.90) ≈ 1.28 requêtes (donc dès le 2ème appel)

Tableau d'Économies

Tokens cachésSans cache (100 req)Avec cache (100 req)Économie
1 000$0.30$0.0583%
5 000$1.50$0.2385%
10 000$3.00$0.4186%
50 000$15.00$1.8887%
100 000$30.00$3.6888%

Prix basés sur Claude Sonnet à $3/M tokens d'entrée, sur 100 requêtes (1 cache write + 99 cache reads).

Monitoring du Cache

Métriques à Suivre

def log_cache_metrics(response):
    """Log les métriques de cache pour monitoring."""
    usage = response.usage
    
    cache_write = getattr(usage, 'cache_creation_input_tokens', 0)
    cache_read = getattr(usage, 'cache_read_input_tokens', 0)
    regular_input = usage.input_tokens
    
    cache_hit = cache_read > 0
    cache_ratio = cache_read / (cache_read + regular_input) if (cache_read + regular_input) > 0 else 0
    
    print(f"Cache hit: {cache_hit}")
    print(f"Cache read: {cache_read} tokens")
    print(f"Cache write: {cache_write} tokens")
    print(f"Regular input: {regular_input} tokens")
    print(f"Cache ratio: {cache_ratio:.1%}")
    
    return {
        "cache_hit": cache_hit,
        "cache_read_tokens": cache_read,
        "cache_write_tokens": cache_write,
        "regular_input_tokens": regular_input,
        "cache_ratio": cache_ratio
    }

Dashboard de Cache

MétriqueCibleAlerte si
Cache hit rate> 90%< 70%
Cache ratio (tokens cachés / total)> 80%< 50%
Cache writes / heureStablePics soudains (cache expiré)
Économie mensuellePrévisibleBaisse inattendue

Contraintes et Limites

ContrainteDétail
Minimum de tokensLe contenu à cacher doit contenir au moins 1 024 tokens (2 048 pour Opus)
TTL fixe5 minutes, non configurable
Ordre des blocsLe contenu caché doit être au début (préfixe)
Nombre de breakpointsMaximum 4 points de cache par requête
CompatibilitéFonctionne avec streaming, tool use, images

Erreurs Courantes

ErreurCauseSolution
Pas de cache hitContenu légèrement différent entre appelsLe contenu caché doit être IDENTIQUE bit pour bit
Cache expire trop vitePas d'appels pendant 5+ minutesImplémenter un warmup ping
Surcoût inattenduTrop de cache writes vs readsVérifier que le contenu est stable
Minimum non atteintContenu < 1 024 tokensAjoutez du contexte ou regroupez les contenus

GO DEEPER — FREE GUIDE

Module 0 — Prompting Fundamentals

Build your first effective prompts from scratch with hands-on exercises.

D

Dorian Laurenceau

Full-Stack Developer & Learning Designer

Full-stack web developer and learning designer. I spent 4 years as a freelance full-stack developer and 4 years teaching React, JavaScript, HTML/CSS and WordPress to adult learners. Today I design learning paths in web development and AI, grounded in learning science. I founded learn-prompting.fr to make AI practical and accessible, and built the Bluff app to gamify political transparency.

Prompt EngineeringLLMsFull-Stack DevelopmentLearning DesignReact
Published: March 10, 2026Updated: April 24, 2026
Newsletter

Weekly AI Insights

Tools, techniques & news — curated for AI practitioners. Free, no spam.

Free, no spam. Unsubscribe anytime.

FAQ

Qu'est-ce que le prompt caching Claude ?+

Le prompt caching permet de mettre en cache des portions de votre prompt (system prompt, documents, exemples) pour ne pas les retraiter à chaque requête. Les tokens cachés coûtent 90% moins cher et réduisent la latence de 85%.

Comment fonctionne le prompt caching ?+

Ajoutez un marqueur cache_control sur un bloc de contenu. Lors du premier appel, le contenu est mis en cache (cache write). Les appels suivants avec le même contenu utilisent le cache (cache hit) à coût réduit.

Combien de temps dure le cache ?+

Le TTL (Time-To-Live) par défaut est de 5 minutes. Chaque cache hit réinitialise le TTL. Le cache expire automatiquement après 5 minutes sans utilisation.

Quand utiliser le prompt caching ?+

Utilisez-le quand vous envoyez le même contenu volumineux dans plusieurs requêtes : system prompts longs, documents de référence, exemples few-shot, contexte de conversation fixe.

Y a-t-il un coût supplémentaire pour le cache write ?+

Oui, l'écriture en cache coûte 25% plus cher que les tokens d'entrée normaux. Mais la lecture en cache coûte 90% moins cher. Le break-even est atteint dès le 2ème appel avec cache hit.