Guide complet de la recherche hybride : combiner BM25 et recherche vectorielle

La recherche hybride combine BM25 et vecteurs, supérieure dans 95 % des cas.

  • RRF fusionne les listes top-k en un classement final.
  • BM25 indispensable pour codes, références et noms propres.
  • Vecteurs essentiels pour synonymes et paraphrases.
  • Pattern courant : conserver le moteur lexical existant.
  • 95 % des cas justifient l’usage hybride vs moteur unique.

Qu’est-ce que la recherche hybride (BM25 + vecteurs) et quand l’utiliser ?

La recherche hybride combine deux moteurs de retrieval distincts en parallèle : un moteur lexical (BM25) qui matche les mots exacts, et un moteur vectoriel (embeddings) qui capture le sens de la requête. Plutôt que de choisir l’un ou l’autre, les deux listes de résultats sont générées simultanément puis fusionnées en une seule réponse classée.

L’intérêt n’est pas de complexifier l’architecture pour le plaisir. Chaque moteur répond à un besoin différent que l’autre ne couvre pas. Une requête utilisateur peut porter une intention expliquée (« je veux résilier mon contrat ») ou contenir des termes précis (« résiliation contrat 19-A/7 »). Selon les estimations d’ingénierie, la recherche hybride s’avère supérieure dans 95% des cas par rapport à l’usage d’un seul moteur.

Définition : deux moteurs, une requête, une réponse fusionnée

Concrètement, le système envoie la même requête à deux index distincts. Le moteur BM25 interroge un index inversé classique (celui d’Elasticsearch, Lucene ou SQLite FTS5), tandis que la base vectorielle cherche les embeddings les plus proches via une similarité cosinus. Les deux listes de top-k sont ensuite combinées par exemple avec la méthode RRF (Reciprocal Rank Fusion) pour produire un classement final unique.

Cette approche n’impose pas de réécrire le stack existant. Dans la pratique, vous pouvez conserver votre moteur lexical actuel et ajouter une base vectorielle dédiée (ChromaDB, Pinecone, Weaviate), un choix qui s’appuie sur les cas d’usage des bases vectorielles. C’est d’ailleurs le pattern le plus courant en production lorsqu’on ne part pas de zéro.

Quand chaque moteur est indispensable

  • BM25 : indispensable pour les codes, références internes, noms propres et acronymes où la moindre variation de caractère change le sens.
  • Vecteurs : indispensables pour les synonymes, paraphrases et questions formulées en langage naturel que BM25 ne rattrapera jamais.
  • Hybride : requis dès que les requêtes réelles contiennent les deux types d’information par exemple un numéro de client associé à une question complexe.

Une recherche purement vectorielle échouera sur des termes exacts comme un nom de produit ou un identifiant : les embeddings récents traitent des expressions proches sémantiquement mais distinctes comme des équivalents. À l’inverse, BM25 ne comprend ni synonyme ni reformulation. Le choix n’est donc pas une question de préférence technique mais de nature des données et des requêtes à servir.

Explication de BM25 (retrieval lexical) et de la recherche vectorielle (embeddings)

rag hybride bm25 et vecteurs

Le fonctionnement de BM25 et ses forces

BM25 est un algorithme de classement lexical dont les racines remontent aux années 80. Il est intégré nativement dans des moteurs comme Elasticsearch, Lucene ou SQLite FTS5. Son principe repose sur deux piliers : la fréquence du terme (TF) et la fréquence inverse de document (IDF). Concrètement, plus un mot apparaît dans un document, plus celui-ci est jugé pertinent, mais cette pertinence est pondérée par la rareté du terme dans l’ensemble du corpus.

