# Sessiebeheer en context window compaction via LLM-API's

[Naar de inhoud](#lm-inhoud)Netwerk/NL[EN](/en/)[Hubhub.llmnet.nlModellen vergelijken op taak, taal, kosten en licentie.](https://hub.llmnet.nl/)[Communitycommunity.llmnet.nlPrompttechnieken, patronen en systeemprompts.](https://community.llmnet.nl/)[APIapi.llmnet.nlLLM's robuust in software: rate limits, routing, structured output.](https://api.llmnet.nl/)[Consultancyconsultancy.llmnet.nlAI invoeren in een organisatie, van pilot tot productie.](https://consultancy.llmnet.nl/)[Nieuwsnieuws.llmnet.nlOntwikkelingen in AI, geduid voor Nederland.](https://nieuws.llmnet.nl/)[Benchmarkbenchmark.llmnet.nlZelf meten wat AI-kwaliteit is, voor jouw taken.](https://benchmark.llmnet.nl/)[Vacaturesvacatures.llmnet.nlAI-rollen, salarissen en carrièrepaden in Nederland.](https://vacatures.llmnet.nl/)[Lerenleren.llmnet.nlAI-concepten in gewoon Nederlands, van beginner tot bouwer.](https://leren.llmnet.nl/)[Gidsgids.llmnet.nlAI privé draaien op eigen Mac, pc, NAS of thuisserver.](https://gids.llmnet.nl/)[Directorydirectory.llmnet.nlHet AI-ecosysteem in kaart: tools, modellen, bedrijven.](https://directory.llmnet.nl/)[Radarradar.llmnet.nlSignalen uit X, onderzoek en communities voor indie developers.](https://radar.llmnet.nl/)[llmnet.nl — hoofdsite](https://llmnet.nl/)[](https://x.com/intent/post?url=https%3A%2F%2Fapi.llmnet.nl%2Fsessiebeheer-en-context-window-compaction-via-de-llm-api&text=Sessiebeheer%20en%20context%20window%20compaction%20via%20LLM-API%27s)[](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fapi.llmnet.nl%2Fsessiebeheer-en-context-window-compaction-via-de-llm-api)[](https://www.reddit.com/submit?url=https%3A%2F%2Fapi.llmnet.nl%2Fsessiebeheer-en-context-window-compaction-via-de-llm-api&title=Sessiebeheer%20en%20context%20window%20compaction%20via%20LLM-API%27s)[](#)[](https://x.com/intent/post?url=https%3A%2F%2Fapi.llmnet.nl%2Fsessiebeheer-en-context-window-compaction-via-de-llm-api&text=Sessiebeheer%20en%20context%20window%20compaction%20via%20LLM-API%27s)[](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fapi.llmnet.nl%2Fsessiebeheer-en-context-window-compaction-via-de-llm-api)[](https://www.reddit.com/submit?url=https%3A%2F%2Fapi.llmnet.nl%2Fsessiebeheer-en-context-window-compaction-via-de-llm-api&title=Sessiebeheer%20en%20context%20window%20compaction%20via%20LLM-API%27s)[](#)

 
# Sessiebeheer en context window compaction via de LLM-API

 Door Ivo Donker — samengesteld met AI-ondersteuning (Claude & Gemini)

 Stateless API-architecturen vormen het fundament van moderne machine learning pipelines, maar interactieve applicaties zoals klantenservice-assistenten, programmeertools en data-analyse-omgevingen vereisen doorlopende gesprekscontinuïteit over tientallen beurten heen. Wie bij elke opeenvolgende interactie blindelings de volledige gesprekshistorie meestuurt, loopt snel vast in exponentieel stijgende kosten, harde rate limits en een meetbare degradatie van de redeneerkwaliteit. Dit artikel valt onder pijler A5 (Requestpatronen & datacontract) en bouwt voort op de principes voor [het ophalen van betrouwbare structured output](https://api.llmnet.nl/structured-output) om voorspelbare, gecompacteerde contextstructuren af te dwingen.

 We behandelen de architectuur van client-side en gateway-side sessiebeheer, en methoden om berichtreeksen cyclisch te verkleinen (context compaction). Dit artikel behandelt promptversiebeheer niet; zie [versiebeheer voor prompts in een codebase](https://api.llmnet.nl/versiebeheer-voor-prompts-in-code) voor het gecontroleerd uitrollen van prompt-templates. Wie wil begrijpen hoe ongebreidelde contextgroei de operationele uitgaven direct opdrijft, vindt verdiepende analyses in het artikel over [wat een lang contextvenster echt kost](https://hub.llmnet.nl/wat-kost-een-lang-contextvenster-echt).

 
## De faalmodus van naïef sessiebeheer: contextbloat en aandachtsverwatering

 De eenvoudigste methode om een dialoog via een LLM-API te onderhouden, is het lokaal opslaan van een array met berichten en deze bij elke beurt integraal in de messages-parameter te versturen. In een productieomgeving faalt dit primitieve patroon structureel op drie afzonderlijke dimensies:

 
 Ten eerste veroorzaakt het een kwadratische toename in tokenverbruik. Bij een conversatie van twintig interacties betaalt de beheerder niet alleen voor het laatste antwoord, maar bij interactie twintig opnieuw voor de invoertokens van interacties één tot en met negentien. Dit leidt tot een snelle uitputting van de ingestelde verbruikslimieten, zoals beschreven in de handleiding over [rate limits, tokens en kostenbeheer](https://api.llmnet.nl/rate-limits-en-kosten). De cumulatieve inputkosten van beurt $N$ schalen als $O(N^2)$, wat bij lange sessies leidt tot budgetoverschrijdingen binnen enkele uren.

 Ten tweede treedt het fenomeen van aandachtsverwatering op, ook wel 'lost-in-the-middle' genoemd. Naarmate het contextvenster groeit tot tienduizenden tokens, verliest het self-attention mechanisme van het transformer-model zijn precisie op instructies die in het midden van de gespreksgeschiedenis zijn weggewerkt. Het model begint eerdere beperkingen te negeren, herhaalt reeds weerlegde aannames of hallucineert inconsistente parameters die eerder expliciet door de gebruiker waren gecorrigeerd.

 Ten derde ontstaat er een ernstige degradatie van de Time-To-First-Token (TTFT). Het achterliggende model moet bij elke API-aanroep de gehele prompt prefillen. Zonder doordachte caching verdrievoudigt de wachttijd voor de eindgebruiker binnen tien gespreksbeurten, wat de interactieve gebruikerservaring direct schaadt.

 
## Architectuurpatronen voor sessiebeheer: Client, API en Gateway

 Het beheer van de gespreksstatus kan op drie verschillende niveaus in het applicatielandschap worden belegd. Elke keuze brengt specifieke trade-offs met zich mee ten aanzien van latency, beveiliging en schaalbaarheid:

 Client-side state: De client-applicatie (bijvoorbeeld een browser-SPA of mobiele app) houdt de volledige gesprekshistorie bij in lokaal geheugen of IndexedDB en verstuurt bij elk verzoek de samengestelde array naar de backend. Hoewel dit de backend volledig stateless houdt, is het patroon extreem kwetsbaar voor manipulatie (prompt injection via gemanipuleerde historische berichten) en leidt het tot onnodig zware netwerkpayloads vanaf mobiele apparaten.

 Application backend session storage: De backend bewaart de actieve berichtengeschiedenis in een snelle sleutel-waardestatus (zoals Redis of DynamoDB), gekoppeld aan een cryptografisch gegenereerde sessie-ID. De frontend stuurt uitsluitend de nieuwe gebruikersinput en de sessie-ID mee. De backend-service laadt de historie, past compactie toe, roept de LLM-API aan en slaat de bijgewerkte staat op. Dit is de meest gangbare industriestandaard voor enterprise-toepassingen.

 LLM Gateway managed context: Een centrale API-gateway onderschept het verkeer naar externe modelproviders, beheert de sessiestatus en voert transparante compaction-algoritmen uit voordat de payload de provider bereikt. Dit ontlast applicatie-ontwikkelaars van repetitieve contextlogica en centraliseert monitoring en caching op één infrastructureel punt.

 
## Drie compaction-patronen vergeleken

 Om een interactieve sessie binnen strakke budgetgrenzen te houden zonder historische feiten te verliezen, bestaan er drie toonaangevende strategieën. De onderstaande matrix zet de architectonische eigenschappen naast elkaar:

 
 
 
 
 Strategie | 
 Implementatiecomplexiteit | 
 Tokenbesparing | 
 Risico op informatieverlies | 
 Impact op TTFT | 
 

 
 
 
 Sliding Window (FIFO) | 
 Zeer laag | 
 Voorspelbaar / Constant | 
 Zeer hoog (verliest eerdere context volledig) | 
 Minimaal | 
 

 
 Recursieve Samenvatting | 
 Gemiddeld | 
 Hoog (60% tot 80%) | 
 Gemiddeld (semantische vervaging) | 
 Extra LLM-call vereist | 
 

 
 Entiteits- en Geheugenextractie | 
 Hoog | 
 Zeer hoog (>85%) | 
 Laag (strikt deterministisch) | 
 Asynchrone overhead | 
 

 
 
 

 Voor eenvoudige vraag-en-antwoordstromen volstaat een rolling window, maar voor geavanceerde bedrijfsassistenten is gestructureerde extractie noodzakelijk. Een bredere conceptuele vergelijking tussen losse prompts en geavanceerd geheugenbeheer is te vinden op het community-platform via [de gids voor context window management](https://community.llmnet.nl/context-management).

 
## Patroon 1: Rolling token-bounded FIFO buffer

 Het meest basale compaction-mechanisme hanteert een hard tokenplafond voor de actieve gespreksgeschiedenis. In plaats van primitief te snoeien op basis van het aantal berichten (dat sterk kan variëren in lengte), snoeit het algoritme op basis van exact gemeten BPE-tokens (Byte Pair Encoding). Hierbij blijft het initiële systeembericht altijd op positie nul verankerd, terwijl de oudste gebruikers- en assistent-berichten paarsgewijs worden verwijderd zodra de drempelwaarde wordt overschreden.

 De zwakte van dit patroon is evident: als een gebruiker in beurt twee een cruciale constraint noemt (bijvoorbeeld "schrijf uitsluitend TypeScript en gebruik geen externe dependencies"), verdwijnt deze regel geruisloos uit het venster zodra beurt twaalf bereikt is. Gebruik deze aanpak daarom alleen bij kortcyclische taken waarbij eerdere interacties geen bindende randvoorwaarden voor latere stappen bevatten.

 
## Patroon 2: Recursieve semantische samenvatting

 Bij recursieve samenvatting splitst de applicatielaag de context op in drie functionele zones: het vaste systeembericht, een gecomprimeerd statusblok (de lopende samenvatting van afgesloten interacties), en een actieve werkbuffer met de meest recente interacties (bijvoorbeeld de laatste 4 tot 6 berichten).

 Zodra de totale tokenomvang van de werkbuffer een vooraf gedefinieerd drempelpercentage passeert (de trigger threshold, bijvoorbeeld 75% van het tokenbudget), activeert de orchestrator een compactietaak. Hierbij worden de bestaande statussamenvatting en de oudste berichten uit de werkbuffer samengevoegd tot een nieuw geconsolideerd tekstblok. Dit verlaagt de tokenomvang aanzienlijk, maar introduceert het risico van semantische drift: na vier opeenvolgende samenvattingscycli kunnen specifieke technische details, zoals foutcodes, bestandsnamen of exacte numerieke variabelen, geleidelijk vervagen of muteren.

 
## Patroon 3: Deterministische extractie van entiteiten en status

 Om semantische drift effectief te elimineren, isoleert dit patroon de gesprekscontext in een strikt JSON-schema. In plaats van een vrije tekstuele samenvatting genereert een achtergrondproces een statusobject dat de actuele toestand van de sessie reflecteert (bijvoorbeeld geselecteerde filters, account-ID's, vastgestelde software-eisen en nog openstaande vragen).

 Door het statusobject via gestructureerde output af te dwingen, blijft de context deterministisch en programmeerbaar manipuleerbaar door backend-code. In de promptinjectie wordt dit statusobject als JSON aangeboden in het ontwikkelaarsbericht. Hierdoor hoeft de ruwe chathistorie niet bewaard te worden in het contextvenster om feitelijke precisie over lange sessies te garanderen.

 
## Implementatie: Een compactielaag met sliding window en statusblok

 Het onderstaande Python-voorbeeld toont een productieklare sessiemanager. De implementatie combineert een vast systeembericht, een compacte statussamenvatting en een dynamische sliding window die rekening houdt met tokenlimieten en robuuste foutafhandeling bij netwerkstoringen.

 import os
import time
import tiktoken
import httpx

class SessionContextManager:
 def __init__(self, system_instruction: str, max_context_tokens: int = 4000):
 self.system_instruction = system_instruction
 self.max_context_tokens = max_context_tokens
 self.summary_state = ""
 self.history = []
 self.tokenizer = tiktoken.get_encoding("cl100k_base")

 def _count_tokens(self, text: str) -> int:
 return len(self.tokenizer.encode(text))

 def add_message(self, role: str, content: str):
 self.history.append({"role": role, "content": content})

 def _build_payload_messages(self) -> list:
 messages = [{"role": "system", "content": self.system_instruction}]
 if self.summary_state:
 messages.append({
 "role": "system", 
 "content": f"Status van eerdere interacties:\n{self.summary_state}"
 })
 messages.extend(self.history)
 return messages

 def compact_if_needed(self, client: httpx.Client, api_url: str, api_key: str):
 total_tokens = sum(self._count_tokens(m["content"]) for m in self._build_payload_messages())
 
 # Activeer compaction zodra 80% van het tokenbudget is bereikt
 if total_tokens < (self.max_context_tokens * 0.8) or len(self.history) <= 4:
 return

 # Pak de oudere helft van de actieve historie om samen te vatten
 split_point = len(self.history) - 4
 to_compact = self.history[:split_point]
 self.history = self.history[split_point:]

 compact_prompt = (
 "Vat de volgende interacties feitelijk en compact samen in maximaal 100 woorden. "
 "Behoud specifieke entiteiten, afspraken, foutcodes en variabelen:\n" +
 "\n".join([f"{m['role']}: {m['content']}" for m in to_compact])
 )

 payload = {
 "model": "gpt-4o-mini",
 "messages": [
 {"role": "system", "content": "Je bent een context-compressor. Reageer strikt zakelijk."},
 {"role": "user", "content": compact_prompt}
 ],
 "temperature": 0.0
 }

 try:
 response = client.post(
 api_url,
 json=payload,
 headers={"Authorization": f"Bearer {api_key}"},
 timeout=10.0
 )
 response.raise_for_status()
 new_summary = response.json()["choices"][0]["message"]["content"]
 self.summary_state = f"{self.summary_state}\n{new_summary}".strip()
 except httpx.HTTPError as err:
 # Foutmitigatie: herstel de historie indien samenvatting mislukt
 self.history = to_compact + self.history
 raise RuntimeError(f"Context compaction gefaald: {err}")

 def prepare_request(self, client: httpx.Client, api_url: str, api_key: str) -> list:
 self.compact_if_needed(client, api_url, api_key)
 return self._build_payload_messages()

 
## Interactie met KV-cache en context caching

 Context compaction mag niet geïsoleerd van moderne provider-architecturen worden ontworpen. Grote LLM-leveranciers passen geautomatiseerde prefix caching (KV-caching) toe. Hierbij herkent de provider identieke reeksen tokens aan het begin van de prompt en hergebruikt deze de reeds berekende key-value aandachtsvectoren. Dit leidt tot kortingen tot 50% of meer op inputtokens en een drastisch lagere TTFT.

 Onzorgvuldig ontworpen sessiebeheer verbreekt deze cache-consistentie voortdurend. Als een sessiemanager bij elke beurt een dynamische tijdstempel, een actuele kloktijd of een continu wijzigende samenvatting helemaal bovenaan de prompt plaatst, faalt de prefix-matching bij de provider. Om optimaal te profiteren van [caching van LLM-antwoorden en prefixen](https://api.llmnet.nl/caching-llm-antwoorden), dient de payload hiërarchisch te worden gestructureerd:

 Plaats ten eerste de volledig statische systeemprompt en vaste toolschema's vooraan in het contextvenster. Plaats ten tweede het gecompacteerde statusblok (dat slechts periodiek en trapsgewijs wijzigt) direct daarna. Plaats pas als laatste element de volatiele, recente chathistorie. Hierdoor blijft het grootste en zwaarste deel van de context statisch en geschikt voor de prefix-cache van de gateway of provider.

 
## Meetmethodes voor compactiekwaliteit en contextbehoud

 Om te evalueren of een compactie-algoritme succesvol functioneert in productie, zijn puur intuïtieve steekproeven onvoldoende. We hanteren drie kwantitatieve metrieken om sessiekwaliteit te monitoren:

 1. Compression Ratio (CR): De verhouding tussen het aantal tokens van de ruwe gesprekshistorie en de gecompacteerde weergave. Formule: $\text{CR} = 1 - (\text{Tokens}_{\text{gecompacteerd}} / \text{Tokens}_{\text{ruw}})$. Een gezonde pipeline realiseert een CR tussen de 0,65 en 0,85 zonder significant precisieverlies.

 2. Entity Recall Accuracy (ERA): Een geautomatiseerde testprocedure waarbij een evaluatiemodel controleert of vooraf gedefinieerde feiten (zoals productnummers, datums of gebruikersrestricties) die in vroege beurten zijn genoemd, na meerdere compactieslagen nog correct kunnen worden gereproduceerd vanuit de gecompacteerde staat.

 3. Compaction Latency Overhead (CLO): De p95-latency van de compactiestap zelf. Indien inline uitgevoerd, meet dit de extra vertraging die de eindgebruiker ervaart tijdens een compaction-beurt ten opzichte van een reguliere interactiebeurt.

 
## Randgevallen en complexe scenario's in productie

 In complexe productie-omgevingen ontstaan vaak randgevallen die een eenvoudige FIFO- of samenvattingslus doen ontsporen:

 
### Multimodale sessies met afbeeldingen en documenten

 Wanneer een gebruiker een afbeelding of een groot PDF-document uploadt, neemt deze interactie duizenden tokens in beslag. Een klassieke tekstsamenvatter kan binaire of multimodale tokens niet eenvoudig comprimeren. De robuuste oplossing is om direct na verwerking een tekstuele beschrijving van de visuele input op te slaan in het statusblok en de zware multimodale data na één beurt direct uit de actieve geschiedenis te verwijderen.

 
### Grote tool-outputs en JSON-resultaten

 Wanneer een LLM een externe tool aanroept (bijvoorbeeld een database-query die 50 rijen retourneert), blaast dit de historie in één klap op. De applicatie moet tool-outputs agressief filteren of converteren naar een compact schema voordat ze aan de sessiehistorie worden toegevoegd. Stuur nooit ruwe SQL-dumps of complete API-responses terug naar de chatgeschiedenis.

 
### Gebruikerscorrecties en tegenstrijdigheden

 Als een gebruiker zegt: "Vergeet wat ik net zei over budget X, het budget is nu Y", kan een naive samenvatter beide getallen behouden ("oorspronkelijk X, later gewijzigd naar Y"). Dit schept verwarring in latere redeneerstappen. Deterministische status-extractie via een JSON-schema overschrijft simpelweg het veld budget, waardoor tegenstrijdigheden definitief worden geëlimineerd.

 
## Foutpaden en herstelstrategieën

 Bij het uitvoeren van geautomatiseerde context compaction kunnen specifieke foutcondities optreden die de robuustheid van de applicatie bedreigen:

 
### 1. Compaction time-out tijdens een actieve gebruikerssessie

 Wanneer de achterliggende API-aanroep voor de samenvatting vertraagt of faalt met een HTTP 504 gateway time-out, mag de actieve gebruikerssessie niet blokkeren. De sessiemanager moet gracefully degraderen: voer een tijdelijke FIFO-truncatie uit op de oudste berichten of stuur de ongecompacteerde payload eenmalig door, mits het absolute modelmaximum dit toelaat.

 
### 2. Hallucinatie in de samenvatting

 Het compressiemodel kan feiten verdraaien (bijvoorbeeld "de gebruiker wil het abonnement opzeggen" in plaats van "de gebruiker vraagt naar de opzegtermijn"). Mitigeer dit door compactie-prompts met een lage temperatuur (0.0) uit te voeren, specifieke extractierichtlijnen mee te geven en kritieke statusparameters altijd via deterministische validatieregels te verifiëren.

 
### 3. Tokenbudget-overschrijding door tool-loops

 Wanneer een agent in een herhalende loop van tool calls terechtkomt, kan het contextvenster binnen enkele seconden vollopen. De sessiemanager moet een harde drempel handhaven op het aantal opeenvolgende tool-interacties binnen één beurt en ingrijpen zodra een vooraf ingesteld tokenlimiet wordt benaderd.

 
## Kosten, latency en complexiteit: de operationele afweging

 Context compaction is geen kosteloze ingreep. Wie compaction ontwerpt, moet drie afwegingen zorgvuldig tegen elkaar afwegen:

 Latency-overhead: Een inline samenvattings-call voegt tussen de 400ms en 1500ms toe aan de reactietijd van de specifieke beurt waarin de compactie plaatsvindt. Dit kan worden voorkomen door compactie asynchroon in een achtergrondtaak uit te voeren direct nadat het vorige antwoord naar de gebruiker is gestreamd.

 Financiële kosten: Het genereren van samenvattingen verbruikt outputtokens, die per token duurder zijn dan inputtokens. Bij korte sessies (minder dan 5 interacties) is context compaction vaak duurder dan het simpelweg meesturen van de volledige geschiedenis. Pas compactie pas toe wanneer gesprekken structureel langer duren dan het economische omslagpunt van het model.

 Operationele complexiteit: Zodra status geëxtraheerd en opgeslagen wordt, vereist het systeem een redundante opslaglaag (zoals Redis of PostgreSQL) om de sessiestatus tussen verzoeken te synchroniseren. Dit introduceert stateful componenten in een voorheen stateless microservice-landschap.

 
## Conclusie

 Effectief sessiebeheer bij LLM-API's vereist een strikte scheiding tussen statische systeeminstructies, een periodiek geconsolideerd statusblok en een dynamische, recente werkbuffer. Door gerichte compactie-algoritmen te combineren met deterministische structured output en rekening te houden met provider-side prefix caching, blijven interactieve LLM-integraties schaalbaar, voorspelbaar in kosten en consistent in antwoordkwaliteit onder zware productiebelasting.
