Claude Platform Docs
MessagesRéflexion

Réflexion préservée

Modifier une conversation entraîne désormais une erreur ou la suppression d'un bloc ; comment vérifier si votre intégration le fait et comment migrer.

Sur Claude Fable 5.1, modifier les tours précédents de la conversation (le prompt system, les tools ou tout message antérieur) affecte la réponse de l'API. Par défaut, l'API rejette alors la requête avec une erreur, sauf si vous choisissez plutôt que les blocs de réflexion concernés soient supprimés de ce que voit le modèle (prefix_mismatch_behavior: "drop_block"). La vérification est appliquée par défaut pour les nouveaux comptes créés à partir du 31 août 2026, 00:00 UTC. Vous trouverez plus de détails dans Fonctionnement et Qui est concerné.

Lorsque vous renvoyez un bloc, l'API utilise sa signature pour vérifier que la conversation antérieure est inchangée et que le modèle actuel peut lire le bloc. Cette vérification existe afin qu'un raisonnement produit sous un ensemble d'instructions ne puisse pas être rejoué sous un autre ensemble d'instructions, potentiellement malveillant.

L'API fournit des alternatives de premier ordre pour modifier une conversation au fur et à mesure de sa progression, couvrant la plupart des cas d'usage des modifications de transcription : les messages système en cours de conversation pour de nouvelles instructions, les messages système limités au tour pour des rappels à chaque tour, les changements d'outils en cours de conversation pour ajouter et retirer des outils, et l'effort par message pour ajuster la profondeur de réflexion à chaque tour. Le reste de cette page explique comment déterminer si votre intégration est concernée et comment migrer les schémas de harnais courants vers ces fonctionnalités. Avantage supplémentaire : conserver tout ce qui précède chaque bloc de réflexion inchangé octet pour octet maintient également le préfixe stable pour le « prompt caching » (mise en cache des prompts), voir mise en cache des prompts.

La nécessité d'agir dépend de ce qui gère votre historique de conversation :

  • Vous utilisez un produit ou SDK officiel Claude : Claude Code, claude.ai, Claude Managed Agents ou le Claude Agent SDK. Ceux-ci conservent le préfixe intact pour vous.
  • Vous appelez directement l'API Messages, depuis votre propre boucle d'agent ou tout autre contexte. Vous devez vérifier votre code et vous assurer que le tableau messages est traité en ajout seul (append-only). Ces schémas courants modifient le préfixe et invalident la réflexion située après la modification :
    • Tronquer ou supprimer les tours les plus anciens
    • Résumer les tours les plus anciens côté client et conserver les plus récents
    • Injecter un rappel dans un tour antérieur et le retirer à la requête suivante
    • Reconstruire le prompt system à chaque requête (heure actuelle, budget de tokens, indicateurs de mode)
    • Ajouter ou retirer des entrées dans tools en cours de session

Fonctionnement

Pour les nouvelles requêtes, l'API vérifie :

  • Le modèle est le même ou plus récent. Un bloc est lisible par le modèle qui l'a produit et par les modèles ultérieurs, pas par les modèles antérieurs. Une conversation qui passe à un modèle plus récent conserve son raisonnement. Une conversation qui passe à un modèle plus ancien échoue à la vérification de modèle pour ces blocs, et l'API les supprime pour cette requête. Consultez Réflexion préservée pour la liste exacte par modèle.
  • Rien avant le bloc n'a changé. Le prompt system de premier niveau, l'ensemble des outils dans tools et chaque message précédant le bloc. Avec la compaction côté serveur, le préfixe vérifié commence au bloc de compaction le plus récent.
  • La chaîne des blocs de réflexion antérieurs est ininterrompue. Les blocs thinking et redacted_thinking antérieurs ne font pas partie du préfixe, mais chaque bloc de réflexion enregistre celui qui le précède, d'un tour à l'autre. Vous pouvez retirer des blocs de réflexion au début de l'historique. En retirer un au milieu invalide tous les blocs de réflexion qui le suivent.

