bge-m3 a résolu les noms propres en français dans Mnemo

  • embeddings
  • rag
  • evaluation
  • mnemo

Avant, mon bot avait du mal à comprendre le français : Mnemo remontait souvent la mauvaise note, par exemple « Bible de l’Univers » quand on lui demandait ce qu’est Mnemo. Cette difficulté était particulièrement marquée pour les sigles et les noms propres.

L’architecture retenue

Le pipeline utilise Qdrant pour le stockage vectoriel, Ollama pour l’exécution locale de bge-m3, et un monorepo Python avec cinq crates : core (config, embedder, indexer), ingest, api, watch et mcp. L’ingestion parse le markdown, découpe les textes en chunks, génère les embeddings et les indexe dans Qdrant avec un payload riche (chemin, titre, tags, etc.).

L’embedder appelle Ollama via une session HTTP persistante. Il gère les prefixes conditionnels, désactivés pour bge-m3, et le batching des documents pour limiter les allers-retours réseau.

Ce que ça change en pratique

Les catégories les plus améliorées sont celles des noms propres (Mnemo, Cendré, ARIA) et des sigles (RAG, OOP, REST API), tous passés de 0 % à 100 %.

Les tradeoffs, assumés

J’ai abandonné nomic-embed-text pour bge-m3, qui est plus lent à l’ingestion (1 h 45 contre 1 heure) mais bien meilleur en français.

J’ai aussi reporté la recherche hybride BM25 et le reranking : à 90 % Hit@1, le gain marginal ne valait pas l’effort. J’ai préféré passer à l’auto-ingestion.

Quand ça vaut le coup, et quand non

bge-m3 vaut le coup lorsque les notes sont en français et pleines de sigles et noms propres.

Il ne vaut pas le coup pour un corpus en anglais ou sur une machine trop limitée, où nomic ou une simple recherche plein texte suffit.

Ce que je changerais si je recommençais

Avec le recul, j’aurais testé plusieurs modèles d’embedding sur mon propre corpus français avant de tout indexer : j’ai fait confiance à l’étiquette « multilingue » de nomic, et j’ai dû tout réindexer.

J’aurais aussi construit mon framework d’évaluation dès le départ. Une heure de travail m’aurait évité de découvrir le problème après coup.

La stack

Qdrant v1.18 pour le vector store.

bge-m3 via Ollama pour les embeddings.

FastAPI + Uvicorn + Pydantic pour l’API REST.

Python 3.11 + uv pour la gestion des dépendances et le monorepo.

Nous utilisons watchdog pour détecter les changements de fichiers en temps réel.

FastMCP pour le serveur MCP consommé par Claude Desktop.

CouchDB + Self-hosted LiveSync + livesync-bridge pour la synchronisation du vault Obsidian.

Une question sur ce sujet ?

Si votre cas ressemble à celui décrit ici et que vous voulez un avis avant de vous lancer, écrivez-moi. Une réponse courte et honnête ne coûte rien.