Cette fonctionnalité est éligible à la Zero Data Retention (ZDR) avec une rétention technique limitée. Consultez la section Rétention des données pour plus de détails sur ce qui est conservé et pourquoi.
La mise en cache des prompts réduit considérablement la latence et les coûts, mais uniquement lorsque le début de votre prompt est identique octet par octet à une requête récente. Un outil réordonné, un horodatage interpolé dans votre invite système ou une modification d'un message antérieur peut invalider silencieusement le cache. Sans les diagnostics de cache, le seul signal est usage.cache_read_input_tokens qui tombe à zéro, sans aucune indication de ce qui a changé.
Les diagnostics de cache comblent cette lacune. Transmettez l'id de votre réponse précédente, et l'API compare les deux requêtes et vous indique où elles ont divergé (le modèle, l'invite système, les outils ou l'historique des messages) afin que vous puissiez corriger la cause première au lieu de deviner.
Les diagnostics de cache sont en version bêta. Incluez l'en-tête bêta cache-diagnosis-2026-04-07 dans vos requêtes API pour utiliser cette fonctionnalité.
Les diagnostics de cache sont actuellement disponibles uniquement sur l'API Claude. Ils ne sont pas pris en charge sur Amazon Bedrock ni sur Vertex AI.
Lorsque l'en-tête bêta est présent, l'API stocke une empreinte légère de chaque requête, indexée par l'id de la réponse. Lors de votre requête suivante, incluez cet id en tant que diagnostics.previous_message_id. L'API reconstruit l'empreinte pour la nouvelle requête, la compare à celle stockée et joint un objet diagnostics à la réponse décrivant le premier point de divergence.
La comparaison porte sur la structure de la requête, indépendamment du fait que le cache ait effectivement été utilisé ou non. Consultez Lire les diagnostics conjointement avec l'utilisation pour savoir comment combiner le résultat diagnostics avec usage.cache_read_input_tokens.
Les empreintes contiennent uniquement des hachages et des estimations de nombre de tokens (jamais le contenu brut du prompt), sont conservées pendant une durée limitée, sont limitées à votre organisation et à votre espace de travail, et ne sont utilisées à aucune autre fin.
Envoyez l'en-tête bêta à chaque tour. Au premier tour, transmettez "previous_message_id": null pour activer la fonctionnalité sans message antérieur à comparer. Aux tours suivants, transmettez l'id de la réponse précédente.
Dans les réponses en streaming, diagnostics apparaît dans l'événement message_start.
L'événement message_start contient le champ diagnostics complet ; consultez Format de réponse pour les valeurs possibles.
Dans une conversation multi-tours, reportez le dernier id de réponse en tant que previous_message_id à chaque tour. La première itération transmet null pour activer la fonctionnalité ; chaque itération suivante transmet l'id de la réponse précédente.
Le champ diagnostics sur le Message de réponse a quatre états possibles :
| Valeur | Signification |
|---|---|
| champ absent | La requête n'incluait pas diagnostics, ou l'en-tête bêta était manquant. |
null | Soit previous_message_id était null (premier tour, rien à comparer), soit une comparaison a été effectuée et n'a trouvé aucune divergence. |
{"cache_miss_reason": null} | La comparaison était encore en cours lorsque la réponse a été sérialisée. Cela peut se produire lorsque la réponse démarre très rapidement. Considérez ce résultat comme non concluant et vérifiez au tour suivant. |
{"cache_miss_reason": {...}} | Un cache_miss_reason est joint. Pour les types *_changed, cela identifie le premier point de divergence ; previous_message_not_found et unavailable sont des cas où aucune comparaison n'a été produite. |
Lorsque cache_miss_reason n'est pas null, il ressemble à ceci :
{
"id": "msg_01Xyz...",
"type": "message",
"role": "assistant",
"content": [{ "type": "text", "text": "..." }],
"usage": {
"input_tokens": 42,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 41850,
"output_tokens": 210
},
"diagnostics": {
"cache_miss_reason": {
"type": "system_changed",
"cache_missed_input_tokens": 41850
}
}
}cache_miss_reason est une union discriminée sur type. La réponse signale uniquement la divergence la plus précoce, donc corrigez-la en premier ; les suivantes peuvent être masquées derrière elle.
| Type | Signification | Ce qu'il faut changer |
|---|---|---|
model_changed | Le model diffère de la requête précédente (par exemple, un routeur, un test A/B ou un mécanisme de secours a sélectionné un modèle différent). Le cache est propre à chaque modèle. | Maintenez le modèle constant au sein d'une conversation mise en cache. |
system_changed | Le paramètre system diffère. Généralement, un horodatage, un identifiant de requête ou une autre valeur propre à chaque requête a été interpolé dans l'invite système. | Faites de l'invite système une constante stable au niveau des octets et déplacez les données dynamiques dans le premier message user après votre point de rupture de cache. |
tools_changed | Le tableau tools diffère : des outils ont été ajoutés, supprimés ou réordonnés entre les tours, ou le JSON input_schema des outils a été sérialisé de manière non déterministe. | Envoyez la même liste d'outils à chaque tour dans un ordre fixe avec des schémas sérialisés de manière déterministe (par exemple, triez les clés). |
Les quatre types *_changed comportent également un entier cache_missed_input_tokens : une estimation du nombre de tokens d'entrée situés après le point de divergence, vous donnant une idée de la quantité de préfixe pouvant être mis en cache qui a été perdue. Il est dérivé des longueurs en octets avant la tokenisation, donc considérez-le comme un indicateur d'ordre de grandeur plutôt qu'un chiffre de facturation. Il peut différer de (et occasionnellement dépasser) usage.input_tokens.
diagnostics répond à la question « ma requête a-t-elle changé ? » tandis que usage.cache_read_input_tokens répond à « le cache a-t-il été utilisé ? ». Les combiner vous indique où chercher.
Cette matrice s'applique aux tours où vous avez transmis un previous_message_id réel. Au premier tour (previous_message_id: null), diagnostics est toujours null et cache_read_input_tokens est normalement zéro car le cache est en cours d'écriture, pas de lecture ; aucun dépannage n'est nécessaire. La matrice ne s'applique pas non plus lorsque cache_miss_reason est null (la comparaison est encore en attente ; vérifiez au tour suivant) ou lorsque son type est previous_message_not_found ou unavailable (aucune comparaison n'a été produite).
| Résultat des diagnostics | Tokens lus depuis le cache | Interprétation |
|---|---|---|
null | élevé | Fonctionne comme prévu. Votre préfixe est stable et le cache a été utilisé. |
null | faible ou zéro | Vos requêtes correspondent mais l'entrée de cache n'était plus disponible. Envisagez de raccourcir les intervalles entre les tours ou d'utiliser la durée de vie du cache de 1 heure. |
cache_miss_reason est un type *_changed | faible ou zéro | Votre bug. La requête a changé ; corrigez la cause indiquée par type. |
cache_miss_reason est un type *_changed | élevé | Rare. Un changement s'est produit tard dans le prompt mais un point de rupture cache_control antérieur a quand même été utilisé. Vaut la peine d'être corrigé, mais impact faible. |
previous_message_id expirent après une courte période. Effectuez les comparaisons de diagnostic entre des requêtes rapprochées dans le temps.unavailable plutôt qu'un emplacement précis.unavailable, ou cache_miss_reason: null lorsque la comparaison était encore en cours.Les diagnostics de cache sont éligibles ZDR (qualifiés). Anthropic ne stocke pas le texte brut de vos prompts ni les sorties de Claude pour cette fonctionnalité.
L'empreinte stockée pour chaque requête se compose uniquement de hachages cryptographiques et d'estimations de nombre de tokens, indexée par l'id de la réponse et limitée à votre organisation et à votre espace de travail. Les empreintes expirent après une courte période et ne sont utilisées à aucune autre fin.
Pour l'éligibilité ZDR sur l'ensemble des fonctionnalités, consultez API et rétention des données.
Was this page helpful?
client = anthropic.Anthropic()
SYSTEM = "You are an AI assistant analyzing a large document. <document>...</document>"
# Tour 1 : activer l'option avec previous_message_id=None
r1 = client.beta.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[{"role": "user", "content": "Summarize section 1."}],
diagnostics={"previous_message_id": None},
betas=["cache-diagnosis-2026-04-07"],
)
# Tour 2 : référencer l'identifiant de la réponse précédente
r2 = client.beta.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[
{"role": "user", "content": "Summarize section 1."},
{"role": "assistant", "content": r1.content},
{"role": "user", "content": "Now summarize section 2."},
],
diagnostics={"previous_message_id": r1.id},
betas=["cache-diagnosis-2026-04-07"],
)
diagnostics = r2.diagnostics
if diagnostics is None:
print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
print("Comparison still pending.")
else:
print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")# Tour 2 : streaming, en référençant l'identifiant de la réponse précédente
with client.beta.messages.stream(
model="claude-opus-4-8",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system=SYSTEM,
messages=[
{"role": "user", "content": "Summarize section 1."},
{"role": "assistant", "content": r1.content},
{"role": "user", "content": "Now summarize section 2."},
],
diagnostics={"previous_message_id": r1.id},
betas=["cache-diagnosis-2026-04-07"],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
print()
r2 = stream.get_final_message()
diagnostics = r2.diagnostics
if diagnostics is None:
print("No divergence detected.")
elif diagnostics.cache_miss_reason is None:
print("Comparison still pending.")
else:
print(f"cache_miss_reason: {diagnostics.cache_miss_reason.type}")messages_changed | Le modèle, le système et les outils correspondent tous, mais une entrée antérieure dans messages a été modifiée, réordonnée ou supprimée plutôt qu'ajoutée à la fin. Généralement, l'historique de conversation a été tronqué ou modifié, ou les tours de l'assistant et les blocs tool_result ont été re-sérialisés différemment lors du renvoi. | Traitez l'historique comme étant en ajout uniquement ; renvoyez le content de l'assistant et les résultats d'outils textuellement. |
previous_message_not_found | Aucune empreinte stockée n'existe pour le previous_message_id fourni. Ce n'est pas une preuve que votre requête a changé. Généralement, la requête précédente ne portait pas l'en-tête bêta, elle provenait d'un espace de travail différent, ou trop de temps s'est écoulé depuis son envoi. | Envoyez l'en-tête bêta à chaque tour et gardez les tours consécutifs rapprochés dans le temps. |
unavailable | Les informations de diagnostic n'étaient pas disponibles pour cette requête. Cela inclut le cas où model, system et tools correspondent mais où un autre paramètre de requête affectant le prompt (tool_choice, thinking, context_management, output_config, output_format ou l'ensemble des en-têtes anthropic-beta actifs) diffère, ainsi que les conversations très longues où la divergence se situe au-delà de l'horizon de comparaison. Votre requête a été traitée normalement. | Maintenez constants les paramètres de requête affectant le prompt pendant toute la durée de vie d'une conversation mise en cache. Si le problème persiste, appliquez les vérifications manuelles décrites sous Résolution des problèmes courants sur la page de mise en cache des prompts. |