Reranking : Améliorer la Précision de Récupération
Cross-encoders, reranking basé sur LLM et stratégies de reranking pour optimiser le contexte récupéré et améliorer les réponses RAG.
TL;DR
- Reranking = Deuxième passage de notation des docs récupérés pour une meilleure précision
- Cross-encoders apportent 10-25% d'amélioration de précision par rapport à la récupération pure
- API Cohere Rerank : Option la plus simple (1 $/1000 requêtes)
- Auto-hébergé : cross-encoders ms-marco (gratuit, bonne qualité)
- Comparez les rerankers sur vos données avec Ailog
Le Problème du Reranking
La récupération initiale (recherche vectorielle, BM25) jette un large filet pour rappeler les documents potentiellement pertinents. Cependant :
- Faux positifs : Certains chunks récupérés ne sont pas réellement pertinents
- Qualité de classement : Les chunks les plus pertinents peuvent ne pas être classés en premier
- Pertinence spécifique à la requête : Le classement initial ne tient pas compte des nuances de la requête
Solution : Reclasser les candidats récupérés avec un modèle plus sophistiqué.
Récupération en Deux Étapes
Requête → [Étape 1: Récupération] → 100 candidats
→ [Étape 2: Reranking] → 10 meilleurs résultats
→ [Étape 3: Génération] → Réponse
Pourquoi deux étapes ?
- Récupération : Rapide, s'adapte à des millions/milliards de documents
- Reranking : Coûteux mais précis, seulement sur un petit ensemble de candidats
- Le meilleur des deux : Vitesse + Qualité
Approches de Reranking
Modèles Cross-Encoder
Contrairement aux bi-encoders (embedder requête et document séparément), les cross-encoders traitent la requête et le document ensemble.
Bi-encoder (Récupération)
DEVELOPERpythonquery_emb = embed(query) # [768] doc_emb = embed(document) # [768] score = cosine(query_emb, doc_emb) # Similarity
Cross-encoder (Reranking)
DEVELOPERpython# Traiter ensemble input = f"[CLS] {query} [SEP] {document} [SEP]" score = model(input) # Score de pertinence direct
Pourquoi les cross-encoders sont meilleurs :
- Attention entre les tokens de requête et de document
- Capture les interactions au niveau des mots
- Notation de pertinence plus précise
Pourquoi ne pas les utiliser pour la récupération :
- Doit noter chaque paire requête-document (O(n))
- Trop lent pour de grandes collections
- Pas d'embeddings pré-calculés
Modèles Cross-Encoder Populaires
ms-marco-MiniLM-L6-v2
DEVELOPERpythonfrom sentence_transformers import CrossEncoder model = CrossEncoder('cross-encoder/ms-marco-MiniLM-L6-v2') # Score query-document pairs scores = model.predict([ (query, doc1), (query, doc2), (query, doc3) ]) # Rerank by score ranked_indices = np.argsort(scores)[::-1]
Caractéristiques :
- Taille : 80MB
- Vitesse : ~50ms par batch
- Qualité : Bonne pour l'anglais
- Entraînement : Entraîné sur MS MARCO
ms-marco-TinyBERT-L2-v2
- Encore plus petit/rapide
- Légère baisse de qualité
- Bon pour les applications critiques en latence
mmarco-mMiniLMv2-L12-H384-v1
- Support multilingue
- Performance similaire aux modèles anglais
- Supporte plus de 100 langues
Implémentation
DEVELOPERpythonclass RerankedRetriever: def __init__(self, base_retriever, reranker_model): self.retriever = base_retriever self.reranker = CrossEncoder(reranker_model) def retrieve(self, query, k=5, rerank_top_n=20): # Stage 1: Retrieve more candidates candidates = self.retriever.retrieve(query, k=rerank_top_n) # Stage 2: Rerank pairs = [(query, doc['content']) for doc in candidates] scores = self.reranker.predict(pairs) # Sort by reranker scores ranked_indices = np.argsort(scores)[::-1] reranked_docs = [candidates[i] for i in ranked_indices] # Return top-k return reranked_docs[:k]
Reranking Basé sur LLM
Utiliser un LLM pour juger la pertinence.
Pertinence Binaire
Demander au LLM si le document est pertinent.
DEVELOPERpythondef llm_rerank_binary(query, documents, llm): relevant_docs = [] for doc in documents: prompt = f"""Ce document est-il pertinent pour la requête ? Requête: {query} Document: {doc} Réponds seulement 'yes' ou 'no'.""" response = llm.generate(prompt, max_tokens=5) if 'yes' in response.lower(): relevant_docs.append(doc) return relevant_docs
Notation de la Pertinence
Obtenir des scores numériques de pertinence.
DEVELOPERpythondef llm_rerank_score(query, documents, llm): scored_docs = [] for doc in documents: prompt = f"""Note la pertinence de ce document pour la requête sur une échelle de 1-10. Requête: {query} Document: {doc} Score de pertinence (1-10):""" score = int(llm.generate(prompt, max_tokens=5)) scored_docs.append((doc, score)) # Sort by score scored_docs.sort(key=lambda x: x[1], reverse=True) return [doc for doc, score in scored_docs]
Classement Comparatif
Comparer les documents par paires ou par lots.
DEVELOPERpythondef llm_rerank_comparative(query, documents, llm): prompt = f"""Classe ces documents par pertinence pour la requête. Requête: {query} Documents: {format_documents(documents)} Fournis le classement (du plus au moins pertinent):""" ranking = llm.generate(prompt) ranked_docs = parse_ranking(ranking, documents) return ranked_docs
Avantages :
- Très précis
- Peut gérer une pertinence nuancée
- Explique le raisonnement
Inconvénients :
- Coûteux (appel LLM par document ou lot)
- Lent (centaines de ms à secondes)
- Peut dépasser la fenêtre de contexte avec de nombreux docs
Utiliser quand :
- Qualité maximale requise
- Coût/latence acceptable
- Petit ensemble de candidats (< 10 docs)
API Cohere Rerank
Service de reranking géré.
DEVELOPERpythonimport cohere co = cohere.Client(api_key="your-key") def cohere_rerank(query, documents, top_n=5): response = co.rerank( query=query, documents=documents, top_n=top_n, model="rerank-english-v2.0" ) return [doc.document for doc in response.results]
Modèles :
rerank-english-v2.0: Anglaisrerank-multilingual-v2.0: Plus de 100 langues
Tarification :
- 1,00 $ pour 1000 recherches (en 2025)
Avantages :
- Service géré
- Haute qualité
- Multilingue
Inconvénients :
- Latence API
- Coût continu
- Dépendance au fournisseur
FlashRank
Reranking local efficace.
DEVELOPERpythonfrom flashrank import Ranker, RerankRequest ranker = Ranker(model_name="ms-marco-MultiBERT-L-12") def flashrank_rerank(query, documents, top_n=5): rerank_request = RerankRequest( query=query, passages=[{"text": doc} for doc in documents] ) results = ranker.rerank(rerank_request) return [r.text for r in results[:top_n]]
Avantages :
- Très rapide (inférence optimisée)
- Auto-hébergé
- Pas de coûts API
Reranking Hybride
Combiner plusieurs signaux.
DEVELOPERpythondef hybrid_rerank(query, documents, weights=None): if weights is None: weights = { 'vector_score': 0.3, 'bm25_score': 0.2, 'cross_encoder': 0.5 } # Obtenir les scores de différents modèles vector_scores = get_vector_scores(query, documents) bm25_scores = get_bm25_scores(query, documents) ce_scores = get_cross_encoder_scores(query, documents) # Normaliser les scores à [0, 1] vector_scores = normalize(vector_scores) bm25_scores = normalize(bm25_scores) ce_scores = normalize(ce_scores) # Combinaison pondérée final_scores = ( weights['vector_score'] * vector_scores + weights['bm25_score'] * bm25_scores + weights['cross_encoder'] * ce_scores ) # Classer les documents ranked_indices = np.argsort(final_scores)[::-1] return [documents[i] for i in ranked_indices]
Stratégies de Reranking
Reranking Top-K
Reclasser uniquement les meilleurs candidats de la récupération initiale.
DEVELOPERpython# Récupérer top 20, reclasser pour obtenir top 5 candidates = retriever.retrieve(query, k=20) reranked = reranker.rerank(query, candidates, top_n=5)
Paramètres :
- Récupérer : 3-5x le k final
- Reranker : K final nécessaire
Exemple :
- Besoin de 5 résultats finaux
- Récupérer 20 candidats
- Reclasser en top 5
Reranking en Cascade
Plusieurs étapes de reranking avec précision croissante.
DEVELOPERpython# Stage 1: Fast retrieval candidates = fast_retriever.retrieve(query, k=100) # Stage 2: Fast reranker reranked_1 = tiny_reranker.rerank(query, candidates, top_n=20) # Stage 3: Accurate reranker reranked_2 = large_reranker.rerank(query, reranked_1, top_n=5) return reranked_2
Utiliser quand :
- Ensembles de candidats très larges
- Plusieurs niveaux de qualité nécessaires
- Optimisation coût/latence
Reranking Adaptatif à la Requête
Différent reranking selon le type de requête.
DEVELOPERpythondef adaptive_rerank(query, documents): query_type = classify_query(query) if query_type == "factual": # Utiliser des signaux de mots-clés return bm25_rerank(query, documents) elif query_type == "semantic": # Utiliser cross-encoder return cross_encoder_rerank(query, documents) elif query_type == "complex": # Utiliser LLM return llm_rerank(query, documents)
Optimisation des Performances
Traitement par Lots
Reclasser plusieurs requêtes efficacement.
DEVELOPERpython# Mauvais : Un à la fois for query in queries: rerank(query, docs) # Bon : Par lots pairs = [(q, doc) for q in queries for doc in docs] scores = reranker.predict(pairs, batch_size=32)
Mise en Cache
Mettre en cache les résultats de reranking.
DEVELOPERpythonfrom functools import lru_cache import hashlib def cache_key(query, doc): return hashlib.md5(f"{query}:{doc}".encode()).hexdigest() @lru_cache(maxsize=10000) def cached_rerank_score(query, doc): return reranker.predict([(query, doc)])[0]
Reranking Asynchrone
Paralléliser les appels de reranking.
DEVELOPERpythonimport asyncio async def async_rerank_batch(query, documents): tasks = [ rerank_async(query, doc) for doc in documents ] scores = await asyncio.gather(*tasks) return rank_by_scores(documents, scores)
Évaluation
Métriques
Precision@k : Docs pertinents dans le top-k après reranking
DEVELOPERpythondef precision_at_k(reranked_docs, relevant_docs, k): top_k = set(reranked_docs[:k]) relevant = set(relevant_docs) return len(top_k & relevant) / k
NDCG@k : Normalized Discounted Cumulative Gain
DEVELOPERpythonfrom sklearn.metrics import ndcg_score def evaluate_reranking(predictions, relevance_labels, k=5): return ndcg_score([relevance_labels], [predictions], k=k)
MRR : Mean Reciprocal Rank
DEVELOPERpythondef mrr(reranked_docs, relevant_docs): for i, doc in enumerate(reranked_docs, 1): if doc in relevant_docs: return 1 / i return 0
Tests A/B
Comparer les stratégies de reranking.
DEVELOPERpython# Contrôle : Pas de reranking control_results = retriever.retrieve(query, k=5) # Traitement : Avec reranking treatment_candidates = retriever.retrieve(query, k=20) treatment_results = reranker.rerank(query, treatment_candidates, k=5) # Mesurer : Satisfaction utilisateur, qualité de réponse
Analyse Coût-Bénéfice
| Reranker | Latence | Coût/1K | Qualité | Meilleur Pour |
|---|---|---|---|---|
| Pas de reranking | 0ms | 0 $ | Baseline | Budget/vitesse critique |
| TinyBERT | +30ms | 0 $ (auto-hébergé) | +10% | Équilibré |
| MiniLM | +50ms | 0 $ (auto-hébergé) | +20% | Axé qualité |
| Cohere | +100ms | 1 $ | +25% | Simplicité gérée |
| LLM | +500ms | 5-20 $ | +30% | Qualité maximale |
Bonnes Pratiques
- Toujours sur-récupérer pour le reranking : Récupérer 3-5x le k final
- Commencer avec cross-encoder : MiniLM est un bon défaut
- Mesurer l'impact : Test A/B reranking vs pas de reranking
- Ajuster le nombre de récupération : Équilibrer coût et rappel
- Considérer le budget de latence de requête : Le reranking ajoute 50-500ms
- Surveiller les coûts : Le reranking LLM peut être coûteux à grande échelle
Choisir un Reranker
Prototypage :
- cross-encoder/ms-marco-MiniLM-L6-v2
- Facile à utiliser, bonne qualité
Production (Sensible aux Coûts) :
- cross-encoder/ms-marco-TinyBERT-L2-v2
- Auto-hébergé, rapide
Production (Axé Qualité) :
- API Cohere Rerank
- Qualité maximale, géré
Multilingue :
- mmarco-mMiniLMv2-L12-H384-v1
- cross-encoder/mmarco-mMiniLMv2-L12
Qualité Maximale (Budget Disponible) :
- Reranking basé LLM
- GPT-4, Claude pour les meilleurs résultats
Conseil d'Expert d'Ailog : Le reranking a un impact élevé mais n'est pas la première priorité. Commencez par bien faire votre découpage, vos embeddings et votre récupération - ce sont les fondations. Une fois que vous avez un système RAG fonctionnel, le reranking est le moyen le plus simple de gagner 10-25% de précision supplémentaire. Commencez avec l'API Cohere Rerank pour des gains sans configuration. Nous avons ajouté le reranking en production en un après-midi et avons immédiatement vu moins d'hallucinations et une meilleure qualité de réponse.
Tester le Reranking sur Ailog
Comparez les modèles de reranking sans configuration :
La plateforme Ailog inclut :
- Cohere Rerank, cross-encoders, reranking LLM
- Comparaison de qualité côte à côte
- Analyse de latence et de coût
- Tests A/B avec de vraies requêtes
Testez le reranking gratuitement →
Prochaines Étapes
Avec la récupération et le reranking optimisés, il est crucial de mesurer les performances. Le prochain guide couvre les métriques et méthodologies d'évaluation pour évaluer la qualité du système RAG.
Tags
Articles connexes
Réclassement Cross-Encoder pour la Précision RAG
Atteindre 95%+ de précision : utilisez des cross-encoders pour réclasser les documents récupérés et éliminer les faux positifs.
API Cohere Rerank pour RAG Production
Boostez la Précision RAG de 40% avec l'API Rerank de Cohere : Intégration Simple, Support Multilingue, Prêt pour la Production.
Optimisation des Requêtes : Améliorer l'Efficacité de la Récupération
Techniques pour optimiser les requêtes utilisateur et améliorer la récupération : réécriture de requêtes, expansion, décomposition et stratégies de routage.