Naar inhoud springen
24/30Hoofdstuk 24 van 30

Context engineering: waarom je agent bij beurt 40 dommer wordt

Eén feit drie regels lager in een prompt die 2,6% van het window vult: retrieval zakt van 84% naar 19%. Het window was niet het probleem.

Op deze pagina

Hier is één prompt die 288 keer naar hetzelfde model is gestuurd met greedy decoding. Hij is 853 tokens lang. Hij bevat een register van vijfentwintig supporttickets — stad, wachtrij, prioriteit, eigenaar, toestelnummer — en één vraag: Marta Ferreira heeft een terugbelverzoek over haar ticket. Wat is het directe toestelnummer voor dat ticket?

Het register is elke keer identiek. Het model is elke keer identiek. Het enige dat verandert, is welke van de vijfentwintig regels het antwoord bevat.

positie van het antwoordhitsretrieval rate95 % interval
1 van 2527/3284 %68–93 %
4 van 256/3219 %9–35 %
7 van 256/3219 %9–35 %
10 van 259/3228 %16–45 %
13 van 258/3225 %13–42 %
16 van 256/3219 %9–35 %
19 van 256/3219 %9–35 %
22 van 253/329 %3–24 %
25 van 257/3222 %11–39 %

Tweeëndertig trials per rij, een ander ticket per trial, Wilson-intervallen uit hoofdstuk 4, omdat zeventien van de twintig niets van iets anders onderscheidt.

Positie één wordt 84 % van de tijd beantwoord. Elke andere positie zit tussen 9 % en 28 %, en alle acht van die intervallen overlappen, dus de eerlijke lezing is: eerst, en daarna al het andere. Liu et al. vonden een U — hoog aan beide uiteinden, laag in het midden — en de recency-arm is hier niet duidelijk aanwezig: 22 % op de laatste positie valt binnen de spreiding van de middelste. Wat nergens binnen valt, is de daling van positie 1 naar positie 4. Drie regels.

De context window van dit model is 32.768 tokens. De prompt gebruikt er 853, 2,6 %. Er liep niets over, er werd niets afgekapt, er werd geen limiet bereikt, er verscheen geen waarschuwing. Het model stopte met het vinden van een regel die het had gekregen, omdat die regel drie posities omlaag schoof in een lijst van vijfentwintig.

Hoofdstuk 16 becijferde de context window en eindigde met de waarschuwing dat een miljoen tokens hebben niet hetzelfde is als ze gebruiken, en wees hiernaartoe. Dit is dat punt.

Details tonen

Wat dit hoofdstuk uit de eerdere hoofdstukken nodig heeft.

  • Hoofdstuk 9 leidde self-attention en de O(n2)O(n^2)-kosten ervan af. Elke token attends to elke andere token, waardoor het aantal paarsgewijze relaties groeit met het kwadraat van de lengte. Dat feit wordt hieronder gebruikt, niet opnieuw afgeleid.
  • Hoofdstuk 16 telde de vijf factureerbare token-buckets en liet zien dat de rekening van een gesprek kwadratisch groeit. Dit hoofdstuk gaat over wat je daaraan doet zonder de agent te breken.
  • Hoofdstuk 18 bouwde de toolcatalogus en mat dat twintig tools de selectie niet schaadden, maar de prompt met zes vermenigvuldigden. Hier is de rekening daarvoor.
  • Hoofdstuk 19 bouwde retrieval. Just-in-time retrieval hieronder is dat hoofdstuk toegepast op de eigen geschiedenis van een agent; chunking wordt niet opnieuw uitgelegd.
  • Hoofdstuk 23 bouwde de harness. Alles in dit hoofdstuk is een policy die binnen die loop draait, en daarom is het TypeScript: het artefact is een langlevende service die state vasthoudt, geen notebook dat tensors vasthoudt.

Anthropic trok de grens in september 2025, en de twee zinnen horen naast elkaar te staan. Prompt engineering is "methods for writing and organizing LLM instructions for optimal outcomes". Context engineering is "the set of strategies for curating and maintaining the optimal set of tokens (information) during LLM inference, including all the other information that may land there outside of the prompts".1

