# Memory — Langzeitgedächtnis für Agenten > **Bauplan zu einem gebauten System.** Umgesetzt; der Stand steht in der > [Roadmap](Roadmap.md) 3.2. Die drei Punkte unter „Offen" laufen dort weiter. Löst K1 aus der [Bestandsaufnahme](archiv/Bestandsaufnahme-2026-07.md): Geplante Agenten begannen bei jedem Cron-Lauf bei null. Ein Agent, der alle 30 Minuten lief, wusste nichts von seinem letzten Durchgang — er rief dieselben Quellen ab, zog dieselben Schlüsse und konnte keine Entwicklung über Zeit verfolgen. ## Warum nicht der vorhandene State-Store `IStateStore` ist eine Schlüssel-Wert-Tabelle für kleine Marker („zuletzt gesehene ID"). Ein Gedächtnis darin abzulegen hieße, JSON in eine `Value`-Spalte zu schreiben — damit lässt sich nichts filtern, sortieren oder auswerten. Deshalb typisierte Spalten in einer eigenen Tabelle. Das Schema ist bewusst schlicht gehalten, damit eine MySQL-Variante später dieselbe Struktur mit wenigen Dialektunterschieden bekommen kann. ## Modell | Feld | Zweck | |---|---| | `Scope` | `agent` (privat) oder `shared` (alle Agenten der Instanz) | | `Subject` | Worum es geht — Ticker, Kunde, Projekt | | `Key` | **Optional.** Erneutes Merken darunter *aktualisiert* statt anzulegen | | `Category` | `fact`, `decision`, `observation`, `task`, `contact`, `other` | | `Tags` | Schlagworte zum Wiederfinden | | `Importance` | 1–5, steuert die Reihenfolge beim Abruf | | `CreatedBy` | Bleibt auch im geteilten Bereich sichtbar | Die Scope-Trennung ist absichtlich dieselbe wie beim `FileRW`-Tool (`personal`/`shared`) — für Agenten bleibt das Konzept dadurch wiedererkennbar. ## Der Schlüssel ist das Wichtigste Ohne ihn wüchse das Gedächtnis eines alle 30 Minuten laufenden Agenten um 48 Einträge pro Tag zur selben Sache. Mit `key='kursziel_nvda'` bleibt es **ein** Eintrag, der sich fortschreibt — das Anlagedatum bleibt erhalten, nur `UpdatedAt` wandert. Beobachtungen ohne Schlüssel sammeln sich weiterhin an; das ist gewollt, wenn ein Verlauf entstehen soll. ## Abruf Sortiert nach Wichtigkeit, dann Aktualität. Das ist wesentlich, weil das Ergebnis begrenzt wird: Bei einer Kappung muss das Wichtigste überleben. Zusätzlich greift eine Zeichenobergrenze (8.000 Zeichen) — ein Abruf darf den Kontext nicht sprengen, dieselbe Überlegung wie bei der Tool-Ergebnis-Kappung (T2). ## Speicher-Fundament `SqliteStorage` bündelt den Zugang zur Instanz-Datenbank: - **WAL** — beliebig viele Leser parallel zu einem Schreiber - **busy_timeout** — ein Schreiber wartet kurz, statt sofort zu scheitern - **Connection-Pooling** — kein Verbindungsaufbau je Aufruf - **Schreib-Warteschlange im Prozess** — macht Fehlerbilder reproduzierbar Vorher öffnete jeder Aufruf eine Verbindung ohne diese Einstellungen. Bei mehreren gleichzeitig schreibenden Agenten gab das `database is locked` — das sah nach einer Grenze von SQLite aus, war aber nur fehlende Konfiguration. Zwei Tests decken das gezielt ab (60 gleichzeitige Schreibvorgänge, gemischtes Lesen und Schreiben). ## Offen - **Automatische Einblendung**: Ein Agent muss `recall` derzeit selbst aufrufen. Für geplante Läufe wäre eine kurze Übersicht der wichtigsten Erinnerungen im Auftrag hilfreich. Sie gehört in die Nutzernachricht, nicht in den System-Prompt — sonst verfällt bei jedem Lauf der Prompt-Cache (T1). - **Verfall**: Alte, unwichtige Beobachtungen könnten nach einer Frist entfallen. - **MySQL**: Zweite Implementierung von `IMemoryRepository`, wenn mehrere Rechner dazukommen.