Coûts et latence avec Claude : observabilité, prompt caching, streaming et Message Batches API

Septième article de la série « Production Engineering, Evals & Security avec Claude ».

Une application Claude peut être fiable et produire de bonnes réponses tout en restant impropre à la production pour deux raisons très simples :

elle coûte trop cher ou elle est trop lente.

Le module Production Engineering, Evals & Security insiste donc sur une règle fondamentale : on ne peut pas gérer un budget que l’on ne mesure pas. Il recommande d’instrumenter chaque appel afin de suivre au minimum les tokens, la latence et le taux d’erreur, puis d’optimiser le composant réellement responsable au lieu de deviner à partir de la facture finale.

Les principaux leviers sont :

model selection
prompt & context size
number of tool calls
streaming
batch processing
prompt caching
agent architecture

L’objectif n’est pas d’utiliser toutes ces optimisations.

L’objectif est de choisir le bon levier pour le bon problème.


1. Mesurer avant d’optimiser

Prenons deux requêtes.

Requête A

Input tokens: 1 200
Output tokens: 300
Latency: 700 ms
Tool calls: 0

Requête B

Input tokens: 18 000
Output tokens: 400
Latency: 3 800 ms
Tool calls: 4

Dire simplement :

« Claude coûte trop cher »

n’aide pas beaucoup.

Dans la deuxième requête, plusieurs causes sont immédiatement visibles :

large context
+
multiple tool calls
+
higher latency

Le module recommande donc d’instrumenter chaque appel, et non uniquement la facture mensuelle.

Une télémétrie minimale pourrait enregistrer :

{
    "model": "...",
    "input_tokens": 18240,
    "output_tokens": 412,
    "latency_ms": 3817,
    "tool_calls": 4,
    "status": "success"
}

Puis agréger ces données par :

feature
model
endpoint
customer
workflow

Les métriques essentielles

Le document met particulièrement en avant :

input tokens
output tokens
latency
error rate

Pour un agent, il devient également utile de suivre :

number of model calls
number of tool calls
number of subagents

Pourquoi ?

Parce qu’un workflow agentique peut transformer une seule requête utilisateur en :

1 request
→ 8 model calls
→ 12 tool calls
→ 4 subagents

Le coût visible par l’utilisateur est celui d’une requête.

Le coût réel est celui de toute l’exécution.


Le budget doit être défini avant l’architecture

Le module rattache cette question au design document.

Avant de construire le système, il recommande de définir :

per-request budget
monthly cost ceiling
latency target
minimum reliability

Par exemple :

P95 latency < 2 s

Cost/request < X

Success rate >= Y

Les nombres dépendent évidemment de l’application.

Le principe important est qu’ils doivent être définis avant de choisir une architecture complexe.

Sinon, on construit d’abord puis on découvre après coup :

« Notre orchestrator-worker est trois fois trop cher. »


Identifier le bon levier

Le cours regroupe les principaux leviers de coût et de latence autour de quelques causes mesurables.

CauseLevier possible
Modèle surdimensionnéChanger de modèle ou router
Prompt très longRéduire le contexte
Préfixe répétéprompt caching
Trop d’appels toolsSimplifier le workflow
Utilisateur attend la réponsestreaming
Gros traitement non urgentMessage Batches API
Beaucoup de subagentsRevoir l’architecture

Une bonne optimisation commence donc par :

measure
→ identify bottleneck
→ choose lever
→ re-evaluate

et non :

add caching everywhere

Prompt caching : éviter de retraiter le même préfixe

Avant de produire une réponse, Claude doit traiter les tokens qui composent l’input.

Si plusieurs requêtes commencent par le même contenu volumineux :

long system prompt
+
large tool definitions
+
stable reference material

ce travail peut être répété inutilement.

Le prompt caching permet de réutiliser le traitement associé à un préfixe stable.

Le document décrit le fonctionnement comme :

first request
→ cache write

later identical prefix
→ cache read

La documentation Anthropic actuelle confirme que le cache couvre le préfixe composé des tools, du system et des messages, jusqu’au point de cache concerné.


Exemple

Supposons une application qui envoie à chaque requête :

System prompt:          4 000 tokens
Tool schemas:           6 000 tokens
User request:             200 tokens

Sans cache :

request 1 → process 10 200 input tokens
request 2 → process 10 200
request 3 → process 10 200
...

Si les 10 000 premiers tokens sont stables :