Sa grande force réside dans sa précision sur les termes exacts. Pour une requête comme une référence produit, un nom propre ou un acronyme, BM25 ne se trompe pas. Il ne s’agit pas d’interprétation, mais d’une correspondance stricte. C’est d’ailleurs ce qui lui permet de rester extrêmement rapide et mature. Un bon réflexe consiste à configurer correctement BM25 avant d’ajouter de la sémantique : un mauvais réglage donne souvent une fausse impression que la recherche vectorielle est supérieure, alors que le problème vient du lexical.

Le fonctionnement des embeddings et la recherche sémantique

À l’inverse, la recherche vectorielle transforme les textes en vecteurs numériques grâce à des modèles d’embeddings. La similarité entre vecteurs capture le sens, les synonymes et les paraphrases. Elle comprend qu’un utilisateur cherchant « procédure pour résilier » attend des résultats liés à la résiliation, même sans ce mot exact. Cette capacité à comprendre le contexte est sa valeur ajoutée principale.

Cependant, cette puissance a un prix. Les embeddings peuvent halluciner des relations : deux références internes comme X-25 et X-26 peuvent être jugées proches sémantiquement, ce qui fausse les résultats pour des identifiants précis. La performance dépend entièrement du modèle choisi, et la quantification des modèles LLM peut réduire leur empreinte mémoire. Des modèles spécialisés ou fine-tunés sur votre domaine donneront des résultats bien supérieurs aux modèles génériques, notamment pour des corpus techniques ou métiers,.

Fusion des résultats : RRF, score pondéré et learn-to-rank

La fusion RRF et ses avantages

La méthode la plus robuste pour combiner vos deux classements est la Reciprocal Rank Fusion (RRF). Popularisée dès 2009 lors d’une publication SIGIR, cette technique repose sur une idée simple : elle additionne une fonction décroissante du rang de chaque document dans les listes BM25 et vectorielle. Peu importe que vos scores soient exprimés en « Celsius » d’un côté et en « kilomètres » de l’autre, le RRF ne se soucie que de la position des résultats.

Avantage principal : aucune normalisation requise, les scores des deux moteurs peuvent être incomparables.
Égalité de traitement : par défaut, le RRF traite les listes à égalité ; un facteur < 1 favorise discrètement BM25. - Stabilité : la fusion est déterministe, simple à déboguer et à reproduire en test.
Règle pratique : commencez toujours par cette approche avant d’envisager des options plus complexes.

Score pondéré, normalisation et alternatives de fusion

Si vous préférez une somme pondérée des scores, la normalisation est non négociable. Additionner brut de décoffrage un score BM25 et une distance cosinus revient à additionner des unités incompatibles. Appliquez une normalisation min-max ou z-score sur chaque liste avant la fusion. Le réglage du poids alpha commence à 0.5 de chaque côté, puis s’ajuste empiriquement sur votre jeu de test.

Pour les volumes importants, le pattern moderne de l’union + rerank s’impose : on fusionne les top-k parallèles BM25 et embeddings une taille de 20 par liste est un bon départ puis un reranker recoupe et réordonne ce lot de candidats. Enfin, le learn-to-rank (LTR) représente l’approche avancée : un modèle entraîné sur vos clics et conversions apprend à pondérer les signaux lexicaux et sémantiques. C’est la solution idéale lorsque votre trafic justifie l’effort d’infrastructure.

Architecture et implémentation de la recherche hybride en production

Architecture Composants Cas d’usage
Tout-en-un Hybride natif (OpenSearch, Weaviate) Équipe réduite, time-to-market court
Best-of-breed BM25 séparé + base vectorielle Requêtes complexes, contrôle fin
Vector-only Embeddings uniquement Dette technique déguisée en minimalisme

Les trois architectures types (tout-en-un, best-of-breed, vector-only)

Le choix de l’architecture dépend de votre contrainte principale. L’option tout-en-un séduit par sa simplicité : un seul moteur gère l’index inversé et les vecteurs, avec une API hybride prête à l’emploi. L’option best-of-breed sépare les deux moteurs et fusionne les résultats au niveau applicatif elle offre un contrôle maximal sur les poids et les filtres. La troisième option, vector-only, ignore la recherche lexicale : rapide à déployer, elle échoue systématiquement sur les codes internes, les identifiants et les noms propres. Contrairement à une idée répandue, il existe au moins 12 façons de faire de l’hybride, et 11 d’entre elles sont erronées.