Un bloc qui échoue à la vérification de modèle est toujours supprimé. Pour une non-correspondance de préfixe, vous choisissez ce qui se passe avec thinking.block_binding.prefix_mismatch_behavior, qui nécessite l'en-tête bêta thinking-binding-controls-2026-08-01 :

  • "drop_block" : l'API retire le bloc et tous les blocs de réflexion qui le suivent dans la conversation, et la requête réussit. Les blocs supprimés ne sont pas facturés. La réponse les liste dans un tableau input_transformations de premier niveau (sur l'événement message_start en streaming).
  • "error" : l'API rejette la requête avec une erreur 400 invalid_request_error qui nomme le premier bloc en échec.

La valeur par défaut est "error". L'en-tête vous permet de définir le champ et ajoute input_transformations aux réponses.

Qui est concerné

Claude Fable 5.1. Consultez Réflexion préservée pour la liste des modèles.

Sur Claude Fable 5.1, l'API applique la vérification pour les nouveaux comptes. Un nouveau compte est un compte créé à partir du 31 août 2026, 00:00 UTC. La même définition s'applique sur l'API Claude et sur les plateformes cloud. Les modèles ultérieurs appliqueront la vérification pour tous les utilisateurs.

Une requête qui définit prefix_mismatch_behavior active l'application de la vérification quel que soit l'âge du compte, ce qui vous permet de tester depuis un compte plus ancien. Pour vérifier si la vérification est appliquée par défaut à votre compte, envoyez une requête qui modifie l'historique sans l'en-tête bêta : une erreur 400 qui nomme l'en-tête signifie qu'elle est appliquée.

Comment déterminer si votre intégration est concernée

Capturez les corps de requête exacts que votre intégration envoie sur quelques tours normaux, y compris une compaction ou un changement d'outil si votre produit en effectue. Pour chaque paire de requêtes consécutives, comparez system, tools et la partie commune de messages. Ils doivent être identiques octet pour octet jusqu'aux tours nouvellement ajoutés.

Confirmez ensuite auprès de l'API. Avec l'en-tête bêta thinking-binding-controls-2026-08-01 et claude-fable-5-1, définissez thinking.block_binding.prefix_mismatch_behavior sur "drop_block" et exécutez une session multi-tours normale via votre intégration. Cette requête est le deuxième tour d'une telle session, renvoyant le tour assistant de la première réponse exactement tel qu'il a été reçu :

curl https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
  -d '{
    "model": "claude-fable-5-1",
    "max_tokens": 16000,
    "thinking": {
      "type": "adaptive",
      "block_binding": { "prefix_mismatch_behavior": "drop_block" }
    },
    "system": "You are a coding agent.",
    "messages": [
      { "role": "user", "content": "Fix the failing test." },
      {
        "role": "assistant",
        "content": [
          { "type": "thinking", "thinking": "", "signature": "EqQBCkYIBxgCKkD..." },
          { "type": "text", "text": "I need to see the test first. Which file is it in?" }
        ]
      },
      { "role": "user", "content": "tests/test_auth.py" }
    ]
  }'

Chaque réponse comporte alors un tableau input_transformations de premier niveau. Journalisez-le à chaque tour :

{
  "input_transformations": [
    {
      "type": "thinking_dropped",
      "path": "messages.1.content.0",
      "reason": "prefix_binding_mismatch"
    }
  ]
}
  • Vide à chaque tour : votre intégration conserve l'historique intact.
  • reason: "prefix_binding_mismatch" : quelque chose avant le bloc situé à path a changé entre cette requête et la précédente. Comparez system, tools et messages jusqu'à ce tour pour le trouver.
  • reason: "model_binding_mismatch" : la conversation est passée à un modèle qui ne peut pas lire les blocs du modèle précédent (un routeur, un repli). Ce n'est pas un bug de votre intégration. Continuez à envoyer les blocs et laissez l'API supprimer ce que le modèle actuel ne peut pas lire.

Cela fonctionne depuis n'importe quel compte, car définir le champ active l'application de la vérification pour la requête. Pour échouer bruyamment en CI à la place, définissez "error". L'erreur 400 commence par :

messages.1.content.0: Invalid `signature` in `thinking` block. The block is bound to a different conversation. Remove the block, or set `thinking.block_binding.prefix_mismatch_behavior` to "drop_block".

