Votre RAG ne pèche pas par le modèle, mais par l'ordre
La recherche vectorielle excelle à ramener des candidats et reste médiocre pour les ordonner. C'est pourquoi une recherche documentaire sérieuse se fait en deux étapes : l'une rapide et approximative, l'autre précise et coûteuse. Nous expliquons pourquoi le reranking fait plus que doubler la qualité du classement (chiffres à l'appui), le coût caché que presque personne ne compte, comment se situe le paysage (Cohere, Voyage, Pinecone, ELSER, ColBERT, Jina) et comment nous construisons un index de reranking qui ne vit que le temps d'une requête — et pourquoi cela nous rend meilleurs.
Bien réordonner 10 000 paires avec un cross‑encoder prend environ 65 heures ; les embeddings en donnent une approximation en 5 secondes, mais se trompent d'ordre — et aucun modèle ne rattrape ensuite un contexte mal ordonné. C'est pourquoi une recherche sérieuse ne s'arrête pas au vecteur : la réponse se gagne à la deuxième étape, le reranking, qui fait plus que doubler la qualité du classement.
L'intuition naïve veut que la similarité d'embeddings suffise. En pratique, la recherche vectorielle excelle en rappel — ramener vite un ensemble raisonnable de candidats — et reste médiocre en précision — ordonner ces candidats selon leur pertinence réelle. Une recherche sérieuse se fait donc en deux étapes. Et c'est la seconde, le reranking, qui emporte la réponse.
Les problèmes que rencontrent vraiment les développeurs
Le premier réflexe quand un RAG échoue est d'augmenter top_k : ramener plus de
fragments. C'est un piège. Avec un k petit, le bon document reste dehors ; avec un
k grand, on inonde la fenêtre de contexte — et les modèles perdent
l'information qui tombe au milieu (Liu et al., 2023). Plus de contexte n'est pas un
meilleur contexte.
Le second réflexe est de tout confier aux embeddings denses. Autre piège : en évaluation zero-shot sur de nouveaux domaines, les retrievers denses peuvent faire moins bien que le bon vieux BM25 (Thakur et al., 2021). La similarité vectorielle à elle seule généralise moins bien qu'on ne le croit.
La cause de fond ? Un cross-encoder — le modèle qui juge vraiment la pertinence en regardant la requête et le document ensemble — est précis mais extrêmement coûteux : il faut l'exécuter une fois par paire (requête, document). Reimers et Gurevych ont mesuré que comparer exhaustivement 10 000 phrases avec un cross-encoder prend environ 65 heures ; avec des embeddings indépendants, environ 5 secondes (Reimers & Gurevych, 2019). Impossible de passer le cross-encoder sur tout le corpus. Mais sa précision est exactement ce dont on a besoin. La réponse à cette tension, ce sont deux étapes.
La recherche en deux étapes
La première étape récupère de façon approximative les fragments les plus alignés avec la requête. Elle travaille sur des embeddings denses (Karpukhin et al., 2020) et mesure la proximité par la similarité cosinus :
Elle est bon marché et passe à l'échelle de millions de fragments, mais l'embedding comprime chaque document en un seul vecteur : il perd des nuances qui n'apparaissent qu'en comparant la requête et le document mot à mot.
La seconde étape — le reranker — réordonne uniquement ces candidats avec un cross-encoder qui, lui, examine la paire conjointement (Nogueira & Cho, 2019). Le gain de qualité est important : sur le benchmark de référence MS MARCO, le reranking avec BERT fait plus que doubler le MRR@10 par rapport à BM25 (Nguyen et al., 2016; Nogueira & Cho, 2019).
Le reranker attribue à chaque candidat un score et le convertit en une distribution sur l'ensemble récupéré :
Et le schéma se généralise : sur BEIR, la combinaison BM25 + cross-encoder est la meilleure en moyenne face à la recherche lexicale ou dense seule, et l'emporte sur 16 des 18 domaines (Thakur et al., 2021). Lorsqu'il existe plusieurs sources de rappel (lexicale et dense), on les fusionne par rang avec la Reciprocal Rank Fusion avant le reranking (Cormack et al., 2009).
L'asymétrie clé
La première étape décide ce qui entre dans le jeu ; la seconde décide de l'ordre. Un bon rappel avec un mauvais ordre gaspille la fenêtre de contexte ; un ordre parfait sur un mauvais rappel ne peut pas retrouver ce qui n'a jamais été ramené. Il faut les deux — et chacun se mesure avec sa propre métrique (recall@k et MRR/nDCG).
Le coût caché du reranking
Si le reranking est si bon, pourquoi tout le monde ne le pousse-t-il pas au maximum ? Le coût. Un cross-encoder exécute une passe du modèle par paire : réordonner est donc cher et lent. Les chiffres de ColBERT le montrent clairement : réordonner les candidats d'une requête avec un cross-encoder BERT-large prend environ 33 secondes ; l'interaction tardive de ColBERT atteint une qualité comparable en 61 millisecondes (Khattab & Zaharia, 2020).
L'issue habituelle consiste à maintenir en permanence un index de reranking spécialisé et chaud — un GPU servi 24 h/24 et 7 j/7, ou un énorme index multivecteur (ColBERT avait besoin de 154 Gio pour MS MARCO, ramenés à 16–25 Gio seulement grâce à la compression (Santhanam et al., 2022)). Le problème : cet index coûte cher à entretenir et reste la plupart du temps inactif, à attendre des requêtes qui arrivent par rafales.
Le reranking éphémère
Notre pari — ce que nous appelons en interne Turbovec — consiste à inverser l'équation : construire l'index de reranking à la demande, au moment où la requête arrive, et le jeter une fois le travail fait.
async function retrieve(query: string, projectId: string) {
// Stage 1 — cheap recall over the persistent vector index
const candidates = await vectorSearch(query, projectId, { k: 50 })
// Stage 2 — ephemeral reranking index, alive only for this query
const boost = await buildEphemeralIndex(candidates)
const scored = await boost.rerank(query, candidates)
return scored
.sort((a, b) => b.score - a.score)
.slice(0, 8) // only the best makes it into the agent's window
}L'index éphémère ne concurrence pas le stockage persistant : il le complète. La recherche vectorielle garantit que le bon candidat figure parmi les 50 ; le reranker garantit qu'il arrive dans le top 8 que l'agent lit réellement. Et comme le reranking ne s'applique qu'à ces 50 candidats — pas à tout le corpus — le coût croît avec (maîtrisable), non avec (intraitable). On paie la précision uniquement quand il y a une question, pas pour un GPU qui attend.
Comment se situe le paysage
Le reranking est devenu une excellente commodité, mais presque toutes les options supposent un service ou un index permanent :
| Solution | Mécanisme | Coût / limite |
|---|---|---|
| Cohere Rerank | Cross-encoder géré | API payée à l'usage ; fenêtre d'environ 4096 tokens par document, découpe les documents longs |
| Voyage rerank | Cross-encoder géré | Budget de tokens par requête ; tronque par défaut |
| Pinecone rerank | Cross-encoder hébergé | Contexte de 512 tokens sur son propre modèle ; par requête |
| Elastic ELSER + Rerank | Sparse appris + cross-encoder | 512 tokens ; recommandé pour l'anglais ; coût d'inférence par requête |
| sentence-transformers | Cross-encoder auto-hébergé | C'est vous qui gardez le GPU chaud ; ne passe pas à l'échelle du corpus |
| ColBERT / RAGatouille | Interaction tardive (multivecteur) | Index spécialisé volumineux et persistant |
| Jina Reranker | Cross-encoder / listwise | Inférence par paire ; service ou poids auto-hébergés |
Ce sont d'excellentes briques. Mais presque toutes demandent quelque chose qui tourne en permanence : une API payée à la requête, un GPU servi ou un index spécialisé qu'il faut tenir à jour. Le reranking éphémère par requête n'est pas le modèle pour lequel elles ont été conçues.
Comment nous comptons être les meilleurs
Nous ne rivalisons pas sur la taille du cross-encoder : nous rivalisons sur la capacité à offrir la précision d'un cross-encoder sans payer pour le garder chaud. C'est là que nous concentrons notre avantage :
L'approche habituelle
BiVelio
- Un coût proportionnel à l'usage. Pas de GPU inactif : l'index de précision n'existe que pendant la requête. Vous payez les questions, pas l'attente.
- Rappel hybride, précision ciblée. Nous combinons des signaux lexicaux (Robertson & Zaragoza, 2009) et denses (Karpukhin et al., 2020), fusionnés par rang (Cormack et al., 2009), et seulement ensuite appliquons le reranking — le schéma que les données récompensent (Thakur et al., 2021).
- Moins de contexte, mieux ordonné. Nous remettons à l'agent le top 8, pas le top 50 : nous nous attaquons de front au « perdu au milieu » (Liu et al., 2023) au lieu d'inonder la fenêtre.
- Un reranking doté de contexte opérationnel. Nous ne réordonnons pas les fragments à l'aveugle : nous le combinons avec le graphe de connaissances de l'entreprise, l'idée que nous développons dans Le graphe comme contexte ambiant.
- Traçabilité. Chaque résultat réordonné conserve son origine et son score : vous pouvez vérifier pourquoi un fragment est parvenu à l'agent.
Note : les chiffres de cet article proviennent de la littérature citée (Reimers & Gurevych, Nogueira & Cho, Khattab & Zaharia, Santhanam et al., Thakur et al., Liu et al.) et décrivent le reranking en général. Ils motivent notre conception ; ce ne sont pas des mesures figées du produit.
Références
- #recherche documentaire
- #reranking
- #embeddings
- #rag
- #cross-encoder

