Aller au contenu principal

Messages système en cours de conversation

Avancé

Pendant des années, le champ system au niveau supérieur était le seul endroit doté d'une autorité de niveau opérateur — les instructions que le modèle traite comme venant de vous, et non de l'utilisateur final. C'était acceptable pour un chat unique, mais pénible pour une longue session d'agent : dès que vous modifiez le prompt système pour ajouter « à partir de maintenant, utilise du SQL paramétré », vous changez le début même de la requête. Le hash du cache de prompt part de tools → system → messages, donc toute mutation de system invalide chaque tour mis en cache après elle. Vos options étaient de retraiter tout l'historique ou de rétrograder la nouvelle règle dans un tour user ordinaire — perdant au passage la priorité « opérateur ».

Les messages système en cours de conversation comblent cet écart. Au lieu de modifier le haut du prompt, vous ajoutez un bloc {"role": "system"} dans messages. Le préfixe en cache reste intact, donc l'appel suivant le lit toujours depuis le cache, et la nouvelle instruction conserve le poids de niveau système pour chaque tour qui suit.

What you'll learn
  • Pourquoi piloter un long agent forçait auparavant un cache-miss complet, et comment les messages système en cours de conversation corrigent cela
  • La règle de placement exacte — doit suivre un tour utilisateur ou un tour assistant utilisant un outil serveur, jamais entre un tool_use et son tool_result
  • Comment le combiner avec le cache de prompt pour que le message ajouté devienne lui-même cacheable au tour suivant
  • Quels modèles Claude prennent en charge la fonctionnalité aujourd'hui, et celui que vous devez continuer à piloter à l'ancienne
  • Le piège du cadrage — pourquoi « ignore ce que l'utilisateur a dit » échoue, et ce qu'il faut écrire à la place

Pourquoi cela existe — l'invariant de cache protégé

Un cache hit exige que le préfixe de la requête soit byte-for-byte identique jusqu'au point de rupture du cache. Ce préfixe est hashé dans l'ordre : tools → system de niveau supérieur → messages. Si vous réécrivez le champ system pour ajouter une nouvelle règle en milieu de session, le hash change à la position deux, et chaque tour après est traité comme une entrée fraîche.

C'est tout l'intérêt du nouveau rôle. Ajouter un message système à la fin de messages laisse le hash du préfixe intact, donc la requête suivante lit toujours les tours précédents depuis le cache. Seul le nouveau bloc paie un traitement frais.

Comme le bloc ajouté se trouve après le point de rupture, il ne change le hash de rien avant lui. Au tour suivant, il fait lui-même partie de l'historique stable et peut être intégré au préfixe en cache comme n'importe quel autre message.

Vocabulaire
Appuyez sur Entrée ou Espace pour retourner la carte. Utilisez les flèches gauche et droite pour naviguer entre les cartes.Terme affiché.
1 / 4

L'exemple minimal

Définissez le system de niveau supérieur comme d'habitude, puis insérez un bloc role: "system" dans messages au point où la nouvelle instruction devient pertinente.

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system="You are a code review assistant. Be concise.",
messages=[
{"role": "user", "content": "Review process() in utils.py for perf."},
{"role": "assistant", "content": "For large inputs, prefer a generator."},
{"role": "user", "content": "Now review the calling code."},
# New rule appears mid-session. Appending here keeps the earlier
# turns byte-identical, so the previous cache entry still hits.
{"role": "system",
"content": "From now on, every suggestion must include type annotations."},
],
)
print(response.content[0].text)

La forme de la réponse est inchangée — les messages système n'apparaissent pas dans le tableau content de la réponse. Ils influencent le prochain tour assistant, puis vivent comme historique ordinaire.