Sans l'en-tête bêta sur la requête, le message se poursuit ainsi : That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header. Le message se termine généralement par une phrase indiquant ce qui a changé, par exemple que le prompt system ou la liste tools diffère de ce qu'ils étaient lors de la création du bloc.

Consultez Dépannage de la réflexion pour toutes les variantes de cette erreur.

Ce qui compte comme une modification

Entre deux requêtes consécutives :

Changement entre les requêtesBlocs de réflexion ultérieurs
Ajouter des messages à la finValide
Ajouter un outil avec defer_loading: true que rien n'a encore référencéValide
Retirer des blocs thinking au début de l'historique (tous les blocs de réflexion avant un certain point)Valide
Modifier tout paramètre de requête en dehors de system, tools et messages (max_tokens, output_config, tool_choice, metadata, etc.)Valide
Ajouter, déplacer ou retirer des marqueurs cache_controlValide
Une URL signée rotative qui renvoie les mêmes octetsValide
La compaction côté serveur ou l'édition de contexte retire ou remplace du contenuValide (la vérification compare ce que vous avez envoyé, pas la copie modifiée du serveur)
Un message système limité au tour effacé et laissé en placeValide
Modifier, réordonner ou supprimer tout message user, assistant ou system antérieurInvalide
Ajouter un bloc de texte à un tour utilisateur antérieur, ou en retirer un que vous aviez ajouté la fois précédenteInvalide
Modifier la chaîne ou les blocs system de premier niveauInvalide
Ajouter, retirer, renommer ou modifier un outil dans toolsInvalide
Retirer un bloc thinking au milieu de l'historique et conserver les suivantsInvalide pour tous les blocs de réflexion ultérieurs
Une URL d'image ou de document qui renvoie des octets différents à la requête suivanteInvalide
Le même message limité au tour supprimé ou reformulé lors d'une requête ultérieureInvalide

Mettre à jour votre intégration

Chaque schéma remplace un type de modification de l'historique par une fonctionnalité de l'API qui a le même effet sur le modèle sans modifier les octets antérieurs.

Ajouter les tours assistant exactement tels qu'ils sont renvoyés

Stockez le tableau content de chaque réponse et renvoyez-le inchangé comme tour assistant, chaque type de bloc dans l'ordre reçu, y compris les blocs thinking dont le champ thinking est vide. Ne resérialisez pas via un type intermédiaire qui supprime les types de blocs inconnus ou les champs vides.

Ajouter des instructions avec un message système en cours de conversation, et non en modifiant system

Si votre code reconstruit le prompt system de premier niveau à chaque requête (heure actuelle, budget de tokens, indicateur de mode, contexte de projet nouvellement découvert), chaque bloc de réflexion de la conversation échoue à la vérification. Figez system au début de la session et, lorsque quelque chose change, ajoutez un message role: "system" à l'endroit de messages où cela devient vrai :

{
  "role": "system",
  "content": "The user switched the workspace to read-only mode. Do not write files until told otherwise."
}

Le modèle le traite avec l'autorité d'une invite système, et tout ce qui le précède reste inchangé. Aucun en-tête bêta n'est nécessaire sur Claude Fable 5.1. Dans une boucle d'outils, placez-le après le message utilisateur tool_result, jamais entre un tool_use de l'assistant et son tool_result (voir Limitations).

Envoyer les rappels par tour sous forme de messages système limités au tour

La modification d'historique la plus courante est le rappel par tour : une ligne ajoutée après chaque lot de résultats d'outils (« regroupez les lectures indépendantes », « vous n'avez pas informé l'utilisateur depuis un moment ») et retirée à la requête suivante pour que les rappels ne s'accumulent pas. C'est ce retrait qui constitue la modification.

À la place, envoyez le rappel sous forme de message système en cours de conversation avec clear_at: "next_user_message" après le message utilisateur tool_result (en-tête bêta mid-conversation-system-clear-at-2026-08-21). Ce tableau messages est la requête après deux tours d'outils. messages[3] est le rappel de la requête précédente, laissé en place, et messages[6] est la copie de cette requête :

