Aller au contenu
24/30Chapitre 24 sur 30

Context Engineering : pourquoi votre agent devient moins fiable au tour 40

Déplacer un fait trois lignes plus bas dans un prompt qui occupe 2,6 % de la fenêtre fait chuter la récupération de 84 % à 19 %.

Dans cet article

Voici un prompt envoyé 288 fois au même modèle avec un décodage greedy. Il fait 853 tokens. Il contient un registre de vingt-cinq tickets de support — ville, file, priorité, propriétaire, extension — et une question : Marta Ferreira attend un rappel au sujet de son ticket. Quelle est l’extension de ligne directe pour ce ticket ?

Le registre est identique à chaque fois. Le modèle est identique à chaque fois. La seule chose qui change est laquelle des vingt-cinq lignes contient la réponse.

emplacement de la réponseréussitestaux de récupérationintervalle à 95 %
1 sur 2527/3284 %68–93 %
4 sur 256/3219 %9–35 %
7 sur 256/3219 %9–35 %
10 sur 259/3228 %16–45 %
13 sur 258/3225 %13–42 %
16 sur 256/3219 %9–35 %
19 sur 256/3219 %9–35 %
22 sur 253/329 %3–24 %
25 sur 257/3222 %11–39 %

Trente-deux essais par ligne, un ticket différent à chaque essai, des intervalles de Wilson issus du Chapitre 4, parce que dix-sept sur vingt ne distingue rien de rien.

Le premier emplacement reçoit une réponse correcte 84 % du temps. Toutes les autres positions se situent entre 9 % et 28 %, et les huit intervalles se chevauchent tous ; la lecture honnête est donc d’abord le premier, puis tout le reste. Liu et al. ont observé un U — élevé aux deux extrémités, faible au milieu — et le bras de récence n’est pas clairement présent ici : les 22 % du dernier emplacement se trouvent dans la dispersion des positions du milieu. Ce qui n’entre dans aucune dispersion, c’est la chute de l’emplacement 1 à l’emplacement 4. Trois lignes.

La context window de ce modèle est de 32 768 tokens. Le prompt en utilise 853, soit 2,6 %. Rien n’a débordé, rien n’a été tronqué, aucune limite n’a été atteinte, aucun avertissement n’est apparu. Le modèle a cessé de retrouver une ligne qu’on lui avait fournie, parce que cette ligne a été déplacée trois positions plus bas dans une liste de vingt-cinq.

Le Chapitre 16 a chiffré la context window et s’est terminé en avertissant qu’avoir un million de tokens n’est pas les utiliser, puis a pointé ici. Nous y sommes.

Afficher les détails

Ce dont ce chapitre a besoin des précédents.

  • Chapitre 9 a dérivé le self-attention et son coût O(n2)O(n^2). Chaque token porte attention à tous les autres, donc le nombre de relations par paires croît avec le carré de la longueur. Ce fait est utilisé ci-dessous, pas redérivé.
  • Chapitre 16 a compté les cinq compartiments de tokens facturables et montré que la facture d’une conversation croît quadratiquement. Ce chapitre explique quoi faire à ce sujet sans casser l’agent.
  • Chapitre 18 a construit le catalogue d’outils et mesuré que vingt outils ne nuisaient pas à la sélection, mais multipliaient le prompt par six. Voici leur facture.
  • Chapitre 19 a construit la récupération. La récupération juste-à-temps ci-dessous est ce chapitre appliqué à l’historique propre d’un agent ; le chunking n’est pas réexpliqué.
  • Chapitre 23 a construit le harness. Tout ce chapitre est une politique qui s’exécute dans sa boucle, ce qui explique pourquoi c’est du TypeScript : l’artefact est un service durable qui détient un état, pas un notebook qui détient des tenseurs.

Anthropic a tracé la ligne en septembre 2025, et les deux phrases doivent être lues côte à côte. Le prompt engineering désigne les « méthodes pour rédiger et organiser les instructions des LLM afin d’obtenir des résultats optimaux ». Le context engineering est « l’ensemble des stratégies visant à sélectionner et maintenir l’ensemble optimal de tokens (informations) pendant l’inférence LLM, y compris toutes les autres informations susceptibles d’y atterrir en dehors des prompts ».1

