Donnez une mémoire sémantique à Hermes Agent avec LanceDB : installation, configuration, benchmark

L’une des expériences les plus frustrantes avec un agent IA, c’est qu’il oublie. Vous lui dites lundi : « J’utilise les workspaces pnpm et je déploie avec wrangler. » Vendredi, dans une nouvelle session, il n’a aucune idée de ce dont vous parlez. Hermes Agent dispose bien d’une mémoire intégrée (MEMORY.md / USER.md sous ~/.hermes/memories/) et d’un rappel inter-sessions — mais au fond, il s’agit de correspondance lexicale. Dites « deploy » en disant « ship it », ou « pnpm » en parlant du « gestionnaire de paquets », et la mémoire n’est tout simplement pas retrouvée.
En août 2026, LanceDB a publié un plugin mémoire sémantique officiel pour Hermes Agent — hermes-agent-memory — qui transforme ce problème en simple problème d’ingénierie : les faits sont stockés sous forme de vecteurs dans une table LanceDB locale, et le rappel se fait par similarité sémantique plutôt que par mots-clés. Dans le benchmark LongMemEval du plugin, le rappel purement vectoriel obtient une précision de 0.661 / Recall@5 de 0.795, nettement devant la recherche de session FTS5 intégrée d’Hermes à 0.533 / 0.659.
Cet article vous guide pas à pas dans l’installation complète, explique comment fonctionnent les quatre outils mémoire, comment choisir entre les modes de recherche hybride, et lit attentivement les chiffres du benchmark.
1. Comprendre d’abord l’architecture mémoire d’Hermes
Avant d’installer quoi que ce soit, passez deux minutes à comprendre comment la couche mémoire d’Hermes est conçue — sinon vous risquez d’installer tout et de vous demander pourquoi rien ne fonctionne.
La mémoire d’Hermes repose sur une architecture de providers. agent/memory_provider.py définit une interface abstraite MemoryProvider, et agent/memory_manager.py l’orchestre (prefetch, sync, arrêt). Deux hooks comptent le plus :
on_pre_compress(messages)— extrait ce qui vaut la peine d’être conservé avant que la compression du contexte s’exécute ;on_session_end(messages)— un dernier passage d’extraction à la fin d’une session.
La commande interactive hermes memory setup analyse les providers installés sous plugins/memory/, vous laisse en choisir un, et écrit memory.provider: <name> dans ~/.hermes/config.yaml (la ligne 277 de hermes_cli/memory_setup.py fait exactement cette écriture). En d’autres termes : le backend mémoire est un registre enfichable. D’usine, Hermes embarque huit providers : mem0, hindsight, honcho, supermemory, byterover, retaindb, holographic et openviking.
Le plugin LanceDB emprunte le même canal : il s’enregistre comme provider mémoire, s’installe dans ~/.hermes/plugins/lancedb/ via hermes plugins install, puis se sélectionne dans hermes memory setup.
Envie d’essayer sans toucher à votre configuration existante ?
hermes profile create lancedb-democrée un profil isolé ; ajoutez-p lancedb-demoà chaque commande ci-dessous, puisrm -rf ~/.hermes/profiles/lancedb-demoune fois terminé.
2. Installation : quatre étapes, environ cinq minutes
Étape 1 : installer le plugin
hermes plugins install lancedb/hermes-agent-memory
Cette commande clone en shallow https://github.com/lancedb/hermes-agent-memory.git dans ~/.hermes/plugins/lancedb/. Relancez la même commande plus tard pour récupérer les mises à jour.
Étape 2 : installer les dépendances d’exécution dans le Python d’Hermes
Hermes charge les plugins dans son propre interpréteur ; les dépendances doivent donc aller dans le venv d’Hermes — pas dans un virtualenv séparé :
# If you used the one-line installer:
uv pip install --python ~/.hermes/hermes-agent/venv/bin/python3 lancedb openai pyyaml
Note : l’interpréteur d’Hermes est partagé entre tous les profils, donc cette étape n’a pas de drapeau
-pet ne doit être exécutée qu’une seule fois. La configuration par défaut n’a besoin d’aucune pile ML locale — les embeddings passent par l’API OpenAI. Seule l’activation du reranker cross-encoder nécessitesentence-transformers(qui entraîne ~2 Go de torch).
Étape 3 : activer le provider
hermes memory setup
# pick "lancedb" in the interactive menu
Attendez-vous à une sortie de ce type, avec memory.provider: lancedb écrit dans ~/.hermes/config.yaml :
# ✓ LanceDB memory configured (embedding dim: 1536)
# Start a new session to activate.
Les embeddings utilisent par défaut OpenAI text-embedding-3-small (1536 dimensions) ; une OPENAI_API_KEY doit donc être disponible.
Étape 4 : vérifier (ne sautez pas cette étape)
Le signalement « la mémoire ne fonctionne pas » le plus courant est tout simplement un provider inactif — si memory.provider n’est pas défini, Hermes retombe silencieusement sur ses notes intégrées et vous ne verrez jamais les outils lancedb_*. Vérifiez qu’il est bien actif :
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"
Si memory status ne montre rien (ou le mauvais provider), relancez hermes memory setup et choisissez à nouveau lancedb.
3. Les quatre outils mémoire
Une fois actif, l’agent gagne quatre nouveaux outils :
| Tool | Purpose |
|---|---|
lancedb_recall |
Rappel vectoriel (par défaut) ou hybride sur la mémoire de l’espace de travail ; renvoie les IDs, extraits, scores et IDs de tour de provenance |
lancedb_remember |
Stocke un fait durable, typé preference / entity / event / case / pattern / general ; dédupliqué par hash du contenu |
lancedb_read |
Récupère une mémoire par ID, éventuellement avec les tours de provenance dont elle a été extraite |
lancedb_forget |
Suppression en deux étapes : action: preview liste les candidats par description, puis action: delete avec l’ID exact |
Le bloc de system prompt du provider indique au modèle quand utiliser chaque outil : lancedb_remember uniquement lorsque l’utilisateur demande explicitement de se souvenir, et toujours preview avant toute suppression — pour que l’agent ne puisse pas effacer une mémoire importante par accident.
Au-delà des appels explicites, il existe un pipeline d’extraction automatique : dès qu’une session accumule assez de tours (par défaut min_turns: 3), un LLM auxiliaire extrait de la conversation les faits durables, à la fois avant la compression du contexte et en fin de session. Même si vous ne dites jamais « retiens ça », les informations utiles à long terme sont quand même persistées — c’est le mécanisme « plus vous utilisez l’agent, plus il devient intelligent ».
4. Modes de récupération : vector vs hybrid
Le rappel est le cœur de la mémoire sémantique, et le plugin vous offre deux niveaux de contrôle :
1. Mode de recherche (par appel) : vector (par défaut) ou hybrid (vector + plein texte BM25), à outrepasser à chaque appel via le paramètre mode de lancedb_recall.
2. Fusion hybride (configuration globale) : en mode hybrid, la façon dont les branches vectorielle et plein texte fusionnent est définie par plugins.lancedb.retrieval.reranker.type :
rrf(par défaut) — Reciprocal Rank Fusion, fusion à poids égaux basée sur les rangs ;linear— combinaison linéaire pondérée ;reranker.weight(par défaut 0.7) favorise la branche vectorielle ;cross-encoder— réordonne un pool suréchantillonné avec un modèle sentence-transformers local ; la meilleure qualité, le plus lent.
Exemple de configuration (~/.hermes/config.yaml — n’écrivez que les clés que vous voulez redéfinir) :
plugins:
lancedb:
retrieval:
mode: hybrid # vector (default) | hybrid
top_k: 10
reranker:
type: linear # rrf | linear | cross-encoder
weight: 0.7
Un mode
ftspurement lexical existe aussi, mais les auteurs le déconseillent explicitement : une correspondance par mots-clés uniquement tend à remonter des lignes fortuites et hors sujet qui polluent le contexte de l’agent. Le rappel sémantique vit dansvector/hybrid.
5. Backends d’embedding : pas seulement OpenAI
Dans la configuration par défaut, le seul appel distant est l’API d’embedding — tout le reste est local. Pointez le client compatible OpenAI vers n’importe quel endpoint qui parle le même langage, et c’est réglé, sans modification de code. Quelques exemples pratiques :
# 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
Changer de modèle d’embedding demande de la prudence : si la dimension du nouveau modèle ne correspond pas à la table existante, le plugin échoue bruyamment au lieu de renvoyer silencieusement rien. La solution consiste à supprimer ~/.hermes/lancedb/memories.lance/ et à laisser la prochaine session recréer la table (acceptable si les anciennes mémoires ne vous importent pas).
Le LLM auxiliaire utilisé pour l’extraction des faits peut aussi viser un modèle moins cher, via le routage auxiliaire propre à Hermes (routage des providers, fallback et épuisement du crédit gérés pour vous) :
auxiliary:
lancedb_extraction:
provider: openrouter
model: google/gemini-3-flash
6. Lire le benchmark : le rappel sémantique est-il vraiment meilleur ?
Le dépôt du plugin embarque un banc d’essai QA de longues conversations LongMemEval-S (60 cas stratifiés, répondus par gpt-5.4, évalués par gpt-5.4-mini, top-k 5). Il compare les options de rappel dont dispose réellement un utilisateur d’Hermes :
| Variant | Accuracy | Recall@5 | MRR@5 | Query p50 |
|---|---|---|---|---|
| hermes-session-search (built-in FTS5/BM25 baseline) | 0.533 | 0.659 | 0.639 | 0.002s |
| lancedb-vector (default) | 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 |
À retenir :
- Le rappel sémantique bat nettement la baseline lexicale : précision 0.661 contre 0.533, Recall@5 0.795 contre 0.659 — la paraphrase (deploy vs ship) est exactement là où BM25 devient aveugle, et la récupération vectorielle est bien plus robuste, à ~0.2s par requête.
- Le RRF à poids égaux nuit en réalité (0.610 < 0.661) : des correspondances lexicales bruitées déplacent de bons résultats vectoriels. C’est pourquoi le défaut livré est
vector, pashybrid. - Si vous voulez du signal lexical, utilisez
linear, pasrrf: la fusion pondérée ramène le Recall@5 à 0.718 pour un coût de latence minime. - Le cross-encoder domine en qualité (0.678 / 0.754) mais le p50 grimpe à ~0.7s et il exige torch — pour les configurations tolérantes à la latence et sensibles à la précision.
Les auteurs qualifient ces chiffres d’illustratifs : la précision absolue suit le modèle qui répond (ici gpt-5.4), mais l’ordre relatif des méthodes de récupération est stable. Le banc d’essai ne mesure d’ailleurs que le substrat de récupération (rappel textuel des tours d’origine), pas le cycle complet d’extraction des faits — en usage réel, une récupération orientée faits peut faire encore mieux.
7. Organisation du stockage et compaction automatique
Tout est local, aucun service externe :
| Path | Contents |
|---|---|
~/.hermes/lancedb/memories.lance/ |
Dataset LanceDB (fragments, manifeste, index). Table unique memories ; la colonne kind sépare les lignes de type fait vs tour |
~/.hermes/lancedb/.last_optimize_version |
Fichier sentinelle : table.version au dernier optimize() réussi |
~/.cache/huggingface/ |
Cache du reranker cross-encoder ; présent uniquement quand reranker.type: cross-encoder est activé |
Envie de fouiller le stockage directement, façon SQL :
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())
"
Les workloads d’agents sont dominés par des écritures mono-ligne, et chaque add/delete Lance est un commit — sans intervention, les petits fragments et fichiers de versions s’accumulent indéfiniment. La compaction automatique du plugin (activée par défaut) compare la version au fichier sentinelle et exécute table.optimize(cleanup_older_than=timedelta(days=7)) dans un thread démon dès que le delta dépasse optimize_every_commits (50 par défaut). Un verrou non bloquant garantit une seule optimisation à la fois et les écrivains ne sont jamais bloqués. Désactivez-la (maintenance.enabled: false) et le dataset grossit sans limite — généralement déconseillé.
8. Référence rapide de dépannage
hermes plugins listn’affiche paslancedb: vérifiez que le symlink~/.hermes/plugins/lancedbpointe bien vers le dépôt.- L’agent n’écrit que la mémoire intégrée, aucun outil
lancedb_*: le provider n’est pas actif. Lancezhermes memory status— vous voulez voirProvider: lancedbavecavailable ✓; si c’est vide, relancezhermes memory setup. - Le rappel échoue avec une erreur d’authentification : les embeddings appellent l’API OpenAI — assurez-vous que
OPENAI_API_KEYest définie (variable d’environnement ou~/.hermes/.env). - Le répertoire
.lancene cesse de grossir : vérifiez quemaintenance.enabled: trueet que~/.hermes/lancedb/.last_optimize_versionprogresse entre les sessions ;lancedb optimize startingdansagent.logsignifie que la compaction tourne. - Vous avez changé
embedding.modelet le rappel ne renvoie rien : incohérence de dimension. Supprimez~/.hermes/lancedb/memories.lance/pour recréer la table.
En résumé
Le plugin LanceDB comble la lacune la plus importante de la mémoire à long terme de Hermes Agent : le rappel par le sens, pas par le mot-clé. Cinq minutes d’installation, aucun réglage sur les valeurs par défaut, toutes les données en local — en échange d’une précision supérieure d’environ 24 % (0.661 contre 0.533) et d’un bond du Recall@5 sur LongMemEval. Pour les travailleurs du savoir, cela signifie que « les choses que vous avez dites une fois reviennent, même quand vous demandez autrement ».
Pour aller plus loin :
- Envie de distiller vos mémoires dans une base de connaissances lisible par un humain ? Voir transformer les conversations Hermes en notes Obsidian.
- Les stocks de mémoire grossissent aussi — gérer les sessions et l’espace disque : guide d’optimisation du stockage Hermes.
- D’autres conseils quotidiens pour tirer le meilleur de votre agent : astuces de productivité pour Hermes Agent.
- Pas encore installé Hermes ? Commencez par le guide d’installation.