Aller au contenu principal

La récupération contextuelle

Mis à jour le 30 juillet 2026

Dernière amélioration de notre pipeline, et l’une des plus efficaces : la récupération contextuelle. Elle s’attaque à un problème fondamental du RAG, présent depuis la première leçon de découpage : quand on segmente un document, chaque segment perd sa connexion au contexte global. « Le chiffre a doublé par rapport à l’année précédente » — quel chiffre ? quelle année ? Le paragraphe le savait dans le document ; isolé dans l’index, il ne le sait plus, et aucune recherche ne le retrouvera sur une question mentionnant le sujet réel.

Le principe

La parade consiste à réparer cette perte avant l’indexation, par une étape de preprocessing supplémentaire :

  1. Prendre chaque segment et le document source complet
  2. Demander à Claude d’ajouter du contexte
  3. Claude génère un court texte situant le segment dans le document global
  4. Combiner ce contexte avec le segment original pour créer un « segment contextualisé »
  5. Utiliser le segment contextualisé dans les index

Le résultat : chaque segment entre dans l’index précédé d’une phrase du type « Ce passage provient de la section résultats financiers du rapport annuel 2024 d’Acme et détaille l’évolution du chiffre d’affaires ». Les pronoms orphelins retrouvent leurs référents, les embeddings capturent le vrai sujet, et BM25 matche désormais sur des termes que le segment seul ne contenait pas. On paie un appel à Claude par segment — une fois, à l’indexation — pour une précision de récupération améliorée à chaque question, pour toujours.

Gérer les gros documents

Un obstacle pratique surgit vite : fournir « le document complet » à chaque appel de contextualisation suppose qu’il tienne dans le contexte de Claude. Pour les documents trop volumineux, on remplace le document entier par un contexte réduit mais représentatif :

  • Quelques segments du début du document (souvent des résumés)
  • Les segments juste avant le segment à contextualiser

L’intuition est documentaire : le début d’un rapport pose le cadre (titre, résumé exécutif, plan), et les segments immédiatement précédents portent le fil local — de quoi situer correctement la plupart des passages sans relire l’ensemble.

Implémentation

def add_context(text_chunk, source_text):
    prompt = f"""
Écris un court extrait pour situer ce segment dans le document global,
afin d'ameliorer la recuperation lors de la recherche.

<document>
{source_text}
</document>

<chunk>
{text_chunk}
</chunk>

Réponds uniquement avec le contexte succinct.
"""
    messages = []
    add_user_message(messages, prompt)
    result = chat(messages)
    return result + "\n" + text_chunk

La structure du prompt vous est familière : balises XML pour séparer document et segment, consigne de sortie stricte (« uniquement le contexte succinct ») pour éviter le bavardage. La dernière ligne fait l’assemblage : le contexte généré, un saut de ligne, puis le segment original intact — c’est cette concaténation qui sera indexée, jamais le segment nu.

Stratégie pour les gros documents

num_start_chunks = 2
num_prev_chunks = 2

for i, chunk in enumerate(chunks):
    context_parts = []
    context_parts.extend(chunks[:min(num_start_chunks, len(chunks))])
    start_idx = max(0, i - num_prev_chunks)
    context_parts.extend(chunks[start_idx:i])
    context = "\n".join(context_parts)
    contextualized_chunk = add_context(chunk, context)
    retriever.add_document({"content": contextualized_chunk})

Le code met en œuvre la stratégie du contexte réduit : pour chaque segment, on assemble les deux premiers segments du document plus les deux précédant la position courante, et c’est ce condensé qui joue le rôle de « document » dans add_context. Les gardes min et max gèrent proprement les bords — les tout premiers segments ont moins de prédécesseurs. Notez la dernière ligne : le segment contextualisé part dans le Retriever de la leçon précédente — la récupération contextuelle s’empile naturellement sur l’architecture hybride et le reranking.

Quand l’utiliser

La technique donne son plein rendement sur les documents dont les sections se répondent : relations internes complexes, segments faisant référence à des concepts définis ailleurs — « comme défini en section 2 », « ce mécanisme » — et plus généralement les documents techniques, rapports et articles académiques. Pour une FAQ dont chaque entrée est autonome, elle n’apporterait presque rien : le contexte perdu au découpage est exactement ce qu’elle restitue, encore faut-il qu’il y en ait eu un.

Points clés à retenir

  • Le découpage ampute chaque segment de son contexte — la contextualisation le restitue avant indexation
  • Claude génère une phrase de situation, concaténée devant le segment original ; c’est ce couple qu’on indexe
  • Coût : un appel par segment, une fois à l’indexation — bénéfice à chaque recherche
  • Documents trop gros : contexte réduit = segments de tête (résumés) + segments précédents
  • À réserver aux documents dont les sections se référencent — inutile sur des contenus autonomes