La différence opératoire est quand, et par qui. Un prompt est rédigé une fois, par une personne, puis relu. Un contexte est assemblé à chaque appel, par du code que personne ne regarde, à partir de matériaux que personne n’a écrits à la main : quarante tours d’historique, six résultats d’outils, quatre passages récupérés, un profil utilisateur, douze schémas JSON. Le Chapitre 15 a mesuré ce que de meilleures instructions rapportent. Ce chapitre porte sur les autres quatre-vingt-dix pour cent des tokens, qui arrivent d’eux-mêmes.

Le même document nomme la ressource qu’ils consomment tous : les modèles « disposent d’un “attention budget” dans lequel ils puisent lorsqu’ils analysent de grands volumes de contexte. Chaque nouveau token introduit épuise ce budget dans une certaine mesure ». Et il nomme le symptôme : « à mesure que le nombre de tokens dans la context window augmente, la capacité du modèle à rappeler correctement des informations issues de ce contexte diminue » — le context rot.1

Cette dernière phrase est une affirmation sur le comportement, ce qui signifie qu’on peut la vérifier, et le tableau en haut de cette page est cette vérification.

Quarante lignes contre l’endpoint local du Chapitre 22 — un petit serveur Python qui garde Qwen2.5-0.5B-Instruct sur le CPU et parle le format chat-completions, afin que la boucle reste en TypeScript et que les tenseurs restent de l’autre côté du port.

position.tsTS
const DEPTHS = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1];

for (const d of DEPTHS) {
  const slot = Math.round(d * (N - 1));
  let hits = 0, other = 0;
  for (let t = 0; t < TRIALS; t++) {
    const recs = buildRecords(N, 1000 + t);          // 25 unique tickets
    const gold = recs[Math.floor(rng(7 + t)() * N)]; // a different one each trial
    const rest = recs.filter((x) => x.ticket !== gold.ticket).slice(0, N - 1);
    const lines = [...rest.slice(0, slot).map((x) => x.line),   
                   gold.line,                                   
                   ...rest.slice(slot).map((x) => x.line)];     
    const r = await complete(prompt(lines, ask(gold.owner)), { maxTokens: 12 });
    const said = /\d{4}/.exec(r.text)?.[0];
    if (said === String(gold.ext)) hits++;
    else if (said && recs.some((x) => String(x.ext) === said)) other++;
  }
}

Le compteur other est ce qui transforme un résultat décevant en résultat utile : quand le modèle se trompe, est-il perdu ou est-il confiant ?

La réponse est : confiant. Sur les huit positions non initiales, 136 des 205 mauvaises réponses étaient l’extension d’un autre ticket — un vrai nombre à quatre chiffres, correctement formaté, lu sur la mauvaise ligne. À l’emplacement 1, un seul des cinq échecs l’était ; à l’emplacement 7, vingt et un sur vingt-six l’étaient.

C’est cette distinction qui compte en production. Un modèle qui dit je ne le trouve pas est un bug que vous remarquez ; un modèle qui renvoie le numéro de la ligne voisine est un bug que vous livrez, parce qu’à l’écran les deux se ressemblent. C’est l’échec contre lequel le Chapitre 19 a construit des citations vérifiables, mais il arrive depuis l’intérieur du prompt plutôt que depuis l’index.

La position est un axe. La longueur en est un autre, plus facile à tester : gardez la réponse au milieu et faites grandir la liste.

enregistrementstokens du promptréussitestauxintervalle à 95 %mauvaise ligneni l’un ni l’autre
19718/2090 %70–97 %02
315911/2055 %34–74 %90
83153/2015 %5–36 %170
206952/2010 %3–30 %162
401 3243/2015 %5–36 %152
802 5871/205 %1–24 %181
1404 4772/2010 %3–30 %180

Un enregistrement et 97 tokens : 90 %. Trois enregistrements et 159 tokens : 55 %. Huit enregistrements et 315 tokens : 15 %, puis le taux reste plat et bas jusqu’à 140 enregistrements et 4 477 tokens. Tout l’effondrement se produit entre la première et la huitième ligne d’une liste.

La dernière colonne regroupe tout ce qui n’est ni la bonne extension ni celle d’un autre enregistrement, ce qui, avec un seul enregistrement sur la page, est le seul endroit où une mauvaise réponse peut atterrir. Les deux échecs avec un enregistrement méritent d’être rapportés plutôt qu’arrondis, parce qu’aucun n’était un refus : l’un a répondu 5806 à un registre dont l’unique ligne dit 5805. À 97 tokens avec un seul candidat, ce modèle recopie encore mal un chiffre deux fois sur vingt, et c’est le plancher par rapport auquel tout le reste est mesuré.

