Hoe je geheugen toevoegt aan een AI-agent: statuspersistentiepatronen voor productie
Staatloze agents — degenen die alles vergeten wanneer de Worker stopt — zijn prima voor eenmalige taken. Op het moment dat een agent moet onthouden wat er gisteren is gebeurd, een terugkerende klant moet herkennen, of moet voortbouwen op eerdere output, heb je geheugen nodig. Er zijn drie patronen: werkgeheugen (context in vlucht, leeft in KV voor de duur van een run), episodisch geheugen (wat er is gebeurd en wanneer, een opvraagbaar logboek) en semantisch geheugen (wat je weet, opgehaald via vectorzoekopdrachten of gestructureerde gegevens). Koppel het juiste patroon aan de juiste taak.
Elke woensdag. 28.400+ operators. Geen opvulling.
✓ Controleer je inbox — klik op de bevestigingslink om je aanmelding te voltooien.
✓ Je bent aangemeld!
✓ Je staat al op de lijst.
Inhoudsopgave
Bijgewerkt juni 2026.
TL;DR: Staatloze agents — degenen die alles vergeten wanneer de Worker stopt — zijn prima voor eenmalige taken. Op het moment dat een agent moet onthouden wat er gisteren is gebeurd, een terugkerende klant moet herkennen, of moet voortbouwen op eerdere output, heb je geheugen nodig. Er zijn drie patronen: werkgeheugen (context in vlucht, leeft in KV voor de duur van een run), episodisch geheugen (wat er is gebeurd en wanneer, een opvraagbaar logboek) en semantisch geheugen (wat je weet, opgehaald via vectorzoekopdrachten of gestructureerde gegevens). Koppel het juiste patroon aan de juiste taak.
[Operator-perspectief] Ik ben meer dan eens tegen de staatloze muur opgelopen. De social reply-agent die zichzelf bleef voorstellen aan klanten met wie hij al 20 keer had gepraat. De dagelijkse briefing-agent die hetzelfde probleem vier dagen achter elkaar meldde omdat hij geen herinnering had aan het melden ervan gisteren. Het toevoegen van het juiste soort geheugen heeft beide opgelost. Dit is wat ik gebruik.
Waarom staatloze agents blijven falen
Een staatloze agent begint elke run alleen met wat je hem expliciet doorgeeft: de systeemprompt, het gebruikersbericht en welke gegevens je op het moment van aanroep ophaalt. Hij heeft geen bewustzijn van eerdere runs, eerdere gebruikers of eerdere beslissingen.
Voor een eenmalige classificatietaak — een reactie lezen, een categorie teruggeven — is staatloze correct. Het is snel, goedkoop en voorspelbaar.
Het faaloppervlak verschijnt zodra je continuïteit nodig hebt:
- Een klantgerichte agent die de geschiedenis van de klant niet herkent
- Een contentagent die een artikel aanbeveelt dat hij vorige week al aanbeveelde
- Een moderatieagent die een opgelost geval blijft escaleren
- Een dagelijkse briefing die dezelfde verouderde melding voor onbepaalde tijd toont
Dit zijn allemaal symptomen van hetzelfde probleem: de agent heeft geen manier om context over runs heen te dragen.
Drie soorten geheugen
Het kader dat ik nuttig vind in productie:
- Werkgeheugen — wat de agent nu weet, tijdens een enkele run. Bewaard in KV of in het geheugen voor de levensduur van de aanroep.
- Episodisch geheugen — wat er is gebeurd en wanneer. Een gestructureerd logboek dat de agent aan het begin van elke run leest om zich te oriënteren.
- Semantisch geheugen — wat het weet over de wereld, klanten of een kennisbank. Opgehaald via gestructureerde query’s of vectorzoekopdrachten wanneer relevant.
Je hebt niet altijd alle drie nodig. De meeste agents die ik run hebben werkgeheugen + episodisch nodig. Semantisch geheugen is het moeilijkst te bouwen en verdient zijn plek pas wanneer de kennisbank te groot is om in het contextvenster te passen.
Werkgeheugen: context in vlucht
Werkgeheugen is een status die leeft gedurende de duur van één agent-run. De eenvoudigste vorm zijn variabelen in de functiescope. De interessantere vorm is een gedeelde KV-sleutel die subtaken binnen dezelfde run lezen en schrijven.
Mijn social reply-agent gebruikt werkgeheugen om context te accumuleren terwijl hij een batch reacties in één wachtrij-bericht verwerkt. Hij leest aan het begin de recente gespreksgeschiedenis voor elke klant uit KV, voegt nieuwe context toe tijdens de verwerking en schrijft aan het einde terug.
// workers/social-reply.ts
async function processComment(
comment: SocialCommentEvent,
env: Env
): Promise<void> {
// Recente geschiedenis van deze klant laden uit KV (werkgeheugen)
const historyKey = `customer:${comment.userId}:history`;
const rawHistory = await env.AGENT_KV.get(historyKey);
const history: ConversationTurn[] = rawHistory
? JSON.parse(rawHistory)
: [];
// Een contextbewuste systeemprompt opbouwen vanuit de geschiedenis
const systemPrompt = buildSystemPrompt(history);
const response = await anthropic.messages.create({
model: "claude-opus-4-8",
max_tokens: 512,
system: systemPrompt,
messages: [{ role: "user", content: comment.text }],
});
const reply =
response.content[0].type === "text" ? response.content[0].text : "";
// Geschiedenis bijwerken — de laatste 10 beurten bewaren, TTL 30 dagen
const updatedHistory: ConversationTurn[] = [
...history.slice(-9),
{ role: "assistant", content: reply, timestamp: comment.timestamp },
];
await env.AGENT_KV.put(historyKey, JSON.stringify(updatedHistory), {
expirationTtl: 60 * 60 * 24 * 30,
});
await postReply(comment, reply, env);
}Twee dingen om op te merken. De geschiedenis is beperkt tot 10 beurten — gebruik een schuifvenster, laat het niet onbeperkt groeien. En de TTL is 30 dagen: als een klant een maand zwijgt, verloopt de geschiedenis en begint de agent opnieuw. Beide zijn opzettelijk.
Episodisch geheugen: wat er is gebeurd en wanneer
Episodisch geheugen is het logboek van de agent. Een gestructureerd overzicht van vroegere runs dat de agent aan het begin van elke nieuwe run leest om herhaling te vermijden.
Mijn dagelijkse briefing-agent toonde elke dag dezelfde verouderde meldingen omdat elke run geen bewustzijn had van wat al was gemeld. De oplossing: een gestructureerd logboek van vroegere meldingen dat de agent leest vóór het genereren van de briefing.
// workers/daily-brief.ts
interface AlertLogEntry {
id: string;
surfacedAt: string; // ISO-tijdstempel
resolvedAt?: string;
summary: string;
}
async function buildDailyBrief(env: Env): Promise<void> {
const [emails, calendar, tasks] = await Promise.all([
fetchOvernightEmails(env),
fetchTodayCalendar(env),
fetchTopTasks(env),
]);
// Episodisch geheugen laden: wat al is gemeld
const rawLog = await env.AGENT_KV.get("brief:alert-log");
const alertLog: AlertLogEntry[] = rawLog ? JSON.parse(rawLog) : [];
// Filteren op alleen recente, onopgeloste meldingen
const sevenDaysAgo = new Date(
Date.now() - 7 * 24 * 60 * 60 * 1000
).toISOString();
const recentAlerts = alertLog.filter(
(e) => e.surfacedAt > sevenDaysAgo && !e.resolvedAt
);
const brief = await synthesizeBrief(
{ emails, calendar, tasks, recentAlerts },
env
);
// Het logboek bijwerken met nieuwe meldingen die in deze run zijn gevlagd
const newAlerts: AlertLogEntry[] = brief.newAlerts.map((a) => ({
id: crypto.randomUUID(),
surfacedAt: new Date().toISOString(),
summary: a,
}));
const updatedLog = [...alertLog, ...newAlerts].slice(-100); // de laatste 100 bewaren
await env.AGENT_KV.put("brief:alert-log", JSON.stringify(updatedLog));
await writeToWorkspace(brief.content, env);
}De agent weet nu wat hij al heeft gezegd. Dubbele meldingen blijven buiten de briefing totdat het onderliggende probleem verandert. Wanneer ik een melding als opgelost markeer, verdwijnt deze van de actieve lijst.
Dit patroon generaliseert: elke agent die beslissingen, vlaggen of aanbevelingen produceert, heeft baat bij een logboek. Het logboek is goedkoop (een paar KB in KV), de opbrengst is hoog (geen redundante output meer).
Semantisch geheugen: wat je weet
Semantisch geheugen is de kennisbank. Het beantwoordt “wat weet je over X?” op het moment van de query, in plaats van alles vooraf in de systeemprompt te proppen.
De eenvoudigste vorm is een gestructureerde zoekopdracht in KV of een database. Mijn Pickleland-boekingsagent raadpleegt klantprofielen en baanvoorkeuren voordat hij bevestigingen opstelt:
// workers/booking-agent.ts
interface CustomerProfile {
userId: string;
preferredCourts: string[];
experienceLevel: "beginner" | "intermediate" | "advanced";
specialNotes: string;
}
async function draftConfirmation(
booking: BookingEvent,
env: Env
): Promise<string> {
// Klantprofiel ophalen uit KV (semantisch geheugen — feitelijke kennis)
const profileKey = `customer:${booking.userId}:profile`;
const rawProfile = await env.AGENT_KV.get(profileKey);
const profile: CustomerProfile | null = rawProfile
? JSON.parse(rawProfile)
: null;
const systemPrompt = profile
? `Je stelt gepersonaliseerde boekingsbevestigingen op. Deze klant geeft de voorkeur aan ${profile.preferredCourts.join(", ")}, is een ${profile.experienceLevel}-speler. ${profile.specialNotes}`
: "Je stelt boekingsbevestigingen op voor een pickleballfaciliteit.";
const response = await anthropic.messages.create({
model: "claude-haiku-4-5-20251001",
max_tokens: 256,
system: systemPrompt,
messages: [
{
role: "user",
content: `Stel een bevestiging op voor: ${JSON.stringify(booking)}`,
},
],
});
return response.content[0].type === "text" ? response.content[0].text : "";
}Voor grotere kennisbanken — productdocumentatie, een support-kennisbank, alles wat te groot is om in een contextvenster te passen — heb je een vectoropslag nodig. De workflow is: de query insluiten, de k meest relevante chunks ophalen, ze in de context injecteren. Cloudflare Vectorize handelt dit native af als je al op Workers zit. Voor grotere indexen heb ik Upstash Vector gebruikt. De keuze hangt af van de schaal, niet van het principe.
De eerlijke noot over semantisch geheugen: het is de moeilijkste van de drie om te bouwen en te onderhouden. De index moet actueel blijven. De kwaliteit van het ophalen varieert. Begin met gestructureerde zoekopdrachten — KV, een tabel in D1 — en grijp pas naar vectorzoekopdrachten wanneer de gestructureerde aanpak het kennisoppervlak dat je nodig hebt niet kan dekken.
Het geheugen-beslissingsraamwerk
Voordat je geheugen aan een agent toevoegt, beantwoord drie vragen:
-
Moet de agent onthouden tussen runs? Als elke aanroep echt onafhankelijk is — een vertaling, een classificatie, een eenmalige generatie — sla dan geheugen over. Staatloos is eenvoudiger en goedkoper.
-
Herhaalt de agent zichzelf of handelt hij blind voor zijn eigen geschiedenis? Zo ja, voeg dan eerst episodisch geheugen toe. Het is de oplossing met de minste moeite en dekt de meeste klachten over “de agent blijft X doen”.
-
Behandelt de agent elke gebruiker of entiteit identiek wanneer dat niet zou moeten? Zo ja, voeg werkgeheugen toe (klantgeschiedenis, gebruikersprofiel) of semantisch geheugen (een zoek- of ophaal-systeem).
De fout die ik het vaakst zie: iemand voegt een enorme kennisbank (semantisch geheugen) toe aan een agent die eigenlijk faalde omdat hij geen episodisch geheugen had — geen logboek van wat hij al had gedaan. De complexiteit past niet bij het probleem.
Wat ik echt gebruik in productie
Bij 30+ agents:
- Alle hebben minstens werkgeheugen — een of andere vorm van status binnen een run, al is het alleen het contextvenster zelf.
- Ongeveer de helft heeft episodisch geheugen — een logboek van vroegere runs, beslissingen of vlaggen. Dit is bijna altijd de moeite waard om toe te voegen.
- Drie of vier hebben echt semantisch geheugen ondersteund door een vectoropslag. Dit zijn de agents die vragen beantwoorden over een grote, dynamische kennisbank.
Cloudflare KV is mijn standaard opslag voor werk- en episodisch geheugen. Het is snel, goedkoop en native geïntegreerd in Workers — geen extra client, geen aparte credential. De beperking: KV is uiteindelijk consistent en niet geweldig voor schrijfacties met hoge frequentie. Voor agents die meerdere keren per seconde status schrijven, gebruik ik in plaats daarvan Durable Objects of een D1-database.
Voor semantisch geheugen ondersteund door vectoren gebruik ik Cloudflare Vectorize voor kleine tot middelgrote indexen (minder dan ~100K vectoren) en Upstash Vector voor alles wat groter is. Beide hebben eersteklas JavaScript-clients.
De conclusie van de operator
Voeg geheugen toe aan een agent alleen wanneer staatloos gedrag echte problemen veroorzaakt — herhaalde output, blinde vlekken in de klantgeschiedenis, onwetendheid over vroegere beslissingen. Kies dan de juiste laag: werkgeheugen voor context tijdens de run, episodisch voor wat er historisch is gebeurd, semantisch voor wat je weet. Begin met episodisch als je het niet zeker weet — het repareert het meest voorkomende faalpatroon met de minste complexiteit. Grijp niet naar een vectordatabase totdat je gestructureerde zoekopdrachten hebt uitgeput. Het beste geheugensysteem is het eenvoudigste dat de agent correct laat gedragen.
Gerelateerd: De agent-stack die ik gebruik voor 30+ productie-agents · Gebeurtenisgestuurde vs. geplande agents · Hoe ik meet of een AI-agent echt werkt
Hulp nodig bij het ontwerpen van agentgeheugen voor jouw gebruik? Neem contact op — ik ontwerp productie-agentsystemen voor operatorteams.
Elke woensdag. 28.400+ operators. Geen opvulling.
✓ Controleer je inbox — klik op de bevestigingslink om je aanmelding te voltooien.
✓ Je bent aangemeld!
✓ Je staat al op de lijst.
Gerelateerde berichten
Hoe Bouw Je Je Eerste MCP-Server: Een Praktische Gids
Bijgewerkt voor 2026. De exacte TypeScript-code die ik gebruik om MCP-servers te bouwen en te registreren — stdio-transport, tooldefinities en hoe je ze in Claude Desktop test in minder dan 30 minuten.
AI AgentsPrompt caching met de Claude API: verlaag je invoerkosten zonder van model te wisselen
Hoe je cache_control gebruikt om de invoerkosten van de Claude API met tot 90% te verlagen bij agents met grote, stabiele prompts — het prefix-match-principe, wat je cachet, stille cache-brekers en de break-evenberekening.
AI AgentsClaude Fable 5 eerste indrukken: de kijk van een operator
Bijgewerkt voor 2026. Eerste indrukken van Claude Fable 5 van iemand die 30+ agents in productie draait — wat er echt anders is, de kostenval waar niemand je voor waarschuwt, en of je moet overstappen.
Ontvang het AI-playbook in je inbox
Elke woensdag. 28.400+ operators. Geen opvulling.
Controleer je inbox.
We hebben je een bevestigingsmail gestuurd — klik op de link om je aanmelding te voltooien. Controleer je spam als je hem niet binnen een minuut ziet.
Je bent aangemeld.
Welkom — de volgende editie valt binnenkort in je inbox.
Je staat al op de lijst — kijk er elke woensdag naar uit.