La génération augmentée par récupération (RAG) a transformé notre interaction avec les grands modèles de langage (LLM) en les ancrant dans des connaissances externes. Cependant, la qualité de la sortie dépend fortement de la qualité du contexte récupéré. Bien que la recherche de similarité vectorielle soit efficace pour trouver des documents largement pertinents, elle a souvent du mal à assurer un alignement sémantique précis, ce qui entraîne de « faux positifs » susceptibles de désorienter le LLM. C'est ici que le re-classement intervient.
Pourquoi le re-classement est essentiel
Les algorithmes de recherche vectorielle standard utilisent généralement des bi-encodeurs, qui encodent la requête et le document indépendamment. Bien que cela soit rapide et évolutif, cela manque de la capacité d'interagir entre les jetons de la requête et du document pour capturer des relations nuancées. Le re-classement applique un processus plus coûteux en calcul, impliquant généralement des cross-encodeurs, aux K meilleurs candidats retournés par la recherche initiale. En analysant l'interaction entre la requête et chaque document, le re-classeur attribue un nouveau score de pertinence plus précis, promouvant les fragments les plus pertinents en tête de liste.
Cross-encodeurs vs. Bi-encodeurs
Comprendre la différence est crucial. Un bi-encodeur crée des embeddings séparés pour la requête et le document, calculant la similarité cosinus entre eux. Un cross-encodeur, en revanche, prend la requête et le document comme une seule entrée concaténée et les traite simultanément à travers le modèle transformeur. Cela permet au modèle de comprendre les dépendances contextuelles perdues lors de l'encodage indépendant. Bien que les cross-encodeurs soient plus lents, ils sont nettement plus précis, ce qui les rend idéaux pour l'étape de re-classement où vous n'avez besoin de traiter qu'un petit sous-ensemble de documents (par exemple, les 20 premiers sur 1000).
Mise en œuvre du re-classement en Python
L'intégration d'un re-classeur dans votre pipeline RAG est simple à l'aide de frameworks IA modernes. Ci-dessous, un exemple utilisant la bibliothèque `sentence-transformers` avec un modèle cross-encoder, un choix populaire pour son équilibre entre performance et facilité d'utilisation.
from sentence_transformers import CrossEncoder
from typing import List, Tuple
class ReRanker:
def __init__(self, model_name: str = "cross-encoder/ms-marco-MiniLM-L-6-v2"):
self.model = CrossEncoder(model_name)
def rerank(self, query: str, documents: List[str], top_k: int = 5) -> List[Tuple[int, float]]:
"""
Re-classe une liste de documents en fonction de leur pertinence par rapport à la requête.
Args:
query: La chaîne de la requête de recherche.
documents: Une liste de chaînes de documents à re-classer.
top_k: Nombre de meilleurs résultats à retourner.
Returns:
Une liste de tuples contenant (index_document, score).
"""
# Préparer les paires d'entrée (requête, doc)
inputs = [(query, doc) for doc in documents]
# Évaluer les paires
scores = self.model.predict(inputs)
# Obtenir les indices des K meilleurs scores
top_indices = sorted(range(len(scores)), key=lambda i: scores[i], reverse=True)[:top_k]
# Retourner les indices originaux et les scores
return [(idx, scores[idx]) for idx in top_indices]
# Exemple d'utilisation
query = "Quels sont les bienfaits pour la santé du gingembre ?"
documents = [
"Le gingembre a des propriétés anti-inflammatoires et peut aider contre les nausées.",
"Il fait beau aujourd'hui à Londres.",
"Le thé au gingembre est un remède populaire pour les rhumes et les problèmes de digestion.",
"Python est un langage de programmation populaire.",
"Les biscuits à la cannelle sont faits avec des épices, y compris du gingembre."
]
reranker = ReRanker()
results = reranker.rerank(query, documents, top_k=3)
for idx, score in results:
print(f"Score: {score:.4f} | Doc: {documents[idx]}")
Bonnes pratiques et considérations
- Compromis sur la latence : Limitez toujours le nombre de candidats passés au re-classeur. Le re-classement de 1000 documents augmentera considérablement la latence. Le re-classement des 20 à 50 meilleurs résultats de la recherche vectorielle est un bon compromis.
- Sélection du modèle : Choisissez un re-classeur entraîné sur des données similaires à votre domaine. Les modèles à usage général comme
ms-marco-MiniLMfonctionnent bien pour les connaissances générales, mais les modèles spécifiques au domaine (par exemple, pour les textes juridiques ou médicaux) peuvent donner de meilleurs résultats. - Intégration : Utilisez les scores re-classés pour ajuster dynamiquement le nombre de fragments passés au LLM. Si le meilleur score est très faible, envisagez de revenir à une recherche plus large ou de ne pas effectuer de récupération du tout.
Conclusion
Le re-classement est un composant critique dans la construction de systèmes RAG de haute qualité. En ajoutant cette couche de raffinement, vous pouvez réduire considérablement les hallucinations et améliorer la précision factuelle des sorties de votre LLM. À mesure que les modèles cross-encodeurs continuent d'améliorer leur vitesse et leur efficacité, l'écart entre la recherche approximative rapide et le scoring de pertinence précis se réduira, rendant le re-classement un outil de plus en plus accessible et essentiel dans la boîte à outils de l'ingénieur IA.