Deux choses en découlent. Une context window plus grande achète le droit d’envoyer plus, pas la certitude d’être lu : ce modèle a une fenêtre de 32 768 tokens et une plage de fonctionnement, sur cette tâche, de quelques centaines de tokens. Et il n’y a pas de seuil, pas de falaise, pas d’état « contexte plein » — la dégradation est déjà en cours au troisième enregistrement et complète au huitième, à un pour cent de la fenêtre. Quelle que soit une limite de contexte, ce n’est pas elle qui gouverne cela.

Deux mécanismes sont généralement proposés. Le premier est l’arithmétique du Chapitre 9, qu’Anthropic énonce dans les mêmes termes que ce cours : les modèles « reposent sur l’architecture transformer, qui permet à chaque token de prêter attention à chaque autre token dans tout le contexte. Il en résulte n² relations par paires pour n tokens ».1 L’attention sur une séquence plus longue n’est pas la même opération appliquée à davantage de matériau ; c’est un budget fixe de masse de probabilité réparti entre davantage de concurrents. Le second est l’entraînement : les modèles voient beaucoup plus de séquences courtes que de longues, si bien que les motifs positionnels à longue portée sont la partie du réseau la moins pratiquée. C’est un argument, pas une mesure, et ce chapitre ne peut pas le trancher.

Ce qui est établi, c’est la forme, et elle l’est depuis 2023. Liu et al. ont testé la réponse à des questions multi-documents et la récupération clé-valeur sur plusieurs familles et tailles de modèles, et ont constaté que « les performances sont souvent maximales lorsque l’information pertinente apparaît au début ou à la fin du contexte d’entrée, et se dégradent significativement lorsque les modèles doivent accéder à l’information pertinente au milieu de longs contextes, même pour des modèles explicitement long-context ».2 Le Chapitre 15 a tiré de cet article sa règle de position ; le Chapitre 19 en a tiré la raison pour laquelle vingt chunks récupérés peuvent obtenir un score inférieur à quatre. La forme pratique du fait tient dans la seule phrase sur laquelle vous devriez agir ici : cela prend cinq minutes à mesurer sur votre propre modèle avec vos propres données, et aucune courbe publiée ne remplace la vôtre.

Personne ne sait ce qu’il y a dans sa fenêtre

Lien vers la section : Personne ne sait ce qu’il y a dans sa fenêtre

Demandez à une équipe ce qui remplit le contexte de son agent et vous obtenez une estimation, parce qu’aucune API ne renvoie la réponse : la réponse vous donne prompt_tokens, un seul nombre pour tout.

Vous pouvez reconstruire la ventilation avec quatre comptes et trois soustractions — le prompt rendu complet, le même sans définitions d’outils, le message système seul avec et sans elles, et l’ensemble avec les résultats d’outils retirés :

buckets.tsTS
async function buckets(messages: Msg[]) {
  const sys = messages.slice(0, 1);
  const withoutResults = messages.filter((m) => m.role !== "tool");
  const [total, sysWithTools, sysNoTools, noResults] = await Promise.all([
    countPrompt(messages, CATALOGUE),        // everything
    countPrompt(sys, CATALOGUE),             // system + scaffolding + schemas
    countPrompt(sys),                        // system + scaffolding
    countPrompt(withoutResults, CATALOGUE),  // everything but tool output
  ]);
  return {
    system: sysNoTools,
    tools: sysWithTools - sysNoTools,                                  
    toolResults: total - noResults,                                    
    conversation: total - sysWithTools - (total - noResults),          
    total,
  };
}

countPrompt applique le template de chat propre au modèle avant de tokeniser, ce qui compte plus qu’il n’y paraît : votre texte n’est pas ce qui est compté. Les marqueurs de rôle, le préambule de tool-calling et le rendu des schémas sont tous des tokens que vous payez et que vous n’avez jamais tapés. Le Chapitre 7 a construit un tokenizer et le Chapitre 16 a compté avec js-tiktoken ; ici le compte vient du même modèle qui lira le prompt, ce qui est le seul compte exactement correct.

Faites maintenant passer un vrai agent dedans : quarante tours d’une enquête d’incident, douze outils, un faux environnement d’exploitation renvoyant des dumps de logs et des séries de métriques réalistes.