Combiner BM25 et vecteurs en Python avec ChromaDB

Pour un prototype efficace, combinez rank_bm25 et ChromaDB en Python. La procédure se déroule en cinq étapes :

  • Instancier l’index inversé : tokenisez et entraînez rank_bm25 sur votre corpus
  • Enrichir avec les embeddings ChromaDB : générez les vecteurs et indexez-les
  • Filtrer par ACL avant fusion : appliquez les autorisations des deux côtés, jamais après
  • Appliquer RRF sur les deux listes : récupérez les top-20 de chaque moteur
  • Régler alpha à 0.5 initialement : ajustez ensuite sur un jeu de test notez que RRF traite les deux listes à égalité par défaut

Pendant que vos deux moteurs interrogent en parallèle, la fusion RRF formalisée lors de la publication SIGIR de 2009 additionne une fonction décroissante du rang. Ce pattern moderne recommande d’élargir la fenêtre de candidats avant de laisser un reranker affiner l’ordre final. L’hybride ainsi construit reste supérieur dans 95% des cas, pour un coût de développement maîtrisé.

Comparaison : BM25 seul vs vecteurs seuls vs recherche hybride

Type de recherche Termes exacts (codes, ID) Synonymes, paraphrases Robustesse et maturité
BM25 seul Excellent Nul Très mature
Vecteurs seuls Faible Excellent Dépend du modèle
Hybride Excellente couverture Excellente couverture Supérieur dans 95% des cas

Le tableau ci-dessus résume l’essentiel : BM25 excelle sur les termes exacts codes internes, identifiants, acronymes tandis que la recherche vectorielle rattrape les synonymes et les questions formulées en langage naturel. Leur combinaison couvre les deux spectres sans compromis.

Un piège courant consiste à comparer un BM25 mal configuré à un bon modèle d’embeddings. Avec un scoring TF-IDF approximatif, on conclut rapidement que « la sémantique gagne ». En réalité, un BM25 correctement réglé reste imbattable sur les requêtes de type « résiliation contrat 19-A/7 », tandis que les vecteurs seuls échouent sur ces mêmes identifiants précis.

Concrètement, la recherche hybride offre une meilleure précision que le vectoriel seul dans la grande majorité des cas mesurés. Elle protège également contre les « hallucinations » des embeddings : deux références proches sémantiquement, comme X-25 et X-26, peuvent être considérées à tort comme identiques par un modèle vectoriel seul. La partie lexicale du système corrige ce biais.

Pour les équipes qui débutent, la stratégie recommandée reste : construire une baseline BM25 propre d’abord, puis ajouter la couche vectorielle et fusionner avec RRF. Cette approche progressive permet de mesurer la valeur ajoutée de chaque composant avant de complexifier l’architecture.

Bonus : ce qui distingue les implémentations performantes en production

Les déploiements efficaces commencent par un jeu de test réaliste : 30 requêtes dont 10 « moches » (codes, fautes de frappe, acronymes). Sans cette base, le réglage du mélange hybride reste un exercice aveugle. L’évaluation doit porter à la fois sur la qualité du top-k (pertinence des candidats) et sur la qualité end-to-end (réponse finale du LLM).

Le piège le plus courant reste l’addition brute de scores BM25 et vectoriels sans normalisation un mélange « Celsius + kilomètres ». La pratique robuste consiste à appliquer les filtres ACL et de langue directement au moment du retrieval (pas après), pour préserver le recall. Enfin, commencez par une baseline BM25 propre avant d’ajouter la composante vectorielle : un dégradé sans cible mesurable ne survit jamais au passage en production.