Gib Hermes Agent mit LanceDB ein semantisches Gedächtnis: Installieren, Konfigurieren, Benchmarken

Eine der frustrierendsten Erfahrungen mit einem KI-Agenten ist, dass er Dinge vergisst. Du sagst ihm am Montag: „Ich nutze pnpm workspaces und deploye via wrangler.“ Bis Freitag, in einer frischen Sitzung, hat er keine Ahnung, wovon du redest. Hermes Agent hat zwar ein eingebautes Gedächtnis (MEMORY.md / USER.md unter ~/.hermes/memories/) und sessionsübergreifenden Recall — aber im Kern ist es lexikalisches Matching. Sag „deploy“ als „ship it“ oder „pnpm“ als „der Paketmanager“, und das Gedächtnis findet die Information schlicht nicht.
Im August 2026 hat LanceDB ein offizielles semantisches Memory-Plugin für Hermes Agent veröffentlicht — hermes-agent-memory — das daraus ein reines Engineering-Problem macht: Fakten werden als Vektoren in einer lokalen LanceDB-Tabelle gespeichert, und der Recall matcht auf semantische Ähnlichkeit statt auf Schlüsselwörter. Im LongMemEval-Benchmark des Plugins erreicht der reine Vector-Recall 0.661 Accuracy / 0.795 Recall@5 — deutlich vor der eingebauten FTS5-Sitzungssuche von Hermes mit 0.533 / 0.659.
Dieser Beitrag führt dich durch die komplette Installation, erklärt, wie die vier Memory-Tools funktionieren, wie du zwischen den Hybrid-Retrieval-Modi wählst, und liest die Benchmark-Zahlen sorgfältig.
1. Verstehe zuerst die Memory-Architektur von Hermes
Bevor du etwas installierst, nimm dir zwei Minuten, um zu verstehen, wie die Memory-Schicht von Hermes aufgebaut ist — sonst installierst du am Ende alles und wunderst dich, warum nichts funktioniert.
Das Gedächtnis von Hermes ist eine Provider-Architektur. agent/memory_provider.py definiert ein abstraktes MemoryProvider-Interface, und agent/memory_manager.py orchestriert es (Prefetch, Sync, Shutdown). Zwei Hooks sind am wichtigsten:
on_pre_compress(messages)— extrahiert, was es wert ist, behalten zu werden, bevor die Kontextkompression läuft;on_session_end(messages)— ein letzter Extraktionsdurchlauf am Ende einer Sitzung.
Der interaktive Befehl hermes memory setup scannt die installierten Provider unter plugins/memory/, lässt dich einen auswählen und schreibt memory.provider: <name> in ~/.hermes/config.yaml (Zeile 277 von hermes_cli/memory_setup.py ist exakt dieser Schreibvorgang). Anders gesagt: das Memory-Backend ist ein steckbares Registry-System. Von Haus aus bringt Hermes acht Provider mit: mem0, hindsight, honcho, supermemory, byterover, retaindb, holographic und openviking.
Das LanceDB-Plugin nutzt denselben Kanal: Es registriert sich selbst als Memory-Provider, wird über hermes plugins install nach ~/.hermes/plugins/lancedb/ installiert und anschließend in hermes memory setup ausgewählt.
Du willst es ausprobieren, ohne dein bestehendes Setup anzufassen?
hermes profile create lancedb-demoerstellt ein isoliertes Profil; füge-p lancedb-demozu jedem Befehl unten hinzu, undrm -rf ~/.hermes/profiles/lancedb-demo, wenn du fertig bist.
2. Installation: vier Schritte, etwa fünf Minuten
Schritt 1: Plugin installieren
hermes plugins install lancedb/hermes-agent-memory
Das klont https://github.com/lancedb/hermes-agent-memory.git flach (Shallow Clone) nach ~/.hermes/plugins/lancedb/. Führe denselben Befehl später erneut aus, um Updates zu ziehen.
Schritt 2: Laufzeit-Abhängigkeiten in Hermes’ eigenes Python installieren
Hermes lädt Plugins in seiner eigenen Interpreter-Umgebung, daher müssen die Abhängigkeiten in das venv von Hermes — nicht in eine separate virtualenv:
# If you used the one-line installer:
uv pip install --python ~/.hermes/hermes-agent/venv/bin/python3 lancedb openai pyyaml
Hinweis: Der Interpreter von Hermes wird von allen Profilen geteilt, daher hat dieser Schritt kein
-p-Flag und muss nur einmal ausgeführt werden. Die Standardkonfiguration braucht keinen lokalen ML-Stack — Embeddings laufen über die OpenAI-API. Nur wenn du den Cross-Encoder-Reranker aktivierst, brauchst dusentence-transformers(das ~2GB torch mitbringt).
Schritt 3: Provider aktivieren
hermes memory setup
# pick "lancedb" in the interactive menu
Erwarte eine Ausgabe wie diese, und memory.provider: lancedb wird in ~/.hermes/config.yaml geschrieben:
# ✓ LanceDB memory configured (embedding dim: 1536)
# Start a new session to activate.
Embeddings verwenden standardmäßig OpenAI text-embedding-3-small (1536-dimensional), daher muss ein OPENAI_API_KEY verfügbar sein.
Schritt 4: Verifizieren (diesen Schritt nicht überspringen)
Der häufigste Grund für „Memory funktioniert nicht“-Meldungen ist schlicht, dass der Provider nicht aktiv ist — wenn memory.provider nicht gesetzt ist, fällt Hermes still auf seine eingebauten Notizen zurück, und du siehst die lancedb_*-Tools nie. Prüfe, dass er aktiv ist:
hermes memory status # look for: Provider: lancedb, installed ✓, available ✓
hermes plugins list # should list "lancedb"
hermes chat -q "Hello" # agent.log should contain "lancedb provider initialized"
Wenn memory status nichts zeigt (oder den falschen Provider), führe hermes memory setup erneut aus und wähle wieder lancedb.
3. Die vier Memory-Tools
Sobald das Plugin aktiv ist, erhält der Agent vier neue Tools:
| Tool | Zweck |
|---|---|
lancedb_recall |
Vector-Recall (Standard) oder Hybrid-Recall über das Workspace-Gedächtnis; liefert IDs, Snippets, Scores, Provenienz-Turn-IDs |
lancedb_remember |
Speichert einen dauerhaften Fakt, typisiert als preference / entity / event / case / pattern / general; dedupliziert über Content-Hash |
lancedb_read |
Holt eine Memory per ID, optional mit den Provenienz-Turns, aus denen sie extrahiert wurde |
lancedb_forget |
Zweistufiges Löschen: action: preview listet Kandidaten nach Beschreibung auf, dann action: delete mit der exakten ID |
Der System-Prompt-Block des Providers sagt dem Modell, wann es welches Tool verwenden soll: lancedb_remember nur, wenn der Nutzer explizit darum bittet, sich etwas zu merken, und vor jedem Löschen immer preview — damit der Agent nicht aus Versehen eine wichtige Memory löscht.
Über explizite Aufrufe hinaus gibt es eine automatische Extraktions-Pipeline: Sobald eine Sitzung genügend Turns angesammelt hat (Standard min_turns: 3), werden dauerhafte Fakten von einer Hilfs-LLM aus dem Gespräch gezogen — sowohl vor der Kontextkompression als auch am Sitzungsende. Selbst wenn du nie „merke dir das“ sagst, werden langfristig nützliche Informationen trotzdem persistiert — das ist der Mechanismus hinter „der Agent wird schlauer, je mehr du ihn benutzt“.
4. Retrieval-Modi: Vector vs. Hybrid
Recall ist das Herzstück des semantischen Gedächtnisses, und das Plugin gibt dir zwei Ebenen der Kontrolle:
1. Suchmodus (pro Aufruf): vector (Standard) oder hybrid (Vector + BM25-Volltext), pro Aufruf überschreibbar über den Parameter mode von lancedb_recall.
2. Hybrid-Fusion (globale Konfiguration): Im hybrid-Modus legt plugins.lancedb.retrieval.reranker.type fest, wie die Vector- und die Volltext-Komponente zusammengeführt werden:
rrf(Standard) — Reciprocal Rank Fusion, rangbasierte gleichgewichtete Fusion;linear— gewichtete lineare Kombination;reranker.weight(Standard 0.7) gewichtet zugunsten der Vector-Komponente;cross-encoder— rerankt einen überabgetasteten Pool mit einem lokalen sentence-transformers-Modell; höchste Qualität, am langsamsten.
Beispiel-Konfiguration (~/.hermes/config.yaml — schreibe nur die Schlüssel, die du überschreiben willst):
plugins:
lancedb:
retrieval:
mode: hybrid # vector (default) | hybrid
top_k: 10
reranker:
type: linear # rrf | linear | cross-encoder
weight: 0.7
Es gibt auch einen rein lexikalischen
fts-Modus, aber die Autoren raten ausdrücklich davon ab: reines Schlüsselwort-Matching spült zufällige, irrelevante Zeilen an die Oberfläche, die den Kontext des Agents verschmutzen. Semantischer Recall lebt invector/hybrid.
5. Embedding-Backends: nicht nur OpenAI
Im Standard-Setup ist der einzige Remote-Aufruf die Embedding-API — alles andere ist lokal. Richte den OpenAI-kompatiblen Client auf einen beliebigen Endpunkt aus, der dieselbe Form spricht, und du bist fertig, ohne Codeänderungen. Ein paar praktische Beispiele:
# Non-OpenAI model via OpenRouter
plugins:
lancedb:
embedding:
model: google/gemini-embedding-001
base_url: https://openrouter.ai/api/v1
api_key_env: OPENROUTER_API_KEY
# Fully local: Ollama
plugins:
lancedb:
embedding:
model: nomic-embed-text
base_url: http://localhost:11434/v1
api_key_env: OLLAMA_API_KEY # any value works for local Ollama
Beim Wechsel des Embedding-Modells ist Vorsicht geboten: Wenn die Dimension des neuen Modells nicht zur bestehenden Tabelle passt, schlägt das Plugin laut fehl, statt still nichts zurückzuliefern. Die Lösung: Lösche ~/.hermes/lancedb/memories.lance/ und lass die nächste Sitzung die Tabelle neu anlegen (in Ordnung, wenn dir die alten Memories nichts ausmachen).
Die Hilfs-LLM für die Faktenextraktion kann ebenfalls auf ein günstigeres Modell zeigen, über Hermes’ eigenes Auxiliary-Routing (Provider-Routing, Fallback und Kontingent-Erschöpfung werden für dich übernommen):
auxiliary:
lancedb_extraction:
provider: openrouter
model: google/gemini-3-flash
6. Den Benchmark lesen: Ist semantischer Recall wirklich besser?
Das Plugin-Repo bringt eine LongMemEval-S-Harness für lange Konversations-QA mit (60 stratifizierte Fälle, beantwortet von gpt-5.4, bewertet von gpt-5.4-mini, top-k 5). Sie vergleicht die Recall-Optionen, die ein Hermes-Nutzer tatsächlich hat:
| Variante | Accuracy | Recall@5 | MRR@5 | Query p50 |
|---|---|---|---|---|
| hermes-session-search (eingebaute FTS5/BM25-Baseline) | 0.533 | 0.659 | 0.639 | 0.002s |
| lancedb-vector (Standard) | 0.661 | 0.795 | 0.682 | 0.207s |
| lancedb-hybrid-rrf | 0.610 | 0.650 | 0.635 | 0.235s |
| lancedb-hybrid-linear | 0.610 | 0.718 | 0.676 | 0.246s |
| lancedb-hybrid-cross-encoder | 0.678 | 0.754 | 0.689 | 0.702s |
Wichtige Erkenntnisse:
- Semantischer Recall schlägt die lexikalische Baseline klar: 0.661 vs. 0.533 Accuracy, 0.795 vs. 0.659 Recall@5 — Paraphrasen (deploy vs. ship) sind genau der Fall, in dem BM25 blind ist, und Vector-Retrieval ist weitaus robuster, bei ~0.2s pro Query.
- Gleichgewichtetes RRF schadet tatsächlich (0.610 < 0.661): verrauschte lexikalische Treffer verdrängen gute Vector-Ergebnisse. Deshalb ist der ausgelieferte Standard
vectorund nichthybrid. - Wenn du lexikalisches Signal willst, nimm linear, nicht RRF: Die gewichtete Fusion hebt Recall@5 auf 0.718, bei winzigen Latenzkosten.
- Cross-Encoder bringt die höchste Qualität (0.678 / 0.754), aber p50 klettert auf ~0.7s und er braucht torch — für latenz-tolerante, genauigkeitskritische Setups.
Die Autoren bezeichnen die Zahlen als illustrativ: Die absolute Accuracy hängt vom Antwortmodell ab (hier gpt-5.4), aber die relative Reihenfolge der Retrieval-Methoden ist stabil. Die Harness misst außerdem nur das Retrieval-Substrat (wörtlicher Recall der ursprünglichen Turns), nicht den kompletten Faktenextraktions-Lebenszyklus — in der Praxis könnte Fakt-zuerst-Retrieval sogar noch besser abschneiden.
7. Speicherlayout und Auto-Kompaktierung
Alles ist lokal, kein externer Dienst:
| Pfad | Inhalt |
|---|---|
~/.hermes/lancedb/memories.lance/ |
LanceDB-Dataset (Fragmente, Manifest, Indizes). Eine einzelne memories-Tabelle; die Spalte kind trennt Fakt- von Turn-Zeilen |
~/.hermes/lancedb/.last_optimize_version |
Sentinel-Datei: table.version beim letzten erfolgreichen optimize() |
~/.cache/huggingface/ |
Cache des Cross-Encoder-Rerankers; nur vorhanden, wenn reranker.type: cross-encoder aktiviert ist |
Du willst direkt im Speicher stöbern, SQL-artig:
uv run --project ~/.hermes/hermes-agent python -c "
import lancedb
db = lancedb.connect('~/.hermes/lancedb')
df = db.open_table('memories').to_pandas()
print(df[['kind', 'category', 'content']].head())
"
Agent-Workloads werden von Einzelzeilen-Schreibvorgängen dominiert, und jeder Lance-Add/Delete ist ein Commit — ohne Eingriff sammeln sich winzige Fragmente und Versionsdateien endlos an. Die Auto-Kompaktierung des Plugins (standardmäßig aktiv) vergleicht die Version mit der Sentinel-Datei und führt table.optimize(cleanup_older_than=timedelta(days=7)) in einem Daemon-Thread aus, sobald die Differenz optimize_every_commits (Standard 50) überschreitet. Ein nicht blockierendes Lock garantiert, dass jeweils nur ein optimize läuft, und Schreiber werden nie blockiert. Deaktiviere sie (maintenance.enabled: false) und das Dataset wächst unbegrenzt — generell nicht zu empfehlen.
8. Troubleshooting-Kurzreferenz
hermes plugins listzeigtlancedbnicht: Prüfe, ob der Symlink~/.hermes/plugins/lancedbauf das Repo auflöst.- Der Agent schreibt nur ins eingebaute Gedächtnis, keine
lancedb_*-Tools: Der Provider ist nicht aktiv. Führehermes memory statusaus — du willstProvider: lancedbmitavailable ✓; ist das Feld leer, führehermes memory setuperneut aus. - Recall schlägt mit einem Auth-Fehler fehl: Die Embeddings rufen die OpenAI-API auf — stelle sicher, dass
OPENAI_API_KEYgesetzt ist (Umgebung oder~/.hermes/.env). - Das
.lance-Verzeichnis wächst ständig: Prüfe, dassmaintenance.enabled: trueist und~/.hermes/lancedb/.last_optimize_versionüber Sitzungen hinweg fortschreitet;lancedb optimize startinginagent.logbedeutet, dass die Kompaktierung läuft. embedding.modelgeändert und Recall liefert nichts: Dimensions-Mismatch. Lösche~/.hermes/lancedb/memories.lance/, um die Tabelle neu anzulegen.
Fazit
Das LanceDB-Plugin schließt die wichtigste Lücke im Langzeitgedächtnis von Hermes Agent: Recall nach Bedeutung, nicht nach Schlüsselwort. Fünf Minuten Installation, null Tuning bei den Standardwerten, alle Daten lokal — im Austausch für ~24% bessere Accuracy (0.661 vs. 0.533) und einen großen Recall@5-Sprung bei LongMemEval. Für Wissensarbeiter bedeutet das: „Dinge, die du einmal gesagt hast, kommen zurück, selbst wenn du anders fragst.“
Weiterführende Lektüre:
- Du willst Memories in einer menschenlesbaren Wissensbasis? Siehe Hermes-Konversationen in Obsidian-Notizen verwandeln.
- Auch Memory-Stores wachsen — Sitzungen und Speicherplatz verwalten: Hermes-Speicheroptimierungs-Guide.
- Weitere Alltagstipps, um das Beste aus deinem Agent herauszuholen: Hermes-Agent-Produktivitätstipps.
- Hermes noch nicht installiert? Starte mit der Installationsanleitung.