toursystèmedéfinitions d’outilsconversationrésultats d’outilsprompt totalentrée facturée ce tour
1851 8171554902 5474 370
2851 8172825292 7135 275
5851 8176471 8704 4198 093
10851 8179462 1414 9894 951
20851 8171 5002 9436 3456 316
30851 8172 1874 0008 0898 059
40851 8173 0535 67710 63221 090

Lisez la première ligne face à la dernière.

Au tour 1, le prompt fait 2 547 tokens et 71 % de celui-ci correspond aux définitions d’outils. Le system prompt représente 3 %. Ce que l’utilisateur a tapé représente 6 %. L’agent n’a encore rien fait et transporte déjà 1 817 tokens de schéma JSON.

Au tour 40, le prompt fait 10 632 tokens et les parts se sont inversées : définitions 17 %, conversation 29 %, résultats d’outils 53 %. La sortie d’outil a dépassé les définitions au tour 5 ; la conversation ne les a dépassées qu’au tour 25, si bien que pendant les soixante premiers pour cent de la session, le catalogue d’outils était plus gros que tout ce qui avait été dit.

Puis le total. Sur 57 appels modèle, l’exécution a facturé 370 291 input tokens pour un contexte final de 10 632 — le dernier prompt payé environ trente-cinq fois, soit le quadratique du Chapitre 16 avec le multiplicateur d’un agent en plus. Sur ces 370 291, 103 569, soit 28 % de tout ce qui a été facturé, étaient les douze définitions d’outils, renvoyées à l’octet près à chaque appel.

Le catalogue d’outils est le plus grand coût fixe d’un agent et il est invisible, parce que vous ne le voyez jamais : vous passez un tableau d’objets et le fournisseur le rend dans le prompt pour vous. Mesuré, sur les mêmes douze outils :

tooldefs.ts outputTEXT
system prompt + chat scaffolding, no tools:        85 tokens
all twelve definitions:                          1,817 tokens
  of which fixed tool-calling scaffolding:         126 tokens
three tools instead of twelve:                     605 tokens
same twelve, one-sentence descriptions,
  no parameter prose:                            1,291 tokens  (-29 %)

Par outil, le coût marginal va de 80 tokens pour get_current_time, qui prend une chaîne, à 263 pour search_tickets, qui prend quatre paramètres avec un enum et une phrase de guidage chacun. C’est le taux de change derrière le conseil central du Chapitre 18 selon lequel la description est l’API : une bonne description coûte environ cent tokens à chaque requête pour le reste de la vie de l’agent. Trois conséquences.

Un outil que vous n’utilisez pas est quand même facturé. L’agent a appelé sept des douze outils. Les cinq autres ont coûté 697 tokens sur chacune des 57 requêtes — 39 729 au total, plus d’un dixième de tout ce qui a été facturé pour l’exécution, pour des capacités qu’il n’a jamais touchées. L’un de ces cinq porte le détail le plus net de la trace : le modèle a essayé trois fois d’appeler read_log, qui n’existe pas. L’outil qu’il voulait était search_logs, la deuxième définition la plus chère du catalogue à 237 tokens. Il a payé cette définition 57 fois, ne l’a jamais utilisée et n’a jamais retrouvé son nom.

Élaguer la prose est l’optimisation la moins chère disponible, et c’est un compromis. Réduire les descriptions à une phrase et supprimer la documentation des paramètres a économisé 526 tokens par appel, soit 29 %, sans toucher à une ligne de logique — et a fait appeler les outils moins bien par le modèle, ce que le Chapitre 18 a mesuré. Le point est que les deux côtés de ce compromis sont maintenant dans la même unité.

À une certaine échelle, envoyer les définitions n’a plus de sens. Anthropic a donné un chiffre en novembre 2025 : un grand ensemble de serveurs connectés signifie traiter « des centaines de milliers de tokens » de définitions avant que la requête soit lue, et remplacer cela par de l’exécution de code — l’agent découvrant et chargeant uniquement les définitions dont il a besoin — « réduit l’usage de tokens de 150 000 tokens à 2 000 tokens, soit un gain de temps et de coût de 98,7 % ».3 Même idée que le reste de ce chapitre, appliquée aux schémas plutôt qu’à l’historique : gardez l’index, résolvez l’entrée à la demande.