Het werkende verschil is wanneer, en door wie. Een prompt wordt één keer geschreven, door een mens, en beoordeeld. Een context wordt bij elke call samengesteld, door code waar niemand naar kijkt, uit materiaal dat niemand met de hand heeft geschreven: veertig beurten geschiedenis, zes toolresultaten, vier opgehaalde passages, een gebruikersprofiel, twaalf JSON-schema's. Hoofdstuk 15 mat wat betere instructies opleveren. Dit hoofdstuk gaat over de andere negentig procent van de tokens, die vanzelf binnenkomen.

Hetzelfde document benoemt de resource die ze allemaal verbruiken: models "have an 'attention budget' that they draw on when parsing large volumes of context. Every new token introduced depletes this budget by some amount". En het benoemt het symptoom: "as the number of tokens in the context window increases, the model's ability to accurately recall information from that context decreases" — contextrot.1

Die laatste zin is een claim over gedrag, wat betekent dat je hem kunt controleren, en de tabel bovenaan deze pagina is die controle.

Veertig regels tegen de lokale endpoint uit hoofdstuk 22 — een kleine Python-server die Qwen2.5-0.5B-Instruct op de CPU vasthoudt en de chat-completions-vorm spreekt, zodat de loop TypeScript blijft en de tensors aan de andere kant van de poort blijven.

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++;
  }
}

De other-teller is wat een teleurstellend resultaat nuttig maakt: als het model fout zit, is het dan kwijt of zelfverzekerd?

Het antwoord is zelfverzekerd. Over de acht niet-eerste posities waren 136 van de 205 foute antwoorden het toestelnummer van een ander ticket — een echt viercijferig nummer, correct geformatteerd, afgelezen van de verkeerde regel. Op positie 1 was slechts één van de vijf missers dat; op positie 7 waren het er eenentwintig van de zesentwintig.

Dat onderscheid is wat telt in productie. Een model dat zegt ik kan het niet vinden is een bug die je opmerkt; een model dat het nummer van een naburige rij teruggeeft is een bug die je shipt, omdat de twee er op het scherm identiek uitzien. Het is de failure waartegen hoofdstuk 19 verifieerbare citaties bouwde, maar nu afkomstig van binnen de prompt in plaats van uit de index.

Het gaat niet alleen om waar. Het gaat om hoeveel.

Link naar de sectie: Het gaat niet alleen om waar. Het gaat om hoeveel.

Positie is één as. Lengte is de andere, en makkelijker te testen: houd het antwoord in het midden en laat de lijst groeien.

recordsprompt tokenshitspercentage95 % intervalverkeerde regelgeen van beide
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

Eén record en 97 tokens: 90 %. Drie records en 159 tokens: 55 %. Acht records en 315 tokens: 15 %, en vanaf daar vlak en laag helemaal tot 140 records en 4.477 tokens. De volledige instorting gebeurt tussen de eerste en de achtste regel van een lijst.

De laatste kolom is alles wat noch het juiste toestelnummer noch dat van een ander record is, wat met één record op de pagina de enige plek is waar een fout antwoord kan landen. De twee missers bij één record zijn het waard om te melden in plaats van weg te middelen, omdat geen van beide een weigering was: één antwoordde 5806 op een register waarvan de enige regel 5805 zegt. Bij 97 tokens met één enkele kandidaat kopieert dit model nog steeds twee keer op twintig een cijfer verkeerd, en dat is de vloer waartegen al het andere wordt gemeten.

Daar volgen twee dingen uit. Een grotere context koopt het recht om meer te sturen, niet de zekerheid dat het gelezen wordt: dit model heeft een context window van 32.768 tokens en een werkbereik, op deze taak, van een paar honderd tokens. En er is geen threshold, geen klif, geen "context vol"-staat — de degradatie is al bezig bij het derde record en compleet bij het achtste, op één procent van de window. Wat een contextlimiet ook is, dit is niet wat dit bestuurt.

Meestal worden twee mechanismen genoemd. Het eerste is de rekenkunde uit hoofdstuk 9, die Anthropic in dezelfde termen formuleert als deze cursus: models "are based on the transformer architecture, which enables every token to attend to every other token across the entire context. This results in n² pairwise relationships for n tokens".1 Attention over een langere sequentie is niet dezelfde operatie toegepast op meer materiaal; het is één vast budget aan waarschijnlijkheidsmassa uitgesmeerd over meer concurrenten. Het tweede is training: models zien veel meer korte sequenties dan lange, dus langeafstands-positionele patronen zijn het minst geoefende deel van het netwerk. Dat is een argument, geen meting, en dit hoofdstuk kan het niet beslechten.

