← Articles

Prompt Caching : Économisez 90% sur vos requêtes API Claude

Le prompt caching vous permet de réutiliser des contextes volumineux entre requêtes. Découvrez comment réduire drastiquement vos coûts API et accélérer vos temps de réponse.

Prompt Caching : Économisez 90% sur vos requêtes API Claude

Vous envoyez le même contexte de 50 000 tokens à chaque requête ? Vous payez pour retraiter encore et encore la même documentation ? Le prompt caching est votre meilleur allié. Je vais vous montrer comment j’ai réduit mes coûts API de 90% sur un projet réel.

Comment ça marche : les bases techniques

Le prompt caching permet à Claude de mettre en cache certaines parties de votre prompt. Au lieu de retraiter tout le contexte à chaque requête, Claude réutilise ce qui est déjà en mémoire.

Les chiffres qui changent tout :

  • Écriture en cache : 25% plus cher que le tarif normal
  • Lecture depuis le cache : 90% moins cher que le tarif normal
  • Durée de vie : 5 minutes d’inactivité avant expiration

Si vous faites plusieurs requêtes dans les 5 minutes avec le même contexte, vous payez une seule fois l’écriture, puis 90% de réduction sur toutes les lectures suivantes. Le ROI est immédiat dès la 2e requête.

Implémentation pratique avec le SDK Python

Voici comment activer le caching. Le secret : ajouter des cache_control breakpoints dans votre prompt.

import anthropic

client = anthropic.Anthropic(api_key="votre-cle")

# Exemple : assistant qui connaît votre codebase
response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": "Tu es un assistant qui connaît notre codebase Python."
        },
        {
            "type": "text",
            "text": "Voici le contenu de notre fichier utils.py:\n\n" + open("utils.py").read(),
            "cache_control": {"type": "ephemeral"}
        }
    ],
    messages=[
        {"role": "user", "content": "Comment utiliser la fonction parse_config ?"}
    ]
)

print(response.content)

Le cache_control marque la fin d’un bloc à mettre en cache. Tout ce qui précède ce marqueur sera caché. Vous pouvez mettre plusieurs breakpoints dans votre prompt.

Les 3 cas d’usage qui rentabilisent vraiment

1. Documentation volumineuse

Vous construisez un chatbot qui connaît votre doc produit de 100 pages ? Mettez toute la doc en system prompt avec un cache breakpoint. Chaque question utilisateur réutilise le même contexte caché.

system_prompt = [
    {"type": "text", "text": "Tu es le support client de ProductX."},
    {
        "type": "text",
        "text": load_documentation(),  # 50k tokens de doc
        "cache_control": {"type": "ephemeral"}
    }
]

# Chaque conversation client réutilise le cache
for question in user_questions:
    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=512,
        system=system_prompt,
        messages=[{"role": "user", "content": question}]
    )

2. Conversations longues avec contexte

Vous gérez une conversation multi-tours ? Cachez tout l’historique sauf le dernier message.

messages = [
    {"role": "user", "content": "Explique-moi les decorators Python"},
    {"role": "assistant", "content": "Les decorators sont..."},
    {"role": "user", "content": "Donne un exemple avec @property"},
    {"role": "assistant", "content": "Voici un exemple..."},
    # ... 10 tours de conversation
]

# Cachez tout l'historique
messages[-2]["cache_control"] = {"type": "ephemeral"}

# Nouvelle question
messages.append({"role": "user", "content": "Et avec @staticmethod ?"})

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    messages=messages
)

3. Code review automatisé

Vous analysez plusieurs fichiers d’une PR ? Cachez le contexte du repo et les guidelines.

system = [
    {"type": "text", "text": "Tu fais des code reviews selon nos standards."},
    {"type": "text", "text": load_coding_guidelines(), "cache_control": {"type": "ephemeral"}},
    {"type": "text", "text": load_repo_structure(), "cache_control": {"type": "ephemeral"}}
]

# Reviewez chaque fichier modifié sans repayer le contexte
for file in modified_files:
    response = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=2048,
        system=system,
        messages=[{"role": "user", "content": f"Review ce fichier:\n{file.content}"}]
    )

Les pièges à éviter

Piège 1 : Cache trop petit Le cache doit faire minimum 1024 tokens. Si votre bloc est plus petit, il ne sera pas caché. Regroupez vos contextes.

Piège 2 : Oublier les 5 minutes Si vous espacez vos requêtes de plus de 5 minutes, le cache expire. Pour un traitement batch, parallélisez ou accélérez votre pipeline.

Piège 3 : Cache au mauvais endroit Cachez ce qui ne change pas, pas ce qui varie. La question de l’utilisateur ne doit jamais être cachée, seulement le contexte stable.

Piège 4 : Trop de breakpoints Chaque cache_control crée un point de cache. Plus vous en avez, plus c’est complexe à gérer. En général, 1 à 3 breakpoints suffisent.

Monitoring et optimisation

La réponse API vous indique exactement ce qui s’est passé :

response = client.messages.create(...)

print(f"Tokens cachés écrits: {response.usage.cache_creation_input_tokens}")
print(f"Tokens cachés lus: {response.usage.cache_read_input_tokens}")
print(f"Tokens normaux: {response.usage.input_tokens}")

Vous pouvez calculer vos économies réelles :

def calculate_savings(usage, price_per_mtok_input=3.0):
    # Prix pour Claude 3.5 Sonnet (ajustez selon votre modèle)
    normal_cost = usage.input_tokens * price_per_mtok_input / 1_000_000
    cache_write_cost = usage.cache_creation_input_tokens * price_per_mtok_input * 1.25 / 1_000_000
    cache_read_cost = usage.cache_read_input_tokens * price_per_mtok_input * 0.1 / 1_000_000

    total_cost = normal_cost + cache_write_cost + cache_read_cost
    saved = usage.cache_read_input_tokens * price_per_mtok_input * 0.9 / 1_000_000

    return total_cost, saved

Avec TypeScript aussi

Le SDK TypeScript supporte exactement la même syntaxe :

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

const client = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
});

const response = await client.messages.create({
  model: 'claude-3-5-sonnet-20241022',
  max_tokens: 1024,
  system: [
    {
      type: 'text',
      text: 'Tu es un assistant technique.',
    },
    {
      type: 'text',
      text: largeDocumentation,
      cache_control: { type: 'ephemeral' },
    },
  ],
  messages: [
    { role: 'user', content: 'Ma question' },
  ],
});

Conclusion : quand l’activer ?

Activez le prompt caching si :

  • Vous avez un contexte de plus de 1024 tokens qui se répète
  • Vous faites plusieurs requêtes dans un intervalle de 5 minutes
  • Vous voulez réduire la latence (le cache accélère aussi le traitement)

Ne l’activez pas si :

  • Votre contexte change à chaque requête
  • Vous faites une seule requête isolée
  • Votre contexte fait moins de 1024 tokens

Dans mon projet de chatbot documentation, je suis passé de 2,40€ par jour à 0,25€ avec exactement le même volume. Le prompt caching n’est pas une option, c’est une évidence économique dès que vous avez du contexte répétitif.

Testez sur vos prochaines requêtes et regardez les métriques cache_read_input_tokens exploser. C’est là que vous voyez vos économies en temps réel.