Deux éléments avaient été plantés dans cette transcription de quarante tours. Au tour 2, avant tout vrai travail, l’utilisateur énonce une règle permanente : tout ticket que vous ouvrez doit être classé sous mon numéro d’employé, 4417. Au tour 19, au milieu de l’incident, un fait : le shard affecté est pay-shard-7, confirmé par l’équipe paiements. Au tour 40, l’utilisateur demande à l’agent d’ouvrir le ticket d’incident, ce qui exige les deux. Chaque sonde est posée en six formulations différentes et notée sur six — le décodage greedy est déterministe, donc un appel donne un oui ou non non répétable, et six donnent un taux.

La transcription est ensuite rejouée selon sept politiques de contexte. Rejouée plutôt que réexécutée, délibérément : les messages, les appels d’outils et les résultats d’outils sont identiques à l’octet près dans les sept cas, donc la seule variable est ce que chaque politique a choisi de garder. Le Chapitre 16 a montré pourquoi une fenêtre glissante est une mauvaise décision économique, parce qu’elle détruit le préfixe cacheable. Voici ce qu’elle fait au comportement :

politique de contexteinput tokens sur les 40 toursprompt du tour 40règle du tour 2fait du tour 19
historique complet370 29110 6326/65/6
fenêtre glissante, 12 derniers messages157 5782 9225/60/6
élider les résultats d’outils de plus de 4 tours243 4456 3116/63/6
compaction tous les 6 tours195 5153 2206/60/6
compaction plus notes écrites par le modèle200 8493 2866/60/6
épingler les tours de l’utilisateur, au début168 5503 5596/65/6
épingler les tours de l’utilisateur, à la fin168 8353 5646/66/6
contrôle : les deux tours et rien d’autre1 9816/66/6

Les lignes de compaction incluent ce qu’a coûté la compaction : 18 581 input tokens pour sept résumés et 3 392 de plus pour le preneur de notes. La ligne de contrôle est là pour qu’un zéro puisse être lu comme un zéro — avec les deux messages seuls dans un prompt de 1 981 tokens, ce modèle répond parfaitement aux deux sondes ; aucune ligne ne correspond donc à une tâche trop difficile.

L’historique complet se souvient, et c’est l’option la plus chère du tableau : 370 291 input tokens pour une session dont le contenu durable tient en deux phrases.

Cela répond à une question laissée ouverte par le début. Pourquoi une transcription de 10 632 tokens conserve-t-elle un fait qu’un registre de 853 tokens perd ? Parce que la longueur est la mauvaise variable. Le registre contient vingt-cinq extensions à quatre chiffres dans vingt-cinq phrases identiques — vingt-quatre leurres presque parfaits pour celle que vous cherchez. La transcription contient exactement un numéro d’employé et un nom de shard. Le context rot est de l’interférence avant d’être du volume, ce qui explique pourquoi 136 des 205 mauvaises réponses ci-dessus étaient la valeur d’une voisine. La question utile à propos d’une fenêtre n’est pas sa longueur ; c’est combien de choses dedans ressemblent à la réponse.

La fenêtre glissante coûte 57 % de moins et a perdu l’incident. Le numéro d’employé survit seulement parce que l’agent l’avait répété dans les tours récents. Le shard, énoncé une seule fois au tour 19, ne figure pas dans les douze derniers messages — et le modèle ne le dit pas. Interrogé six fois, il a répondu « le shard de paiement affecté est shard 4417 », en allant chercher le numéro d’employé, le seul autre identifiant restant dans sa fenêtre, puis deux fois « pool », extrait de la chaîne pool_exhausted dans une ligne de log.

La compaction est bon marché et a perdu le même fait. Sept résumés, écrits par le modèle avec l’instruction explicite de garder les identifiants, les nombres, les consignes permanentes et les questions ouvertes, et pay-shard-7 n’apparaît dans aucun de ceux qui comptaient ; les six suppositions étaient shard 1, pay_shard_1 et pool. La compaction n’échoue pas bruyamment. Elle produit une session fluide, plausible, beaucoup plus courte, qui a discrètement supprimé une ligne.

Trois lignes ont obtenu 0/6 sur le fait du tour 19 — la fenêtre glissante, la compaction et la compaction avec notes. Dix-huit mauvaises réponses entre elles, et aucune n’était « je ne sais pas ».

