37 points par GN⁺ 2026-01-16 | 3 commentaires | Partager sur WhatsApp
  • Sur Hacker News, un utilisateur demande comment les autres implémentent le Retrieval-Augmented Generation (RAG) dans un environnement local
  • Une tendance forte se dégage : en RAG local, il est souvent possible de très bien s’en sortir sans base de données vectorielle, avec de la recherche textuelle comme SQLite FTS5, BM25 ou grep
  • Pour la recherche dans le code, beaucoup rapportent que les embeddings sont lents et bruités, et plusieurs estiment qu’une approche à base de mots-clés comme BM25 + trigrammes fonctionne mieux
  • Même lorsqu’une recherche vectorielle est nécessaire, de nombreux exemples montrent qu’on peut s’en sortir avec une configuration légère comme Postgres + pgvector, le stockage de vecteurs en BLOB dans SQLite, ou un chargement FAISS en mémoire
  • Il est possible d’améliorer la qualité de recherche avec des combinaisons comme la recherche hybride BM25 + vecteurs, le RRF (Reciprocal Rank Fusion), le reranking ou l’expansion multi-requêtes
  • Plutôt que de figer le principe « RAG = base de données vectorielle », on voit se dessiner une tendance consistant à choisir entre recherche simple → hybride → agentique selon le type de documents, l’échelle et la charge opérationnelle

Conclusion commune sur l’étape de recherche

  • Au lieu de partir du principe qu’une base vectorielle ou un graphe est indispensable, beaucoup privilégient une approche consistant à commencer simplement selon l’infrastructure existante, les types de fichiers et les performances requises
  • Certains mentionnent qu’une approche où un agent interroge directement le système de fichiers ou des API est plus simple à configurer et à maintenir, mais peut être un peu plus lente
  • L’idée que « ce que le RAG transmet au LLM, ce sont de courts fragments textuels issus de la recherche » amène à recentrer les efforts d’optimisation sur la qualité de la recherche
  • À propos de la « définition du RAG », certains répondent que retrieval + generation suffit à parler de RAG, même sans base vectorielle, tandis que d’autres estiment que le terme suppose souvent ce type d’outil

Modèles d’embedding et recherche vectorielle

  • Le modèle d’embedding mdbr-leaf-ir, développé chez MongoDB, fonctionne uniquement sur CPU et s’est classé 1er sur plusieurs leaderboards dans cette catégorie de taille
    • Sur un serveur standard à 2 vCPU, il peut traiter environ 22 documents par seconde et 120 requêtes par seconde
    • Il obtient 53,55 sur le benchmark BEIR (contre 42,69 pour all-MiniLM-L12-v2)
  • Des embeddings statiques de mots comme model2vec/minish sont plus rapides en inférence, mais moins précis pour la recherche
    • Ils se limitent à la tokenisation + table de correspondance + moyenne, donc restent plus rapides que les approches basées sur des transformers
  • Une autre approche consiste à générer des vecteurs par chunk de texte avec Meta-Llama-3-8B, à les stocker dans une colonne BLOB SQLite, puis à effectuer la recherche avec FAISS
    • À l’échelle de 5 millions de chunks, cela consomme environ 40 Go de mémoire
    • Sur une A6000, faiss-gpu est très rapide, et sur un M1 Ultra, faiss-cpu est plus lent mais reste suffisant pour quelques requêtes par jour
Publicité

Recommandations pour la recherche dans le code

  • Pour le code, il est recommandé d’éviter les bases de données vectorielles et de privilégier une combinaison BM25 + trigrammes
    • Les embeddings sont lents et peu adaptés au code
    • Sans reranker, le bruit est important, et la réindexation des fichiers est coûteuse
    • La vitesse de réponse est élevée et la qualité des résultats est jugée excellente
  • Dans PostgreSQL, il est possible d’implémenter une recherche BM25 avec plpgsql_bm25
    • Le support de la recherche hybride avec pgvector + Reciprocal Rank Fusion est également mentionné
  • Appliquer des embeddings au chemin de fichier + à la signature, puis fusionner cela avec BM25, peut donner de bons résultats
  • Une approche agentique consistant à exécuter gpt-oss 20B avec ripgrep dans une boucle while est aussi décrite comme efficace

