Les instructions système résident normalement dans le champ system de niveau supérieur, avant tous les messages de la conversation. Cette position est idéale pour la mise en cache des prompts : l'invite système fait partie du préfixe stable, de sorte que les tours suivants bénéficient du cache. C'est en revanche une mauvaise position pour les instructions dont vous ne découvrez le besoin qu'en cours de session, car modifier le champ system de niveau supérieur change le tout début du prompt et invalide le cache pour tout ce qui suit.
Les messages système en cours de conversation comblent cette lacune. Vous ajoutez un message {"role": "system"} à l'endroit de la conversation où la nouvelle instruction devient pertinente, au lieu de modifier le champ system de niveau supérieur. Le préfixe mis en cache reste identique, de sorte que la requête suivante le lit toujours depuis le cache, et la nouvelle instruction est toujours appliquée comme une instruction système plutôt que comme du texte utilisateur ordinaire.
Cette page couvre deux fonctionnalités : les messages système en cours de conversation, qui sont disponibles de manière générale, et les changements d'outils en cours de conversation, une version bêta introduite avec Claude Opus 5 qui applique la même approche au tableau tools.
Le tableau tools se situe encore plus tôt dans le préfixe de requête haché que le champ system de niveau supérieur, de sorte que le modifier invalide la mise en cache des prompts pour l'ensemble de la conversation. Les changements d'outils en cours de conversation, une version bêta introduite avec Claude Opus 5, sont l'équivalent pour les outils des messages système en cours de conversation. Au lieu de figer la liste des outils pour toute la durée de la conversation, vous modifiez les outils proposés au modèle entre les tours : déclarez l'ensemble complet des outils dans tools dès le départ, puis utilisez des blocs tool_addition et tool_removal pour proposer un outil au modèle, ou le retirer, à partir d'un point spécifique de la conversation. Le tableau tools lui-même ne change jamais, de sorte que le préfixe mis en cache reste intact.
tool_addition et tool_removal sont des blocs de contenu dans le tableau content d'un message role: "system", et ils peuvent être mélangés avec des blocs text dans le même message. Le message suit les mêmes règles de placement que tout message système en cours de conversation (voir Limitations), et le changement s'applique à partir de ce point de la conversation. Le champ tool de chaque bloc référence un outil plutôt que d'en définir un : {"type": "tool_reference", "name": "..."} nomme un outil déclaré dans le tableau tools de la requête, et les outils du connecteur MCP peuvent être référencés individuellement avec mcp_tool_reference (server_name et name) ou en tant qu'ensemble d'outils complet avec mcp_toolset_reference (server_name). Référencer un nom qui n'est pas déclaré dans tools renvoie une erreur 400.
Chaque outil déclaré dans tools est proposé au modèle dès le début de la conversation, sauf s'il est déclaré avec defer_loading: true, ce qui le maintient retenu jusqu'à ce qu'un bloc tool_addition le fasse apparaître. tool_addition propose également à nouveau un outil qu'un tool_removal antérieur avait retiré.
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5",
max_tokens=1024,
betas=["mid-conversation-tool-changes-2026-07-01"],
# L'ensemble complet d'outils est déclaré dès le départ et ne change jamais, donc le
# préfixe mis en cache reste intact.
tools=[
{
"name": "get_weather",
"description": "Get the current weather for a location.",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"},
},
"required": ["location"],
},
},
],
messages=[
{
"role": "user",
"content": "Say OK.",
},
# Retirez get_weather à partir de ce point. Le bloc référence
# l'outil par son nom au lieu de modifier `tools`, ainsi les tours précédents restent
# identiques à l'octet près et le cache est toujours utilisé.
{
"role": "system",
"content": [
{
"type": "tool_removal",
"tool": {"type": "tool_reference", "name": "get_weather"},
},
],
},
],
)
for block in response.content:
if block.type == "text":
print(block.text)Les changements d'outils en cours de conversation sont en version bêta. Pour les utiliser, incluez l'en-tête bêta mid-conversation-tool-changes-2026-07-01 dans vos requêtes. Ils sont disponibles sur Claude Fable 5, Claude Mythos 5, Claude Opus 4.8 et Claude Opus 5, sur l'API Claude, Amazon Bedrock et Google Cloud.
La mise en cache des prompts hache le préfixe de la requête dans l'ordre : tools, puis system, puis messages. Un succès de cache nécessite que le préfixe corresponde exactement à une requête récente, octet par octet, jusqu'au point d'arrêt du cache.
Cet ordre signifie que le champ system de niveau supérieur se situe tout près du début du préfixe haché. Toute modification de celui-ci, même l'ajout d'une phrase, produit un hachage différent, et la requête manque le cache pour l'invite système et tous les messages mis en cache qui la suivent.
Les messages système en cours de conversation vous permettent d'ajouter l'instruction à la fin de l'historique des messages à la place. Tout ce qui précède la nouvelle instruction reste inchangé, de sorte que l'entrée de cache existante correspond toujours, et seul le nouveau message est traité comme une entrée nouvelle.
Voici quelques situations où cela est important :
system de niveau supérieur retraiterait l'intégralité de l'historique.Dans tous ces cas, vous pourriez placer l'instruction dans un message user ordinaire, et Claude suit effectivement les instructions qui arrivent dans les tours utilisateur. La différence réside dans la priorité : un message user est traité comme provenant de l'utilisateur final, tandis qu'un message system est traité comme provenant de vous, l'opérateur de l'application. Lorsque les deux entrent en conflit, les instructions système ont la priorité ; utilisez donc le rôle system pour les faits et contraintes de niveau opérateur qui doivent tenir même si l'utilisateur final demande quelque chose de différent. Un message système en cours de conversation conserve cette priorité de niveau opérateur sans payer le coût d'échec de cache lié à la modification du champ system de niveau supérieur.
Ajoutez un message avec "role": "system" au tableau messages. Utilisez une chaîne simple ou des blocs de contenu pour content, de la même manière que pour un tour user ou assistant. L'instruction s'applique à partir de ce point de la conversation. Lorsque des instructions entrent en conflit, les messages système ultérieurs ont la priorité sur les précédents, et les messages système en cours de conversation ont la priorité sur le champ system de niveau supérieur pour les tours qui les suivent.
Vous pouvez toujours définir le champ system de niveau supérieur pour les instructions qui doivent s'appliquer à l'ensemble de la conversation. Réservez les messages système en cours de conversation aux instructions qui ne deviennent pertinentes que plus tard, ou que vous souhaitez ajouter sans invalider le préfixe mis en cache.
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
# Mise en cache des prompts automatique : chaque requête met en cache la conversation jusqu'ici,
# et la requête suivante lit le préfixe inchangé depuis le cache.
cache_control={"type": "ephemeral"},
system="You are a code review assistant. Be concise.",
messages=[
{
"role": "user",
"content": "Review process() in utils.py for performance issues.",
},
{
"role": "assistant",
"content": "The list comprehension is fine for small inputs. For large inputs, consider a generator to avoid materializing the full list.",
},
{
"role": "user",
"content": "Now review the calling code that invokes process().",
},
# Le relecteur réalise en cours de session que toutes les suggestions doivent
# aussi respecter la politique de typage strict de l'équipe. Ajouter
# l'instruction ici garde les tours précédents identiques à l'octet près,
# donc le préfixe mis en cache par la requête précédente est toujours lu depuis le cache.
{
"role": "system",
"content": "From now on, every suggestion must include explicit type annotations.",
},
],
)
for block in response.content:
if block.type == "text":
print(block.text)Cet exemple active la mise en cache automatique avec le champ cache_control de niveau supérieur. La mise en cache des prompts est optionnelle : si une requête ne comporte aucun champ cache_control (automatique ou point d'arrêt explicite), rien n'est mis en cache et chaque requête paie le prix normal des tokens d'entrée pour l'intégralité de la conversation. Avec la mise en cache activée, l'ajout du message système laisse les tours déjà mis en cache inchangés, de sorte que la requête qui porte la nouvelle instruction les lit toujours depuis le cache au lieu de les traiter à nouveau. La mise en cache nécessite également que la conversation atteigne la longueur minimale de prompt pouvant être mise en cache ; un exemple aussi court que celui-ci se situe en dessous de ce seuil, de sorte que cache_creation_input_tokens et cache_read_input_tokens restent à 0 jusqu'à ce que la conversation s'allonge.
Un message système en cours de conversation doit immédiatement suivre un tour user (ou un tour assistant se terminant par un résultat d'outil serveur), et doit soit être la dernière entrée dans messages, soit être immédiatement suivi d'un tour assistant. Un message user qui porte des blocs tool_result compte : dans une boucle agentique, vous pouvez placer le message système juste après les résultats d'outils, avant le prochain tour de Claude. Toute autre position, y compris entre un bloc tool_use de l'assistant et le tool_result qui y répond, renvoie une erreur 400.
Dans une boucle agentique, le message système se place après le message user qui livre les résultats d'outils. C'est également là que votre application peut relayer une entrée que l'utilisateur a saisie pendant que Claude travaillait, afin que le nouveau contexte soit absorbé sans redémarrer le tour :
[
{ "role": "user", "content": "Run the test suite and fix any failures." },
{
"role": "assistant",
"content": [{ "type": "tool_use", "id": "toolu_01", "name": "run_tests", "input": {} }]
},
{
"role": "user",
"content": [
{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "12 passed, 0 failed" }
]
},
{
"role": "system",
"content": "The user sent the following message while you were working: also update the changelog before you finish."
}
]Formulez le contenu système comme du contexte plutôt que comme une commande qui supplante l'utilisateur. Énoncez le fait (« une nouvelle entrée est arrivée de l'utilisateur : X », « le budget de tokens restant est maintenant de Y ») et laissez Claude agir en conséquence. Claude est entraîné à résister aux instructions qui semblent aller à l'encontre de l'utilisateur, et cette protection s'applique toujours au rôle système ; un langage tel que « ignore ce que l'utilisateur a dit » est donc moins efficace que d'énoncer ce qui a changé.
Ce schéma sert à relayer une entrée provenant de l'utilisateur final de la conversation elle-même. Ne l'utilisez pas pour transmettre des sorties d'outils, des documents récupérés ou d'autres contenus tiers ; conservez ce contenu dans des blocs tool_result (voir Limitations).
Les messages système en cours de conversation et la mise en cache des prompts sont conçus pour être utilisés ensemble :
cache_control, soit le champ de mise en cache automatique de niveau supérieur, soit un point d'arrêt explicite sur un bloc de contenu. Un message système en cours de conversation ne crée pas d'entrée de cache à lui seul, et sans mise en cache activée, il n'y a aucune économie à préserver.cache_control sur le dernier bloc qui reste identique d'une requête à l'autre, qu'il s'agisse de la fin du champ system de niveau supérieur, de la fin de vos définitions d'outils ou d'un point stable dans l'historique des messages.Évitez de modifier ou de supprimer un message système en cours de conversation qui a déjà été envoyé. Comme toute autre modification de messages antérieurs, cela invalide le cache à partir de ce point. Si l'instruction doit évoluer, ajoutez un nouveau message système plutôt que de réécrire l'ancien. Les messages système consécutifs sont acceptés et traités comme une seule section système, qui suit la même règle de placement dans son ensemble.
system ne peut pas être la première entrée dans messages. Utilisez le champ system de niveau supérieur pour les instructions qui s'appliquent dès le tout début.system doit immédiatement suivre un tour user (y compris un tour user qui porte des blocs tool_result) ou un tour assistant se terminant par un résultat d'outil serveur, et doit précéder un tour assistant ou terminer le tableau. Il ne peut pas se situer entre un bloc tool_use et son tool_result. Le placer ailleurs renvoie une erreur 400.tool_result et continuez à suivre Atténuer les jailbreaks et les injections de prompt.Comment fonctionne la mise en cache, où placer les points d'arrêt et comment lire les champs d'utilisation du cache.
Découvrez exactement où deux requêtes ont divergé lorsqu'un succès de cache attendu ne se produit pas.
Structure des messages, conversations multi-tours et champ system.
Rédiger des prompts et des instructions système efficaces.
Comment les blocs tool_use et tool_result sont structurés dans le tableau messages.
Was this page helpful?