request 1
→ cache creation

request 2
→ cache hit + new user message

request 3
→ cache hit + new user message

Le bénéfice augmente avec le nombre de réutilisations.


Qu’est-ce qu’un bon candidat au cache ?

Le cours cite notamment :

long system prompt
large stable tool schema

Pourquoi ?

Parce qu’ils réunissent trois propriétés :

long
+
stable
+
frequently reused

Un exemple typique :

tools schema = 8 000 tokens

qui est identique pour des centaines de requêtes.


Exact prefix match : le point crucial

Le cache fonctionne sur un préfixe identique.

Le module insiste sur ce détail : une modification avant le breakpoint peut provoquer un cache miss.

Par exemple :

Request A:
"You are a support assistant."

Request B:
"You are a helpful support assistant."

Même si ces prompts sont presque équivalents sémantiquement, ils ne constituent plus le même préfixe.

Donc :

stable bytes/tokens
→ cache hit possible

changed prefix
→ recomputation

Pour bénéficier du cache, il faut donc éviter de placer des données dynamiques avant la partie stable que l’on souhaite réutiliser.


TTL : combien de temps le cache reste-t-il utilisable ?

Le support fourni indique :

default TTL = 5 minutes
optional TTL = 1 hour

J’ai vérifié ce point dans la documentation Anthropic actuelle : le TTL par défaut reste bien 5 minutes, renouvelé lorsqu’une entrée est utilisée, et une durée 1 heure est également disponible avec un coût supplémentaire.

Conceptuellement :

same prefix reused every 30 seconds
→ good candidate

same prefix reused every 3 hours
→ default 5-minute cache not useful

Économie du cache : writes vs reads

Le document donne la logique économique suivante :

cache write
→ more expensive than normal input

cache read
→ much cheaper

Il indique comme multiplicateurs standard :

5 min write = 1.25× input price
1 h write   = 2× input price
cache read  = 0.1× input price

La documentation Anthropic actuelle confirme ces multiplicateurs standards, avec toutefois des exceptions selon certains modèles actuels.

C’est pourquoi :

many reads
+
few writes
→ caching pays

mais :

write
+
never reuse
→ caching can cost more

Exemple économique simplifié

Supposons 10 000 tokens de préfixe.

Sans cache, pour quatre requêtes :

10 000 × 4
=
40 000 input-token equivalents

Avec cache 5 minutes, en prenant les multiplicateurs standards :

write:
10 000 × 1.25
=
12 500

3 reads:
10 000 × 0.1 × 3
=
3 000

total:
15 500

On passe conceptuellement de :

40 000

à :

15 500

unités de coût d’input équivalentes.

Ce calcul est illustratif ; la facturation réelle dépend du modèle et de la tarification en vigueur.


Le piège du contenu dynamique

Supposons que vous mettiez dans votre system prompt :

Current stock price: ...
Current weather: ...
Current inventory: ...

Ces valeurs changent à chaque requête.

Vous créez alors potentiellement :

cache miss
cache miss
cache miss

Le cache est beaucoup plus adapté à :

stable instructions
stable tool definitions
stable reference documents

Le problème de la staleness

Le module souligne un deuxième risque : ce que vous réutilisez doit encore être correct.

Pour :

system prompt
tool schema

le problème est généralement limité, car ces éléments sont volontairement stables.

Pour :

live pricing
permissions
inventory
security policy updated minutes ago

il faut examiner beaucoup plus attentivement la cohérence temporelle.

Le cache est une optimisation.

Il ne doit pas transformer :

fresh data

en :

stale data

Mise en cache automatique ou breakpoints explicites

Le support décrit deux stratégies :

automatic caching

et :

explicit breakpoints

La documentation actuelle confirme ces deux modes. La mise en cache automatique se configure avec un cache_control au niveau supérieur ; avec des breakpoints explicites, on place cache_control sur des blocs spécifiques.

Le principe d’un breakpoint explicite :

[stable tools]

[stable system]

[stable reference] ← cache breakpoint [user-specific data]

La partie avant le breakpoint peut être réutilisée.

La partie dynamique reste traitée normalement.


Streaming : réduire la latence perçue

Le streaming ne réduit pas nécessairement le coût total de la génération.

Son intérêt principal est différent :

Faire apparaître la réponse au fur et à mesure au lieu d’attendre qu’elle soit entièrement générée.

Architecture non-streaming :

