Hermes : la mémoire longue Mnemosyne
1. Quoi ? — Définition et contexte
Section intitulée « 1. Quoi ? — Définition et contexte »Un agent qui oublie tout entre deux conversations n’est qu’un chatbot avec des outils. Ce qui distingue Hermes d’un appel LLM ponctuel, c’est qu’il capitalise : ce qui est dit lundi reste disponible jeudi.
Mnemosyne est le provider mémoire externe qui assure cette persistance — une base SQLite locale avec recherche hybride vecteur + FTS5 et capture en tâche de fond à chaque tour.
Ce que remplace Mnemosyne
Section intitulée « Ce que remplace Mnemosyne »La mémoire native de Hermes est un fichier MEMORY.md réinjecté dans le prompt système. Simple et lisible, mais elle plafonne vite.
MEMORY.md natif | Mnemosyne | |
|---|---|---|
| Stockage | Un fichier Markdown | Base SQLite |
| Recherche | Aucune — tout est réinjecté | Hybride : vecteur + FTS5 |
| Budget | Plafond de caractères dans le prompt | Rappel sélectif selon la requête |
| Capture | Écriture explicite | Tâche de fond à chaque tour |
| Structure | Texte libre | Épisodes, triplets temporels, graphe |
Le fichier natif n’est pas supprimé pour autant : il reste en place et redevient la mémoire active si le provider externe est désactivé.
Configuration active
Section intitulée « Configuration active »memory: memory_enabled: true user_profile_enabled: true memory_char_limit: 2200 user_char_limit: 1375 provider: mnemosyne nudge_interval: 10 flush_min_turns: 6Deux budgets distincts : memory_char_limit pour ce que l’agent a retenu, user_char_limit pour le profil utilisateur qu’il construit au fil des échanges.
2. Pourquoi ? — Enjeux et motivations
Section intitulée « 2. Pourquoi ? — Enjeux et motivations »Pourquoi le mode wrapper plutôt qu’une image custom ?
Section intitulée « Pourquoi le mode wrapper plutôt qu’une image custom ? »C’est la décision structurante de cette installation. Trois voies étaient possibles :
| Voie | Coût | Problème |
|---|---|---|
| Image custom | Un Dockerfile qui étend l’image upstream | Casse le flux DIUN : plus de détection automatique des mises à jour amont, rebuild manuel à chaque version |
Patch de /opt/hermes | Modifier l’arbre applicatif dans le conteneur | Écrasé à chaque mise à jour d’image |
| Mode wrapper | Venv latéral + plugin, entièrement sous /opt/data | Survit aux recreate et aux mises à jour d’image |
Le mode wrapper gagne parce que /opt/data est un bind mount : tout ce qui y vit est hors du cycle de vie de l’image. Le conteneur reste strictement l’image upstream, DIUN continue de détecter les nouvelles versions, et rien n’est à reconstruire.
Pourquoi local-first ?
Section intitulée « Pourquoi local-first ? »La capture tourne à chaque tour, sur tout ce qui passe dans la conversation : notes de réunion, décisions techniques, informations sur des contacts. Envoyer ce flux à un service de vectorisation externe reviendrait à exporter en continu le contenu des échanges.
Mnemosyne calcule ses embeddings localement et stocke tout dans un SQLite du volume de données. Aucune donnée de conversation ne sort du VPS pour être indexée.
3. Comment ? — Mise en œuvre technique
Section intitulée « 3. Comment ? — Mise en œuvre technique »Où vit quoi
Section intitulée « Où vit quoi »| Élément | Chemin |
|---|---|
Venv latéral (mnemosyne-hermes → mnemosyne-memory[embeddings]) | /opt/data/.mnemosyne/venv |
| Shim de plugin + manifeste (découverte par Hermes) | /opt/data/plugins/mnemosyne/ |
| Skill embarquée | /opt/data/skills/memory/mnemosyne-memory-override/ |
| Base SQLite | /opt/data/mnemosyne/data/mnemosyne.db |
L’activation tient en une ligne : memory.provider: mnemosyne dans le fichier de config.
Les outils exposés
Section intitulée « Les outils exposés »Le plugin déclare 20 outils et 3 hooks (pre_llm_call, on_session_start, post_tool_call) :
| Famille | Outils |
|---|---|
| Mémoire | mnemosyne_remember, mnemosyne_recall, mnemosyne_update, mnemosyne_forget, mnemosyne_invalidate |
| Graphe et triplets | mnemosyne_triple_add, mnemosyne_triple_query, mnemosyne_graph_query, mnemosyne_graph_link |
| Bloc-notes | mnemosyne_scratchpad_write, mnemosyne_scratchpad_read, mnemosyne_scratchpad_clear |
| Consolidation | mnemosyne_sleep |
| Transfert | mnemosyne_export, mnemosyne_import, mnemosyne_sync_push, mnemosyne_sync_pull, mnemosyne_sync_status |
| Diagnostic | mnemosyne_stats, mnemosyne_diagnose |
Les hooks font le travail invisible : on_session_start charge le contexte pertinent, pre_llm_call injecte le rappel dans le prompt, post_tool_call capture ce qui mérite d’être retenu.
Exploitation
Section intitulée « Exploitation »# Le provider est-il bien actif ?docker exec hermes hermes memory status # → Provider: mnemosyne, available
# Statistiques de la basedocker exec --user hermes -e HOME=/opt/data -e HERMES_HOME=/opt/data hermes \ /opt/data/.mnemosyne/venv/bin/mnemosyne stats
# Mise à jourdocker exec --user hermes -e HOME=/opt/data hermes \ /opt/data/.mnemosyne/venv/bin/pip install --no-cache-dir -U mnemosyne-hermesdocker compose -f ai-stack/docker-compose.yaml restart hermesSauvegarde
Section intitulée « Sauvegarde »La base de données part dans le backup quotidien. Le venv et le cache de modèles fastembed en sont exclus : ils pèsent lourd et se réinstallent en une commande.
Conséquence à connaître pour une restauration : la base revient telle quelle, mais le venv est à recréer avant que le provider redevienne disponible.
4. Et si ? — Perspectives et limites
Section intitulée « 4. Et si ? — Perspectives et limites »Limites actuelles
Section intitulée « Limites actuelles »| Limite | Impact | Mitigation |
|---|---|---|
| Mémoire liée au conteneur | Un second utilisateur partagerait la même mémoire et le même profil | Un conteneur par utilisateur plutôt qu’une allowlist élargie |
| Consolidation sans LLM | Le regroupement d’épisodes reste mécanique | MNEMOSYNE_HOST_LLM_ENABLED=true, au prix du quota |
| Contenu opaque | La base SQLite n’est pas lisible dans Obsidian | Export en notes markdown, prévu |
| Wrapper fragile au bump Python | Panne silencieuse après une mise à jour d’image | Vérifier hermes memory status après chaque update |
| Pas de mémoire partagée avec le poste | Ce que sait Hermes, l’assistant local l’ignore | Synchronisation bidirectionnelle, prévue |
Scénarios d’évolution
Section intitulée « Scénarios d’évolution »Si la mémoire doit devenir lisible :
- Export des mémoires en notes markdown dans
vps-vault, avec frontmatter de provenance. - L’intérêt dépasse la lecture : une mémoire versionnée dans Git devient auditable et corrigeable à la main.
- La skill
mnemosyne-operationscouvre déjà la gouvernance de cet export.
Si la mémoire doit être unique entre l’agent et le poste de travail :
- Les outils
mnemosyne_sync_push/mnemosyne_sync_pullexistent déjà côté plugin. - Reste à choisir le sens de vérité en cas de conflit, et à décider si le chiffrement côté client est nécessaire.
Si le volume devient un problème :
mnemosyne_invalidateetmnemosyne_forgetpermettent déjà un élagage ciblé.- Une passe de consolidation régulière compresse mieux qu’une suppression brutale.
Pages liées
Section intitulée « Pages liées »- Hermes Agent — Le déploiement et son modèle de sécurité
- Plugins — Mnemosyne est l’un des quatre plugins actifs
- Skills —
mnemosyne-operations, la procédure de gouvernance mémoire
Infrastructure
Section intitulée « Infrastructure »- Backup des bases de données — La base est sauvegardée, le venv non
- AI Stack — Qdrant, l’autre base vectorielle de l’infra
Référence
Section intitulée « Référence »- Glossaire — Mémoire à long terme, Embeddings, Vector Database