Solutions basées sur des bases de données

  • SQLite FTS5 : bien adapté aux documents basés sur des fichiers Markdown, et permet de mettre en place un RAG même sans base de données vectorielle
    • On peut ajouter à chaque fichier un court champ descriptif pour naviguer dans les documents via la recherche par mots-clés
    • Il est aussi possible de stocker des vecteurs fp16 dans SQLite sous forme de BLOB, de créer un sous-ensemble via des filtres, puis de calculer la similarité en mémoire
    • Parmi les autres options citées : sqlite-vec, sqlite-vector, vec0 et le bm25 de SQLite
    • « SQLite fonctionne étonnamment bien »
  • PostgreSQL + pgvector : permet de réutiliser les compétences Postgres déjà en place et facilite la transmission à l’équipe d’exploitation
    • La bibliothèque llmemory prend aussi en charge le BM25 hybride, l’expansion multi-requêtes et le reranking
  • LanceDB : une base vectorielle embarquée pratique à utiliser
    • Utilisée avec les embeddings nomic-embed-text d’Ollama
    Publicité
  • DuckDB : propose une extension de recherche par similarité vectorielle, adaptée aux petits projets de moins de 3 Go
  • Meilisearch, Typesense, Manticore : plus simples à exploiter qu’Elasticsearch/OpenSearch

Recherche hybride et agentique

  • nori (usenori.ai) : combine recherche sémantique et recherche lexicale avec SQLite + vec0 + fts5
  • Turbopuffer : prend en charge la recherche hybride vecteurs + BM25
  • La simple combinaison de recherche agentique et de recherche textuelle peut déjà donner de très bons résultats
    • Ajouter une recherche vectorielle et un graph RAG peut apporter un léger gain de vitesse et de qualité
  • Claude Code / Codex utilisent ripgrep en interne
  • Appliquer des embeddings aux chemins de fichiers peut aussi être efficace, et la fusion avec BM25 améliore encore les résultats

Cas d’usage de BM25

  • shebe : outil CLI/MCP d’indexation et de recherche de code basé sur BM25
    • Particulièrement utile dans les workflows de refactoring (par ex. lister les emplacements à modifier lors d’une mise à niveau d’Istio)
  • Dans 85 % des cas, une simple correspondance par tags suffit sans base de données vectorielle
    • Des opérateurs ont ajouté des tags à la fois aux entrées et aux documents pour atteindre un taux de correspondance de 100 %
  • Certains considèrent que la plupart des bases vectorielles sont « un marteau pour résoudre un problème de non-trouvabilité »
Publicité

Outils et bibliothèques spécifiques

  • qmd : outil CLI de recherche dans des fichiers Markdown, avec de meilleurs résultats en requêtes floues que fzf
  • ck : outil de grep sémantique écrit en Rust
  • Kiln : permet d’ajouter des fichiers en glisser-déposer et de comparer plusieurs configurations
    • Prend en charge la comparaison des méthodes d’extraction, des modèles d’embedding et des modes de recherche (BM25, hybride, vectoriel)
    • Inclut l’évaluation de la précision de recherche et la génération automatique de jeux de données d’évaluation
  • libragen : serveur CLI/MCP servant à créer une bibliothèque de contenus RAG versionnée
    • Peut transformer un dépôt GitHub en base de données RAG
  • piragi : bibliothèque Python de RAG simple, prenant en charge diverses sources comme le local, S3 ou des API
  • ragtune : outil CLI pour le débogage et le benchmarking de la recherche dans un RAG local

Traitement documentaire et OCR

  • discovery : effectue l’OCR de documents avec Qwen-3-VL-8B et stocke les vecteurs dans ChromaDB
    • Met en œuvre un RAG hybride BM25 + embeddings
  • docling : outil d’extraction de documents utilisé dans plusieurs projets RAG
  • Lors de la conversion de PDF, le traitement des tableaux, des mises en page multi-colonnes et des tableaux s’étendant sur plusieurs pages reste difficile
    • Le modèle Mistral OCR donne les meilleurs résultats (modèle non public)
Publicité

