0Pricing
AI Engineering Academy · Leçon

Architecture RAG : indexation et récupération

Découvrez les deux phases de RAG : la phase d’indexation hors ligne, qui segmente, transforme et stocke les documents, et la phase de récupération en ligne, qui trouve le contexte pertinent pour chaque requête.

Architecture RAG : indexation et récupération est une leçon AI Engineering Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Engineering Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Engineering Academy comprend 4 leçons au total.

RAG comporte deux phases distinctes

Un système RAG fonctionne selon deux phases fondamentalement différentes, qui s'exécutent à des moments distincts. La phase d'indexation hors ligne traite vos documents une fois (ou lorsqu'ils sont modifiés) et prépare un index interrogeable. La phase de récupération en ligne s'exécute en temps réel pour chaque requête utilisateur. Comprendre cette séparation est essentiel pour concevoir des systèmes à la fois rapides au moment des requêtes et faciles à maintenir au fil du temps.

La phase d'indexation : étape 1 — Charger

L'indexation commence par le chargement des documents : la lecture de fichiers bruts provenant de vos systèmes sources. Les documents peuvent être des PDF, des fichiers Word, des pages HTML, des fichiers Markdown, des lignes de base de données ou toute autre source textuelle. Chaque document est chargé en mémoire sous forme de texte brut, en préservant autant que possible sa structure. Des bibliothèques comme pypdf, python-docx et unstructured prennent en charge l'essentiel de l'analyse propre à chaque format.

from pypdf import PdfReader

def load_pdf(path):
    reader = PdfReader(path)
    pages = []
    for i, page in enumerate(reader.pages):
        text = page.extract_text()
        pages.append({'text': text, 'page': i + 1, 'source': path})
    return pages

docs = load_pdf('company_policy.pdf')
print(f'Loaded {len(docs)} pages')

La phase d'indexation : étape 2 — Segmenter

Les LLM disposent de fenêtres de contexte limitées et récupérer des documents entiers est inefficace. Le texte chargé est divisé en petits segments d'environ 200 à 1 000 jetons chacun. Une bonne segmentation préserve la cohérence sémantique : un segment doit exprimer une idée complète. Une stratégie courante utilise des fenêtres qui se chevauchent, afin que les phrases proches des limites d'un segment apparaissent dans deux segments et que les informations ne soient pas perdues aux points de séparation.

from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,      # characters per chunk
    chunk_overlap=50,    # overlap between chunks
    separators=['\n\n', '\n', '. ', ' ']
)

for page in docs:
    chunks = splitter.split_text(page['text'])
    for chunk in chunks:
        # Each chunk carries metadata from its source page
        print(f'Chunk ({len(chunk)} chars): {chunk[:80]}...')

La phase d'indexation : étape 3 — Vectoriser

Chaque segment de texte est converti en une représentation vectorielle dense qui encode numériquement sa signification sémantique. Vous appelez un modèle de représentation vectorielle — comme text-embedding-3-small d'OpenAI — pour chaque segment et recevez un tableau de nombres flottants à grande dimension. Les segments de sens similaire produisent des vecteurs proches dans cet espace à grande dimension, ce qui permet la recherche de similarité sémantique.

from openai import OpenAI

client = OpenAI()

def embed_chunks(chunks):
    texts = [c['text'] for c in chunks]
    response = client.embeddings.create(
        model='text-embedding-3-small',
        input=texts
    )
    for i, chunk in enumerate(chunks):
        chunk['embedding'] = response.data[i].embedding
    return chunks

# Batch up to 2048 texts per API call
embedded = embed_chunks(all_chunks)

La phase d'indexation : étape 4 — Stocker

Les segments vectorisés sont stockés dans une base de données vectorielle avec leurs métadonnées (fichier source, numéro de page, titre de section). L'entrepôt vectoriel construit une structure d'index (généralement HNSW) qui permet une recherche rapide des plus proches voisins approximatifs. Cet index est conservé sur le disque afin de survivre aux redémarrages. L'indexation a généralement lieu une fois lors de la configuration, puis de manière incrémentielle lorsque de nouveaux documents sont ajoutés.

import pinecone

pc = pinecone.Pinecone(api_key='YOUR_KEY')
index = pc.Index('rag-documents')

# Upsert vectors with metadata
vectors_to_upsert = [
    (
        chunk['id'],
        chunk['embedding'],
        {'text': chunk['text'], 'source': chunk['source'], 'page': chunk['page']}
    )
    for chunk in embedded_chunks
]

# Upsert in batches of 100
for i in range(0, len(vectors_to_upsert), 100):
    index.upsert(vectors=vectors_to_upsert[i:i+100])
print('Indexing complete')

La phase de récupération : vectorisation de la requête

Lorsqu'un utilisateur envoie une requête, la phase de récupération en ligne commence. La première étape consiste à vectoriser la question de l'utilisateur à l'aide du même modèle de représentation vectorielle que celui utilisé lors de l'indexation. C'est essentiel : si vous avez indexé avec text-embedding-3-small, vous devez également effectuer la requête avec text-embedding-3-small. La représentation vectorielle de la requête est un vecteur qui encode le sens de la demande de l'utilisateur.

def embed_query(question):
    response = client.embeddings.create(
        model='text-embedding-3-small',  # MUST match indexing model
        input=[question]
    )
    return response.data[0].embedding

user_question = 'What is our parental leave policy?'
query_vector = embed_query(user_question)
print(f'Query embedded: {len(query_vector)}-dim vector')

La phase de récupération : recherche ANN