Wat wel vaststaat is de vorm, en dat is al zo sinds 2023. Liu et al. testten multi-document question answering en key-value retrieval over model families en groottes en vonden dat "performance is often highest when relevant information occurs at the beginning or end of the input context, and significantly degrades when models must access relevant information in the middle of long contexts, even for explicitly long-context models".2 Hoofdstuk 15 haalde zijn positieregel uit dat paper; hoofdstuk 19 haalde eruit waarom twintig opgehaalde chunks slechter kunnen scoren dan vier. De praktische vorm van het feit is de enige zin hier waarop je moet handelen: dit kost vijf minuten om te meten op je eigen model met je eigen data, en geen gepubliceerde curve vervangt die van jou.

Vraag een team wat de context van hun agent vult en je krijgt een schatting, omdat geen enkele API het antwoord teruggeeft: de response geeft je prompt_tokens, één getal voor alles samen.

Je kunt de uitsplitsing herstellen met vier tellingen en drie aftrekkingen — de volledig gerenderde prompt, dezelfde zonder tooldefinities, alleen het system-bericht met en zonder die definities, en alles met de toolresultaten verwijderd:

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 past de eigen chat-template van het model toe vóór tokenizing, en dat doet er meer toe dan het klinkt: jouw tekst is niet wat wordt geteld. Rolmarkeringen, de tool calling-preamble en de schema-rendering zijn allemaal tokens waarvoor je betaalt en die je nooit hebt getypt. Hoofdstuk 7 bouwde een tokenizer en hoofdstuk 16 telde met js-tiktoken; hier komt de telling van hetzelfde model dat de prompt zal lezen, en dat is de enige telling die exact klopt.

Laat er nu een echte agent doorheen lopen: veertig beurten van een incidentonderzoek, twaalf tools, een neppe operations-omgeving die realistische logdumps en metricreeksen teruggeeft.

beurtsystemtooldefinitiesgesprektoolresultatentotale promptinput gefactureerd deze beurt
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

Lees de eerste rij naast de laatste.

Bij beurt 1 is de prompt 2.547 tokens en bestaat 71 % ervan uit tooldefinities. De system prompt is 3 %. Wat de gebruiker typte is 6 %. De agent heeft nog niets gedaan en draagt al 1.817 tokens aan JSON-schema.

Bij beurt 40 is de prompt 10.632 tokens en zijn de verhoudingen omgekeerd: definities 17 %, gesprek 29 %, toolresultaten 53 %. Tooloutput haalde de definities in bij beurt 5; het gesprek haalde ze pas in bij beurt 25, dus gedurende de eerste zestig procent van de sessie was de toolcatalogus groter dan alles wat er was gezegd.

Dan het totaal. Over 57 model calls factureerde de run 370.291 input tokens voor een uiteindelijke context van 10.632 — de laatste prompt ongeveer vijfendertig keer betaald, wat de kwadratische groei uit hoofdstuk 16 is met daarbovenop de multiplier van een agent. Van die 370.291 waren 103.569, of 28 % van alles wat werd gefactureerd, de twaalf tooldefinities, byte-identiek opnieuw verstuurd bij elke call.

De toolcatalogus is de grootste vaste kostenpost in een agent en hij is onzichtbaar, omdat je hem nooit ziet: je geeft een array van objecten door en de provider rendert die voor je in de prompt. Gemeten, op dezelfde twaalf tools:

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 %)

Per tool loopt de marginale kost van 80 tokens voor get_current_time, die één string neemt, tot 263 voor search_tickets, die vier parameters neemt met een enum en elk een zin aan guidance. Dat is de wisselkoers achter het centrale advies van hoofdstuk 18 dat de beschrijving de API is: een goede beschrijving kost ongeveer honderd tokens op elk request voor de rest van het leven van de agent. Drie gevolgen.