Mémoire et gestion du contexte

  • Ce que le RAG transmet au LLM, ce sont uniquement de courtes chaînes de résultats de recherche
    • Sur les petits modèles, une valeur de TOP_K autour de 5 semble être une limite, au-delà de laquelle on observe un oubli du contexte
  • On peut améliorer cela en pré-résumant les fichiers et dossiers
  • Certains utilisent aussi une approche consistant à tout mettre dans le contexte avec Sonnet + une fenêtre de contexte de 1M
  • Un exemple mentionne la construction d’un système de mémoire pour Claude Code via recherche sémantique sur des fichiers de session

Usage en entreprise et à grande échelle

  • Lorsqu’on traite 300 000 interactions clients par jour, la latence et la précision sont des facteurs critiques
    • Une approche hybride embeddings + recherche plein texte + IVF-HNSW est utilisée
    • La gestion de la diffusion de l’information à travers environ 600 systèmes distribués constitue un défi
  • Une approche KAG (Knowledge Augmented Generation) est testée pour cartographier des règles métier
  • Un RAG entièrement local a aussi été mis en place avec succès sur plus de 500 000 articles de presse via une base vectorielle Postgres

Autres outils et approches

  • AnythingLLM : inclut un bundle de base vectorielle pour les documents
  • LibreChat : inclut également une base vectorielle packagée pour les documents
  • ChromaDB : utilisé via une extension Obsidian pour la recherche sémantique/hybride
  • SurrealDB : utilisé en combinaison avec une vectorisation locale
  • Interface de requêtes OData : efficace lorsqu’elle est fournie comme outil au LLM, y compris pour analyser un fichier Excel de 40 000 lignes
  • Nextcloud MCP Server : utilise Qdrant comme base vectorielle et fournit une recherche sémantique sur des documents personnels
  • LSP (Language Server Protocol) : ajouté à Claude Code, mais des bugs existent actuellement
    • TreeSitter peut être plus utile (recherche par nom de symbole, navigation entre définitions et usages)

3 commentaires

 
ryj0902 2026-01-20

En voyant les performances de notre système RAG interne assez bricolé, ce genre de post me fait effectivement un peu changer de perspective.

 
tensun 2026-01-16