Puis vient la ligne qui devrait être embarrassante. Garder textuellement les quarante messages de l’utilisateur, plus les quatre derniers tours en entier et rien d’autre, coûte 168 550 tokens — 54 % de moins que l’historique complet — et répond aux deux sondes aussi bien que l’historique complet, voire mieux. Pas de résumeur, pas de preneur de notes, pas de second modèle : un filtre sur role === "user". Les mots de l’utilisateur sont les tokens à haute valeur les moins chers dans la fenêtre d’un agent, et la plupart des conceptions les jettent avec tout le reste.

Les deux dernières lignes sont à nouveau le tableau d’ouverture, mais à l’intérieur de l’agent. Le même bloc épinglé, déplacé du message système vers la fin du prompt : 5/6 devient 6/6. Sur six essais, ce n’est pas une différence significative et ce n’est pas présenté comme tel — c’est présenté comme un rappel que est un paramètre que vous définissez, que vous le sachiez ou non.

Les quatre stratégies ci-dessous sont celles d’Anthropic, dans son ordre, même si seules les trois dernières constituent sa liste long-horizon.1 Les quatre sont des variations sur une seule instruction : ne transportez pas ce que vous pouvez aller chercher, et ne transportez pas en brut ce que vous pouvez transporter compressé.

Ne préchargez pas de contenu. Gardez les identifiants — un chemin de fichier, une requête, un numéro de ticket, un nom d’outil et ses arguments — et résolvez-les au besoin. Le plus gros compartiment dans l’agent ci-dessus est une sortie d’outil qui a été lue une fois, utilisée une fois, puis transportée pendant trente tours supplémentaires. Remplacer chaque résultat vieux de plus de quatre tours par un stub disant ce qu’il était et comment le récupérer tient en six lignes :

policies.tsTS
const elide: Policy = (h) => [SYSTEM, ...h.flatMap((turn, ti) =>
  turn.map((m) => (ti < h.length - 4 && m.role === "tool"
    ? { role: "tool", name: m.name,
        content: `[${m.name} result from turn ${ti + 1}, ${m.content.length} chars, ` +
                 `elided; call ${m.name} again with the same arguments to re-read it]` }
    : m)))];

C’est le Chapitre 19 avec le corpus remplacé par le propre passé de l’agent. La mécanique de récupération existe déjà — c’est le catalogue d’outils.

Quand la transcription dépasse un seuil, remplacez sa partie la plus ancienne par un résumé écrit par le modèle et continuez. Le prompt qui écrit le résumé est toute la conception, et c’est là que la compaction se gagne ou se perd : garder les identifiants, les nombres, les consignes permanentes et les questions ouvertes ; supprimer les politesses et les sorties d’outils que vous pouvez récupérer à nouveau.

La compaction est lossy par construction, ce qu’elle perd est choisi par un modèle en votre nom, et rien ne génère d’erreur lorsqu’il choisit mal. Elle n’est pas gratuite non plus : chaque compaction est un appel supplémentaire dont l’entrée est ce qui est compacté.

Maintenez un petit magasin hors du contexte et réinjectez-le en entier à chaque tour. Contrairement à un résumé, il est append-only et adressable : une règle écrite au tour 2 est encore là textuellement au tour 400. La version mesurée ici demande au modèle, après chaque message utilisateur, s’il contient quelque chose de durable :

notes.tsTS
const r = await complete([
  { role: "system", content:
      "You keep a durable note file for a support session. Given one user message, " +
      "output one short note ONLY if it states a standing rule, an identifier or a fact " +
      "that must survive the rest of the session. Otherwise output exactly NONE." },
  { role: "user", content: `Turn ${i + 1}: ${user}` },
], { maxTokens: 40 });
if (!/^none\b/i.test(r.text.trim())) notes.push(`turn ${i + 1}: ${r.text.trim()}`);

C’est la stratégie au plafond le plus élevé ici, et c’est celle qui a échoué dans la mesure. Sur quarante messages utilisateur, le preneur de notes a gardé trois notes et aucune des deux qui comptaient : une ligne de conseil runbook, une annonce que la session se terminait, et Europe/Madrid est actuellement 13:45 — une heure qu’il a inventée, puisque l’outil qu’il paraphrasait renvoyait 09:52 UTC. Le preneur de notes est un modèle, et tout ce chapitre s’applique aussi à lui.