Een tool die je niet gebruikt, wordt nog steeds gefactureerd. De agent riep zeven van de twaalf aan. De andere vijf kostten 697 tokens op elk van de 57 requests — 39.729 in totaal, meer dan een tiende van alles wat de run werd gefactureerd, voor capabilities die hij nooit aanraakte. Eén van de vijf draagt het scherpste detail in de trace: het model probeerde drie keer read_log aan te roepen, dat niet bestaat. De tool die het wilde was search_logs, de op één na duurste definitie in de catalogus met 237 tokens. Het betaalde 57 keer voor die definitie, gebruikte hem nooit en vond de naam nooit.

Proza inkorten is de goedkoopste optimalisatie die beschikbaar is, en het is een trade-off. Beschrijvingen tot één zin terugbrengen en parameterdocumentatie laten vallen bespaarde 526 tokens per call, 29 procent, zonder een regel logica aan te raken — en liet het model de tools slechter aanroepen, wat hoofdstuk 18 mat. Het punt is dat beide kanten van die trade nu in dezelfde eenheid staan.

Op een bepaalde schaal houdt het op logisch te zijn om überhaupt definities te sturen. Anthropic plakte er in november 2025 een getal op: een grote set verbonden servers betekent "hundreds of thousands of tokens" aan definities verwerken voordat het request wordt gelezen, en dat vervangen door code execution — de agent ontdekt en laadt alleen de definities die hij nodig heeft — "reduces the token usage from 150,000 tokens to 2,000 tokens, a time and cost saving of 98.7%".3 Zelfde idee als de rest van dit hoofdstuk, toegepast op schema's in plaats van geschiedenis: bewaar de index, los de entry on demand op.

Twee dingen werden in dat transcript van veertig beurten geplant. Bij beurt 2, vóór echt werk, stelt de gebruiker een vaste regel: elk ticket dat je opent moet onder mijn personeelsnummer, 4417, worden ingediend. Bij beurt 19, midden in het incident, een feit: de getroffen shard is pay-shard-7, bevestigd door het payments-team. Bij beurt 40 vraagt de gebruiker de agent het incidentticket te openen, waarvoor beide nodig zijn. Elke probe wordt in zes verschillende formuleringen gevraagd en uit zes gescoord — greedy decoding is deterministisch, dus één call geeft een onherhaalbare ja of nee en zes geven een percentage.

Het transcript wordt daarna onder zeven context policies afgespeeld. Bewust afgespeeld in plaats van opnieuw gerund: de berichten, de tool calls en de toolresultaten zijn byte-identiek in alle zeven, dus de enige variabele is wat elke policy koos te bewaren. Hoofdstuk 16 liet zien waarom een sliding window een slechte economische zet is, omdat die de cachebare prefix vernietigt. Dit is wat hij met gedrag doet:

context policyinput tokens over de 40 beurtenbeurt-40 promptbeurt-2-regelbeurt-19-feit
volledige geschiedenis370.29110.6326/65/6
sliding window, laatste 12 berichten157.5782.9225/60/6
toolresultaten ouder dan 4 beurten weglaten243.4456.3116/63/6
compaction elke 6 beurten195.5153.2206/60/6
compaction plus door model geschreven notities200.8493.2866/60/6
de eigen beurten van de gebruiker pinnen, vooraan168.5503.5596/65/6
de eigen beurten van de gebruiker pinnen, achteraan168.8353.5646/66/6
controle: alleen de twee beurten en niets anders1.9816/66/6

De compaction-rijen bevatten wat compacting kostte: 18.581 input tokens voor zeven samenvattingen en 3.392 extra voor de note-taker. De controlerij staat er zodat een nul als nul gelezen kan worden — met alleen de twee berichten in een prompt van 1.981 tokens beantwoordt dit model beide probes perfect, dus geen enkele rij is een taak die te moeilijk is.

Volledige geschiedenis onthoudt, en is het duurste op tafel: 370.291 input tokens voor een sessie waarvan de duurzame inhoud twee zinnen is.

Dat beantwoordt een vraag die de opening openliet. Waarom houdt een transcript van 10.632 tokens een feit vast dat een register van 853 tokens kwijtraakt? Omdat lengte de verkeerde variabele is. Het register bevat vijfentwintig viercijferige toestelnummers in vijfentwintig identieke zinnen — vierentwintig bijna perfecte lokmiddelen voor die ene die je wilt. Het transcript bevat precies één personeelsnummer en één shard-naam. Contextrot is interference voordat het volume is, en daarom waren 136 van de 205 foute antwoorden hierboven de waarde van een buur. De nuttige vraag over een window is niet hoe lang hij is; het is hoeveel dingen erin op het antwoord lijken.

