Typen agentgeheugen en de bijbehorende kosten
Ontdek de verschillen tussen semantisch, episodisch en procedureel geheugen voor AI-agents. Wij berekenen de werkelijke opslagkosten en de kosten voor re-embedding op een VPS.
Wat de drie typen agentgeheugen zijn
Geheugentypen voor agents zijn onder te verdelen in drie categorieën, die elk op een andere manier beslag leggen op de hardware waarvoor u betaalt: semantisch geheugen bevat feiten, episodisch geheugen bevat gebeurtenissen en procedureel geheugen bevat instructies voor het uitvoeren van taken. De onderstaande tabel definieert elk type aan de hand van een servervoorbeeld. Alles wat daarna volgt, is het deel dat doorgaans onbeschreven blijft: wat de opslag van elk type kost en wat het kost om dit opnieuw op te bouwen.
The data behind this chart
[
{
"label": "Semantic",
"what_it_holds": "Facts the agent should treat as currently true",
"server_example": "The database listens on 10.8.0.4:5432 and the nightly dump runs at 03:15 UTC"
},
{
"label": "Episodic",
"what_it_holds": "A record of one past event or session",
"server_example": "On 2026-08-11 the deploy failed because the disk was full, and rotating logs fixed it"
},
{
"label": "Procedural",
"what_it_holds": "How to carry out a task, as steps the agent can run",
"server_example": "The restore runbook: stop the service, load the dump, run migrations, start the service"
}
]De namen zijn ontleend aan de menselijke psychologie, waarbij de vergelijking losjes moet worden geïnterpreteerd. De onderverdeling is om een praktische reden waardevol: de drie typen verschillen in omvang en herstelmethode. Het onderbrengen van alle typen in één vector store maakt elk van deze onderdelen minder efficiënt.
Semantisch geheugen is beperkt en u zult dit handmatig willen bewerken
Een paar honderd feiten over uw eigen servers beslaan enkele tientallen kilobytes aan tekst. Opslag is hier niet het probleem. Correctie wel. Een onjuist feit in het semantisch geheugen is onjuist in elk antwoord dat de agent daarna geeft. Daarom moet het opslagsysteem u in staat stellen om één feit op naam te vinden, dit te wijzigen en er zeker van te zijn dat de oude waarde is verwijderd.
Dit wijst op een opslag met sleutels: een Postgres-tabel met een primaire sleutel, of een map met kleine markdown-bestanden in git. Beide laten u één query uitvoeren, de waarde inzien en deze direct bewerken. Zoekopdrachten op basis van gelijkenis bieden dit niet, omdat u ophaalt op basis van overeenkomst in plaats van op basis van een sleutel. "Wijzig de databasepoort" wordt dan "zoek elk fragment dat de databasepoort noemt", en u kunt niet bewijzen dat u ze allemaal heeft gevonden. Houd de feiten voorzien van een sleutel. Sla ze ook op als embeddings als u ook losse herinnering wilt, maar beschouw de versie met sleutel als de bron van waarheid.
Verouderde feiten kondigen zichzelf niet aan. De poort wijzigt en de rij blijft staan, waardoor de agent antwoorden blijft geven met een nummer dat in juni correct was. Een beleid voor veroudering en opschoning van agentgeheugen is de andere helft van deze pagina, en het is veel goedkoper om dit te ontwerpen terwijl de tabel nog klein is.
Waarom episodisch geheugen onbeperkt groeit
Episodisch geheugen is een logboek, en logboeken groeien. Elke sessie, elke tool-aanroep en elk mislukt commando is een kandidaat-episode. Een agent die per beurt één rij schrijft, zal in een maand tijd veel meer rijen schrijven dan iemand ooit kan lezen, en schijfruimte is niet de enige kostenpost: elke ingesloten episode wordt ook onderdeel van de index die doorzoekbaar moet zijn.
Bepaal de retentieregel op de dag dat u de tabel aanmaakt, terwijl verwijderen nog gratis is. Twee vragen beantwoorden het grootste deel hiervan. Ten eerste: wat is het waard om überhaupt te schrijven? Een samenvatting van een sessie meestal wel, de volledige output van een ls -la meestal niet. Ten tweede: hoe lang leeft elke klasse van episodes? Denk aan ruwe episodes voor 30 dagen en sessiesamenvattingen voor een jaar.
Geef elke episoderij een created_at timestamp en een source kolom. Zonder created_at kunt u niet op basis van leeftijd verwijderen. Zonder source kunt u niet alles verwijderen wat afkomstig is van één slechte bron, wat precies is wat u nodig heeft op de dag dat blijkt dat een webpagina of een ticket instructies in het geheugen heeft geschreven.
DELETE FROM episodes WHERE created_at < now() - interval '30 days';Voer dit uit via een systemd timer en observeer daarna hoe het aantal rijen en de tabelgrootte daadwerkelijk veranderen. Een retentiebeleid dat niemand uitvoert, is slechts een opmerking.
psql -d agentmem -c "SELECT count(*) FROM episodes;"
psql -d agentmem -c "SELECT pg_size_pretty(pg_total_relation_size('episodes'));"Procedureel geheugen hoort in een repository
Procedureel geheugen is de manier waarop de agent een taak uitvoert: een shell script, een skill-bestand of een runbook met genummerde stappen. Dit is code, en code hoort thuis waar code hoort te staan: in een git repository met code-reviews, versiebeheer en leesbare diffs.
Slaat u een runbook op als ingesloten brokken (chunks), dan krijgt u slechts een benadering terug. Bij het ophalen worden de brokken geretourneerd die het hoogst scoorden. Hierdoor kan de agent stap 2 en stap 5 uitvoeren terwijl stap 3 nooit naar voren kwam, en wordt nergens vastgelegd welke versie van de procedure is uitgevoerd. In git beantwoordt git log beide vragen. De opslagkosten zijn nagenoeg nul, wat de tweede reden is om hier geen vector-opslagprijzen voor te betalen.
Wat een embedding daadwerkelijk kost op schijf
The data behind this chart
[
{
"label": "bge-small-en-v1.5 (384 dims)",
"bytes_per_vector": 1544,
"mib_per_100k_rows": 147.2
},
{
"label": "bge-base-en-v1.5 (768 dims)",
"bytes_per_vector": 3080,
"mib_per_100k_rows": 293.7
},
{
"label": "bge-large-en-v1.5 (1024 dims)",
"bytes_per_vector": 4104,
"mib_per_100k_rows": 391.4
},
{
"label": "text-embedding-3-small (1536 dims)",
"bytes_per_vector": 6152,
"mib_per_100k_rows": 586.7
},
{
"label": "text-embedding-3-large (3072 dims)",
"bytes_per_vector": 12296,
"mib_per_100k_rows": 1172.6
}
]pgvector slaat een vector op als 4 bytes per dimensie plus een header van 8 bytes. Deze berekening staat vast, waardoor u de opslag kunt plannen voordat u gegevens laadt. Eén vector met 384 dimensies is 1544 bytes, wat 100.000 chunks 147.2 MiB aan vectoren maakt. Hetzelfde corpus, geëmbed met 3.072 dimensies, is 1172.6 MiB, bij 12296 bytes per rij. Dezelfde tekst, bijna acht keer zoveel opslag.
Dat is enkel de vector-kolom. De chunk-tekst, de primaire sleutel, de overhead per rij en de index komen daar nog bovenop, en de index is het onderdeel dat vaak wordt vergeten. HNSW (hierarchical navigable small world, de graaf-index die pgvector opbouwt) houdt een eigen kopie bij van de vectoren waarnaar wordt verwezen. Een geïndexeerde opslag is daardoor ruimschoots meer dan het dubbele van de bovenstaande cijfers. Meet uw eigen verbruik in plaats van te gokken.
SELECT pg_size_pretty(pg_total_relation_size('memories')) AS total,
pg_size_pretty(pg_relation_size('memories_embedding_idx')) AS idx;RAM bepaalt of een zoekopdracht snel aanvoelt, omdat de graaf alleen snel te doorlopen is wanneer deze in het geheugen staat. Wanneer de index groter is dan het geheugen dat Postgres kan reserveren, beginnen zoekopdrachten vanaf de schijf te lezen en neemt de latentie toe. Het opbouwen van de index heeft een eigen limiet, maintenance_work_mem; wanneer de graaf hieruit groeit, meldt het build-proces dit en vertraagt de uitvoering:
NOTICE: hnsw graph no longer fits into maintenance_work_mem after 61440 tuples
HINT: Increase maintenance_work_mem to speed up builds.Er zijn twee manieren om hetzelfde corpus te verkleinen. Kies een kleiner model, aangezien 384 dimensies een kwart kosten van 1.536 dimensies, en voor het terugvinden van uw eigen notities is het verschil in nauwkeurigheid vaak verwaarloosbaar. Of sla gegevens op in halve precisie: het halfvec-type neemt 2 bytes per dimensie in beslag plus dezelfde header van 8 bytes, wat de kolom en de bijbehorende index samen bijna halveert.
Eén limiet is belangrijk om te kennen voordat u een model kiest. Sinds augustus 2026 kan een vector-kolom worden geïndexeerd tot maximaal 2.000 dimensies. Een embedding van 3.072 dimensies wordt wel geaccepteerd door de kolom, maar geweigerd door de index:
ERROR: column cannot have more than 2000 dimensions for hnsw indexhalfvec indexeert tot 4.000 dimensies, dus de gebruikelijke oplossing is om de cast te indexeren:
CREATE INDEX ON memories USING hnsw ((embedding::halfvec(3072)) halfvec_cosine_ops);Wanneer pgvector beter is dan een aparte geheugenservice
Als de server al Postgres draait, zijn vectoren slechts één pakket en één statement verwijderd.
psql -V
sudo apt install postgresql-16-pgvectorCREATE EXTENSION vector;Het nummer in de pakketnaam is uw Postgres major-versie, 16 op Ubuntu 24.04, dus lees psql -V voordat u dit typt.
Het geheugen in die database houden levert u één back-up op die zowel het geheugen als de applicatiedata op hetzelfde moment dekt, één connection pool en transacties: een feit en de rij die het beschrijft worden samen doorgevoerd of falen samen. Een aparte service kan dat niet garanderen.
Stap over naar een toegewezen geheugenservice wanneer een van de volgende punten waar is. De zoekbelasting concurreert met uw applicatie en vereist een eigen machine. Meerdere agents op verschillende hosts delen één geheugen. Of u wilt de extractie- en ontdubbelingslogica die een kant-en-klaar product biedt, wat het argument is voor een zelf-gehoste Mem0 memory server. Voor één agent en een corpus van enkele miljoenen chunks is pgvector op de server die u al draait eenvoudiger te beheren en minder foutgevoelig. De keuze voor de engine zelf, en wat elke engine aan RAM vereist, wordt behandeld in het draaien van een vectordatabase op een VPS.
Wat zijn de kosten van re-embedding bij het wijzigen van het model
Vectoren van twee verschillende modellen zijn niet vergelijkbaar. U kunt daarom niet nieuwe herinneringen met een nieuw model embedden en de oude rijen ongewijzigd laten. Een gemengde tabel levert onzinnige resultaten op, omdat een afstand die is berekend tussen twee verschillende coördinatensystemen een getal zonder betekenis is. Het wijzigen van een model betekent dat de gehele corpus opnieuw moet worden ge-embed.
Die rekening bestaat uit vier onderdelen: de tokens (een API-tarief, of CPU- en GPU-tijd op uw eigen machine), de doorlooptijd terwijl het proces draait, de schijfruimte voor beide kolommen tegelijk tijdens de backfill, en de index-rebuild aan het einde. De veilige volgorde is: voeg een nieuwe kolom toe, voer de backfill in batches uit, wissel de query om en verwijder vervolgens de oude kolom en de bijbehorende index.
Meet de snelheid op uw eigen hardware in plaats van te vertrouwen op gepubliceerde cijfers, omdat embedding op alleen een CPU op een kleine VPS veel langzamer verloopt dan hetzelfde model op een GPU. Meet de tijd van één representatief blok en vermenigvuldig dit met de grootte van de corpus.
ollama pull nomic-embed-text
time curl -s http://localhost:11434/api/embed \
-d '{"model": "nomic-embed-text", "input": "one representative chunk of your corpus"}' > /dev/nullEen lokaal embedding-model plaatst zijn gewichten ook op dezelfde schijf als de memory store, en waar Ollama gedownloade modellen opslaat legt uit waar die ruimte naartoe gaat.
Eén vereiste maakt dit alles mogelijk: bewaar de brontekst naast elke vector. Een store die alleen vectoren bevat, kan helemaal niet opnieuw worden ge-embed, omdat er niets meer over is om aan het nieuwe model te voeren. Als u de vraag "welke tekst heeft deze rij geproduceerd" niet kunt beantwoorden, is uw migratiepad een volledige herbouw vanaf de bron waar de tekst oorspronkelijk vandaan kwam.
Waar u op moet letten zodra het geheugen volloopt
Kosten zijn niet het enige dat verandert naarmate de opslag voller raakt. Oude feiten raken verouderd en oude episodes verdringen nuttige resultaten; dit is opnieuw het snoeiprobleem. Een geheugenopslag is bovendien een beschrijfbare invoer voor het toekomstige gedrag van de agent, dus alles wat naar het geheugen mag schrijven, kan de agent later sturen. Als tekst van webpagina's of tickets het geheugen bereikt, lees dan hoe agent memory poisoning werkt voordat u verruimt wat er mag schrijven. De omvang van de opgevraagde gegevens bepaalt bovendien het tokenverbruik bij elk verzoek, en dat is waar het voorspelbaar houden van de lopende kosten van een agent begint.
FAQ
Heb ik een vectordatabase nodig voor agentgeheugen?
Niet voor feiten. Semantisch geheugen is klein en u moet dit op naam kunnen corrigeren. Een tabel met sleutels of een map met markdown-bestanden in git werkt daarom beter, omdat u één waarde kunt inzien en bewerken. Embeddings zijn hun kosten waard wanneer u op basis van betekenis moet zoeken in een corpus dat te groot is om op te sommen; dit betreft meestal episodisch geheugen en documenten. Als u al Postgres gebruikt, dekt CREATE EXTENSION vector dit zonder dat u een extra service hoeft te beheren.
Hoeveel schijfruimte verbruikt een opslag voor agentgeheugen?
De vectoren zijn voorspelbaar, met 4 bytes per dimensie plus een header van 8 bytes in pgvector. Bij 768 dimensies is dat 293.7 MiB per 100.000 rijen, en bij 384 dimensies is dat 147.2 MiB. Tel daar de tekst van de chunks, de overhead per rij en een HNSW-index bij op die een eigen kopie van de vectoren bijhoudt. Reken daarom op minimaal het dubbele van het vectorcijfer en meet de werkelijke waarde met pg_total_relation_size.
Waar moet procedureel geheugen worden opgeslagen?
In een git-repository, als scripts of skill-bestanden die de agent direct uitvoert. Een procedure vereist exacte weergave en een versiegeschiedenis; een zoekopdracht op basis van gelijkenis biedt geen van beide. Een opgedeeld runbook levert de best scorende fragmenten op, wat kan betekenen dat stap 2 en stap 5 verschijnen terwijl stap 3 ontbreekt, en er wordt nergens vastgelegd welke versie is uitgevoerd.
Wat kost het wijzigen van het embedding-model?
Een volledige herberekening van de embeddings voor het hele corpus, omdat vectoren van verschillende modellen niet met elkaar vergeleken kunnen worden. Houd rekening met de kosten voor tokens of GPU-tijd, de schijfruimte voor zowel de oude als de nieuwe kolommen tijdens het proces, en het opnieuw opbouwen van de index. Voeg de nieuwe kolom toe, vul deze in batches, wissel de query om en verwijder vervolgens de oude kolom. Dit alles is alleen mogelijk als u de brontekst naast elke vector hebt bewaard.