- Skald a été développé avec pour objectif un système RAG entièrement auto-hébergeable, sans envoyer de données à des tiers
- Les composants d’un RAG se divisent en base de données vectorielle, modèle d’embeddings, LLM, reranker et parseur de documents, avec pour chaque élément des alternatives open source
- La stack locale de base de Skald se compose de Postgres+pgvector, Sentence Transformers, Docling et d’un LLM personnalisé
- D’après les résultats de benchmark, les modèles basés sur le cloud (Voyage+Claude) obtiennent une moyenne de 9,45, tandis que le GPT-OSS 20B entièrement local est évalué entre 7,10 et 8,63
- Cette approche montre qu’il est possible de construire un RAG haute performance tout en préservant la confidentialité des données
Composants d’un RAG et alternatives open source
- Un RAG de base se compose d’une base de données vectorielle, d’un modèle d’embeddings et d’un LLM, auxquels peuvent s’ajouter un reranker et un parseur de documents
- Chaque composant peut être remplacé par une alternative locale au lieu d’un SaaS
- Alternatives présentées dans le tableau d’exemple
- Vector DB: Pinecone, Weaviate Cloud → Qdrant, Weaviate, Postgres+pgvector
- Embeddings: OpenAI, Cohere → Sentence Transformers, BGE, E5
- LLM: GPT, Claude → Llama, Mistral, GPT-OSS
- Reranker: Cohere → BGE Reranker, Sentence Transformers Cross-Encoder
- Document Parsing: Reducto → Docling
- Skald vise une stack entièrement open source, avec chaque composant exécuté en local
Configuration de la stack locale de Skald
- Vector DB: utilisation de Postgres + pgvector
- Facile à intégrer dans l’infrastructure existante, avec une capacité allant jusqu’à plusieurs centaines de milliers de documents
- Vector Embeddings: la valeur par défaut est Sentence Transformers (all-MiniLM-L6-v2)
- Réservé à l’anglais, avec un bon équilibre entre vitesse et performances de recherche
- Le modèle bge-m3 (prise en charge multilingue) a aussi été testé
- LLM: aucun modèle fourni par défaut, l’utilisateur l’exécute lui-même
- Lors des tests, GPT-OSS 20B a été exécuté sur EC2
- Reranker: la valeur par défaut est Sentence Transformers Cross-Encoder ; des modèles multilingues comme bge-reranker-v2-m3 peuvent aussi être utilisés
- Document Parsing: utilisation de Docling, exécuté via docling-serve
Résultats de performance et de déploiement
- Le déploiement d’une instance de production Skald avec l’ensemble de la stack a pris 8 minutes
- Incluant Postgres, les services d’embeddings et de reranking, ainsi que Docling
- Le LLM est exécuté séparément (avec
llama.cpp)
- Le jeu de données de test se compose du contenu du site web de PostHog (environ 2 000 documents) et d’un ensemble maison de questions-réponses
- Paramètres expérimentaux
- Vector search topK=100, Reranking topK=50, Query rewriting=Off
- Le critère d’évaluation est centré sur la précision
Comparaison des résultats de benchmark
- Voyage + Claude (configuration cloud)
- Score moyen de 9,45, avec toutes les réponses correctes
- Voyage + GPT-OSS 20B (local partiel)
- Score moyen de 9,18, globalement correct mais avec quelques informations manquantes
- Entièrement local + GPT-OSS 20B
- Modèles anglais de base (all-MiniLM-L6-v2 + ms-marco-MiniLM-L6-v2) : moyenne de 7,10
- Précis pour les requêtes en anglais, mais plus faible sur les requêtes multilingues, ambiguës et l’agrégation multi-documents
- Modèles multilingues (bge-m3 + mmarco-mMiniLMv2-L12-H384-v1) : moyenne de 8,63
- Requêtes en portugais traitées avec succès, avec encore quelques omissions lors de l’agrégation multi-documents
- La principale limite reste l’intégration d’informations dispersées sur plusieurs documents
- Les modèles cloud compensent cela par leurs hautes performances, mais un environnement local demande des techniques supplémentaires
Prochaines étapes
- Skald prévoit d’améliorer les performances du RAG local et de publier des benchmarks de modèles open source
- L’objectif est de proposer une solution pour les entreprises devant exploiter des outils d’IA dans des environnements air-gap
- Les personnes intéressées peuvent collaborer via GitHub(skaldlabs/skald) ou la communauté Slack
7 commentaires
Qui a bien pu lancer cette idée saugrenue selon laquelle il faut une base de données vectorielle pour faire du RAG…
Que ce soit une base de données vectorielle ou autre, au fond il suffit simplement d’implémenter la recherche...
Gemini :
Oui, dans le cadre du RAG (Retrieval-Augmented Generation), l’utilisation d’une base de données vectorielle (Vector Database) repose sur des fondements conceptuels établis dès la première publication des travaux associés en 2020.
Le RAG combine essentiellement la recherche (Retrieval) et la génération (Generation), et, dans cette étape de recherche, les embeddings vectoriels ainsi que les bases de données vectorielles capables de les stocker et de les interroger efficacement jouent un rôle indispensable.
💡 Point de départ du RAG et des bases vectorielles
L’idée selon laquelle une base vectorielle est nécessaire au RAG provient des principaux travaux et concepts suivants.
Les raisons fondamentales pour lesquelles les bases de données vectorielles sont devenues un élément essentiel du RAG sont les suivantes.
Résumé : pourquoi une base vectorielle est nécessaire
Pour permettre à un LLM d’accéder à des connaissances récentes ou spécifiques à un domaine qu’il n’a pas apprises, il faut rechercher l’information non pas par simple correspondance de mots-clés (recherche traditionnelle), mais sur la base de la similarité sémantique. La base vectorielle est la technologie clé qui s’est naturellement intégrée au framework RAG afin d’exécuter efficacement cette recherche fondée sur la similarité sémantique.
En réalité, ce qu’il faut pour le RAG, c’est une fonction de recherche, et le fait de faire des embeddings en vecteurs denses, de les pousser dans une vectorDB puis d’effectuer une recherche par similarité cosinus n’est qu’une des nombreuses façons d’implémenter un moteur de recherche… Il n’y a pas spécialement de raison de ne pas utiliser de vectorDB, mais si on se demande si c’est vraiment indispensable, je reste un peu perplexe, parce qu’il existe depuis longtemps beaucoup d’algorithmes de moteurs de recherche qui fonctionnent très bien.
C’est bon marché et la plupart des LLM de production l’utilisent.
À ce compte-là, pour un serveur web aussi, si on ajoute des fonctions d’infrastructure, tout peut se faire entièrement sur disque, donc pas besoin de DBMS non plus lol
Il est bien exact qu’une base de données est nécessaire pour effectuer une forme de recherche de similarité/sémantique en utilisant comme clé la valeur d’embedding (vecteur) de la requête utilisateur, et puisque la clé est sous forme de vecteur, une base de données vectorielle est également appropriée.
Avis Hacker News
Je voudrais donner un conseil quand on construit ce type de système : ne vous focalisez pas trop sur les bases de données vectorielles ou les embeddings
La recherche plein texte ou des outils comme
grep/rgsont bien plus rapides et moins coûteux, et il n’y a pas besoin de maintenir un indexSi vous donnez un outil de recherche à un bon LLM, il peut générer lui-même des requêtes comme « dog OR canine » et les améliorer de façon itérative
En plus, cela évite d’avoir à résoudre le problème du chunking
À voir sur Search Sensei
Au premier chargement, elle télécharge environ 50 Mo de poids de modèle et onnx runtime, mais ensuite tout fonctionne de manière fluide
Par exemple, BM25 ne comprend pas que « j lo » et « jlo » désignent Jennifer Lopez, tandis que la recherche par embeddings gère bien ce type de fautes de frappe ou d’alias
La recherche porte sur 1 000 articles de presse publiés entre 2016 et 2024
Mais c’est dommage que les performances de BM25 seul n’aient pas été publiées
Dans mes petits tests, il arrivait que les embeddings ratent des pages contenant exactement les mots de la requête — au final, Ctrl+F gagnait
La recherche lexicale a une précision élevée mais un rappel faible, et la recherche sémantique se situe à l’autre extrémité
J’ai eu l’impression qu’un opérateur « NOT » serait utile. J’aimerais aussi en apprendre davantage sur le RAG
J’ai vu certains outils de type agent générer automatiquement ce genre de requêtes, mais je ne sais pas si c’est induit par le prompt ou si c’est leur comportement par défaut
L’une des raisons possibles des mauvaises performances est un manque de semantic chunking
Si on embedde un document entier, plusieurs concepts se mélangent et la précision baisse
Il faut découper en unités sémantiques avec un outil comme Spacy, puis ajouter pour chaque chunk le contexte qu’il occupe dans le document avant de l’embedder
L’approche contextual retrieval d’Anthropic a été très efficace dans les systèmes RAG
Il suffit de générer le contexte avec le modèle GPT OSS 20B
Il semble qu’il y ait eu un malentendu, car les tests portaient sur des questions nécessitant d’agréger le contexte de plusieurs documents
Je me demande pourquoi on suppose que la recherche sémantique est supérieure à la recherche lexicale
En 2023, quand je l’ai comparée à Tantivy (BM25), la différence de résultats était minime
Même s’il y a un léger gain de rappel, je ne sais pas si cela vaut la peine de construire une architecture aussi complexe
Dans les tests développeurs, on atteignait 90 % de rappel, mais dans les tests avec de vrais utilisateurs, on tombait à environ 30 %
Les utilisateurs ne connaissent pas les termes exacts des documents, donc la recherche lexicale seule ne suffisait pas
On peut ajouter un agent, mais la latence augmente et la satisfaction utilisateur baisse
Chez Wanderfugl, la recherche sémantique retrouve bien des passages ayant un faible score BM25
Au final, un classement hybride est peut-être la bonne réponse
En fin de compte, cela dépend du cas d’usage
Je cherche un outil open source permettant d’interroger en local et hors ligne toutes mes données : e-mails, Slack, GDrive, code, wiki, etc.
Je préférerais éviter de tout construire ou personnaliser moi-même, et j’aimerais de bons réglages par défaut ainsi que des recommandations de modèles
Lien GitHub
Il prend en charge le CRUD par défaut, et si l’on active la recherche vectorielle, il embedde les documents ou les notes
Il prend en charge Ollama et OpenAI comme fournisseurs d’embeddings
Le serveur MCP fournit à la fois une recherche sémantique + BM25 (qdrant fusion) et génère des réponses via l’échantillonnage MCP
Le serveur ne génère pas lui-même les réponses et peut s’intégrer avec n’importe quel client LLM/MCP
Ce pattern MCP sampling/RAG est très puissant, et il est probable qu’une version open source généralisée apparaisse pour d’autres sources de données
L’outil que nous utilisons est haiku.rag
Il fournit un code Python convivial pour les développeurs, une architecture basée sur pydantic-ai, ainsi que des benchmarks et des fonctions avancées de citation
Il prend en charge des agents de recherche approfondie et constitue un véritable projet open source maintenu sur le long terme
Nous utilisons Sentence Transformers (all-MiniLM-L6-v2) comme modèle d’embeddings par défaut, mais nous avons réalisé qu’il est réservé à l’anglais, ce qui peut poser problème pour construire un RAG en allemand
Je me demande ce que valent les modèles non anglophones
Regardez les entrées RTEB Multilingual ou RTEB German dans la section « Retrieval »
Pour un self-hosting sur CPU, mieux vaut filtrer sur des modèles de moins de 100 M de paramètres
Mais l’allemand dispose de relativement nombreuses données d’entraînement, et il existe assez de modèles multilingues
En particulier, la plupart des modèles commerciaux via API sont multilingues
Vous pouvez consulter l’article correspondant via ce lien Springer
À l’époque de GPT-4 (contexte 8K), j’avais écrit un script qui découpait un livre entier en chunks et les envoyait à GPT-4 pour retrouver les passages pertinents
À l’époque, une seule recherche coûtait environ 1 dollar, mais aujourd’hui c’est bien moins cher
L’article d’Anthropic sur le contextual retrieval dit aussi que si tout le document tient dans le contexte, mieux vaut simplement l’y mettre au lieu d’utiliser du RAG
Mais quand le contexte s’allonge, la qualité baisse, et le coût comme la vitesse deviennent aussi un problème
Aujourd’hui, il est possible de mettre un livre entier dans le contexte pour de l’ordre du centime
La partie la plus difficile du RAG, c’est le parsing des documents
Tant qu’on ne traite que du texte, ça va, mais dès qu’il y a des tableaux, des tableaux sur plusieurs pages, des graphiques, une table des matières ou des notes de bas de page, la précision s’effondre
Pour améliorer cela, il existe des approches où le LLM résume le contenu et génère des questions avant de stocker le tout dans une base vectorielle, comme le pattern RAPTOR
Mais une pipeline RAG générique qui fonctionne dans tous les cas reste un défi difficile
Je me demande aussi si les bases vectorielles gèrent mieux de longs groupes de texte ou le format tabulaire
Cette nouvelle perspective sur l’application de la recherche plein texte au RAG m’a semblé intéressante
J’ai trouvé particulièrement éclairantes les remarques sur les boucles d’outils de type agent et la gestion de la recherche floue (fuzzy search)
Je me demande s’il existe des jeux de données d’évaluation standardisés pour ce type de système
Ce serait bien d’avoir un benchmark avec un ensemble de documents et de questions, où un document ou chunk donné devrait ressortir comme résultat le plus pertinent