GraphRAG et Hybrid Search : BM25 + Vecteur
Le RAG vectoriel pur a ses limites. Hybrid search (BM25 + embedding) et GraphRAG résolvent les cas complexes — apprenez à les implémenter avec Agno et LanceDB.
Les Limites du RAG Vectoriel Pur
Le RAG vectoriel classique fonctionne très bien pour les questions directes où la réponse se trouve dans un seul chunk. Mais il échoue sur deux catégories de problèmes fréquents en production.
Problème 1 : Le "Needle in a Haystack"
Imaginez 10 000 documents techniques. L'utilisateur demande le numéro de référence exact d'une pièce : "SKU-78421-B". La recherche vectorielle cherche la proximité sémantique : mais un code produit n'a pas de sens sémantique. Il s'agit d'une correspondance exacte de chaîne de caractères.
Question : "Quel est le prix du composant SKU-78421-B ?"
Recherche vectorielle : trouve des documents sur "composants électroniques",
"références catalogue", "prix unitaires" : mais pas
nécessairement le document contenant exactement SKU-78421-B.
Recherche BM25 (keyword) : trouve EXACTEMENT les documents contenant "SKU-78421-B".
Problème 2 : Le Multihop Reasoning
L'utilisateur pose une question qui nécessite de combiner des informations provenant de plusieurs documents :
Question : "Quel est le responsable du projet qui utilise la technologie
décrite dans le brevet déposé en 2023 ?"
Pour répondre, il faut :
Doc A → Le brevet 2023 décrit la technologie X
Doc B → La technologie X est utilisée dans le projet Alpha
Doc C → Le responsable du projet Alpha est Marie Dupont.
Le RAG vectoriel récupère des chunks individuels.
Il ne reconstitue pas la chaîne de raisonnement A → B → C.
Ces deux problèmes représentent environ 20-30% des questions réelles en entreprise. Si votre RAG échoue sur ces cas, vos utilisateurs auront une mauvaise expérience sur précisément les questions les plus complexes : celles où l'IA devrait apporter le plus de valeur.
Hybrid Search : BM25 + Vectoriel
Pourquoi les Deux Sont Complémentaires
| Dimension | Recherche Vectorielle | BM25 (Keyword) |
|---|---|---|
| Force principale | Compréhension du sens | Correspondance exacte |
| Synonymes | Excellent | Échoue |
| Codes / références | Échoue | Excellent |
| Noms propres | Médiocre | Excellent |
| Reformulations | Excellent | Échoue |
| Termes techniques rares | Médiocre | Excellent |
La recherche hybride combine les scores des deux approches pour obtenir le meilleur des deux mondes :
Score hybride = α × score_vectoriel + (1-α) × score_BM25
Où α est un paramètre de pondération (souvent 0.5 en point de départ).
Fonctionnement de BM25
BM25 (Best Match 25) est une variante améliorée de TF-IDF. Il mesure la pertinence d'un document pour une requête en comptant les occurrences des mots de la requête dans le document, avec une normalisation par la longueur du document.
Score BM25(doc, query) = Σ IDF(term) × (TF(term, doc) × (k1 + 1)) / (TF(term, doc) + k1 × (1 - b + b × |doc| / avgdl))
Où :
- IDF = importance du terme (rare = plus important)
- TF = fréquence du terme dans le document
- k1, b = paramètres de saturation et normalisation
- avgdl = longueur moyenne des documents
Reranking : Raffiner les Résultats
Même avec la recherche hybride, les 20 premiers résultats peuvent contenir du bruit. Le reranking est une étape post-retrieval qui réordonne les résultats par pertinence réelle.
Pipeline avec Reranking
Types de Rerankers
Cross-encoders : modèles qui analysent la paire (question, document) ensemble pour scorer la pertinence. Plus précis mais plus lents.
Cohere Rerank : API de reranking de Cohere, très performante sur le multilingue. Modèle rerank-multilingual-v3.0 pour le français.
BGE Reranker : modèle open-source de BAAI, utilisable localement sans coût par token.
Micro-exercice : Hybrid Search avec Agno + LanceDB
Installation
pip install agno openai lancedb tantivy cohere pypdf
# tantivy est le moteur BM25 utilisé par LanceDB
Code Complet avec Hybrid Search et Reranking
# hybrid_search.py
import os
from agno.agent import Agent
from agno.knowledge.embedder.openai import OpenAIEmbedder
from agno.knowledge.knowledge import Knowledge
from agno.knowledge.reranker.cohere import CohereReranker
from agno.models.openai import OpenAIResponses
from agno.vectordb.lancedb import LanceDb, SearchType
os.environ["OPENAI_API_KEY"] = "sk-..."
os.environ["COHERE_API_KEY"] = "..."
knowledge = Knowledge(
vector_db=LanceDb(
uri="tmp/lancedb",
table_name="docs_hybrid",
search_type=SearchType.hybrid, # BM25 + vectoriel
embedder=OpenAIEmbedder(id="text-embedding-3-small"),
reranker=CohereReranker(
model="rerank-multilingual-v3.0", # Excellent pour le français
top_n=5, # Garder les 5 meilleurs après reranking
),
),
)
# Charger des documents
knowledge.insert(
url="https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf"
)
agent = Agent(
model=OpenAIResponses(id="gpt-4o"),
knowledge=knowledge,
instructions=[
"Utilise ta base de connaissances pour répondre.",
"Sois précis et cite les informations clés.",
],
markdown=True,
)
# Test avec une question nécessitant la précision keyword
agent.print_response(
"Quels plats utilisent du lait de coco comme ingrédient principal ?",
stream=True,
)
Comparer les SearchTypes
from agno.vectordb.lancedb import LanceDb, SearchType
from agno.knowledge.knowledge import Knowledge
from agno.knowledge.embedder.openai import OpenAIEmbedder
EMBEDDER = OpenAIEmbedder(id="text-embedding-3-small")
PDF_URL = "https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf"
# Test des 3 modes
for search_type, label in [
(SearchType.vector, "Vectoriel pur"),
(SearchType.keyword, "BM25 pur"),
(SearchType.hybrid, "Hybride"),
]:
knowledge = Knowledge(
vector_db=LanceDb(
uri="tmp/lancedb",
table_name=f"docs_{search_type.value}",
search_type=search_type,
embedder=EMBEDDER,
),
)
knowledge.insert(url=PDF_URL)
results = knowledge.search("Tom Yum", num_documents=3)
print(f"\n=== {label} ===")
for doc in results:
print(f" → {doc.content[:150]}...")
Utilisez systématiquement SearchType.hybrid dans vos projets Agno. LanceDB + tantivy gèrent automatiquement la fusion BM25 + vectoriel. L'ajout du CohereReranker améliore encore la précision de 10-20% sur les cas difficiles.
GraphRAG : Représenter les Documents comme un Graphe
Concept
Le GraphRAG (Graph Retrieval Augmented Generation) représente les documents non plus comme une collection de chunks indépendants, mais comme un graphe de connaissances où les entités sont des nœuds et leurs relations sont des arêtes.
Document A : "Marie dirige le projet Alpha qui utilise TensorFlow."
Document B : "TensorFlow est un framework créé par Google."
Document C : "Google a investi 100M€ dans DeepMind en 2023."
Graphe :
Marie ──dirige──▶ Projet Alpha
Projet Alpha ──utilise──▶ TensorFlow
TensorFlow ──créé par──▶ Google
Google ──a investi dans──▶ DeepMind
Avec un graphe, la question "Qui dirige le projet qui utilise le framework de l'entreprise qui a investi dans DeepMind ?" peut être résolue en traversant le graphe : DeepMind ← Google → TensorFlow → Projet Alpha → Marie.
Microsoft GraphRAG
Microsoft a publié en 2024 le framework GraphRAG open-source. Il fonctionne en deux phases :
- Indexation : un LLM analyse les documents pour extraire les entités (personnes, lieux, concepts) et leurs relations, puis construit un graphe.
- Requête : deux modes de recherche : local (sous-graphe pertinent) et global (résumés de communautés du graphe entier).
pip install graphrag
# Initialiser un projet GraphRAG
python -m graphrag init --root ./my-graphrag
# Indexer les documents
python -m graphrag index --root ./my-graphrag
# Requête locale (précise, rapide)
python -m graphrag query --root ./my-graphrag --method local "Qui dirige le projet Alpha ?"
# Requête globale (vue d'ensemble, lente)
python -m graphrag query --root ./my-graphrag --method global "Quels sont les thèmes principaux ?"
LightRAG : Une Alternative Légère
LightRAG (2024) propose une approche similaire mais plus légère et plus rapide à indexer :
from lightrag import LightRAG, QueryParam
from lightrag.llm.openai import gpt_4o_mini_complete
rag = LightRAG(
working_dir="./lightrag_data",
llm_model_func=gpt_4o_mini_complete,
)
# Indexer
with open("documents.txt") as f:
rag.insert(f.read())
# Requêtes en différents modes
print(rag.query("Qui est responsable du projet Alpha ?", param=QueryParam(mode="naive")))
print(rag.query("Qui est responsable du projet Alpha ?", param=QueryParam(mode="local")))
print(rag.query("Qui est responsable du projet Alpha ?", param=QueryParam(mode="global")))
print(rag.query("Qui est responsable du projet Alpha ?", param=QueryParam(mode="hybrid")))
L'indexation GraphRAG est coûteuse. Pour 100 documents, Microsoft GraphRAG peut consommer 50-100 dollars de tokens LLM. LightRAG est significativement moins cher. Évaluez le ROI avant de l'adopter.
Tableau Comparatif : RAG Classique vs Hybrid vs GraphRAG
| Dimension | RAG Classique | Hybrid Search | GraphRAG |
|---|---|---|---|
| Questions simples | Excellent | Excellent | Excellent |
| Correspondances exactes | Médiocre | Excellent | Excellent |
| Multihop reasoning | Médiocre | Médiocre | Excellent |
| Vue d'ensemble | Médiocre | Médiocre | Excellent |
| Coût d'indexation | Faible | Faible | Très élevé |
| Latence de requête | Faible | Faible | Élevée |
| Complexité | Simple | Faible | Élevée |
| Mises à jour | Rapide | Rapide | Lente (re-indexation) |
| Cas d'usage | 80% des cas | 90% des cas | Corpus stables complexes |
Quand Utiliser Quoi
Stratégie recommandée : commencez avec le hybrid search (SearchType.hybrid + CohereReranker). Cela résout 90% des cas de manière simple. Envisagez GraphRAG uniquement si vous avez un corpus stable et des besoins de raisonnement multi-documents avérés : le coût d'indexation et la complexité opérationnelle doivent être justifiés par le gain de qualité mesuré sur votre golden dataset.
Specialiste IA — Master Intelligence Artificielle
Diplome d'un Master en Intelligence Artificielle, je travaille au quotidien sur des projets IA en entreprise. J'ai cree IwanttolearnAI pour rendre l'apprentissage de l'IA accessible a tous, gratuitement.
Continuer a apprendre
Stratégies de Chunking et Indexation pour le RAG
La qualité d'un RAG repose à 80% sur le chunking. Découvrez comment découper vos documents pour maximiser la pertinence des réponses de votre agent IA.
Vector Databases : pgvector vs Pinecone vs Weaviate : Comparatif Complet
pgvector, Pinecone, Weaviate, LanceDB, Qdrant… comment choisir sa vector database ? Comparatif complet avec intégration Agno et cas pratique Supabase.
Évaluer un Système RAG avec Ragas
Comment savoir si votre RAG fonctionne vraiment ? Découvrez Ragas, le framework d'évaluation standard, et apprenez à mesurer faithfulness, relevancy et recall.