De sliding window is 57 % goedkoper en is het incident kwijt. Het personeelsnummer overleeft alleen omdat de agent het in recente beurten had herhaald. De shard, één keer genoemd bij beurt 19, staat niet in de laatste twaalf berichten — en het model zegt dat niet. Zes keer gevraagd antwoordde het "the affected payment shard is shard 4417", grijpend naar het personeelsnummer, de enige andere identifier die nog in zijn window zat, en twee keer "pool", geplukt uit de string pool_exhausted in een logregel.

Compaction is goedkoop en verloor hetzelfde feit. Zeven samenvattingen, geschreven door het model onder een expliciete instructie om identifiers, getallen, vaste instructies en open vragen te bewaren, en pay-shard-7 staat in geen van de relevante; de zes gokken waren shard 1, pay_shard_1 en pool. Compaction faalt niet luid. Het produceert een vloeiende, plausibele, veel kortere sessie die stilletjes één regel heeft laten vallen.

Drie rijen scoorden 0/6 op het beurt-19-feit — de sliding window, compaction en compaction met notities. Achttien foute antwoorden samen, en niet één daarvan was "ik weet het niet."

Dan de rij die gênant zou moeten zijn. De eigen veertig berichten van de gebruiker letterlijk bewaren, plus de laatste vier beurten volledig en niets anders, kost 168.550 tokens — 54 % minder dan volledige geschiedenis — en beantwoordt beide probes net zo goed als volledige geschiedenis of beter. Geen summariser, geen note-taker, geen tweede model: een filter op role === "user". De woorden van de gebruiker zijn de goedkoopste tokens met hoge waarde in het window van een agent, en de meeste ontwerpen gooien ze weg met al het andere.

De laatste twee rijen zijn opnieuw de openingstabel, binnen de agent. Hetzelfde gepinde blok, verplaatst van het system-bericht naar het einde van de prompt: 5/6 wordt 6/6. Op zes trials is dat geen significant verschil en wordt het ook niet als zodanig aangeboden — het wordt aangeboden als herinnering dat waar een parameter is die je instelt, of je dat nu weet of niet.

De vier strategieën hieronder zijn die van Anthropic, in die volgorde, al zijn alleen de laatste drie zijn long-horizon-lijst.1 Alle vier zijn variaties op één instructie: draag niet mee wat je kunt ophalen, en draag niet raw mee wat je compressed kunt dragen.

Laad content niet vooraf. Bewaar identifiers — een bestandspad, een query, een ticketnummer, een toolnaam en zijn argumenten — en los ze op wanneer nodig. De grootste bucket in de agent hierboven is tooloutput die één keer werd gelezen, één keer gebruikt en daarna nog dertig beurten werd meegedragen. Elk resultaat ouder dan vier beurten vervangen door een stub die zegt wat het was en hoe je het terughaalt, is zes regels:

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)))];

Dit is hoofdstuk 19 met het corpus vervangen door het eigen verleden van de agent. De retrieval-machinerie is er al — het is de toolcatalogus.

Wanneer het transcript een drempel passeert, vervang je het oudste deel door een door het model geschreven samenvatting en ga je door. De prompt die de samenvatting schrijft is het hele ontwerp, en daar wordt compaction gewonnen of verloren: bewaar identifiers, getallen, vaste instructies en open vragen; laat beleefdheden en tooloutput vallen die je opnieuw kunt ophalen.

Compaction is per definitie lossy, wat het verliest wordt namens jou door een model gekozen, en er gaat niets in error wanneer het verkeerd kiest. Het is ook niet gratis: elke compaction is een extra call waarvan de input het ding is dat wordt gecompact.

