Ein grundlegender Leitfaden zum AgentengedĂ€chtnis: Von Python-Listen ĂŒber Markdown-Dateien bis hin zu Vektorsuche und Graph-Vektor-Hybriden â und schlieĂlich einer sauberen, Open-Source-Lösung fĂŒr all das.

Ein LLM ist von Natur aus zustandslos. Jeder API-Aufruf beginnt bei null. Das âGedĂ€chtnis", das du beim Chatten mit ChatGPT spĂŒrst, ist eine Illusion, die dadurch entsteht, dass bei jeder Anfrage der gesamte GesprĂ€chsverlauf erneut mitgesendet wird.
Dieser Trick funktioniert fĂŒr lockere Unterhaltungen. Er bricht zusammen, sobald du versuchst, einen echten Agenten zu bauen.
Hier sind 7 Fehlermodi, die sofort auftreten, wenn du das GedÀchtnis auslÀsst:
- Kontextamnesie: Der Agent fragt nach Informationen, die du bereits gegeben hast.
- Null Personalisierung: Jede Interaktion wirkt generisch.
- Fehlschlag bei mehrstufigen Aufgaben: Der Zwischenzustand geht wÀhrend der Aufgabe stillschweigend verloren.
- Wiederholte Fehler: Keine episodische Erinnerung bedeutet dieselben Fehler fĂŒr immer.
- Keine Wissensanreicherung: Jede Sitzung beginnt bei null.
- Halluzination durch LĂŒcken: Wenn der Kontext ĂŒberlĂ€uft, erfindet das Modell Dinge.
- IdentitÀtsverlust: Keine KontinuitÀt, kein Vertrauen.
Die naheliegende Reaktion ist: âWirf mehr Kontext darauf." Deshalb fĂŒhlen sich 128K- und 200K-Token-Fenster so an, als ob sie alles lösen sollten.
Tun sie nicht.
Die Genauigkeit sinkt um ĂŒber 30 %, wenn relevante Informationen in der Mitte eines langen Kontexts liegen. Das ist der gut dokumentierte âLost in the Middle"-Effekt.
Kontext ist ein gemeinsames Budget: System-Prompts, abgerufene Dokumente, GesprÀchsverlauf und Ausgabe kÀmpfen alle um dieselben Token.
Selbst bei 100K Token macht das Fehlen von Persistenz, Priorisierung und Relevanz die reine KontextlÀnge unzureichend.

Beim GedÀchtnis geht es nicht darum, mehr Text in den Prompt zu stopfen. Es geht darum, zu strukturieren, woran sich der Agent erinnert, damit er finden kann, was wichtig ist.
Der kognitionswissenschaftliche Rahmen, der wirklich hilft
Lilian Wengs Formulierung von 2023 ist zum Standard-Framework geworden:
Agent = LLM + GedÀchtnis + Planung + Werkzeugnutzung.
Die vier gleichberechtigten SĂ€ulen.
Ihre Taxonomie leiht sich aus der Kognitionswissenschaft, wo das menschliche GedÀchtnis in drei Systeme unterteilt wird:
- Sensorisches GedĂ€chtnis erfasst rohe Wahrnehmungseingaben und hĂ€lt sie fĂŒr einen Bruchteil einer Sekunde. Nur die Teile, denen du Aufmerksamkeit schenkst, werden weitergegeben.
- ArbeitsgedÀchtnis ist der Ort des aktiven Denkens. Es enthÀlt etwa 7±2 Elemente gleichzeitig (Millers Erkenntnis von 1956). Verlierst du den Fokus, verschwindet der Inhalt.
- LangzeitgedÀchtnis ist ein dauerhafter Speicher ohne praktische KapazitÀtsgrenze. Der Abruf ist der Engpass: Du kannst Millionen von Dingen speichern und trotzdem das eine nicht abrufen können, das du brauchst.
Jedes dieser Systeme lÀsst sich direkt auf eine Komponente in modernen Agentenarchitekturen abbilden:

