La gestion du contexte
Sur cette page
Un agent qui travaille longtemps accumule : résultats d’outils, pages lues, réflexions, réponses. Tout cela occupe la fenêtre de contexte, et chaque requête la refacture. La leçon officielle présente les quatre approches publiées par Anthropic pour rester dans la fenêtre sans perdre ce qui compte : trois fonctionnalités de l’API et un principe de conception. Chacune répond à une panne différente : le coût, la taille de la fenêtre, l’oubli d’une session à l’autre.
La fenêtre de contexte, une mémoire de travail
La documentation définit la fenêtre de contexte comme tout le texte auquel le modèle peut se référer pour produire sa réponse, réponse comprise. Ce n’est pas le corpus d’entraînement, c’est une mémoire de travail. Tout ce que Claude voit à un tour y entre :
- le prompt système et l’historique des messages ;
- les définitions d’outils et leurs résultats ;
- les fichiers joints et les skills ;
- la réponse produite, réflexion comprise.
Les modèles actuels ont une fenêtre d’un million de jetons et produisent jusqu’à 128 000 jetons par requête. Si l’entrée seule dépasse la fenêtre, l’API refuse la requête (erreur 400 « prompt is too long »). Si c’est la génération qui atteint la limite, la réponse s’arrête avec stop_reason: "model_context_window_exceeded".
La documentation prévient aussi que plus de contexte n’est pas automatiquement mieux : à mesure que le nombre de jetons grandit, la précision et la capacité à retrouver une information baissent, un phénomène qu’elle appelle context rot (l’érosion du contexte). Le but n’est donc pas de tout faire entrer, mais de faire entrer ce qu’il faut.
Pour savoir où vous en êtes, le point d’accès de comptage (messages.countTokens dans le SDK TypeScript) estime les jetons d’une requête avant l’envoi. Comptez avec le modèle que vous utiliserez : depuis Claude Opus 4.7, un nouveau découpage produit environ 30 % de jetons de plus pour le même texte, et un compte mesuré sur un ancien modèle sous-estime le coût.
1. Charger juste à temps
C’est le principe de conception des quatre : rien de particulier dans l’API, seulement un choix délibéré de ce qu’on charge et quand. Ne mettez pas tout dans la requête dès le départ. Chargez ce dont l’agent a besoin maintenant, et laissez-le aller chercher le reste par ses outils.
L’exemple de la leçon officielle est un agent de contrôle de conformité. Il ne reçoit pas tout le code de la construction dans son prompt système : il appelle un outil lookup_building_code quand il a besoin d’un article précis. Le même principe vaut pour les outils eux-mêmes : quand un agent en a des dizaines, l’outil de recherche d’outils ne charge leurs définitions qu’à la demande (defer_loading: true), au lieu de toutes les envoyer à chaque requête.
2. Résumer l’historique : la compaction
La compaction remplace les tours anciens par un résumé que Claude rédige côté serveur, pour qu’une conversation continue au-delà de la fenêtre. La forme présentée par la leçon officielle est la compaction à un seuil : une entrée compact_20260112 dans context_management, et l’API résume d’elle-même quand l’entrée atteint le seuil, par défaut 150 000 jetons (50 000 au minimum).
const response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "claude-opus-5-5",
max_tokens: 4096,
messages,
context_management: { edits: [{ type: "compact_20260112" }] },
});
// Ajoutez la réponse entière, bloc de compaction compris
messages.push({ role: "assistant", content: response.content });
La documentation décrit trois façons de compacter :
| Compaction à la demande | Compaction à un seuil | Votre propre résumé | |
|---|---|---|---|
| Qui décide quand | Vous, en envoyant une requête | L’API, quand le seuil de jetons est atteint | Vous |
| Ce que vous écrivez | Une boucle qui demande le résumé et le met en place | Un paramètre sur vos requêtes ordinaires | L’appel de résumé, son prompt et la réécriture de l’historique |
| Quand la choisir | Contrôler le moment, ne pas bloquer pendant le résumé, garder les tours récents | Laisser l’API gérer le contexte dans les requêtes ordinaires | Vous avez déjà votre propre système de résumé |
Les deux premières sont en bêta, et la documentation recommande la compaction à la demande partout où elle est disponible (en-tête compact-2026-09-04, paramètre compaction). Une règle vaut dans tous les cas : ajoutez à votre historique tout le contenu de la réponse (response.content), pas seulement son texte, sinon vous perdez les blocs de compaction et l’état qui va avec.
Plus léger qu’un résumé, l’édition du contexte (context editing, en bêta, en-tête context-management-2025-06-27) efface avant que le modèle ne la voie une partie de ce qui ne sert plus : les anciens résultats d’outils (clear_tool_uses_20250919) ou les anciens blocs de réflexion (clear_thinking_20251015).
3. Mettre en cache ce qui ne change pas
Le cache de prompt évite de repayer plein tarif un début de requête identique d’un appel à l’autre : instructions système, définitions d’outils, gros document de référence. C’est une correspondance de préfixe : le moindre octet qui change invalide tout ce qui suit. Placez donc le contenu stable en premier et le contenu variable (date, identifiants de requête, question du jour) après le point de cache.
const response = await client.messages.create({
model: "claude-opus-5-5",
max_tokens: 4096,
system: [
{
type: "text",
text: documentDeReference,
cache_control: { type: "ephemeral" }, // point de cache : fin de la partie stable
},
],
messages: [{ role: "user", content: question }], // la partie variable vient après
});
console.log(response.usage.cache_read_input_tokens); // jetons servis depuis le cache
Le point de cache se pose sur le dernier bloc identique d’une requête à l’autre : l’API n’écrit une entrée qu’à cet endroit. Un cache_control placé au niveau de la requête (le cache automatique) le pose sur le dernier bloc. C’est pratique pour une conversation qui s’allonge, mais sans effet si ce dernier bloc est une question qui change à chaque appel.
Le calcul compte plus qu’il n’y paraît. Reprenons l’exemple de la leçon officielle, un prompt système de 4 000 jetons envoyé 100 fois par heure, avec les tarifs d’Opus 5.5 au 5 novembre 2026 : 4 $ par million de jetons d’entrée, 5 $ pour une écriture en cache de 5 minutes, 0,20 $ pour une lecture.
| Prompt système, 100 appels par heure | Coût par heure |
|---|---|
| Sans cache : 400 000 jetons au tarif d’entrée | 1,60 $ |
| Avec cache : une écriture, puis 99 lectures | environ 0,10 $ |
Le cache de 5 minutes se prolonge sans frais à chaque lecture : à un appel toutes les 36 secondes, il ne refroidit jamais. Si cache_read_input_tokens reste à zéro sur des requêtes répétées, trois causes reviennent souvent. Le point de cache est posé sur un bloc qui change. Ou le préfixe change sans bruit : une date dans le prompt système, des clés JSON dans un ordre variable, une liste d’outils qui change. Ou il est trop court : en dessous du minimum du modèle, 512 jetons sur Opus 5.5, rien n’est mis en cache, et l’API ne renvoie aucune erreur.
4. Garder la mémoire entre les sessions : l’outil memory
Certaines informations doivent survivre à la conversation : les préférences d’un utilisateur, les notes de travail de l’agent, ce qui a été décidé la semaine passée. La primitive recommandée est l’outil memory :
tools: [{ type: "memory_20250818", name: "memory" }]
- Claude lit et écrit des fichiers dans un répertoire
/memories, par des appels d’outil. - L’outil s’exécute côté client : c’est votre application qui stocke, dans un système de fichiers, une base de données ou un stockage chiffré. Votre gestionnaire doit refuser tout chemin hors de
/memories. - Quand l’outil est activé, Claude consulte de lui-même son répertoire de mémoire avant de commencer une tâche.
Le SDK TypeScript fournit un assistant, betaMemoryTool, qui gère l’interface de l’outil pour un stockage de votre choix.
Combiner les quatre
En production, on superpose généralement les quatre. L’agent de conformité met en cache son prompt système et ses définitions d’outils, et va chercher les articles du code au moment voulu. Une conversation qui s’allonge se compacte, et ce qui doit durer passe par la mémoire. Choisissez d’après ce qui casse chez vous : la facture, la taille de la fenêtre ou l’oubli. Les agents gérés, présentés dans les leçons suivantes, compactent l’historique de leurs sessions sans que vous ayez rien à écrire.
À vous de jouer
Mesurer avant d’optimiser. Comptez les jetons d’une requête longue avec le point d’accès de comptage, puis envoyez-la deux fois avec un point de cache : cache_read_input_tokens doit passer de zéro à une valeur positive. Si ce n’est pas le cas, vérifiez où est posé le point de cache et la longueur du préfixe, puis cherchez ce qui change d’une requête à l’autre.
Sources officielles : Context management (Claude Academy) · Context windows · Token counting · Compaction · Compaction at a token threshold · Context editing · Prompt caching · Memory tool
Points clés à retenir
- La fenêtre de contexte (un million de jetons) est une mémoire de travail ; plus n’est pas toujours mieux
- Quatre approches : charger juste à temps, compacter, mettre en cache, garder une mémoire
- Le cache de prompt est une correspondance de préfixe : le stable d’abord, le point de cache à sa fin, le variable ensuite
- Ajoutez toujours
response.contentcomplet à l’historique ; l’outilmemory, côté client, conserve ce qui doit durer