Donnez à une tâche ciblée sa propre fenêtre — son propre system prompt, son propre petit catalogue, aucun historique du parent — et renvoyez une réponse courte plutôt qu’une transcription. Le Chapitre 23 en a placé un derrière un schéma d’outil et a laissé la facture ici ; la facture est que la réponse de l’enfant est la seule partie de la fenêtre de l’enfant que le parent paie jamais.

Le sub-agent n’est pas dans le tableau ci-dessus parce qu’il ne tourne pas pendant quarante tours : il tourne une fois, dans une fenêtre que quelqu’un a délimitée pour lui. Avec le system prompt, les tours 17 à 19 et rien d’autre — 2 737 tokens — il a répondu à la sonde du shard 6/6, mieux que toutes les politiques du tableau, et à la sonde de l’employé 0/6, parce que ce nombre ne figurait pas dans les trois tours qu’on lui avait donnés.

Voilà les sub-agents en deux nombres : une fenêtre propre n’est pas de l’intelligence, c’est un périmètre, et ce périmètre est défini à l’avance par du code qui doit déjà savoir quels tours comptent. Une autre chose dans ces réponses mérite d’être gardée. C’est la seule politique qui a répondu « None available » au lieu d’inventer quelque chose. Un modèle avec un contexte petit et cohérent sait ce qui lui manque ; un modèle avec un contexte grand et bruyant ne le sait pas.

Presque toutes les conversations confuses sur la mémoire des agents sont trois mécanismes portant le même mot. Ils ont des durées de vie, des propriétaires et des modes d’échec différents, et un système qui les garde au même endroit a un problème qu’il n’a pas encore remarqué.

historique de conversationrécupérationmémoire utilisateur persistante
contientce qui a été dit dans cette sessionles documents que vous possédezdes faits sur une personne
vitune sessionjusqu’à réindexationsur toutes les sessions, pour toujours
écrit parla boucle, automatiquementun pipeline d’ingestionle modèle, volontairement
entre dans le prompten entier, à chaque appelquatre passages, lorsqu’une requête corresponden entier, à chaque appel
échoue engrandissant jusqu’à pourrirrécupérant le mauvais chunkse souvenant de quelque chose de faux sur vous
construit dansChapitre 23Chapitre 19ce chapitre

Le cadrage académique est celui de CoALA, qui organise les agents de langage autour de « composants de mémoire modulaires » et sépare la mémoire de travail des magasins épisodiques, sémantiques et procéduraux.4 MemGPT prend la même idée au pied de la lettre, en empruntant la mémoire virtuelle aux systèmes d’exploitation : un niveau rapide à l’intérieur de la fenêtre, un niveau lent à l’extérieur, et le modèle lui-même déplaçant les données entre les deux avec des function calls.5 Les deux forcent la question à laquelle un produit doit de toute façon répondre — non pas combien puis-je garder, mais à quel magasin cela appartient-il, et quand cela expire-t-il.

Le test pratique tient en une question par fait : qu’est-ce qui doit encore être vrai demain ? Un résultat d’outil du tour 12 : rien. Un résumé de la session : jusqu’à la fin de la session. Le fait que le numéro d’employé de l’utilisateur soit 4417 : jusqu’à ce qu’il change de poste. Trois réponses, trois magasins.

Vous pouvez maintenant mesurer ce qu’il y a dans une fenêtre, décider ce qui y reste, et faire la différence entre un agent qui a oublié quelque chose et un agent qui le transportait mais ne l’a pas regardé.

La dernière des quatre stratégies est celle qui ne tient pas ici. Un sub-agent n’est pas une politique de contexte, c’est un second agent, et dès qu’il y en a deux, il faut décider ce qui passe entre eux et lequel commande. Le Chapitre 25 traite de cela : les cinq motifs d’orchestration et l’origine réelle de chacun de leurs noms, les deux topologies que l’on confond — demander à un sub-agent et récupérer une réponse, par opposition à lui transmettre la conversation sans la récupérer — et le constat mesuré que, sur la tâche qu’il chiffre, l’arrangement le plus simple gagne, suivi du test qui indique quand il cesse de gagner.