Das LangzeitgedÀchtnis selbst unterteilt sich weiter:
- Episodisch: Spezifische vergangene Ereignisse (âAm Dienstag ist der PostgreSQL-Cluster ausgefallen")
- Semantisch: Fakten und Konzepte (âPostgreSQL ist eine relationale Datenbank")
- Prozedural: FĂ€higkeiten und ArbeitsablĂ€ufe (âWenn ein Benutzer eine RĂŒckerstattung verlangt, ĂŒberprĂŒfe zuerst das Kaufdatum")
Die BrĂŒcke zwischen episodischem und semantischem GedĂ€chtnis ist die GedĂ€chtniskonsolidierung: Wiederholte spezifische Ereignisse destillieren sich zu allgemeinem Wissen. Ein Agent, der in Dutzenden von Interaktionen bemerkt, dass âBenutzer durchgĂ€ngig Zusammenfassungen bevorzugen", sollte daraus eine wiederverwendbare Regel machen. Ohne Konsolidierung spielt dein Agent einzelne Ereignisse nach, anstatt aus ihnen zu lernen.

Der minimale Agent und was zuerst kaputt geht
Entferne die Frameworks, und ein Agent ist eine Schleife: wahrnehmen, denken, handeln.
1class Agent:2 """Minimaler KI-Agent: wahrnehmen, denken, handeln"""3 def __init__(self):4 self.client = anthropic.Anthropic()5 self.model = "claude-sonnet-4-20250514"67 def run(self, user_input: str) -> str:8 response = self.client.messages.create(9 model=self.model,10 max_tokens=1024,11 messages=[{"role": "user", "content": user_input}],12 )13 return response.content[0].text
Sag ihm âIch habe 4 Ăpfel", frage dann âIch habe einen gegessen, wie viele sind ĂŒbrig?" â und er hat keine Ahnung, von welchen Ăpfeln du sprichst. Jeder Aufruf existiert isoliert.
Schicht 1: Die Python-Liste
Die erste Lösung, zu der jeder greift:
1class Agent:2 def __init__(self):3 self.client = anthropic.Anthropic()4 self.messages = [] # Das gesamte "GedÀchtnis" ist eine Liste56 def chat(self, user_input: str) -> str:7 self.messages.append({"role": "user", "content": user_input})8 response = self.client.messages.create(9 model="claude-sonnet-4-20250514",10 max_tokens=1024,11 messages=self.messages, # VollstÀndiger Verlauf wird jedes Mal gesendet12 )13 reply = response.content[0].text14 self.messages.append({"role": "assistant", "content": reply})15 return reply
Mehrere GesprĂ€chsrunden funktionieren jetzt. Die Ăpfelfrage wird korrekt beantwortet, weil die gesamte Unterhaltung bei jedem Aufruf erneut mitgesendet wird.
Zwei Probleme tauchen schnell auf:
- Die Liste wÀchst unbegrenzt. Etwa bei Runde 200 erreichst du die Kontextobergrenze, und die Àltesten Nachrichten werden stillschweigend fallengelassen. Der Name des Benutzers aus Runde 1 verschwindet lange vor dem belanglosen Witz von gestern. Keine Priorisierung, nur strenge chronologische Reihenfolge.
- Alles lebt im RAM. Sobald der Python-Prozess endet, hat dein Agent keine Ahnung, wer du bist.
Schicht 2: Markdown-Dateien fĂŒr Persistenz
Der nĂ€chste Schritt ist, das GedĂ€chtnis auf die Festplatte zu schreiben. Markdown ist eine natĂŒrliche Wahl: menschenlesbar, Git-freundlich, und der Agent kann es als Klartext zurĂŒcklesen. Claude Code verwendet genau dieses Muster mit CLAUDE.md- und MEMORY.md-Dateien.
1class MarkdownMemoryAgent:2 def __init__(self):3 self.client = anthropic.Anthropic()4 self.history_file = Path("memory/conversation_history.md")5 self.facts_file = Path("memory/known_facts.md")67 def save_to_disk(self, role: str, content: str) -> None:8 with open(self.history_file, "a") as f:9 f.write(f"### {role} at {datetime.now().isoformat()}\n{content}\n\n")1011 def load_history(self) -> str:12 if self.history_file.exists():13 return self.history_file.read_text()14 return ""1516 def chat(self, user_input: str) -> str:17 self.save_to_disk("user", user_input)18 history = self.load_history()19 response = self.client.messages.create(20 model="claude-sonnet-4-20250514",21 max_tokens=1024,22 system=f"Vorherige Unterhaltung:\n{history}",23 messages=[{"role": "user", "content": user_input}],24 )25 reply = response.content[0].text26 self.save_to_disk("assistant", reply)27 return reply
Persistenz ist gelöst. Starte das Skript neu, und die Unterhaltung ist immer noch auf der Festplatte. Du könntest auch eine separate Fakten-Datei fĂŒhren, die der Agent im Laufe der Zeit extrahiert:
1- Der Name des Benutzers ist Sarah2- Sarah leitet das Backend-Team bei Acme Corp3- Acme Corp ist ein B2B-SaaS-Unternehmen4- Derzeit wird die Produktionsdatenbank in eine neue AWS-Region migriert
Du kannst die Datei in jedem Editor öffnen, genau sehen, was der Agent weiĂ, und es von Hand korrigieren. Wirklich nĂŒtzlich fĂŒr das Prototyping.
Mit 4 Fakten funktioniert das perfekt. Lade die gesamte Datei in den Kontext, und das LLM beantwortet jede Frage zu Sarah, ihrem Unternehmen oder ihrer Branche.
Jetzt spule drei Monate vor. Dein Agent hat 2.000 extrahierte Fakten und 200 GesprÀchsprotokolle. Das sind 500K+ Token an Markdown auf der Festplatte, und dein Kontextfenster hat 128K.
Du kannst nicht mehr alles laden. Du musst selektiv nur die Fakten abrufen, die fĂŒr die aktuelle Anfrage relevant sind. Bei flachen Dateien ist deine einzige Option die Stichwortsuche:
1# Benutzer fragt: "Wie ist der Stand unserer Cloud-Migration?"2grep("Cloud-Migration", facts_file)3# Gibt zurĂŒck: []4# Der Fakt auf der Festplatte sagt "migriert die Produktionsdatenbank in eine neue AWS-Region."5# Die Wörter "Cloud-Migration" kommen nirgendwo vor.67# Benutzer fragt: "Welches Team kĂŒmmert sich um die Datenbankarbeit?"8grep("Datenbank-Team", facts_file)9# Gibt zurĂŒck: []10# Ein Fakt sagt, Sarah "leitet das Backend-Team." Ein anderer sagt, das Team11# "migriert die Produktionsdatenbank." Aber keine einzelne Zeile enthĂ€lt12# sowohl "Datenbank" als auch "Team" zusammen.
Im kleinen MaĂstab funktionieren Markdown-Dateien. Im echten MaĂstab erzwingen sie die Stichwortsuche, und Stichwörter können nicht mit Synonymen, Paraphrasen oder Verbindungen zwischen Fakten umgehen.
Die Informationen sind auf der Festplatte. Aber du kannst nicht alles laden, und die Stichwortsuche ist zu spröde, um die richtigen Teile zu finden.
Wenn du OpenClaw verwendet hast, hast du das schon gesehen. Es speichert das GedĂ€chtnis als Markdown-Checkpoint-Dateien, und ĂŒber Wochen der tĂ€glichen Nutzung verschwinden frĂŒhere Fakten leise, wĂ€hrend sich der Kontext ansammelt und komprimiert wird. Der Speicher ist da. Der Abruf nicht.
Speicher ohne intelligenten Abruf ist eine Bibliothek ohne Katalog.
Schicht 3: Vektorsuche und die Wand, an die sie stöĂt
Baue Embeddings ein. Zerlege dein Markdown in Chunks, bette die Chunks ein, suche per Kosinus-Ăhnlichkeit. Jetzt passt âDatenbank" zu âPostgreSQL", weil ihre Vektoren im Embedding-Raum nahe beieinander liegen. Das Synonym-Problem löst sich auf.
Dann stöĂt du auf eine neue Wand. Betrachte diese drei Fakten in deiner Vektor-DB:
1- "Alice ist die Tech-Lead fĂŒr Projekt Atlas"2- "Projekt Atlas verwendet PostgreSQL als primĂ€ren Datenspeicher"3- "Der PostgreSQL-Cluster hatte am Dienstag einen Ausfall"
Benutzer fragt: âWar Alices Projekt von dem Ausfall am Dienstag betroffen?"
Die Abfrage erwĂ€hnt Alice und den Ausfall am Dienstag, also bewertet die Vektorsuche den ersten und dritten Fakt hoch. Aber die entscheidende BrĂŒcke, âProjekt Atlas verwendet PostgreSQL", erwĂ€hnt weder Alice noch Dienstag. Es ist das verbindende StĂŒck, und es ist dasjenige, das nicht auftauchen wird.
Jeder Fakt ist ein isolierter Punkt im Embedding-Raum. Das Bindegewebe, das sie verbindet, ist fĂŒr Vektoren unsichtbar.

Das ist kein Randfall. Es ist die normale Form von Fragen aus der realen Welt. GeschĂ€ftswissen ist von Natur aus relational: Personen gehören zu Teams, Teams besitzen Projekte, Projekte hĂ€ngen von Systemen ab, Systeme haben VorfĂ€lle. Jede Frage, die zwei oder mehr Schritte ĂŒberschreitet, ĂŒbersteigt, was eine flache Vektorsuche beantworten kann.
Die FĂ€higkeitsmatrix
Jede Schicht behebt den vorherigen Schmerz, offenbart aber einen tieferen:

Du brauchst Persistenz, semantisches VerstÀndnis und relationales Denken in einer einzigen GedÀchtnisschicht.
Das selbst zu bauen bedeutet, eine Vektordatenbank, eine Graphdatenbank, einen relationalen Speicher, einen EntitÀtsextraktor, eine Deduplizierungspipeline und ein Kantengewichtungssystem zusammenzukleben. Das sind Wochen an Infrastrukturarbeit, bevor du eine einzige Zeile Agentenlogik schreibst.
Ich verwende eine Lösung, die diese LĂŒcke sauber fĂŒllt. Sie ist vollstĂ€ndig Open-Source, handhabt alle drei Speicherparadigmen unter einem Dach, und du kannst sie in Minuten zum Laufen bringen. Lass uns ĂŒber Cognee sprechen.
Cognee: Drei Speicher, eine Engine, vier Aufrufe
Cognee ist eine Open-Source-Wissens-Engine, die fĂŒr das AgentengedĂ€chtnis entwickelt wurde. Sie kombiniert Vektorsuche mit Wissensgraphen und einer relationalen Provenienzschicht in einem einzigen System.
Die gesamte API-OberflÀche besteht aus vier asynchronen Aufrufen:
1import cognee23await cognee.add("Dein Dokument hier") # Alles aufnehmen4await cognee.cognify() # Wissensgraph + Embeddings erstellen5await cognee.memify() # GedÀchtnis selbst verbessern6await cognee.search("Deine Abfrage") # Mit logischem Denken abrufen
Hinter diesen vier Aufrufen verbirgt sich eine Drei-Speicher-Architektur.

Warum drei Speicher und nicht einer?
Jeder Speicher erfasst eine Dimension des Wissens, die die anderen nicht können:
- Relationaler Speicher â Provenienz: woher die Daten kamen, wann sie aufgenommen wurden, wer Zugriff hat
- Vektorspeicher â Semantik: was der Inhalt bedeutet, wem er Ă€hnlich ist
- Graphspeicher â Beziehungen: wie EntitĂ€ten verbunden sind, was was verursacht, wer wem unterstellt ist
Wenn du einen davon weglĂ€sst, verlierst du Informationen, die fĂŒr die Abrufgenauigkeit wichtig sind.
Der Standard-Stack ist SQLite + LanceDB + Kuzu, vollstÀndig eingebettet und dateibasiert. pip install cognee plus ein LLM-API-Key, und du bist startklar.
Kein Docker, keine externen Dienste.
FĂŒr die Produktion tauschst du SQLite gegen Postgres, LanceDB gegen Qdrant/Pinecone/pgvector und Kuzu gegen Neo4j/FalkorDB/Neptune.
Gleiche Vier-Aufruf-API in beiden FĂ€llen.
Was cognify eigentlich tut?
cognee.cognify() fĂŒhrt eine mehrstufige Pipeline aus, die Rohtext in strukturiertes, vernetztes Wissen umwandelt:
- Dokumentenklassifizierung nach Typ und DomÀne
- BerechtigungsprĂŒfung fĂŒr Multi-Tenant-Zugriffskontrolle
- Chunk-Extraktion, die die Absatzstruktur respektiert (keine festen GröĂen)
- EntitÀts- und Beziehungsextraktion per LLM, mit automatischer Deduplizierung durch Inhalts-Hashing
- Zusammenfassungsgenerierung fĂŒr effizienten Abruf
- Duale Indizierung in den Vektorspeicher (Embeddings) und den Graphspeicher (Kanten)
Der Deduplizierungsschritt ist wichtiger, als es klingt. Wenn dieselbe EntitĂ€t in 50 Dokumenten auftaucht, fĂŒhrt Cognee sie zu einem einzigen Graphknoten mit 50 eingehenden Kanten zusammen. Dein Agent sieht âAlice" nicht mehr als 50 verschiedene Fremde. Und die Pipeline ist standardmĂ€Ăig inkrementell: Nur neue oder aktualisierte Dateien werden erneut verarbeitet.

Jeder Graphknoten hat ein entsprechendes Embedding. Diese duale Darstellung ist der Kern-Trick: Tritt ĂŒber Vektoren ein (finde semantisch Ă€hnlichen Inhalt) und verlasse den Graphen ĂŒber Beziehungen zu verbundenen EntitĂ€ten â oder umgekehrt. Das ist es, was Multi-Hop-Abfragen ermöglicht, ohne die semantische Suche zu opfern.
Memify: GedÀchtnis, das lernt
memify() ist das, was Cognee von jedem âAufnehmen und Suchen"-Tool unterscheidet. Es fĂŒhrt einen von RL inspirierten Optimierungsdurchlauf ĂŒber den Graphen durch:
- StĂ€rkung nĂŒtzlicher Pfade, die zu guten Abrufergebnissen gefĂŒhrt haben
- Beschneidung veralteter Knoten, die nicht mehr berĂŒhrt wurden
- Automatische Anpassung von Kantengewichten basierend auf tatsÀchlicher Nutzung
- HinzufĂŒgen abgeleiteter Fakten durch Identifizierung impliziter Beziehungen
Der Graph eines Kundensupport-Agenten stĂ€rkt auf natĂŒrliche Weise Pfade durch Produktdokumentationen und RĂŒckerstattungsrichtlinien, wĂ€hrend selten abgefragte HR-Kanten verfallen. Der Graph entwickelt mit der Zeit sein eigenes RelevanzgefĂŒhl.

Vierzehn Abrufmodi
Cognee bietet 14 Suchmodi. Die, die du tatsÀchlich verwenden wirst:

Einen echten Agenten mit Cognee-GedÀchtnis bauen
Hier ist das vollstÀndige Muster, um Cognee in die Wahrnehmen-Denken-Handeln-Schleife einzubinden:
1import cognee2from cognee import SearchType34class CogneeMemoryAgent:5 """Agent mit hybridem Graph-Vektor-persistentem GedÀchtnis."""67 def __init__(self, session_id: str = "default"):8 self.llm_client = OpenAI()9 self.session_id = session_id1011 async def ingest(self, text: str, dataset: str = "main"):12 await cognee.add(text, dataset)13 await cognee.cognify([dataset])1415 async def recall(self, query: str) -> str:16 results = await cognee.search(17 query_text=query,18 query_type=SearchType.GRAPH_COMPLETION,19 session_id=self.session_id,20 )21 return results[0] if results else ""2223 async def chat(self, user_input: str) -> str:24 context = await self.recall(user_input)25 messages = [26 {"role": "system", "content": "Du bist hilfreich. Verwende GedÀchtniskontext."},27 {"role": "system", "content": f"GedÀchtniskontext:\n{context}"},28 {"role": "user", "content": user_input},29 ]30 response = self.llm_client.chat.completions.create(31 model="gpt-4o-mini", messages=messages32 )33 reply = response.choices[0].message.content34 await cognee.add(35 f"Benutzer: {user_input}\nAssistent: {reply}",36 "conversations"37 )38 await cognee.cognify(["conversations"])39 return reply
Der GedĂ€chtniszyklus: aufnehmen, extrahieren, speichern, abrufen, antworten, erneut speichern. Jede Runde bereichert den Wissensgraphen, und die inkrementelle Verarbeitung bedeutet, dass du nur fĂŒr die Indizierung neuer Inhalte zahlst.
Das SitzungsgedÀchtnis behandelt die Pronomenauflösung automatisch:
1await cognee.search(query_text="Wo wohnt Alice?", session_id="conv_1")2await cognee.search(query_text="Was macht sie beruflich?", session_id="conv_1")3# "sie" wird aus dem Sitzungskontext zu Alice aufgelöst
Multi-Tenancy ist auf Graph-Ebene mit Berechtigungen pro Datensatz (Lesen, Schreiben, Löschen, Teilen) integriert. Keine Namespace-Trennung, sondern echte Graph-Ebene-Isolation.
Der praktische Weg nach vorne
Wenn du heute einen Agenten baust, ist die eigentliche Ausgangsfrage: âWas muss mein Agent sich merken, und welche Art von Fragen wird er beantworten?"
Wenn deine Abfragen nur eine Ăhnlichkeitssuche benötigen (âFinde Unterhaltungen wie diese"), reicht ein reines VektorgedĂ€chtnis. Sobald Abfragen EntitĂ€tsgrenzen ĂŒberschreiten (âWar Alices Projekt von dem Ausfall am Dienstag betroffen?"), brauchst du Graph-Traversierung.
Du kannst separate Vektor-, Graph- und relationale Speicher selbst miteinander verbinden. Teams, die diesen Weg gehen, verbrennen typischerweise Wochen mit Infrastruktur fĂŒr eine GedĂ€chtnisschicht, die immer noch nicht aus ihrer eigenen Nutzung lernt.
Cognee reduziert das auf vier API-Aufrufe. Eingebettete Standardeinstellungen bringen dich in Minuten zum Laufen. Austauschbare Backends (Postgres, Qdrant, Neo4j) bringen dich in die Produktion, ohne deinen Agentencode zu Àndern.
Intelligenz erfordert Struktur, nicht nur Speicher. Die drei Speicherparadigmen (relational, Vektor, Graph) sind keine konkurrierenden Optionen. Sie sind komplementÀre Schichten desselben GedÀchtnissystems. Sie so zu behandeln, ist das, was einen zustandslosen LLM-Wrapper in etwas verwandelt, das tatsÀchlich lernt.
Was ist das NĂ€chste, woran sich dein Agent morgen erinnern soll, das er heute vergessen hat? Fang dort an.
đ Sieh dir Cognee auf GitHub an â, gib ihm einen Stern und versuche, es in deinen nĂ€chsten Agenten einzubinden.
Vier asynchrone Aufrufe, ein pip install, und du bist startklar.
Das war's!
Wenn dir das Lesen gefallen hat:
Finde mich â@akshay_pachaar âïž
Jeden Tag teile ich Tutorials und Einblicke zu KI, maschinellem Lernen und Best Practices fĂŒr Vibe Coding.