[
  { "role": "user", "content": "Fix the failing test." },
  {
    "role": "assistant",
    "content": [
      { "type": "thinking", "thinking": "", "signature": "..." },
      {
        "type": "tool_use",
        "id": "toolu_01",
        "name": "read_file",
        "input": { "path": "tests/test_auth.py" }
      }
    ]
  },
  {
    "role": "user",
    "content": [{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "..." }]
  },
  {
    "role": "system",
    "clear_at": "next_user_message",
    "content": "Request every independent read in one turn."
  },
  {
    "role": "assistant",
    "content": [
      { "type": "thinking", "thinking": "", "signature": "..." },
      {
        "type": "tool_use",
        "id": "toolu_02",
        "name": "read_file",
        "input": { "path": "src/auth.py" }
      }
    ]
  },
  {
    "role": "user",
    "content": [{ "type": "tool_result", "tool_use_id": "toolu_02", "content": "..." }]
  },
  {
    "role": "system",
    "clear_at": "next_user_message",
    "content": "Request every independent read in one turn."
  }
]

Un message utilisateur contenant uniquement des tool_result compte comme le « prochain message utilisateur », donc messages[3] est déjà effacé : il ne rend rien et ne coûte aucun token d'entrée, mais il est toujours dans le tableau, de sorte que la réflexion dans messages[4] reste valide. messages[6] est ce que le modèle voit à ce tour. Lors des requêtes ultérieures, conservez les deux à leur place et ajoutez la copie suivante après le prochain message tool_result. Les messages limités au tour ne contiennent que du text et n'acceptent pas de cache_control. Placez le point de rupture du cache sur le tour utilisateur précédent. Consultez Messages système limités au tour.

Sans la bêta, ajoutez le rappel sous forme de bloc text après les blocs tool_result dans le même message utilisateur, et laissez les copies antérieures en place. Le modèle agit selon la plus récente.

Modifier les outils avec tool_addition et tool_removal, et non en modifiant tools

Si l'ensemble des outils change en cours de session (un outil se débloque après authentification, un outil dangereux est retiré après un changement de mode), ne modifiez pas tools. Déclarez l'ensemble complet au début de la session et utilisez les changements d'outils en cours de conversation pour proposer ou retirer un outil à partir de ce point (en-tête bêta mid-conversation-tool-changes-2026-07-01). Un outil qui n'est pas encore disponible reçoit defer_loading: true et un bloc tool_addition ultérieur, de même forme que ce tool_removal :

{
  "role": "system",
  "content": [
    { "type": "tool_removal", "tool": { "type": "tool_reference", "name": "delete_branch" } },
    { "type": "text", "text": "Branch deletion is disabled for the rest of this session." }
  ]
}

