Die Memory-Bloat-Krise: Als Agenten-Dateien auf 95 KB anschwollen
Zwei Wochen nach dem Start war die Memory-Datei meines typescript-implementers 95 KB groß und 2.133 Zeilen lang. Das System, das Agenten schlauer machen sollte, machte sie langsamer.
Das Problem fiel mir zwei Wochen nach dem Start mit 18 Agenten durch Zufall auf. Ich war aus einem anderen Grund im Verzeichnis des typescript-implementers und sah die MEMORY.md-Datei. Die war… groß. Ich öffnete sie. 2.133 Zeilen. 95 Kilobytes.
Ich sah bei den anderen Agenten nach. Nicht ganz so schlimm — aber das Muster war eindeutig. Dateien von einigen Dutzend Kilobytes aufwärts. Sogar der slack-handler, der eigentlich nur Nachrichten formatiert, hatte ordentlich zugelegt.
Das System, das ich gebaut hatte, um die Agenten schlauer zu machen, verlangsamte sie still und leise. Ich hatte es einfach nicht gemerkt.
Wie es dazu kam
Die Architektur hatte damals Sinn ergeben. Jeder Agent hatte seine eigene MEMORY.md. Im laufenden Betrieb notierten die Agenten, was sie lernten: ein Maven-Flag, das ein wiederkehrendes Build-Problem löste, ein Muster in der Codebase, das neue Implementierer immer wieder erwischte, ein Jenkins-Verhalten, das aus der Doku nicht ersichtlich war.
Im Prinzip gut. Das Problem war die Append-only-Disziplin ohne entsprechende Aufräum-Disziplin — dieselbe Disziplin, die das dreistufige Memory-System funktionieren lässt, wenn man sie richtig anwendet. Jede Session, jeder Agent fügte Einträge hinzu. Nichts wurde je entfernt. Nichts wurde je zusammengefasst. Die Dateien wuchsen grenzenlos.
Das hatte spürbare Auswirkungen. Eine 95-KB-MEMORY.md vor jeder Aufgabe zu laden bedeutet, dass der Agent ungefähr 23.000 Tokens allein dafür verbraucht, seine eigene Geschichte zu lesen — bevor er überhaupt angefangen hat. Ein erheblicher Teil des verfügbaren Kontexts ist weg, noch bevor die eigentliche Arbeit beginnt.
Schlimmer noch: Ein Großteil dieser 95 KB war redundant. Dieselben Erkenntnisse tauchten mehrfach auf, anders formuliert. Behobene Probleme, die längst keine Rolle mehr spielten. Veraltete Muster aus einem Codebase-Zustand von vor zwei Wochen. Das Signal-Rausch-Verhältnis hatte sich massiv verschlechtert.
Die Diagnose
Ich analysierte die MEMORY.md des typescript-implementers. Das Ergebnis:
- Rund 40 % der Einträge waren Duplikate oder Beinahe-Duplikate vorhandener Einträge
- Etwa 25 % bezogen sich auf Probleme, die inzwischen behoben worden waren — das Muster, vor dem sie warnten, existierte in der Codebase nicht mehr
- Etwa 15 % waren operative Notizen zu längst abgeschlossenen Aufgaben — im Grunde Closed-Issue-Doku, die niemand brauchte
- Die restlichen 20 % waren wirklich nützlich: wiederkehrende Muster, hartnäckige Fallstricke, nicht offensichtliche Konventionen
80 % der Datei waren Rauschen. Die Agenten lasen 80 KB Rauschen, um zu 15 KB Signal zu gelangen.
Der Schwenk
Der naheliegende Fix wäre gewesen, jede MEMORY.md zu bereinigen — Duplikate löschen, behobene Probleme archivieren, die übrigen Einträge komprimieren. Ich fing damit an und hörte auf halbem Weg auf.
Das Problem war nicht, dass die Dateien gewachsen waren. Das Problem war die architektonische Grundannahme: dass Agenten ihre eigenen Wissensspeicher besitzen und pflegen sollten. Diese Annahme führt zwangsläufig zu grenzenlosem Wachstum. Einmal bereinigen, und in zwei weiteren Wochen stehst du wieder bei 95 KB.
Die richtige Lösung war, die Architektur grundlegend zu ändern — keine agenten-eigenen Memory-Dateien mehr, stattdessen gemeinsame, themenbasierte Logs, gepflegt von einem dedizierten Optimizer-Agenten. Die 6 Themen allein zeigen, wie anders Wissen sich organisiert, wenn man aufhört, in Agentensilos zu denken: build-systems, git-operations, infrastructure, planning, code-quality, meta.
Die Migration war mühsam: jede MEMORY.md durchgehen, das echte Signal herausfiltern, nach Thema statt nach Agent reorganisieren. Was dabei ans Licht kam, ließ das neue Modell als einzige logische Wahl erscheinen — der kotlin-implementer und der code-reviewer hatten unabhängig voneinander dasselbe Muster bei der Nullable-Typ-Behandlung entdeckt. Der typescript-implementer und der npm-tester hatten beide dieselbe Vite-Konfigurationsbesonderheit dokumentiert. Das Silo-Modell hatte Wissen zwischen Agenten dupliziert, die nie miteinander sprachen.
Ergebnis: ~160 KB redundante und veraltete Einträge eliminiert. Die gemeinsamen Logs starteten mit rund 12 KB destilliertem, wirklich nützlichem Wissen.
Die Erkenntnis
KI-Agentensysteme brauchen dieselbe Hygiene wie jede Codebase.
Memory wächst. Ohne aktive Pflege gewinnt die Entropie. Das erste Mal, wenn du einen Agenten baust, der Dinge aufschreibt, fühlt sich das gut an — er lernt, er wird besser. Beim zweiten Blick hat die Datei 2.133 Zeilen, und du verbrennst Context-Tokens für Notizen über einen Bug, den du vor drei Wochen gefixt hast.
Die Bloat-Krise war unangenehm zu entdecken und mühsam zu beheben. Im Nachhinein war sie aber auch vorhersehbar — und das Beheben hat eine bessere Architektur hervorgebracht als die, mit der ich angefangen hatte. Manchmal ist der Fehler das Feature.
Die architektonischen Überlegungen hinter dem neuen System — warum die Trennung von Beobachtung und Kuration das richtige Modell ist und welche Engineering-Muster das widerspiegelt — gibt es in Agenten zeichnen auf, der Optimizer denkt.