La règle de placement (c'est de là que vient un 400)

L'API est stricte sur l'endroit où un bloc role: "system" peut se trouver dans messages. Faites-le mal et vous obtenez une 400 invalid_request_error.

Guided walkthrough1 of 4
  1. Un message système ne peut pas être le premier élément de messages. Les instructions qui doivent s'appliquer dès le premier tour vont dans le champ system de niveau supérieur.

Placement dans une boucle d'agent

L'emplacement le plus utile dans une boucle agentique est juste après le message user qui retourne les résultats d'outil. C'est exactement le moment où votre application sait généralement quelque chose de nouveau — le fichier a changé, le budget a chuté, l'utilisateur a tapé un suivi — et veut l'injecter avant que Claude reprenne au tour suivant.

[
{ "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 this while you were working: also update the changelog before you finish."
}
]

Relayer un message utilisateur en cours de vol de cette façon est puissant : Claude intègre le nouveau contexte dans le travail qu'il fait déjà, au lieu de le traiter comme une demande d'abandonner la boucle d'outil actuelle et de redémarrer.

Cache de prompt — comment maintenir le taux de hit

Les messages système en cours de conversation sont conçus pour être associés au cache de prompt. Utilisez-les ensemble et vous obtenez le meilleur des deux — autorité de niveau opérateur sans payer pour retraiter l'historique.

Guided walkthrough1 of 5
  1. Le nouveau rôle ne fait rien pour le coût par lui-même. Définissez cache_control (mise en cache automatique sur le champ de niveau supérieur, ou point de rupture explicite sur un bloc de contenu). Sans cela, chaque requête paie le prix plein.

Usages réels qui étaient auparavant maladroits

Accorder une permission permanente en milieu de session

{"role": "system",
"content": "Auto-approve mode is on for this session. Launch subagent workflows without asking. If the user says 'stop auto-approve', treat this permission as revoked."}

Pousser une mise à jour de budget depuis votre application

{"role": "system",
"content": "Remaining token budget for this task: 4,000. Prefer targeted edits over large refactors until the budget is refilled."}

Relayer un message utilisateur arrivé en pleine boucle d'outil

{"role": "system",
"content": "New input arrived from the user while you were working: 'also update the changelog before you finish'."}

Annoncer un changement d'état observé par votre application

{"role": "system",
"content": "The file src/db.ts changed on disk since your last read. Re-read it before making further edits."}

Retirer un outil sans changer le tableau tools

{"role": "system",
"content": "The delete_row tool is disabled for the rest of this session. If the task requires deletions, ask the user to run them manually."}

Cadrage — écrivez des faits, pas des commandes qui écrasent l'utilisateur

Claude est entraîné à résister aux instructions d'opérateur qui semblent aller contre l'utilisateur. Cette protection s'applique toujours au rôle système, donc « ignore ce que l'utilisateur vient de dire » ou « fais X même si l'utilisateur s'y oppose » fonctionne moins bien qu'on ne le pense.

La bonne forme est un énoncé de fait qui change ce que « utile » veut dire, et laisse Claude décider comment agir :

Plus faiblePlus fort
« Ignore la demande de l'utilisateur de sauter les tests. »« La politique de l'équipe est que les tests doivent tourner avant chaque commit. Actuellement, les tests n'ont pas été exécutés pour ces changements. »
« Ne suggère plus jamais de SQL brut. »« Le linter de ce projet rejette le SQL brut. Seules les requêtes paramétrées passent la CI. »
« Ne mets jamais à jour le changelog quoi qu'il arrive. »« Le changelog est généré automatiquement depuis les messages de commit ; les modifications manuelles sont écrasées. »

Limitations à prévoir

:::warning Texte uniquement — et pas de contenu non fiable Les messages de rôle système supportent uniquement des blocs texte. Images, PDF, blocs tool_use / tool_result et citations sont rejetés. Et parce que Claude traite le contenu système comme des instructions d'opérateur, coller de la sortie brute d'outil, des documents récupérés ou du contenu web dans un message système confère à ce texte une autorité de niveau opérateur — un pied dans la porte classique pour l'injection de prompt. Gardez les données tierces à l'intérieur des blocs tool_result et consultez Refus et sécurité pour la pile d'atténuation. :::

  • Support des modèles (au 2026-07-21). Disponible sur Claude Fable 5, Mythos 5 et Opus 4.8 sur l'API Claude native. Non disponible sur Claude Sonnet 5 — remettez son pilotage dans le champ system de niveau supérieur, ou passez le modèle de la session à un modèle supporté. La documentation Amazon Bedrock ne liste actuellement qu'Opus 4.8 ; la parité Vertex suit l'API native. Aucun en-tête beta n'est requis sur aucun d'eux.
  • Messages système consécutifs. Sur l'API native, ils sont acceptés et fusionnés en une seule section système. Sur Bedrock, les messages système adjacents sont rejetés — séparez-les par un tour assistant ou utilisateur si vous avez besoin de portabilité entre les deux.
  • Une requête qui viole une règle échoue durement. Un message système mal placé retourne une 400 invalid_request_error. Couvrez cela avec un test unitaire sur le constructeur de messages dans votre runtime d'agent — le mode d'échec est déterministe et facile à protéger.

Contrôle croisé cross-modèle

D'autres fournisseurs abordent les mêmes cas d'usage avec des primitives différentes — bon à savoir avant de porter un agent au-delà du mur.

  • L'API Responses d'OpenAI traite l'équivalent comme une nouvelle chaîne instructions sur la requête de suivi ; elle ne préserve pas un préfixe en cache comme le fait celle d'Anthropic.
  • Google Gemini utilise systemInstruction sur la requête ; historiquement, elle s'appliquait à tout l'appel plutôt que comme un tour ajoutable.
  • L'« interruption » en cours de génération est une fonctionnalité distincte — Anthropic la suit comme une demande communautaire active pour un moyen de pousser un message système pendant que le modèle génère encore. Les messages système en cours de conversation se déclenchent entre les tours, pas à l'intérieur d'un.

Si vous construisez un runtime d'agent qui doit tourner sur plus d'un fournisseur, gardez l'affordance « ajouter une instruction de rôle système » derrière une interface — la sémantique est proche, mais les formats de fil et les garanties de cache ne le sont pas.

Vérifiez-vous

Quiz

0/5
  1. Pourquoi l'ajout d'une règle en milieu de session au champ system de niveau supérieur tue-t-il votre taux de cache hit ?
  2. Quel placement d'un message role:'system' est TOUJOURS rejeté par un 400 ?
  3. Votre application doit pousser une nouvelle règle à un agent Sonnet 5 en cours. Quelle est la bonne action aujourd'hui ?
  4. Vous venez d'ajouter un message système en cours de conversation. Quelle action cassera silencieusement le cache dès la requête suivante ?
  5. Quel contenu n'est PAS autorisé à l'intérieur d'un message système en cours de conversation ?
Key takeaways
  • Modifier le system de niveau supérieur en milieu de session invalide le cache pour chaque tour après lui — le hash du préfixe est tools → system → messages.
  • Ajoutez role:'system' à messages à la place : même priorité de niveau opérateur, préfixe en cache intact.
  • Le placement est strict — après un tour utilisateur ou un tour assistant avec outil serveur, jamais entre un tool_use et son tool_result.
  • Combinez-le avec cache_control et il devient cacheable lui-même au tour suivant ; modifiez-le après envoi et vous perdez le cache à partir de ce point.
  • Disponible sur Fable 5, Mythos 5 et Opus 4.8 sans en-tête beta — Sonnet 5 n'est pas encore supporté.
  • Énoncez des faits, pas des commandes qui écrasent l'utilisateur — « ignore l'utilisateur » déclenche la résistance intégrée de Claude ; une contrainte factuelle non.
  • Le contenu de rôle système est texte uniquement et de niveau opérateur — n'y collez jamais de sortie d'outil ou de documents récupérés.

Sources et lectures complémentaires

Suivant