Un outil dont vous découvrez le schéma en cours de session (un serveur MCP découvert à l'exécution) peut être ajouté à tools avec defer_loading: true et proposé avec tool_addition. Un outil différé non référencé ne fait pas partie du préfixe, donc l'ajouter est sans risque. Ajouter un outil ordinaire ne l'est pas.

Réduire le contexte côté serveur lorsque c'est possible

La troncature et le résumé côté client constituent la deuxième modification la plus courante : supprimer ou résumer les tours les plus anciens et conserver les plus récents tels quels. Les blocs de réflexion des tours récents ont été produits alors que l'historique que vous avez retiré était encore en place, ils échouent donc à la vérification. Les équivalents côté serveur ne comptent pas comme des modifications, car la vérification compare la conversation telle que vous l'avez envoyée :

  • La compaction résume les tours les plus anciens en un bloc de compaction lorsque le contexte approche d'un seuil que vous définissez, et le préfixe vérifié redémarre à partir de ce bloc. Son paramètre instructions accepte votre propre prompt de résumé (« préserver chaque symbole boursier, taille de position et hypothèse énoncée »).
  • L'édition de contexte efface les anciens résultats d'outils (clear_tool_uses_20250919) ou les anciens blocs de réflexion en commençant par les plus anciens (clear_thinking_20251015) selon une règle.

Compaction personnalisée côté client

Cette vérification n'interdit pas la compaction côté client. La règle est plus étroite : ne conservez pas un bloc de réflexion derrière un préfixe que vous avez réécrit.

La compaction simple est la forme recommandée et ne nécessite aucun changement. Lorsque la conversation devient trop longue, résumez-la en un seul message et commencez la requête suivante avec ce résumé plus le nouveau tour utilisateur, sans rejouer aucun tour ni bloc de réflexion antérieur : messages devient [{"role": "user", "content": "<summary of the session so far>\n\n<the next instruction>"}]. Aucune réflexion antérieure ne subsiste, donc rien n'échoue, et le modèle réfléchit à nouveau sur la conversation compactée. Les modèles Claude sont entraînés sur des tâches à long horizon avec ce schéma, et il offre des performances comparables à des schémas plus élaborés pour la plupart des charges de travail. Il réinitialise le cache de prompts au point de compaction, comme toute compaction.

Deux autres formes courantes échouent telles qu'elles sont écrites et nécessitent chacune un changement :

  • La compaction avec conservation de la fin résume les tours les plus anciens et conserve les tours les plus récents tels quels. Les blocs de réflexion des tours conservés ont été produits par rapport à l'historique complet, ils échouent donc derrière le résumé. Correctif : retirez thinking et redacted_thinking de chaque tour assistant que vous reportez, en conservant text et tool_use, ou envoyez prefix_mismatch_behavior: "drop_block" et laissez l'API les retirer.
  • La compaction en arrière-plan construit le résumé hors du chemin critique et le substitue pendant que la conversation se poursuit, de sorte que chaque tour produit entre-temps comporte une réflexion antérieure à la substitution. Correctif : envoyez "drop_block" sur chaque requête qui comporte encore des blocs de réflexion produits avant la substitution (ou retirez ces blocs vous-même ; input_transformations sur la première réponse après la substitution liste exactement lesquels), ou compactez de manière synchrone.

Découper des tours individuels au milieu de la transcription invalide tout ce qui les suit, et aucune forme côté client ne permet de l'éviter. Utilisez un message système en cours de conversation pour le changement d'instruction que vous effectuiez, ou l'édition de contexte côté serveur pour une suppression sélective.

Ne compactez pas au milieu d'un tour d'outils : un tour assistant dont le tool_use attend encore un tool_result doit être renvoyé avec sa réflexion intacte, afin que le modèle termine le tour avec son raisonnement (voir Préserver les blocs de réflexion).

Référencer les fichiers par ID, et non par une URL dont le contenu change

Pour un bloc image ou document avec une source url, les octets récupérés font partie du préfixe vérifié, mais pas la chaîne de l'URL. Un point de terminaison « dernière capture d'écran » ou un document modifié invalide la réflexion ultérieure. Une URL signée rotative pour le même fichier ne le fait pas. Pour le contenu que vous référencez sur plusieurs tours, téléversez-le une fois avec l'API Files et utilisez le file_id, ou envoyez-le en base64.

Décider de ce qui se passe en cas de non-correspondance

Une fois votre intégration en ajout seul, choisissez un prefix_mismatch_behavior pour la production. Il ne régit que les non-correspondances de préfixe. Un bloc que le modèle actuel ne peut pas lire (après un changement de routeur ou un repli côté serveur) est toujours supprimé, et signalé dans input_transformations lorsque l'en-tête bêta est envoyé.

  • "error" (la valeur par défaut) si une non-correspondance de préfixe ne peut signifier qu'un bug dans votre code. Vous l'apprenez par une erreur 400 lors des tests plutôt que par des blocs supprimés silencieusement. Dans l'API Message Batches, la valeur par défaut non définie supprime les blocs en échec au lieu de faire échouer l'élément du lot ; définissez "error" explicitement si vous souhaitez que les éléments échouent.
  • "drop_block" si vous préférez supprimer les blocs concernés plutôt qu'échouer. Journalisez input_transformations.

Si vous interceptez l'erreur 400 en production, réessayer la même requête ne la résoudra pas. Réessayez avec prefix_mismatch_behavior: "drop_block" (et l'en-tête bêta), ce qui retire exactement les blocs en échec, y compris ceux d'un tour assistant dont le tool_use attend encore son tool_result. La suppression ne s'applique qu'à cette requête, continuez donc à envoyer "drop_block" (et l'en-tête bêta) pour le reste de la session. Sans la bêta, retirez tous les blocs thinking et redacted_thinking de l'historique, en laissant en place les blocs text et tool_use de chaque tour, et réessayez une fois. Corrigez ensuite la modification qui en est la cause.