Je me demande si le coréen est bien pris en charge.

 
GN⁺ 2026-01-16
Avis sur Hacker News
  • Notre équipe exploite une base de données de questions-réponses
    Les questions et les réponses sont toutes indexées à la fois avec un index trigramme et des embeddings, puis stockées dans Postgres
    Lors de la recherche, nous utilisons pgvector et la recherche trigramme ensemble, puis fusionnons les résultats à l’aide d’un score de pertinence

  • Pour l’étape de recherche, nous avons développé un modèle d’embedding de texte très efficace et optimisé pour le CPU
    Il s’agit du modèle MongoDB/mdbr-leaf-ir, classé n°1 du leaderboard parmi les modèles de même taille
    Il est compatible avec le modèle Snowflake/snowflake-arctic-embed-m-v1.5
    Le démo search-sensei permet de comparer recherche sémantique vs BM25 vs hybride
    Par exemple, le modèle d’embedding reconnaît que « j lo » signifie « Jennifer Lopez »
    Nous avons aussi publié la recette d’entraînement, qui permet un apprentissage facile même avec du matériel modeste

    • Je me demande comment la vitesse d’embedding et le recall de ce modèle se comparent à des embeddings de mots statiques comme minish ou model2vec
  • Je génère des vecteurs avec Meta-Llama-3-8B depuis avril 2024
    J’utilisais Python et Transformers sur une RTX-A6000 : c’était rapide, mais il y avait beaucoup de bruit et de chaleur
    Je suis ensuite passé à un M1 Ultra avec la bibliothèque MLX d’Apple, avec une vitesse similaire mais bien plus silencieuse
    Les modèles Llama ont 4k dimensions, soit 8 KB par chunk en fp16, et je les stocke avec numpy.save() dans une colonne BLOB de SQLite
    Lors de la recherche, je charge tous les vecteurs depuis SQLite, je les transforme en numpy.array, puis je fais la recherche avec FAISS
    Le faiss-gpu de la RTX6000 est extrêmement rapide, et le faiss-cpu du M1 Ultra est aussi largement suffisant pour mon usage (quelques requêtes par jour)
    Avec 5 millions de chunks, l’utilisation mémoire est d’environ 40 GB, ce que les deux machines gèrent sans problème

  • La plupart de mes documents complexes sont des fichiers Markdown
    Je recommande un petit outil CLI appelé tobi/qmd
    Avant, j’utilisais un workflow basé sur fzf, mais cet outil offre une meilleure recherche floue
    Je ne l’utilise pas pour la recherche dans le code

    • En voyant la présentation, je pensais que ce serait un outil de remplacement de grep écrit en golang, avec peut-être des fonctions comme la pondération des titres Markdown
  • Je déconseille d’utiliser une base de données vectorielle pour la recherche de code
    Les embeddings sont lents et mal adaptés au code
    La combinaison BM25 + trigramme donne de meilleurs résultats et répond plus vite

    • Il est aussi possible de faire de la recherche hybride dans Postgres
      On peut regarder le projet plpgsql_bm25
      Il inclut des exemples de fusion BM25 + pgvector avec Reciprocal Rank Fusion ainsi que des notebooks Jupyter
    • Je suis d’accord. J’ai déjà essayé la recherche hybride dans un outil de remplacement de grep, mais la réindexation continue était pénible
      Avec des modèles non conçus pour le code, la recherche vectorielle génère beaucoup de bruit
      Maintenant, faire tourner gpt-oss 20B en boucle avec ripgrep est bien plus rapide et précis
    • Je me demande si quelqu’un connaît un service simple ou une image Docker qui propose à la fois BM25 et recherche vectorielle
    • J’ai obtenu de bons résultats en l’appliquant aux chemins de fichiers ou aux signatures
      C’est encore meilleur en le fusionnant avec BM25
    • Je serais curieux d’avoir des avis sur l’usage de RAG pour la recherche documentaire
  • J’ai créé local-LLM-with-RAG pour expérimenter le RAG en local
    Je génère les embeddings avec « nomic-embed-text » d’Ollama et j’utilise LanceDB comme base vectorielle
    Récemment, je l’ai mis à jour vers un « agentic RAG », mais c’est peut-être excessif pour de petits projets

    • Je fais quelque chose de similaire. J’utilise lance-context, qui en est une version beaucoup plus simple
    • Merci d’avoir expliqué ce que signifie « RAG ». J’étais perdu en lisant ce fil
  • Je stocke des vecteurs fp16 dans SQLite sous forme de BLOB, puis après filtrage je les charge en mémoire et je calcule la similarité via un produit matrice-vecteur (matvec)
    Avec le multithreading / BLAS / GPU de numpy ou torch, c’est très rapide
    Si cela devient un goulot d’étranglement, je migrerai vers sqlite-vector
    Comme les filtres sur la date ou la localisation réduisent fortement le volume de données, c’est efficace
    Le backend est caché derrière une interface interchangeable

  • 95 % de mes documents sont de petits fichiers Markdown, donc j’utilise SQLite FTS5 avec un index de recherche en texte intégral
    L’index existait déjà, je l’ai donc branché directement à un agent mastra
    Chaque fichier a un court champ de description : après une recherche par mots-clés, si la description correspond, je charge le document complet
    La mise en place a pris environ une heure et cela fonctionne très bien

    • En fait, c’est exactement ça, le RAG (Retrieval-Augmented Generation)
      La recherche par embeddings est plus courante, mais au fond le principe est le même
  • Comme nous connaissons bien Postgres, nous avons commencé avec PGVector
    Plus tard, nous avons constaté qu’un contenu nécessitant des champs semi-structurés dans le prompt correspondait à 100 %
    C’est parce que les opérateurs ont commencé à ajouter des tags à la fois aux entrées et aux documents (environ 50 documents)
    Nous cherchons donc d’abord dans les champs pour insérer le bon fichier dans le prompt, puis nous faisons ensuite une recherche par embeddings
    Au final, dans 85 % des cas, la base vectorielle n’est pas nécessaire

    • La plupart des bases vectorielles donnent l’impression d’être un marteau à la recherche d’un clou
  • J’ai créé llmemory, que j’utilise à la fois en local et dans l’app de mon entreprise
    C’est basé sur PostgreSQL + pgvector, avec BM25 hybride, expansion multi-requêtes et reranking
    Je le rends public pour la première fois, donc il peut encore y avoir quelques bugs
    Je suis assez satisfait des performances