Aller au contenu principal
Leçon 40 sur 67 · Claude sur Amazon Bedrock

Pipeline RAG multi-recherche

Leçon 40 sur 67 Mis à jour le 5 novembre 2026 Développeur
Sur cette page
  1. Un coordinateur : le Retriever
  2. Fusionner des classements : la RRF
  3. L’implémentation
  4. Une architecture extensible
  5. À vous de jouer
  6. Points clés à retenir

La recherche sémantique et la recherche lexicale fonctionnent chacune de leur côté. Reste à les combiner en une seule recherche, qui profite des forces des deux.

Un coordinateur : le Retriever

Les deux index ont la même interface, add_document et search. On peut donc les envelopper dans une classe qui coordonne :

  1. elle reçoit la question de l’utilisateur ;
  2. elle la transmet à chaque index ;
  3. elle recueille les deux classements ;
  4. elle les fusionne en un seul.

Fusionner des classements : la RRF

Fusionner deux classements Trois colonnes : l'index vectoriel classe les sections 2, 7 et 6 ; BM25 classe les sections 6, 2 et 7 ; la fusion RRF avec k égal à 1 donne la section 2 (0,833), la section 6 (0,75) puis la section 7 (0,583). RECHERCHE HYBRIDE Fusionner deux classements Index vectoriel Rang 1 Section 2 Rang 2 Section 7 Rang 3 Section 6 BM25 Rang 1 Section 6 Rang 2 Section 2 Rang 3 Section 7 Fusion RRF, k = 1 0,833 Section 2 0,75 Section 6 0,583 Section 7 Seuls les rangs comptent : chaque index ajoute 1 / (k + rang) au score d'un document.
D'après l'exemple de la leçon « A multi-search RAG pipeline » (Claude Academy, Claude with Amazon Bedrock), recalculé.

Les deux index ne notent pas sur la même échelle : une distance d’un côté, un score BM25 de l’autre. On ne peut pas additionner ces nombres. La fusion par rang réciproque (Reciprocal Rank Fusion, RRF) ne regarde que les rangs :

RRF(d) = Σ 1 / (k + rang_i(d))

Pour chaque document d, on additionne 1 / (k + rang) sur tous les index ; k est une constante, souvent 60. L’exemple du cours officiel, avec k = 1 pour des chiffres plus lisibles : l’index vectoriel classe les sections 2, 7, 6 ; BM25 classe les sections 6, 2, 7.

SectionRang vectorielRang BM25Score RRF (k = 1)
Section 2121/2 + 1/3 = 0,833
Section 6311/4 + 1/2 = 0,75
Section 7231/3 + 1/4 = 0,583

Classement final : section 2, puis 6, puis 7. Un document bien placé dans les deux classements l’emporte sur un document premier d’un seul côté.

L’implémentation

Le cours officiel ne montre qu’une esquisse de la méthode search. Voici une version complète :

class Retriever:
    def __init__(self, *indexes):
        if not indexes:
            raise ValueError("il faut au moins un index")
        self.indexes = list(indexes)

    def add_document(self, document):
        for index in self.indexes:
            index.add_document(document)

    def search(self, query, k=1, k_rrf=60, candidates=20):
        scores, documents = {}, {}
        for index in self.indexes:
            for rank, (doc, _) in enumerate(index.search(query, k=candidates), start=1):
                key = id(doc)
                documents[key] = doc
                scores[key] = scores.get(key, 0.0) + 1 / (k_rrf + rank)
        best = sorted(scores, key=scores.get, reverse=True)[:k]
        return [(documents[key], scores[key]) for key in best]

Chaque index renvoie ses candidates meilleurs résultats, et seuls les rangs comptent. Le même dictionnaire document est passé à tous les index par add_document : son identifiant Python, id(doc), sert de clé commune pour additionner les contributions. VectorIndex reçoit ici la question en texte et la vectorise lui-même avec sa fonction embed_fn.

retriever = Retriever(VectorIndex(generate_embedding), BM25Index())
for chunk in chunk_by_section(text):
    retriever.add_document({"content": chunk})

for doc, score in retriever.search("Que s'est-il passé avec INC-2023-Q4-011 ?", k=3):
    print(round(score, 4), doc["content"][:120])

add_document vectorise chaque morceau avec Titan, un appel par morceau, et l’indexe aussi pour BM25. Dans la démonstration du cours officiel, la recherche hybride place en tête le rapport d’incident de cybersécurité, suivi de la section d’ingénierie logicielle : mieux que chacune des deux méthodes seule.

Une architecture extensible

Tout index qui respecte l’interface add_document et search peut rejoindre le Retriever : un autre modèle d’embedding, une recherche spécialisée dans un domaine, ou toute autre technique. La fusion par rangs n’a pas besoin de connaître leurs échelles de notes.

À vous de jouer

Régler la fusion. Sur votre document, comparez les trois premiers résultats de VectorIndex, de BM25Index et du Retriever, pour une question avec un terme exact et une question formulée librement. Essayez ensuite k_rrf=1 et k_rrf=60 : le classement change-t-il ?

Sources officielles : A multi-search RAG pipeline (Claude Academy) · Contextual Retrieval (Anthropic : recherche hybride)

Points clés à retenir

  • Le Retriever envoie la question à chaque index et fusionne leurs classements.
  • Les échelles de notes diffèrent : la RRF ne regarde que les rangs, RRF(d) = Σ 1 / (k + rang).
  • Un document bien classé partout l’emporte sur un document premier d’un seul côté.
  • Tout index qui respecte add_document et search peut rejoindre la fusion.