Fonctionnalités de l'API utilisées sur cette page

FonctionnalitéCe qu'elle remplaceStatutEn-tête
Contrôles pour les blocs non préservés (thinking.block_binding.prefix_mismatch_behavior, input_transformations)Choisir entre rejet et suppression en cas de non-correspondance de préfixe, et voir ce qui a été suppriméBêtathinking-binding-controls-2026-08-01
Messages système en cours de conversation (role: "system" dans messages)Reconstruire le prompt system de premier niveauStableAucun
Messages système limités au tour (clear_at: "next_user_message")Injecter un rappel et le supprimer à la requête suivanteBêtamid-conversation-system-clear-at-2026-08-21
Changements d'outils en cours de conversation (tool_addition, tool_removal)Modifier le tableau toolsBêtamid-conversation-tool-changes-2026-07-01
Compaction (instructions pour un prompt de résumé personnalisé)Résumé côté client des anciens toursBêtacompact-2026-01-12
Édition de contexte (clear_tool_uses_20250919, clear_thinking_20251015)Suppression côté client des anciens résultats d'outils ou de la réflexionBêtacontext-management-2025-06-27
API Files (sources file_id)URL dont le contenu change entre les requêtesStableAucun
Effort par message (output_config.effort sur un message role: "system")Modifier l'effort de premier niveau entre les requêtes (protège le cache de prompts, pas la réflexion : l'effort ne fait pas partie du préfixe)Bêtamid-conversation-output-config-2026-07-01

Pour combiner les en-têtes dans une seule requête :

anthropic-beta: thinking-binding-controls-2026-08-01,mid-conversation-system-clear-at-2026-08-21,mid-conversation-tool-changes-2026-07-01

Les mêmes noms de bêta s'appliquent sur Amazon Bedrock et Google Cloud. Consultez En-têtes bêta pour savoir comment les envoyer avec chaque SDK.

Liste de contrôle

  • Si un produit ou SDK officiel Claude (Claude Code, claude.ai, Claude Managed Agents, le Claude Agent SDK) gère votre historique de conversation, arrêtez-vous ici.
  • Les corps de requêtes consécutives sont identiques octet pour octet dans system, tools et le préfixe commun de messages.
  • Une session complète sous prefix_mismatch_behavior: "drop_block" ne journalise aucune entrée prefix_binding_mismatch.
  • Les tours assistant sont renvoyés octet pour octet tels qu'ils ont été reçus, tous types de blocs inclus.
  • system et tools de premier niveau sont fixes pour la session. Les changements passent par des messages role: "system" et des blocs tool_addition / tool_removal.
  • Les rappels par tour sont des messages système limités au tour (ou des blocs de texte en fin de message) qui sont ajoutés à neuf et jamais retirés.
  • Le contexte est réduit par compaction ou édition de contexte, ou par une compaction côté client qui ne laisse aucun bloc de réflexion derrière le préfixe réécrit et ne scinde jamais un tour d'outils.
  • Les fichiers utilisés sur plusieurs tours sont des file_id ou du base64, pas des URL modifiables.
  • Un prefix_mismatch_behavior de production est défini et ses erreurs 400 ou entrées supprimées sont surveillées.

Étapes suivantes

Diagnostiquez et corrigez les échecs de réflexion les plus courants : erreurs 400 de configuration, blocs de réflexion vides ou manquants, arrêts max_tokens et échecs de cache.

Modifiez les instructions système ou la disponibilité des outils au cours d'une conversation sans invalider le préfixe mis en cache qui les précède.

Compaction de contexte côté serveur pour gérer les longues conversations qui approchent des limites de la fenêtre de contexte.

Mettez en cache les préfixes de prompts avec cache_control pour réduire les coûts et la latence, en utilisant la mise en cache automatique ou des points de rupture explicites avec des TTL de 5 minutes ou 1 heure.

Was this page helpful?