Prompt Caching Claude : Optimiser Coûts et Performance API
By Learnia Team
Prompt Caching Claude : Optimiser Coûts et Performance API
📅 Dernière mise à jour : 10 mars 2026 — Couvre le prompt caching avec l'API Messages, SDK Python et TypeScript.
🔗 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
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é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 |
Pour aller plus loin
- →Contextual Retrieval et RAG avancé — Exploitez le prompt caching dans vos pipelines RAG
- →MCP avancé : prompt caching et transports — Patterns avancés du Model Context Protocol
Module 0 — Prompting Fundamentals
Build your first effective prompts from scratch with hands-on exercises.
Weekly AI Insights
Tools, techniques & news — curated for AI practitioners. Free, no spam.
Free, no spam. Unsubscribe anytime.
→Related Articles
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.