La représentation vectorielle de la requête est envoyée à l'entrepôt vectoriel, qui effectue une recherche des plus proches voisins approximatifs (ANN) afin de trouver les K segments dont les représentations vectorielles sont les plus similaires au vecteur de la requête. Cette recherche est extrêmement rapide (généralement en moins de 10 ms), car les index HNSW échangent une petite part de rappel contre des gains de vitesse considérables par rapport à une recherche exhaustive. Vous récupérez les K segments les mieux classés — généralement de K=5 à K=20.

results = index.query(
    vector=query_vector,
    top_k=5,
    include_metadata=True
)

print(f'Retrieved {len(results.matches)} chunks:')
for match in results.matches:
    print(f'  Score: {match.score:.3f} | Source: {match.metadata["source"]}')
    print(f'  Text: {match.metadata["text"][:100]}...')
    print()

Relier les deux phases

L'idée essentielle est que l'indexation et la récupération sont conçues pour fonctionner ensemble. Le modèle de représentation vectorielle doit être identique dans les deux phases, car l'espace mathématique dans lequel se trouvent les vecteurs dépend du modèle. Si vous changez de modèle de représentation vectorielle, vous devez réindexer tous les documents. L'entrepôt vectoriel fait le lien : il accepte les vecteurs lors de l'indexation et les renvoie lors de la récupération, dissociant les deux phases dans le temps tout en les maintenant alignées dans l'espace vectoriel.

Filtrage des métadonnées lors de la récupération

La recherche vectorielle trouve des segments sémantiquement similaires, mais vous devez parfois aussi filtrer par métadonnées. Par exemple : ne récupérer que les segments provenant de documents importés en 2025, ou uniquement ceux du dossier du service des ressources humaines. Les entrepôts vectoriels prennent en charge le préfiltrage ou le postfiltrage des champs de métadonnées. Le préfiltrage (pris en charge par Pinecone et Qdrant) applique le filtre avant la recherche ANN, ce qui est plus rapide et plus précis que le postfiltrage des résultats les mieux classés.

# Retrieve only from HR department documents
results = index.query(
    vector=query_vector,
    top_k=5,
    filter={'department': {'$eq': 'HR'}},
    include_metadata=True
)

# Or filter by date range
results = index.query(
    vector=query_vector,
    top_k=5,
    filter={
        'upload_year': {'$gte': 2024},
        'doc_type': {'$eq': 'policy'}
    },
    include_metadata=True
)

Indexation incrémentielle pour les mises à jour

En production, votre corpus de documents évolue au fil du temps. Une architecture d'indexation efficace prend en charge les mises à jour incrémentielles : lorsqu'un document est modifié, supprimez ses vecteurs existants par ID et ajoutez les nouveaux avec upsert. Lorsque des documents sont supprimés, retirez leurs vecteurs. Attribuez à chaque segment un ID déterministe fondé sur le chemin du document source et la position du segment, afin de toujours pouvoir trouver et mettre à jour les bons vecteurs sans tout réindexer.

import hashlib

def make_chunk_id(source_path, chunk_index):
    # Deterministic, stable ID for each chunk
    key = f'{source_path}::chunk_{chunk_index}'
    return hashlib.md5(key.encode()).hexdigest()

def update_document(source_path, index):
    # Delete old vectors for this document
    index.delete(filter={'source': source_path})
    # Re-index the updated document
    new_chunks = load_and_chunk(source_path)
    new_embedded = embed_chunks(new_chunks)
    index.upsert(vectors=new_embedded)
    print(f'Updated {source_path}: {len(new_chunks)} chunks')

L'ensemble du pipeline RAG en un coup d'œil

Voici à quoi ressemble l'architecture RAG complète : Hors ligne : Documents → Chargeur → Segmenteur → Modèle de représentation vectorielle → Entrepôt vectoriel. En ligne : Requête utilisateur → Modèle de représentation vectorielle → Entrepôt vectoriel (recherche ANN) → Segments les mieux classés → Assemblage de l'invite → LLM → Réponse. Le pipeline hors ligne s'exécute une fois par mise à jour de document. Le pipeline en ligne s'exécute en quelques millisecondes pour chaque requête utilisateur, le LLM ne voyant que le contexte pertinent et non l'ensemble du corpus de documents.

Vérification rapide

Évaluez votre compréhension des concepts d'ingénierie de l'IA présentés dans cette leçon.

Récapitulatif de la leçon

Dans cette leçon, vous avez appris : la phase d'indexation hors ligne, composée des étapes de chargement, de segmentation, de vectorisation et de stockage exécutées une fois par document, la phase de récupération en ligne, qui vectorise la requête, effectue une recherche ANN et renvoie les segments les mieux classés en quelques millisecondes, ainsi que les stratégies d'indexation incrémentielle permettant de maintenir l'entrepôt vectoriel à jour lorsque les documents évoluent. Nous allons maintenant voir comment élaborer des invites augmentées efficaces qui exploitent correctement le contexte récupéré.

Questions Fréquemment Posées

La leçon « Architecture RAG : indexation et récupération » est-elle gratuite ?

Oui — le texte complet de « Architecture RAG : indexation et récupération » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Engineering Academy, passe à CoddyKit PRO. Le cours AI Engineering Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Architecture RAG : indexation et récupération » ?

Découvrez les deux phases de RAG : la phase d’indexation hors ligne, qui segmente, transforme et stocke les documents, et la phase de récupération en ligne, qui trouve le contexte pertinent pour chaq… Tu pratiques AI Engineering Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer AI Engineering Academy ?

Aucune expérience préalable n'est requise. AI Engineering Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.

Combien de temps prend la leçon « Architecture RAG : indexation et récupération » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon AI Engineering Academy ?

Oui. Chaque leçon AI Engineering Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Le problème résolu par RAG
  2. Architecture RAG : indexation et récupération
  3. Rédiger le prompt enrichi
  4. RAG ou affinage : quand utiliser l’un ou l’autre
← Retour à AI Engineering Academy