Re-ranking des resultats de recherche
La recherche hybride (vecteurs + BM25) que nous avons construite fonctionne bien, mais elle a ses limites. Par exemple, pour une requete comme “qu’a fait l’equipe engineering avec l’incident INC-2023-Q4-011 ?”, on s’attendrait a voir la section ingenierie logicielle en premier — puisqu’elle mentionne explicitement l’equipe et l’incident. Pourtant, le systeme actuel peut renvoyer la section cybersecurite en tete.
C’est la que le re-ranking entre en jeu : une etape supplementaire de post-traitement qui ameliore la pertinence des resultats.
Comment fonctionne le re-ranking
Le principe est simple. Apres avoir execute la recherche vectorielle et BM25 puis fusionne les resultats, on ajoute une etape finale : on envoie les resultats a Claude pour qu’il les reordonne intelligemment.
Le processus se deroule ainsi :
- On recupere les resultats fusionnes de la recherche hybride
- On les envoie a Claude avec la question originale de l’utilisateur
- On demande a Claude de renvoyer les documents les plus pertinents, tries par ordre decroissant de pertinence
- On utilise cette liste reordonnee comme resultat final
Le prompt de re-ranking
La structure du prompt est directe. On fournit a Claude la question de l’utilisateur et tous les documents potentiellement pertinents, puis on lui demande de faire le tri :
You are tasked with finding the documents most relevant to a user's question.
<user_question>
What happened with INC-2023-Q4-011?
</user_question>
Here are documents that may be relevant:
<documents>
<document>Section 10...</document>
<document>Section 2...</document>
<document>Section 7...</document>
<document>Section 6...</document>
</documents>
Return the 3 most relevant docs, in order of decreasing relevance.
Optimisation avec des identifiants
Un point important en termes d’efficacite : si on demande a Claude de renvoyer le texte complet de chaque chunk pertinent, on lui fait essentiellement recopier de gros blocs de texte. C’est lent et couteux en tokens.
La meilleure approche consiste a attribuer un identifiant unique a chaque chunk en amont, puis a demander a Claude de renvoyer uniquement ces identifiants dans le bon ordre :
<documents>
<document>
<id>ab84</id>
<content>Section 10...</content>
</document>
<document>
<id>51n3</id>
<content>Section 8...</content>
</document>
</documents>
Claude renvoie alors une simple liste comme ["1p5g", "51n3", "ab83"] au lieu de recopier des paragraphes entiers.
Implementation
La fonction de re-ranking est appelee automatiquement par le retriever une fois la recherche hybride terminee. Voici la structure de base :
def reranker_fn(docs, query_text, k):
# Formater les documents avec leurs identifiants
joined_docs = "\n".join([
f"""
<document>
<document_id>{doc["id"]}</document_id>
<document_content>{doc["content"]}</document_content>
</document>
"""
for doc in docs
])
# Creer le prompt et obtenir la reponse de Claude
prompt = f"""..."""
messages = []
add_user_message(messages, prompt)
add_assistant_message(messages, """```json""")
result = chat(messages, stop_sequences=["""```"""])
return json.loads(result["text"])["document_ids"]
Notez l’astuce du pre-remplissage : on commence la reponse de l’assistant par ```json et on utilise ``` comme sequence d’arret. Cela force Claude a produire directement du JSON valide sans texte superflu.
Resultats
En testant avec la requete “qu’a fait l’equipe engineering avec INC-2023-Q4-011 ?”, la section ingenierie logicielle apparait desormais en premier. Claude a compris que la question portait specifiquement sur l’equipe d’ingenierie et sa relation avec l’incident.
Compromis a considerer
Le re-ranking implique des compromis clairs :
- Latence accrue : il faut attendre un appel API supplementaire a Claude
- Precision amelioree : Claude comprend le contexte et la pertinence d’une maniere que la simple similarite vectorielle ne peut pas egaler
Pour la plupart des applications, le gain en precision justifie le cout en latence — surtout pour des requetes complexes ou la comprehension semantique prime sur la correspondance de mots-cles.
Exercice pratique
Essayez d’implementer un re-ranker sur votre propre pipeline RAG :
- Partez de votre recherche hybride existante
- Ajoutez des identifiants uniques a vos chunks
- Ecrivez le prompt de re-ranking avec la technique du pre-remplissage JSON
- Comparez les resultats avec et sans re-ranking sur 5 requetes differentes
- Mesurez la difference de latence