request
   ↓
wait...
wait...
wait...
   ↓
full answer

Avec streaming :

request
   ↓
first tokens
   ↓
more tokens
   ↓
more tokens
   ↓
complete answer

Pour une application interactive, le time-to-first-token peut donc compter davantage que le temps total.

Le support classe ainsi :

user-facing request
→ streaming

Streaming ne signifie pas « réponse terminée »

C’est un point fondamental lorsque Claude utilise des tools.

Un tool_use peut être streamé progressivement.

Les arguments arrivent sous forme de fragments :

input_json_delta

Le document donne l’idée suivante :

delta 1
+
delta 2
+
delta 3
+
...
→ complete JSON

La documentation actuelle confirme que les input_json_delta contiennent des fragments JSON partiels qui doivent être accumulés avant de reconstituer l’objet final.


Exemple

Claude souhaite produire :

{
  "location": "Montpellier",
  "unit": "celsius"
}

Le stream peut arriver sous une forme conceptuelle proche de :

{"loc

puis :

ation":"Mont

puis :

pellier","unit":"celsius"}

Exécuter le tool après le premier fragment serait évidemment incorrect.


Pattern correct avec tool streaming

Le support propose ce modèle mental :

tool_blocks = {}

for event in stream:

    if event.type == "content_block_start":
        # initialize accumulator
        ...

    elif event.type == "content_block_delta":
        if event.delta.type == "input_json_delta":
            # append partial JSON
            ...

# once the block is complete:
tool_input = json.loads(accumulated_json)
execute_tool(tool_input)

La règle à retenir :

Ne jamais déclencher une action à partir d’un tool_use incomplet.


Que faire si le stream casse ?

Le support indique qu’un stream interrompu en cours de réponse doit être traité comme un échec transitoire : il faut retenter la requête complète plutôt que transmettre une sortie partielle au composant suivant.

Le danger serait :

partial model output
      ↓
parser
      ↓
tool
      ↓
side effect

alors que le message n’était pas terminé.

Il faut maintenir une séparation nette entre :

partial data

et :

completed result safe to consume

Streaming et tool use : le piège d’examen

Supposons que vous receviez :

input_json_delta

contenant :

{"amount":

Que devez-vous faire ?

Pas :

execute tool

Mais :

accumulate
→ wait for block completion
→ parse
→ validate
→ execute

C’est un point très probable dans une question de scénario.


Message Batches API : échanger de la latence contre du coût

Toutes les requêtes n’ont pas besoin d’une réponse immédiate.

Exemples :

overnight classification
data backfill
large eval run
scheduled report
bulk extraction

Pour ces workloads, la Message Batches API permet de soumettre de nombreuses requêtes de manière asynchrone.

Le compromis est clair :

less immediate
+
cheaper

Quand utiliser Batch ?

Le support donne comme règle :

non-urgent
+
high volume
→ batch

Par exemple :

10 000 documents à classifier cette nuit

Le traitement peut être lancé sans utilisateur en attente.

Batch est alors particulièrement adapté.


Quand ne pas utiliser Batch ?

Pour :

user asks question
→ expects answer now

Batch est le mauvais outil.

C’est exactement l’inverse du streaming.

interactive request
→ streaming

offline asynchronous workload
→ batch

Le support formule explicitement ce contraste.


Réduction de coût actuelle

Le cours mentionne une réduction d’environ 50 %, tout en demandant de vérifier la valeur actuelle.

La documentation Anthropic actuelle confirme qu’en septembre 2026 la Message Batches API facture l’utilisation à 50 % du tarif standard de l’API.

Comme il s’agit d’une donnée tarifaire, elle doit être revérifiée au moment de la mise en production.


Batch et prompt caching peuvent se cumuler

Le support attire l’attention sur une optimisation particulièrement intéressante :

batch
+
prompt caching

Supposons une tâche nocturne :

100 000 documents

avec le même :

long system prompt
+
tool schema

pour chaque document.

Vous pouvez bénéficier simultanément de :

batch discount

et :

cached repeated prefix

La documentation Anthropic actuelle confirme que les multiplicateurs de prompt caching peuvent se cumuler avec la remise Batch.


Exemple de choix d’architecture

Cas 1 — chatbot interactif

Exigence :

user should see answer immediately

Choix :

stream=True

Le levier vise la latence perçue.


Cas 2 — classification nocturne

Exigence :

1 million records
no user waiting
minimize cost

Choix :

Message Batches API

Cas 3 — assistant utilisant un énorme tool schema

Exigence :

same 12 000-token prefix
repeated frequently

Choix :

prompt caching

Cas 4 — simple lookup dans une base stable

Exigence :

one fact

Choix :

smaller model
+
fetch once

plutôt que plusieurs agents et plusieurs rounds.


Plusieurs leviers peuvent être combinés

Une architecture n’est pas limitée à une optimisation.

Par exemple :

scheduled bulk classification
+
stable long system prompt

peut devenir :

small model
+
Message Batches API
+
prompt caching

C’est précisément une configuration proposée dans l’exercice du module.

À l’inverse :

interactive chat

peut utiliser :

appropriate model
+
prompt caching
+
streaming

si le contexte stable est réutilisé fréquemment.


Le piège : optimiser la latence avec Batch

Question :

Un utilisateur attend une réponse à l’écran. Quelle optimisation choisir ?

Pas :

Message Batches API

car elle est asynchrone.

Le support attend :

streaming

Le piège inverse : utiliser Streaming pour réduire le coût d’un traitement offline

Le streaming change surtout la manière dont les résultats arrivent.

Il ne constitue pas le levier principal pour réduire le coût d’un traitement de masse non urgent.

Dans ce cas :

Message Batches API

est l’outil adapté.


Observabilité et optimisation forment une boucle

L’approche complète est :

Instrument
    ↓
Measure
    ↓
Find bottleneck
    ↓
Choose one lever
    ↓
Change architecture
    ↓
Run evals
    ↓
Measure again

Il faut absolument conserver l’étape :

Run evals

car une optimisation de coût peut diminuer la qualité.

Exemple :

smaller model
→ -40% cost
→ -15% eval score

Ce n’est peut-être pas une optimisation acceptable.


Le reliability floor

Le document introduit un principe très important :

Réduire le coût sans passer sous le niveau minimum de fiabilité.

Le budget n’est donc pas :

minimize cost at all costs

mais :

minimize cost
subject to:
quality >= required level
reliability >= required level
latency <= target

Cela transforme l’optimisation en véritable problème d’ingénierie.


Et les agents ?

Le coût peut exploser très vite lorsque le travail est distribué entre plusieurs agents.

Chaque subagent possède :

its own calls
its own tokens
its own context

Le document rapporte notamment un cas de recherche Anthropic où un système multi-agent consommait environ 15 fois les tokens d’une interaction chat normale. Il précise cependant que ce coût n’est justifié que lorsque la tâche se décompose réellement en parties parallèles indépendantes.

Nous approfondirons cette architecture dans l’article suivant.


Tableau de décision rapide

BesoinLevier principal
Réduire le coût d’un workload simpleModèle plus petit si l’eval tient
Réduire un contexte répétéPrompt caching
Améliorer la réponse perçue par l’utilisateurStreaming
Gros traitement non urgentMessage Batches API
Réduire des appels inutilesSimplifier tools/retrieval
Workload mixteRouting
Travail réellement parallèleOrchestrator-worker
Travail séquentiel dépendantSingle agent

Ce qu’il faut retenir pour la certification

1. On mesure avant d’optimiser

Sur chaque appel :

input tokens
output tokens
latency
error rate

2. Prompt caching

Bon lorsque :

long
+
stable
+
frequently repeated prefix

À retenir :

exact prefix match

et non similarité sémantique.

Le cours et la documentation actuelle indiquent :

5-minute default TTL
1-hour option

3. Streaming

Bon lorsque :

user is waiting

Il améliore principalement la latence perçue.

Avec tool_use :

accumulate input_json_delta
→ wait for completion
→ parse
→ execute

4. Message Batches API

Bon lorsque :

high volume
+
non-urgent

La documentation actuelle confirme une réduction de 50 % par rapport aux tarifs API standards.


5. Batch et cache peuvent se combiner

batch discount
+
cached repeated prefix

peut être particulièrement efficace pour des jobs périodiques volumineux.


Pièges d’examen

Scénario : un utilisateur attend une réponse dans l’interface et vous souhaitez qu’elle paraisse plus immédiate.

Streaming.


Scénario : vous devez traiter 500 000 documents cette nuit et personne n’attend les réponses en temps réel.

Message Batches API.


Scénario : chaque requête réutilise un system prompt de 8 000 tokens et le même tool schema.

Prompt caching.


Scénario : le system prompt change à chaque requête.

→ Le cache risque d’avoir un mauvais hit rate.


Scénario : vous recevez un input_json_delta partiel pour un tool.

Ne pas exécuter le tool. Accumuler les fragments jusqu’à obtenir l’input complet.


Scénario : un job Batch réutilise un très long préfixe identique.

Batch + prompt caching peuvent être combinés.


Scénario : la facture augmente brutalement.

→ Ne pas appliquer une optimisation au hasard. Examiner d’abord les métriques par appel et identifier le levier responsable.


À retenir en une phrase

Optimiser Claude en production consiste à mesurer chaque appel puis à choisir le bon levier : prompt caching pour les préfixes stables répétés, streaming pour l’interactivité, Message Batches API pour les traitements asynchrones volumineux, sans jamais sacrifier le niveau minimal de qualité et de fiabilité défini par les evals.

Le phare info – Média indépendant & critique
Sélectionne, organise, contextualise et partage des contenus pertinents autour d’un thème ou d’une problématique, dans une logique de veille, de transmission et de mise en sens.
Pour cet article, l’intelligence artificielle a été utilisée comme un outil d’aide à l’exploration, à la structuration et à la rédaction. Elle permet de confronter plusieurs angles, de repérer certains biais humains possibles et de faire émerger des points de vigilance. Le curateur humain observe aussi les biais possibles de l’IA, vérifie les éléments essentiels, nuance l’analyse, corrige les formulations fragiles et assume la publication.

Articles liés

Fiche de révision certification — Accelerators & IP Contribution

Cette fiche résume les notions essentielles du module Accelerators & IP Contribution. Le fil conducteur est simple : Un build Claude n’est pas terminé lorsqu’il fonctionne....

Étude de cas : corriger un accelerator Claude mal packagé, mal versionné et mal sécurisé

Un système Claude peut fonctionner parfaitement en démonstration et pourtant être impropre à la production. Le cas cumulatif du module illustre précisément cette situation. L’application : s’exécute...

Applications Claude multi-composants : trust boundaries, least privilege et sécurité

Une application Claude moderne n’est souvent pas constituée d’un seul appel API. Elle peut combiner : une API applicative ; Claude ; un agent ; Claude Code ; un MCP...

Comparer les plateformes Claude : latency, compliance, data residency et total cost

Lorsque plusieurs plateformes permettent d’exécuter Claude, comment choisir ? Une comparaison superficielle pourrait se limiter à : la plateforme la moins chère ; celle que l’équipe connaît...

Model versioning avec Claude : pin what ships, eval gates et rollback

Changer de modèle dans une application Claude peut sembler être une modification minime : model = "new-model" Pourtant, en production, ce changement peut modifier : la qualité...

Le sentier du savoir

De la curiosité à la transmission, explorez les étapes qui permettent de transformer l’information en compréhension durable.

Étape 1 — Construire une culture générale solide

Construire une base solide de connaissances pour comprendre le monde. Relier les faits, les disciplines et les repères essentiels.

Étape 2 — Maîtriser la pensée critique et l’analyse : apprendre à penser contre ses propres certitudes

Apprendre à analyser l’information, repérer les biais et questionner les évidences. Penser par soi-même dans un monde saturé de récits.

Étape 3 – Apprendre à argumenter et à convaincre

Structurer sa pensée pour convaincre sans manipuler. Savoir débattre, nuancer et formuler des idées claires.

Étape 4 – Approfondir un ou plusieurs domaines d’expertise

Explorer un ou plusieurs domaines en profondeur. Passer de la curiosité à la compréhension experte.

Etapes 5 : Devenir polyglotte : élargir sa pensée par les langues

Élargir ses horizons par le langage et les cultures. Penser autrement en changeant de langue.

Étape 6 — Comprendre la méthode scientifique et expérimenter

Comprendre la méthode scientifique et l’expérimentation. Distinguer savoirs établis, hypothèses et croyances.

Étape 7 – Écrire, transTransmission : écrire, transmettre, enseigner

Écrire, expliquer, partager ce que l’on a compris. Transformer le savoir en outil collectif.

Étape 8 — Cultiver l’équilibre corps-esprit pour soutenir l’érudition

Cultiver le corps et l’esprit pour soutenir l’érudition dans le temps. Le savoir durable repose aussi sur l’attention et l’équilibre personnel.