Onderhoud een kleine store buiten de context en injecteer die in zijn geheel opnieuw bij elke beurt. Anders dan een samenvatting is hij append-only en adresseerbaar: een regel die bij beurt 2 is geschreven, staat er bij beurt 400 nog steeds letterlijk. De hier gemeten versie vraagt het model na elk gebruikersbericht of het iets duurzaams bevat:

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()}`);

Dit is de strategie met het hoogste plafond hier, en het is degene die in de meting faalde. Over veertig gebruikersberichten bewaarde de note-taker drie notities en geen van de twee die ertoe deden: een regel runbook-advies, een aankondiging dat de sessie eindigde, en Europe/Madrid is currently 13:45 — een tijd die hij verzon, omdat de tool die hij parafraseerde 09:52 UTC teruggaf. De note-taker is een model, en alles in dit hoofdstuk geldt ook voor hem.

Geef een gefocuste taak zijn eigen window — zijn eigen system prompt, zijn eigen kleine catalogus, niets van de geschiedenis van de parent — en geef een kort antwoord terug in plaats van een transcript. Hoofdstuk 23 zette er één achter een toolschema en liet de rekening hier; de rekening is dat het antwoord van de child het enige deel van de window van de child is waarvoor de parent ooit betaalt.

De sub-agent staat niet in de tabel hierboven omdat hij geen veertig beurten draait: hij draait één keer, in een window dat iemand ervoor heeft afgebakend. Gegeven de system prompt, beurten 17 tot 19 en niets anders — 2.737 tokens — beantwoordde hij de shard-probe 6/6, beter dan elke policy in de tabel, en de employee-probe 0/6, omdat dat nummer niet in de drie beurten staat die hij kreeg.

Dat zijn sub-agents in twee getallen: een schoon window is geen intelligentie, het is scope, en de scoping wordt vooraf gedaan door code die al moet weten welke beurten ertoe doen. Nog één ding in die antwoorden is het bewaren waard. Dit was de enige policy die "None available" antwoordde in plaats van iets te verzinnen. Een model met een kleine, coherente context weet wat het mist; een model met een grote, ruisende context niet.

Bijna elk verward gesprek over agent memory bestaat uit drie mechanismen die één woord dragen. Ze hebben verschillende levensduren, eigenaren en failure modes, en een systeem dat ze op dezelfde plek bewaart heeft een probleem dat het nog niet heeft opgemerkt.

gespreksgeschiedenisretrievalpersistente gebruikersmemory
bevatwat in deze sessie is gezegddocumenten die je bezitfeiten over een persoon
leeftéén sessietot opnieuw geïndexeerdover alle sessies heen, voor altijd
geschreven doorde loop, automatischeen ingestion-pipelinehet model, met opzet
komt de prompt binnenvolledig, elke callvier passages, wanneer een query matchtvolledig, elke call
faalt doorgroeien tot hij rotde verkeerde chunk ophaleniets verkeerds over je onthouden
gebouwd inhoofdstuk 23hoofdstuk 19dit hoofdstuk

Het academische frame is dat van CoALA, dat language agents organiseert rond "modular memory components" en working memory scheidt van episodic, semantic en procedural stores.4 MemGPT neemt hetzelfde idee letterlijk, door virtual memory uit besturingssystemen te lenen: een snelle laag binnen de window, een trage laag erbuiten, en het model zelf dat data tussen beide verplaatst met function calls.5 Beide dwingen de vraag af die een product toch moet beantwoorden — niet hoeveel kan ik bewaren, maar in welke store hoort dit, en wanneer verloopt het.

De praktische test is één vraag per feit: wat moet morgen nog waar zijn? Een toolresultaat uit beurt 12: niets. Een samenvatting van de sessie: tot de sessie eindigt. Dat het personeelsnummer van de gebruiker 4417 is: tot diegene van baan verandert. Drie antwoorden, drie stores.

Je kunt nu meten wat er in een window zit, beslissen wat erin blijft, en het verschil zien tussen een agent die iets vergat en een agent die het meedroeg maar niet keek.

De laatste van de vier strategieën past hier niet. Een sub-agent is geen context policy, het is een tweede agent, en zodra er twee zijn moet je beslissen wat ertussen wordt doorgegeven en wie de leiding heeft. Hoofdstuk 25 is dat: de vijf orchestration patterns en waar elk van hun namen echt vandaan komt, de twee topologieën die door elkaar worden gehaald — een sub-agent vragen en een antwoord terugkrijgen, tegenover hem het gesprek geven en het niet terugkrijgen — en de gemeten bevinding dat op de taak die het becijfert, de eenvoudigere inrichting wint — gevolgd door de test voor wanneer die ophoudt te winnen.

Het erft ook precies wat dit hoofdstuk net heeft gemeten. Een sub-agent geeft een samenvatting terug. Een samenvatting is een compaction die je niet schreef, geproduceerd door een model waarvan je de window niet kunt zien, en de parent heeft geen manier om een goede te onderscheiden van een zelfverzekerd foute — hetzelfde onderscheid dat bovenaan deze pagina 84 % van 19 % scheidde, en dat achttien ontbrekende feiten in achttien verzonnen feiten veranderde. Dus: wanneer de sub-agent fout zit, waar mag de parent dan precies naar kijken?


Elk getal hier is op deze machine geproduceerd en geen enkel is geschat. Het model is Qwen2.5-0.5B-Instruct in float32 op de CPU met greedy decoding, geserveerd over loopback door een kleine Python-endpoint die de chat-completions-vorm spreekt en een token-count-route exposeert — opnieuw de seam uit hoofdstuk 14, tensors aan de Python-kant en de loop aan de TypeScript-kant — zodat elke telling de eigen tokenizer van dat model is toegepast op zijn eigen chat-template. De positietabel bestaat uit 288 calls, negen posities maal tweeëndertig trials met een ander ticket per trial; de lengtetabel is 140 calls; de agent-run is 57 model calls over 43 minuten wandkloktijd; de policy-tabel is dat ene transcript afgespeeld onder zeven policies. Intervallen zijn Wilson's, uit hoofdstuk 4. Er is geen betaalde API aangeroepen, en daarom staat er ook geen enkele prijs in het hoofdstuk: de token counts zijn exact en de tarieven waarmee je ze zou vermenigvuldigen staan in hoofdstuk 16.

  1. Anthropic, Effective context engineering for AI agents, 29 september 2025, anthropic.com/engineering/effective-context-engineering-for-ai-agents, gelezen op 7 september 2026. Bron van de twee definities die bovenaan worden geciteerd, van het "attention budget" en de stelling dat elke nieuwe token het uitput, van de beschrijving van contextrot, van het n²-pairwise-relationships-frame, en van de strategieën die als ruggengraat van dit hoofdstuk zijn gebruikt. Drie ervan zijn de long-horizon-lijst — compaction, structured note-taking en multi-agent architectures; just-in-time retrieval komt eerder in hetzelfde artikel, onder context retrieval en agentic search, en wordt hier met ze gegroepeerd. 2 3 4

  2. Liu, N. F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F. en Liang, P. Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172 (v1 juli 2023, v3 november 2023). Geciteerd in hoofdstukken 15, 16 en 19 en hier gemeten. De geciteerde zin komt uit de abstract; de twee taken van het paper zijn multi-document question answering en key-value retrieval, en de bevinding dat het effect blijft bestaan in expliciet long-context models is het deel dat telt voor een productbeslissing.

  3. Anthropic, Code execution with MCP: building more efficient agents, 4 november 2025, anthropic.com/engineering/code-execution-with-mcp, gelezen op 7 september 2026. Bron van de reductie van 150.000 naar 2.000 tokens en het cijfer van 98,7 %, en van de observatie dat tooldefinities die vooraf worden geladen context innemen voordat het request wordt gelezen.

  4. Sumers, T. R., Yao, S., Narasimhan, K. en Griffiths, T. L. Cognitive Architectures for Language Agents. arXiv:2309.02427 (2023). Organiseert language agents rond "modular memory components, a structured action space to interact with internal memory and external environments, and a generalized decision-making process to choose actions", en splitst memory in working, episodic, semantic en procedural. Hoofdstuk 22 gebruikte de taxonomie voor de learning agent; de tabel met drie stores hierboven is de praktische schaduw ervan.

  5. Packer, C., Wooders, S., Lin, K., Fang, V., Patil, S. G., Stoica, I. en Gonzalez, J. E. MemGPT: Towards LLMs as Operating Systems. arXiv:2310.08560 (oktober 2023). Stelt "virtual context management, a technique drawing inspiration from hierarchical memory systems in traditional operating systems" voor, waarbij het model zelf data verplaatst tussen een snelle laag binnen de window en een trage laag erbuiten. De duidelijkste formulering ergens van waarom de window een cache is en geen memory.

Klaar om LIA te laten kiezen?

Bouw met elk AI-model op één plek — begin vandaag nog gratis.