Das Problem: Die Token-Bombe (Teil 2)
Wir haben Ryan in Phase 3 ja schon das Vektorgedächtnis verpasst. Läuft auch. Aber jetzt kam das nächste Problem: Die Token-Bombe.
Konkret: Ryan wusste zwar theoretisch alles über mich – wo ich wohne, was meine Projekte sind und woran wir zuletzt gesessen haben. Aber bei jeder verdammten Anfrage lud er die komplette History. 50.000+ Tokens. Pro Frage. Nicht weil er so schlau ist, sondern weil er nicht anders konnte.
Ich frag ihn “Was essen wir heute?” und er lädt 3 Monate Smalltalk über Serverkonfiguration. Das nervt, das kostet und das muss anders.
Die Lösung: n8n + Gemini + Postgres-Voodoo
Ich hab mir in n8n einen Workflow gebaut, der jetzt jede Nacht zwei Automatisierungen durchzieht. Einmal diesen “Fakten-Atomizer” (der alles zerlegt und einsortiert) und dann die eigentliche USER.md Erstellung.
03:00 Uhr – Fakten-Sammeln: Er zieht sich die aktuellsten 150 Fakten aus der Postgres-Memory.
05:00 Uhr – Komprimieren: Ein Gemini 2.5 Flash Modell bekommt diesen Datenberg und dampft ihn auf maximal 50 Zeilen ein. Kein Gelaber, nur harte Fakten: Wer bin ich? Was sind die Projekte? Wie ist mein Tech-Stack?
Zurück in die DB: Das fertige Profil wird als “Master-Zusammenfassung” zurück in die DB geschoben.
Damit das in der Postgres-Datenbank sauber landet, nutze ich diesen Query. Da die ID eine UUID sein muss, jage ich den Namen einfach durch md5():
INSERT INTO memory (id, content, category, role, source, is_static, confidence)
VALUES (
md5('user-profile-summary')::uuid,
$$ {{ $json.userMd }} $$,
'personal',
'system',
'manual',
true,
1.0
)
ON CONFLICT (id) DO UPDATE SET
content = EXCLUDED.content,
created_at = NOW();
Wo es richtig geknallt hat (Fails & Learnings)
Ganz ehrlich: Der Weg dahin war heute Nacht alles andere als sauber. Hier sind die größten Fails:
1. Der n8n-Lockdown
Ich wollte eigentlich, dass n8n die Datei direkt per executeCommand auf den Server schreibt. Pustekuchen. Der Node wurde eiskalt als “Unrecognized” blockiert. n8n im Docker ist (zu Recht) verriegelt. Statt den Server unsicherer zu machen, nutze ich jetzt die Datenbank als Brücke.
2. UUID-Hölle
Ich hab ewig versucht, den String “user-profile-summary” als ID zu speichern. Postgres hat mich mit “invalid input syntax for type uuid” ausgelacht. Wenn die DB UUIDs will, gib ihr UUIDs. md5(...)::uuid ist der Cheat-Code dafür.
3. Der “Nodes failed” Loop
Ryan sollte beim Starten das Script per Shell-Pipe ausführen. Das gab nur Timeouts und kryptische Fehlermeldungen wie “Nodes: 1dc7f157 failed”. Lange Shell-Befehle beim Session-Start sind Gift. Einzelne Dateien mit read_file laden ist der stabilere Weg.
Ergebnis / Lösung
Sobald ich eine Session starte oder /new tippe, feuert Ryan jetzt dieses Script. Es holt sich die Zusammenfassung und schreibt sie direkt in die USER.md.
#!/bin/bash
# load-profile.sh – Holt die Profil-Zusammenfassung via UUID
ID_UUID="7a66699a-3f9d-7105-0218-4712499696c1"
psql -h 127.0.0.1 -p 5432 -U ryan -d ryan_memory_db -t -A -c \
"SELECT content FROM memory WHERE id = '$ID_UUID';" > /sven/.openclaw/workspace/USER.md
echo "Ryan-Identität wurde aus der DB synchronisiert!"
Was ich gelernt habe
1. Docker-Einschränkungen akzeptieren
Wer versucht, aus einem Docker-Container (n8n) direkt auf das Host-System zu schreiben, baut sich Sicherheitslücken oder rennt gegen Wände. Die Datenbank als asynchroner Puffer ist zwar ein Umweg, aber der einzig saubere Weg.
2. UUIDs sind keine Strings
Wenn eine Tabelle auf UUIDs optimiert ist, kannst du sie nicht mit Text füttern. Der MD5-Hash-Trick spart hier extrem viel Ärger bei der ID-Verwaltung.
3. Start-Prozeduren schlank halten
KI-Agenten wie Ryan sind bei der Initialisierung extrem empfindlich. Ein Timeout beim Session-Start zerlegt das komplette System-Prompting. read_file ist im Vergleich zu Shell-Pipes wie ein Präzisionswerkzeug gegen einen Vorschlaghammer.
4. UTF-8 ist Pflicht
Wenn man nachts um 1 Uhr mit Datenbanken chattet, sollte man export LANG=C.UTF-8 im Script nicht vergessen, sonst enden Umlaute im Datensalat.
Fazit
Stand jetzt: 66 Fakten verarbeitet, 36 Zeilen Profil. Ryan hat jetzt ein “Self-Learning-System”. Er reflektiert nachts über das, was wir tagsüber besprochen haben, und passt sein Bild von mir an.
Kein “Guten Tag, wie kann ich helfen?”, sondern “Moin Sven, Phase 3 ist durch, machen wir bei den SQL-Indizes weiter?” – So muss das.
P.S.: Wer sein Homelab nicht mit ein bisschen Schmerz beim Debuggen verbindet, hat die Kontrolle über sein Leben verloren. Aber jetzt läuft’s. ☕🚀