Un second cerveau IA privé : système RAG local utilisant AnythingLLM, Ollama et Obsidian.
Un deuxième cerveau privé : AnythingLLM et un modèle d’embedding sur une VM Proxmox permettent à Mistral 7B local de rechercher dans des notes Obsidian via Ollama RAG, tout en affichant l’utilisation réelle des ressources.
Sources: Giving My Local AI a Memory: Turning It Into a Private AI Second Brain with RAG and AnythingLLM
Un amnésique brillant
Un modèle linguistique local peut engager une conversation, expliquer des concepts et aider à réfléchir, tout cela sans que le moindre octet quitte le bâtiment. Ce qu’il ne peut pas faire par défaut, c’est récupérer quoi que ce soit que vous avez enregistré.
Imaginez un an de notes accumulées dans Obsidian : des liens marqués à minuit, des idées à moitié formées, un long article copié sur les moteurs de recherche, des offres d’emploi et des notes de ateliers. Tout cela se trouve dans un dossier sur un ordinateur portable, invisible pour une IA qui a nécessité tout un week-end pour fonctionner hors ligne.
Le stockage n’a jamais été le problème. La récupération, si. Trouver la bonne note au bon moment, c’est ce qui transforme un dossier de liens en connaissances plutôt qu’en un tiroir en désordre. Par conséquent, l’étape suivante naturelle pour une installation d’IA privée est de lui donner accès à ces notes.
Qu’est-ce que RAG et pourquoi c’est important
La plupart des guides sur le « fonctionnement de l’IA localement » omettent cette partie, probablement parce que les embeddings semblent ennuyeux. Ils le sont un peu, mais il vaut la peine de les comprendre.
RAG signifie Retrieval-Augmented Generation. Il permet à un modèle de langage d’utiliser vos propres documents, sans réentraînement et sans besoin de les télécharger sur le serveur d’un tiers.
Pensez à embaucher un bibliothécaire très rapide plutôt que de demander à l’IA de mémoriser chaque livre. Le bibliothécaire ne connaît pas vos notes par cœur, il sait simplement quel livre chercher lorsque vous posez une question.
Voici ce qui se passe en réalité :
- Les documents sont divisés en fragments et transformés en embeddings, des représentations numériques du sens, qui sont stockés dans une base de données vectorielle.
- Une question est également transformée en embedding.
- La base de données trouve les fragments dont le sens est le plus proche de la question.
- Ces fragments sont transmis au modèle de langage en tant que contexte.
Le outil : AnythingLLM
AnythingLLM convient à cette configuration pour plusieurs raisons :
- Les espaces de travail conservent des bases de connaissances distinctes pour différents contextes, tels que des notes, des recherches ou des brouillons de blog.
- Il lit nativement Markdown, donc les notes d’Obsidian n’ont pas besoin d’être converties.
- Il se connecte directement à Ollama.
- Il est auto-hébergé et fonctionne en tant que conteneur Docker, sans compte ni service cloud.
- Il dispose également d’une application de bureau, ce qui aide ceux qui n’ont pas de home lab.
Ce n’est pas la seule option. Open WebUI intègre également RAG. Mais le modèle d’espace de travail d’AnythingLLM correspond plus fidèlement à l’idée d’un « deuxième cerveau », et son interface est suffisamment conviviale pour être recommandée à un lecteur non technique.
Création de l’environnement
Point de départ
La configuration suppose une base comme celle-ci :
- un hôte Proxmox VE en mode bare-metal ;
- une VM Ubuntu 24.04 contenant Ollama avec Mistral 7B ;
- Open WebUI en tant que interface de chat.
La configuration complémentaire ajoute une deuxième VM à côté.
Une nouvelle VM dans Proxmox
Créez une VM Ubuntu 24.04 LTS vierge pour AnythingLLM. La placer séparément de la VM Ollama permet d’effectuer des snapshots, de provoquer délibérément des pannes puis de les restaurer sans toucher à la configuration d’inférence elle-même. C’est mieux de casser des choses exprès que de les endommager par accident plus tard.
Spécifications recommandées :
- 4 cœurs CPU
- 8 GB de RAM
- 40 GB de disque, car les bases de données vectorielles prennent de l’espace
Rien ici n’est difficile. La documentation couvre le sujet, ainsi qu’un peu d’essais et d’erreurs, surtout pour ceux qui ont déjà configuré la VM Ollama. La véritable contrainte est le matériel disponible, et travailler dans ces limites est l’objectif de cet exercice.
Installation du modèle d’incorporation
La plupart des guides omettent cette étape, ce qui provoque le plus de perplexité.
RAG a besoin de deux modèles. L’un est le modèle d’inférence, que Mistral 7B fournit déjà. L’autre est un modèle d’incorporation, qui convertit le texte en vecteurs. Ce sont des choses différentes, et peu de guides le précisent dès le début.
Sur la VM Ollama existante, téléchargez le modèle d’incorporation :
ollama pull nomic-embed-text
nomic-embed-text est de petite taille, d’environ 270 MB, rapide sur un CPU et performant avec du texte en anglais, ce qui en fait un choix judicieux pour du matériel ne disposant pas de GPU.
Un autre problème : par défaut, Ollama ne répond que sur localhost. Pour que AnythingLLM sur une VM différente puisse y accéder, Ollama doit être configuré pour répondre sur toutes les interfaces. Commencez par modifier le service :
sudo systemctl edit ollama
Ensuite, ajoutez cette modification :
[Service]
Environment="OLLAMA_HOST=0.0.0.0"
Redémarrez systemd et relancez le service :
sudo systemctl daemon-reload
sudo systemctl restart ollama
Ensuite, ouvrez le port 11434 dans le pare-feu Proxmox entre les deux machines virtuelles. La leçon se répète : le service fonctionnait bien et le modèle aussi. Ce qui était défaillant, c’était l’hypothèse selon laquelle tout peut communiquer avec tout par défaut.
La configuration réseau pourrait être plus stricte, et elle le devrait probablement à terme. C’est une attitude typique des amateurs : faire fonctionner le système, comprendre ce qui a été construit, puis le démonter pour le refaire correctement.
AnythingLLM via Docker
Sur la nouvelle machine virtuelle, installez d’abord Docker :
# Install Docker
curl -fsSL <https://get.docker.com> | sh
sudo usermod -aG docker $USER
newgrp docker
Ensuite, lancez AnythingLLM :
# Run AnythingLLM
docker run -d \
-p 3001:3001 \
--name anythingllm \
-v ~/.anythingllm:/app/server/storage \
mintplexlabs/anythingllm
Ouvrez http://<new-vm-ip>:3001 dans un navigateur. La configuration pour la première exécution est la suivante :
- Fournisseur de LLM : Ollama, à l’adresse
http://<ollama-vm-ip>:11434 - Modèle de chat : Mistral 7B
- Fournisseur d’embeddings : Ollama, avec
nomic-embed-text - Base de données vectorielle : LanceDB, intégrée et ne nécessitant aucune configuration supplémentaire
Alimenter le système avec les notes
Créez un espace de travail nommé « Second Brain » et pointez AnythingLLM vers le coffre-fort Obsidian. Son gestionnaire de documents accepte les téléchargements de dossiers, donc donnez-lui le répertoire contenant les notes et laissez-le traiter tout le contenu.
Il prend en charge les fichiers .md, .txt, .pdf, .docx et .csv. Les fichiers Obsidian Canvas sont en réalité des fichiers JSON, donc ils ne provoqueront pas d’erreur mais ne fourniront pas non plus d’informations utiles.
Après ingestion, l’espace de travail affiche le nombre de fragments et l’état de l’incorporation. Chaque note est divisée en fragments chevauchants d’environ 500 tokens, ce qui signifie qu’un article long copié sur les moteurs de recherche se transforme en dizaines de fragments pouvant être récupérés séparément.
Le moment où cela fonctionne
La véritable épreuve consiste en une demande simple, comme demander à l’assistant de vérifier une note spécifique intitulée « homelab improvements ».
Il trouve le fichier réel, le cite par son nom et cite la ligne exacte accompagnée d’une date et d’heure. La citation indique le nom du document source ainsi que la date de publication. La récupération fonctionne comme annoncé : le fichier est identifié et retrouvé, sans contenu inventé ni paraphrase vague, uniquement les informations pertinentes accompagnées d’une citation.
Le côté amusant apparaît lorsque le modèle tente d’expliquer la note. Il décrit Claude Code comme une sorte d’assistant personnel ou de service. Mistral 7B, qui fonctionne hors ligne sur une machine domestique ne disposant que d’un CPU, n’a aucune idée de ce qu’est Claude Code ou un serveur MCP. Il peut récupérer les mots, mais ne parvient pas à les comprendre pleinement.
C’est là la leçon la plus utile : la récupération et la compréhension sont deux problèmes distincts. RAG place le bon contexte devant le modèle, mais la capacité à comprendre ce contexte reste limitée par le modèle lui-même. Avec un petit modèle de 7 milliards de paramètres et sans accès à Internet, ces limites se font rapidement sentir.
Qu’est-ce qui a mal tourné et qu’a-t-on appris ?
Quelques hypothèses n’ont pas tenu face à la mise en œuvre.
- RAG n’est pas de la magie. Son utilité dépend uniquement des données qu’on lui fournit, et des notes désordonnées produisent des résultats désordonnés. Entrée de mauvaise qualité, sortie de mauvaise qualité.
- Le réseau fait partie intégrante du projet dès les premières étapes. Lorsque les services sont répartis sur plusieurs machines, il est tout aussi important de s’assurer qu’elles communiquent de manière fiable que de configurer chacune d’elles.
- Ne blâmez pas trop rapidement le modèle. Parfois, le problème réside dans le contexte fourni. Une bonne capacité de récupération peut rendre un modèle de petite taille surprenamment utile, mais elle ne peut pas fournir des connaissances que le modèle n’a jamais eues.
Le résultat final et son coût
Un an de liens, d’idées et de pensées inachevées devient accessible, non seulement par mot-clé mais aussi de manière sémantique. En posant une question sur un concept, les notes associées que vous aviez oubliées apparaissent, chacune accompagnée d’une citation vers son fichier source.
La machine de test était un EliteDesk équipé d’un i5, de 32 GB de RAM et sans GPU, et tout fonctionnait hors ligne. Résultats de cette seule exécution :
| Élément | Résultat |
|---|---|
| Durée totale de la requête | 1 min 35,9 s, avec AnythingLLM indiquant 41,9 s pour la génération |
| Mémoire d’AnythingLLM en veille | environ 440 MB sur 7,76 GB alloués |
| Mémoire de la VM Ollama en utilisation | 7,8 GB sur 19 GB |
| Mémoire utilisée par Mistral | environ 6,5 GB |
| nomic-embed-text | environ 360 MB |
| Open WebUI | environ 1 GB |
L’écart d’environ 54 secondes entre les deux temps de traitement n’est pas expliqué. Une cause plausible est le rechargement du modèle par Ollama depuis un disque dur.
Rien de tout cela n’est rapide, et ce n’est pas prévu pour l’instant. C’est le premier jour d’une installation RAG en home lab qui est encore en phase d’adaptation, et ce n’est pas un benchmark à comparer avec des solutions sérieuses. Ce sera amusant de revoir ces chiffres une fois que le matériel local pourra gérer bien plus de tokens par seconde.
Où cela vous mène
Le projet part d’un objectif simple : permettre à une IA locale de consulter vos notes, mais il enseigne bien plus que cela. Au fil du processus, vous apprenez comment fonctionne RAG, quel rôle jouent les bases de données vectorielles, ce qui rend la récupération d’informations efficace, et pourquoi un contexte adéquat peut être plus important qu’un modèle plus volumineux.
Plus important encore, le résultat est quelque chose que vous utiliserez réellement. Douze mois de connaissances sauvegardées cessent d’être dispersées dans des dossiers pour devenir quelque chose à quoi vous pouvez simplement poser des questions. Tout cela fonctionne sur un ordinateur portable d’occasion dans un coin de la pièce, ce qui n’est pas mal pour une machine destinée à la retraite.
RAG fonctionne. La compréhension, c’est une autre histoire.
Lectures complémentaires
La documentation d’AnythingLLM, Ollama, LanceDB et Obsidian présente tous les détails. L’article original sur RAG, « Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks », explique l’idée sous-jacente à tout cela. Tout ce qui est décrit fonctionne sur du matériel réaffecté, sans cloud, sans abonnement et sans données quittant le réseau.