Il hérite aussi exactement de ce que ce chapitre vient de mesurer. Un sub-agent renvoie un résumé. Un résumé est une compaction que vous n’avez pas écrite, produite par un modèle dont vous ne pouvez pas voir la fenêtre, et le parent n’a aucun moyen de distinguer un bon résumé d’un résumé faux mais confiant — la même distinction qui séparait 84 % de 19 % en haut de cette page, et qui a transformé dix-huit faits manquants en dix-huit inventions. Donc : quand le sub-agent se trompe, qu’est-ce que le parent peut regarder exactement ?


Chaque nombre ici a été produit sur cette machine et aucun n’a été estimé. Le modèle est Qwen2.5-0.5B-Instruct en float32 sur le CPU avec décodage greedy, servi en loopback par un petit endpoint Python qui parle le format chat-completions et expose une route de comptage de tokens — à nouveau la jointure du Chapitre 14, tenseurs côté Python et boucle côté TypeScript — si bien que chaque compte est le tokenizer propre à ce modèle appliqué à son propre template de chat. Le tableau de position correspond à 288 appels, neuf positions par trente-deux essais avec un ticket différent à chaque essai ; le tableau de longueur correspond à 140 appels ; l’exécution de l’agent correspond à 57 appels modèle sur 43 minutes de temps réel ; le tableau des politiques correspond à cette transcription unique rejouée sous sept politiques. Les intervalles sont ceux de Wilson, issus du Chapitre 4. Aucune API payante n’a été appelée, ce qui explique aussi pourquoi il n’y a pas un seul prix dans le chapitre : les comptes de tokens sont exacts et les tarifs par lesquels vous les multiplieriez sont ceux du Chapitre 16.

  1. Anthropic, Effective context engineering for AI agents, 29 septembre 2025, anthropic.com/engineering/effective-context-engineering-for-ai-agents, consulté le 7 septembre 2026. Source des deux définitions citées au début, du « attention budget » et de l’affirmation selon laquelle chaque nouveau token l’épuise, de la description du context rot, du cadrage en relations par paires n², et des stratégies utilisées comme colonne vertébrale de ce chapitre. Trois d’entre elles constituent sa liste long-horizon — compaction, prise de notes structurée et architectures multi-agent ; la récupération juste-à-temps apparaît plus tôt dans le même article, sous context retrieval et agentic search, et est regroupée avec elles ici. 2 3 4

  2. Liu, N. F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F. et Liang, P. Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172 (v1 juillet 2023, v3 novembre 2023). Cité dans les Chapitres 15, 16 et 19 et mesuré ici. La phrase citée vient du résumé ; les deux tâches de l’article sont la réponse à des questions multi-documents et la récupération clé-valeur, et son constat selon lequel l’effet persiste dans les modèles explicitement long-context est la partie qui compte pour une décision produit.

  3. Anthropic, Code execution with MCP: building more efficient agents, 4 novembre 2025, anthropic.com/engineering/code-execution-with-mcp, consulté le 7 septembre 2026. Source de la réduction de 150 000 à 2 000 tokens et du chiffre de 98,7 %, ainsi que de l’observation selon laquelle les définitions d’outils chargées en amont occupent le contexte avant que la requête soit lue.

  4. Sumers, T. R., Yao, S., Narasimhan, K. et Griffiths, T. L. Cognitive Architectures for Language Agents. arXiv:2309.02427 (2023). Organise les agents de langage autour de « composants de mémoire modulaires, d’un espace d’action structuré pour interagir avec la mémoire interne et les environnements externes, et d’un processus de décision généralisé pour choisir les actions », et divise la mémoire en mémoire de travail, épisodique, sémantique et procédurale. Le Chapitre 22 a utilisé sa taxonomie pour l’agent apprenant ; le tableau à trois magasins ci-dessus en est l’ombre pratique.

  5. Packer, C., Wooders, S., Lin, K., Fang, V., Patil, S. G., Stoica, I. et Gonzalez, J. E. MemGPT: Towards LLMs as Operating Systems. arXiv:2310.08560 (octobre 2023). Propose une « gestion du contexte virtuel, une technique inspirée des systèmes de mémoire hiérarchiques des systèmes d’exploitation traditionnels », avec le modèle lui-même déplaçant les données entre un niveau rapide à l’intérieur de la fenêtre et un niveau lent à l’extérieur. L’énoncé le plus clair qui soit sur la raison pour laquelle la fenêtre est un cache et non une mémoire.

Prêt à laisser LIA choisir à votre place ?

Créez avec tous les modèles d'IA au même endroit — commencez gratuitement dès aujourd'hui.