Dans le paysage en évolution rapide de la Génération Augmentée par la Récupération (RAG), la qualité de l'étape de récupération est le déterminant le plus critique des performances du système. Un piège courant pour les développeurs est de supposer que la requête brute de l'utilisateur correspond parfaitement à la terminologie utilisée dans votre base de connaissances. Cependant, les requêtes du monde réel sont souvent ambiguës, concises ou manquent de jargon spécifique au domaine. C'est ici que l'
Expansion de Requête entre en scène — non pas comme un luxe, mais comme une nécessité pour les architectures RAG à haute précision.
L'expansion de requête est le processus consistant à enrichir la requête originale de l'utilisateur avec des termes supplémentaires, des synonymes ou des concepts associés avant d'effectuer la recherche vectorielle ou la correspondance de mots-clés. En élargissant la portée sémantique de la recherche, nous atténuons le risque d'« échec de rappel » (recall failure), où des documents pertinents sont manqués simplement parce qu'ils ne partageaient pas de correspondances lexicales exactes avec l'invite.
Les mécanismes de l'expansion de requête
Une expansion de requête efficace opère à trois niveaux principaux, chacun offrant des compromis différents entre le coût computationnel et la qualité de la récupération.
1. Expansion par synonymes lexicaux
Cette approche utilise des dictionnaires statiques ou des thésaurus pour remplacer ou ajouter des synonymes aux termes clés. Par exemple, si un utilisateur demande des informations sur les « autocars », l'expansion de la requête pour inclure « automobiles », « véhicules » et « voitures » garantit que les documents utilisant une terminologie standard sont toujours récupérés.
2. Enrichissement sémantique via des LLM
Les pipelines RAG modernes exploitent les grands modèles de langage (LLM) pour comprendre l'intention derrière une requête. Au lieu de simplement échanger des mots, un LLM peut générer un ensemble de questions connexes ou reformuler l'invite pour la rendre plus spécifique. Cela est particulièrement puissant pour les concepts abstraits. Si un utilisateur demande : « Comment réparer un PC lent ? », un LLM pourrait étendre cela pour inclure des termes comme « optimiser le registre », « vider les fichiers temporaires », « défragmenter le disque dur » et « vérifier l'utilisation de la RAM ».
3. Décomposition
Pour les questions complexes à plusieurs parties, l'expansion de requête peut impliquer la division de la requête unique en plusieurs sous-requêtes. Chaque sous-requête est ensuite envoyée à la base de données vectorielle indépendamment, et les résultats sont fusionnés. Cela permet au système de récupérer des informations distinctes qui pourraient être dispersées dans différents documents.
Stratégie de mise en œuvre avec LangChain
La mise en œuvre de l'expansion de requête en Python est simplifiée à l'aide de bibliothèques telles que LangChain. Voici un exemple pratique utilisant
SynonymQueryExpander et un réécrivage conceptuel basé sur un LLM.
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import EmbeddingsFilter
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.llms import OpenAI
# Supposons que vous ayez déjà initialisé votre magasin vectoriel 'vectorstore'
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_texts(["Texte de votre base de connaissances ici"], embeddings)
# Créer un retrieveur
base_retriever = vectorstore.as_retriever()
# Appliquer la compression contextuelle pour simuler une forme d'expansion/filtrage
# Dans des configurations avancées, vous utiliseriez une classe QueryExpander spécifique ici
# qui appelle un LLM pour réécrire la requête avant la récupération.
from langchain.retrievers import BM25Retriever, EnsembleRetriever
# L'ensemble de vectoriels (sémantique) et de BM25 (mots-clés) agit souvent comme une expansion implicite
bm25_retriever = BM25Retriever.from_documents(vos_documents)
ensemble_retriever = EnsembleRetriever(retrievers=[base_retriever, bm25_retriever], weights=[0.7, 0.3])
Dans un environnement de production, vous créeriez généralement une classe personnalisée
BaseQueryExpander qui prend la requête d'entrée, la transmet à un LLM avec une invite lui demandant de « Générer 5 mots-clés associés et une version plus spécifique de cette requête », puis concatène ces termes à la chaîne de recherche originale.
Considérations pratiques et pièges à éviter
Bien que l'expansion de requête améliore considérablement le rappel (recall), elle introduit de nouveaux défis. Le risque principal est la
dégradation de la précision. En ajoutant trop de termes faiblement liés, vous risquez de récupérer des documents bruyants ou non pertinents qui diluent la réponse finale générée par le LLM. Pour contrer cela, il est crucial de mettre en œuvre des étapes de réordonnancement robustes après la récupération. Des modèles comme Cohere Reranker ou les Cross-Encoders peuvent évaluer la pertinence des résultats étendus, garantissant que seuls les documents les plus pertinents sont transmis à la phase de génération.
De plus, considérez les implications en matière de latence. Chaque requête supplémentaire ou étape d'expansion ajoute des millisecondes au temps de réponse total. Pour les applications sensibles à la latence, une expansion lexicale légère peut être préférée à une réécriture lourde basée sur des LLM.
Conclusion
L'expansion de requête est un levier puissant dans la boîte à outils du développeur RAG. En allant au-delà de la simple correspondance de mots-clés et en adoptant l'enrichissement sémantique, nous pouvons construire des systèmes qui comprennent véritablement l'intention de l'utilisateur. Qu'il s'agisse de simples dictionnaires de synonymes ou d'une décomposition complexe pilotée par des LLM, l'objectif reste le même : combler l'écart entre la manière dont les utilisateurs posent des questions et la manière dont les informations sont stockées. Alors que vous affinez votre pipeline RAG, privilégiez les stratégies d'expansion qui équilibrent rappel et précision, garantissant que votre assistant IA fournisse des réponses précises et conscientes du contexte à chaque fois.