Prompt Caching Claude : Optimiser Coûts et Performance API
Par Dorian Laurenceau
Mis à jour le
📅 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
| Aspect | Sans cache | Avec cache |
|---|---|---|
| Traitement | Tous les tokens à chaque appel | Seuls les nouveaux tokens sont traités |
| Coût tokens d'entrée | Prix standard | 90% de réduction sur les tokens cachés |
| Latence | Proportionnelle au prompt total | Réduite de ~85% pour les tokens cachés |
| Premier appel | Standard | Légèrement plus cher (+25% cache write) |
| Appels suivants | Standard | Beaucoup 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}`);
À partir de quel appel le prompt caching devient-il rentable ?
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énement | Effet 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 min | Cache 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és | Sans cache (100 req) | Avec cache (100 req) | Économie |
|---|---|---|---|
| 1 000 | $0.30 | $0.05 | 83% |
| 5 000 | $1.50 | $0.23 | 85% |
| 10 000 | $3.00 | $0.41 | 86% |
| 50 000 | $15.00 | $1.88 | 87% |
| 100 000 | $30.00 | $3.68 | 88% |
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étrique | Cible | Alerte si |
|---|---|---|
| Cache hit rate | > 90% | < 70% |
| Cache ratio (tokens cachés / total) | > 80% | < 50% |
| Cache writes / heure | Stable | Pics soudains (cache expiré) |
| Économie mensuelle | Prévisible | Baisse inattendue |
Contraintes et Limites
| Contrainte | Détail |
|---|---|
| Minimum de tokens | Le contenu à cacher doit contenir au moins 1 024 tokens (2 048 pour Opus) |
| TTL fixe | 5 minutes, non configurable |
| Ordre des blocs | Le contenu caché doit être au début (préfixe) |
| Nombre de breakpoints | Maximum 4 points de cache par requête |
| Compatibilité | Fonctionne avec streaming, tool use, images |
Erreurs Courantes
| Erreur | Cause | Solution |
|---|---|---|
| Pas de cache hit | Contenu légèrement différent entre appels | Le contenu caché doit être IDENTIQUE bit pour bit |
| Cache expire trop vite | Pas d'appels pendant 5+ minutes | Implémenter un warmup ping |
| Surcoût inattendu | Trop de cache writes vs reads | Vérifier que le contenu est stable |
| Minimum non atteint | Contenu < 1 024 tokens | Ajoutez du contexte ou regroupez les contenus |
Question 1 sur 5.
Testez vos connaissances sur le Prompt Caching
0 / 5 réponses validées
Q1.Quel est le TTL par défaut du cache Claude ?
5 question(s) restante(s)
- →MCP avancé : prompt caching et transports, Patterns avancés du Model Context Protocol
Approfondir cette méthode
Retrouvez les notions, les exemples et les activités du parcours associé.
Dorian Laurenceau
Développeur web et concepteur pédagogiqueDorian Laurenceau conçoit des parcours de formation en développement web et en intelligence artificielle. LearnIA propose ses méthodes, des exemples et des exercices pour apprendre à utiliser et vérifier les outils IA.
Un cas pratique IA dans votre boîte mail
Méthodes, ressources et nouveaux exercices. Gratuit, avec désinscription à tout moment.
→Pour continuer
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.