Agenten-Gedächtnis: Typen und Kosten im Vergleich
Semantisch, episodisch oder prozedural: Eine Tabelle zeigt Unterschiede, Speicherbedarf und Re-Embedding-Kosten für jeden Agenten-Speichertyp auf einem VPS.
Welche drei Speichertypen für Agenten es gibt
Die Speichertypen für Agenten lassen sich in drei Kategorien einteilen. Jede Kategorie wirkt sich anders auf die von Ihnen bezahlte Hardware aus: Das semantische Gedächtnis enthält Fakten, das episodische Gedächtnis dokumentiert Ereignisse und das prozedurale Gedächtnis beschreibt, wie eine Aufgabe ausgeführt wird. Die folgende Tabelle definiert die einzelnen Typen anhand eines Serverbeispiels. Im Anschluss folgt die Hälfte, die normalerweise unerwähnt bleibt: die Speicherkosten der einzelnen Typen und die Kosten für ihre Wiederherstellung.
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"
}
]Die Bezeichnungen stammen aus der menschlichen Psychologie, werden hier aber nur in einem weiten Sinn verwendet. Die Einteilung ist aus einem praktischen Grund sinnvoll: Die drei Typen unterscheiden sich in Umfang und Wiederherstellungsweg. Wenn Sie sie gemeinsam in einem Vektorspeicher ablegen, verschlechtert sich die Eignung des Speichers für jeden einzelnen Typ.
Semantischer Speicher ist klein, und Sie werden ihn von Hand bearbeiten wollen
Einige hundert Fakten über Ihre eigenen Server umfassen nur einige Dutzend Kilobyte Text. Der Speicherplatz ist hier nicht das Problem. Die Korrektur ist es. Ein falscher Fakt im semantischen Speicher ist in jeder anschließenden Antwort des Agenten falsch. Deshalb muss der Speicher es ermöglichen, einen Fakt anhand seines Namens zu finden, ihn zu ändern und sicherzustellen, dass der alte Wert entfernt wurde.
Das spricht für einen Speicher mit Schlüsseln: eine Postgres-Tabelle mit Primärschlüssel oder ein Verzeichnis mit kleinen Markdown-Dateien in git. Mit beiden Varianten können Sie eine einzelne Abfrage ausführen, den Wert anzeigen und ihn direkt bearbeiten. Eine Ähnlichkeitssuche bietet das nicht, weil sie nach Ähnlichkeit statt nach einem Schlüssel abruft. Aus „Datenbank-Port ändern“ wird dann „jeden Abschnitt finden, der den Datenbank-Port erwähnt“. Sie können nicht nachweisen, dass Sie alle gefunden haben. Speichern Sie die Fakten mit Schlüsseln. Erstellen Sie zusätzlich Embeddings, wenn Sie auch eine unscharfe Suche benötigen. Behandeln Sie jedoch die Kopie mit Schlüsseln als maßgebliche Quelle.
Veraltete Fakten machen sich nicht selbst bemerkbar. Der Port wird geändert, aber die Zeile bleibt bestehen. Daher antwortet der Agent weiterhin mit einer Zahl, die im Juni korrekt war. Eine Richtlinie zur Erkennung von Veralterung und Bereinigung des Agentenspeichers ist die andere Hälfte dieser Seite. Sie lässt sich deutlich günstiger entwerfen, solange die Tabelle noch klein ist.
Warum das episodische Gedächtnis unbegrenzt wächst
Das episodische Gedächtnis ist ein Protokoll, und Protokolle wachsen. Jede Sitzung, jeder Tool-Aufruf und jeder fehlgeschlagene Befehl kann zu einer Episode werden. Ein Agent, der pro Durchlauf eine Zeile schreibt, erzeugt in einem Monat weit mehr Zeilen, als jemals jemand lesen wird. Außerdem entstehen nicht nur Kosten für den Speicherplatz: Jede eingebettete Episode wird auch Teil des Indexes, den die Suche durchsuchen muss.
Legen Sie die Aufbewahrungsregel an dem Tag fest, an dem Sie die Tabelle erstellen, solange das Löschen noch unkompliziert ist. Zwei Fragen klären den größten Teil. Erstens: Was ist überhaupt das Schreiben wert? Eine Zusammenfassung einer Sitzung ist es normalerweise, die vollständige Ausgabe eines einzelnen ls -la in der Regel nicht. Zweitens: Wie lange bleibt jede Episodenklasse erhalten? Beispielsweise können Roh-Episoden 30 Tage und Sitzungszusammenfassungen ein Jahr aufbewahrt werden.
Geben Sie jeder Episodenzeile einen created_at-Zeitstempel und eine source-Spalte. Ohne created_at können Sie nicht nach Alter löschen. Ohne source können Sie nicht alles löschen, was von einer fehlerhaften Quelle stammt. Genau das benötigen Sie an dem Tag, an dem sich herausstellt, dass eine Webseite oder ein Ticket Anweisungen in das Gedächtnis geschrieben hat.
DELETE FROM episodes WHERE created_at < now() - interval '30 days';Führen Sie das über einen systemd-Timer aus. Überwachen Sie anschließend, ob sich die Zeilenanzahl und die Tabellengröße tatsächlich ändern. Eine Aufbewahrungsrichtlinie, die niemand ausführt, ist nur ein Kommentar.
psql -d agentmem -c "SELECT count(*) FROM episodes;"
psql -d agentmem -c "SELECT pg_size_pretty(pg_total_relation_size('episodes'));"Prozedurales Wissen gehört in ein Repository
Prozedurales Wissen beschreibt, wie der Agent eine Aufgabe ausführt: ein Shell-Skript, eine Skill-Datei oder ein Runbook mit nummerierten Schritten. Das ist Code. Code gehört dorthin, wo Code verwaltet wird: in ein Git-Repository mit Reviews, Versionen und einem lesbaren Diff.
Wenn Sie ein Runbook als eingebettete Chunks speichern, erhalten Sie nur eine ungefähre Kopie zurück. Die Abfrage liefert die Chunks mit der höchsten Bewertung. Dadurch kann der Agent Schritt 2 und Schritt 5 ausführen, während Schritt 3 nie abgerufen wird. Außerdem wird nicht festgehalten, welche Version der Prozedur ausgeführt wurde. In Git beantwortet git log beide Fragen. Die Speicherkosten sind nahezu null. Das ist ein weiterer Grund, dafür keine Vektordatenbankpreise zu bezahlen.
Was ein Embedding tatsächlich auf der Festplatte kostet
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 speichert ein vector mit 4 Bytes pro Dimension und einem 8-Byte-Header. Diese Berechnung ist daher festgelegt, und Sie können den Speicherbedarf vor dem Laden der Daten planen. Ein Vektor mit 384 Dimensionen benötigt 1544 Bytes. 100,000 Chunks benötigen damit 147.2 MiB für die Vektoren. Derselbe Korpus benötigt bei 3,072 Dimensionen 1172.6 MiB, bei 12296 Bytes pro Zeile. Der Text ist identisch, der Speicherbedarf ist fast achtmal höher.
Das betrifft nur die Vektorspalte. Der Chunk-Text, der Primärschlüssel, der Zeilen-Overhead und der Index kommen noch hinzu. Der Index wird dabei häufig vergessen. HNSW (hierarchical navigable small world, der von pgvector erstellte Graphindex) verwaltet eigene Kopien der Vektoren, auf die seine Verbindungen verweisen. Ein indizierter Speicher benötigt daher deutlich mehr als das Doppelte der oben genannten Werte. Messen Sie Ihren tatsächlichen Bedarf, statt ihn zu schätzen.
SELECT pg_size_pretty(pg_total_relation_size('memories')) AS total,
pg_size_pretty(pg_relation_size('memories_embedding_idx')) AS idx;Der Arbeitsspeicher entscheidet darüber, ob sich die Suche schnell anfühlt. Der Graph lässt sich nur schnell durchsuchen, solange er im Arbeitsspeicher liegt. Wenn der Index größer ist als der von Postgres verfügbare Arbeitsspeicher, beginnt die Suche, Daten von der Festplatte zu lesen, und die Latenz steigt. Der Build hat ein eigenes Limit, maintenance_work_mem. Wenn der Graph dieses Limit überschreitet, weist der Build darauf hin und wird langsamer:
NOTICE: hnsw graph no longer fits into maintenance_work_mem after 61440 tuples
HINT: Increase maintenance_work_mem to speed up builds.Zwei Einstellungen reduzieren den Speicherbedarf desselben Korpus. Wählen Sie ein kleineres Modell. 384 Dimensionen benötigen ein Viertel des Speichers von 1,536 Dimensionen. Für das Wiederfinden eigener Notizen ist der Genauigkeitsunterschied häufig klein genug, um ihn zu akzeptieren. Oder speichern Sie die Werte mit halber Genauigkeit. Der Typ halfvec benötigt 2 Bytes pro Dimension und denselben 8-Byte-Header. Dadurch werden die Spalte und ihr Index zusammen nahezu halb so groß.
Ein Limit sollten Sie kennen, bevor Sie ein Modell auswählen. Im August 2026 kann eine vector-Spalte bis zu 2,000 Dimensionen indiziert werden. Ein Embedding mit 3,072 Dimensionen wird daher von der Spalte akzeptiert, vom Index jedoch abgelehnt:
ERROR: column cannot have more than 2000 dimensions for hnsw indexhalfvec indiziert bis zu 4,000 Dimensionen. Die übliche Lösung besteht daher darin, den Cast zu indizieren:
CREATE INDEX ON memories USING hnsw ((embedding::halfvec(3072)) halfvec_cosine_ops);Wenn pgvector einen separaten Memory-Dienst übertrifft
Wenn auf dem Server bereits Postgres läuft, benötigen Vektoren nur ein Paket und eine Anweisung.
psql -V
sudo apt install postgresql-16-pgvectorCREATE EXTENSION vector;Die Zahl im Paketnamen entspricht der Major-Version von Postgres. Unter Ubuntu 24.04 ist das 16. Lesen Sie daher psql -V, bevor Sie den Befehl eingeben.
Wenn Sie den Memory in dieser Datenbank speichern, erhalten Sie ein gemeinsames Backup für Memory und Anwendungsdaten zum selben Zeitpunkt, einen gemeinsamen Connection Pool und Transaktionen: Eine Tatsache und die zugehörige Zeile werden gemeinsam festgeschrieben oder gemeinsam verworfen. Ein separater Dienst kann das nicht garantieren.
Wechseln Sie zu einem dedizierten Memory-Dienst, wenn eine dieser Bedingungen zutrifft. Die Suchlast konkurriert mit Ihrer Anwendung und benötigt einen eigenen Server. Mehrere Agents auf mehreren Hosts greifen auf denselben Memory zu. Oder Sie möchten die Extraktions- und Deduplizierungslogik, die ein fertiges Produkt mitbringt. Das spricht für einen selbst gehosteten Mem0-Memory-Server. Für einen Agenten und einen Korpus mit wenigen Millionen Chunks ist pgvector auf dem bereits betriebenen Server einfacher zu verwalten und weniger fehleranfällig. Die Wahl der Engine selbst und die Anforderungen der einzelnen Engines an den Arbeitsspeicher werden in eine Vektordatenbank auf einem VPS ausführen behandelt.
Welche Kosten eine erneute Einbettung beim Modellwechsel verursacht
Vektoren aus zwei verschiedenen Modellen sind nicht vergleichbar. Sie können daher neue Erinnerungen nicht mit einem neuen Modell einbetten und die alten Zeilen unverändert lassen. Eine gemischte Tabelle liefert unsinnige Ergebnisse, weil eine Distanz zwischen zwei verschiedenen Koordinatensystemen keine aussagekräftige Zahl ist. Ein Modellwechsel bedeutet, den gesamten Korpus erneut einzubetten.
Diese Kosten bestehen aus vier Teilen: den Tokens (einer API-Gebühr oder CPU- und GPU-Zeit auf Ihrem eigenen System), der Laufzeit, dem Speicherplatz für beide Spalten während des Backfills und dem abschließenden Neuaufbau des Index. Die sichere Reihenfolge ist: eine neue Spalte hinzufügen, sie stapelweise befüllen, die Abfrage umstellen und anschließend die alte Spalte samt Index entfernen.
Messen Sie die Verarbeitungsgeschwindigkeit auf Ihrer eigenen Hardware, statt einer veröffentlichten Angabe zu vertrauen. CPU-basiertes Einbetten auf einem kleinen VPS läuft deutlich langsamer als dasselbe Modell auf einer GPU. Messen Sie die Zeit für einen repräsentativen Abschnitt und multiplizieren Sie sie mit der Größe des Korpus.
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/nullEin lokales Einbettungsmodell speichert seine Gewichte ebenfalls auf demselben Datenträger wie der Memory Store. Wo Ollama abgerufene Modelle speichert erklärt, wofür dieser Speicherplatz verwendet wird.
Eine Voraussetzung macht all dies möglich: Speichern Sie den Quelltext neben jedem Vektor. Ein Store, der nur Vektoren enthält, kann nicht erneut eingebettet werden, weil keine Daten mehr vorhanden sind, die dem neuen Modell übergeben werden können. Wenn Sie die Frage „Welcher Text hat diese Zeile erzeugt?“ nicht beantworten können, besteht Ihr Migrationsweg aus einem vollständigen Neuaufbau von der ursprünglichen Quelle des Textes.
Was Sie beobachten sollten, sobald der Speicher läuft
Mit zunehmender Füllung des Speichers ändert sich nicht nur der Preis. Alte Fakten werden ungültig, und alte Episoden verdrängen nützliche Ergebnisse. Damit tritt das Problem des Bereinigens erneut auf. Ein Speichersystem ist außerdem eine beschreibbare Eingabe für das künftige Verhalten des Agenten. Alles, was in dieses System schreiben darf, kann den Agenten später beeinflussen. Wenn Text aus Webseiten oder Tickets den Speicher erreicht, lesen Sie zuerst wie Memory Poisoning bei Agenten funktioniert, bevor Sie den Kreis der Schreibberechtigten erweitern. Die Größe der abgerufenen Daten bestimmt zudem bei jeder einzelnen Anfrage den Token-Verbrauch. Dort beginnt auch die laufenden Kosten eines Agenten berechenbar zu halten.
FAQ
Benötige ich eine Vektordatenbank für das Agentengedächtnis?
Nicht für Fakten. Semantischer Speicher ist klein, und Sie müssen ihn nach Namen korrigieren können. Deshalb eignet sich dafür eine Schlüssel-Wert-Tabelle oder ein Verzeichnis mit Markdown-Dateien in git besser: Sie können einen einzelnen Wert anzeigen und bearbeiten. Embeddings lohnen sich, wenn Sie Inhalte anhand ihrer Bedeutung in einem zu großen Korpus suchen müssen, um ihn vollständig aufzulisten. Das betrifft in der Regel episodisches Gedächtnis und Dokumente. Wenn Sie bereits Postgres betreiben, deckt CREATE EXTENSION vector diesen Anwendungsfall ab, ohne dass Sie einen weiteren Dienst verwalten müssen.
Wie viel Speicherplatz benötigt ein Speicher für das Agentengedächtnis?
Die Größe der Vektoren ist vorhersehbar: In pgvector benötigen sie 4 Byte pro Dimension plus einen 8 Byte großen Header. Bei 768 Dimensionen sind das 293.7 MiB pro 100.000 Zeilen. Bei 384 Dimensionen sind es 147.2 MiB. Hinzu kommen der Chunk-Text, der Zeilen-Overhead und ein HNSW-Index, der eine eigene Kopie der Vektoren speichert. Planen Sie daher mindestens das Doppelte des Vektorspeicherbedarfs ein. Ermitteln Sie den tatsächlichen Wert mit pg_total_relation_size.
Wo sollte prozedurales Gedächtnis gespeichert werden?
In einem git-Repository, als Scripts oder Skill-Dateien, die der Agent direkt ausführt. Eine Prozedur muss exakt abgerufen werden können und eine Versionshistorie besitzen. Eine Ähnlichkeitssuche bietet beides nicht. Ein in Chunks aufgeteiltes Runbook liefert die am höchsten bewerteten Abschnitte zurück. Dadurch können Schritt 2 und Schritt 5 eintreffen, während Schritt 3 fehlt. Außerdem wird nicht festgehalten, welche Version ausgeführt wurde.
Welche Kosten entstehen beim Wechsel des Embedding-Modells?
Sie müssen den gesamten Korpus erneut in Embeddings umwandeln, weil Vektoren aus unterschiedlichen Modellen nicht miteinander verglichen werden können. Planen Sie die Tokenkosten oder GPU-Zeit, den Speicherplatz für die alten und neuen Spalten während der Umstellung sowie den Neuaufbau des Index ein. Fügen Sie die neue Spalte hinzu, füllen Sie sie in Batches, stellen Sie die Abfrage um und löschen Sie anschließend die alte Spalte. Das alles setzt voraus, dass der Quelltext neben jedem Vektor gespeichert wurde.