Implémenter le flux RAG
Mis à jour le 30 juillet 2026
Théorie posée, briques prêtes : ce guide pratique démontre l’implémentation complète du RAG sur un document exemple — le rapport annuel d’une entreprise fictive. Nous construisons une base vectorielle et exécutons les cinq étapes du workflow, du fichier brut jusqu’aux segments retrouvés par similarité. Chaque étape tient en quelques lignes, parce que les fonctions de découpage et d’embedding des leçons précédentes font le gros du travail.
Étape 1 : Découper le texte par section
with open("./report.md", "r") as f:
text = f.read()
chunks = chunk_by_section(text)
Le rapport étant un document Markdown bien structuré, la stratégie par section est la bonne : chaque segment épouse une frontière logique du document — une section, une idée. C’est la décision de découpage étudiée à la leçon précédente, appliquée à son cas idéal.
Étape 2 : Générer les embeddings pour chaque chunk
embeddings = [generate_embedding(chunk) for chunk in chunks]
Cette étape implique plusieurs appels API et prend du temps — c’est l’étape lente et payante du pipeline. Chaque chunk est converti en représentation vectorielle numérique qui capture son sens. Notez le contexte d’exécution : ce travail appartient à la phase d’indexation, exécutée une fois par document — pas à chaque question. Son coût s’amortit sur toutes les recherches futures.
Étape 3 : Stocker dans la base vectorielle
store = VectorIndex()
for embedding, chunk in zip(embeddings, chunks):
store.add_vector(embedding, {"content": chunk})
Le zip réapparie chaque vecteur avec son texte source, et c’est le point essentiel de l’étape : stockez à la fois l’embedding et le texte original. Récupérer uniquement une liste de nombres n’est pas utile — vous avez besoin du texte réel qui correspond à ces embeddings. Le dictionnaire de métadonnées attaché au vecteur ({"content": chunk}) est le véhicule de ce texte ; on pourrait y glisser d’autres champs — titre de section, numéro de page — qui voyageraient avec chaque résultat.
Étape 4 : Générer l’embedding de la requête utilisateur
user_embedding = generate_embedding(
"Qu'a fait le département d'ingénierie logicielle l'année dernière ?"
)
Ici commence la phase de question, répétée à chaque interaction. Cela crée une représentation vectorielle de la question qui peut être comparée aux embeddings stockés — et la comparaison n’a de sens que parce que question et chunks passent par le même modèle d’embedding, donc vivent dans le même espace sémantique.
Étape 5 : Rechercher et récupérer les chunks pertinents
results = store.search(user_embedding, 2)
for doc, distance in results:
print(distance, "\n", doc["content"][0:200], "\n")
Les résultats sont classés par pertinence, chaque segment accompagné de sa distance cosinus — des distances plus faibles signalent de meilleurs résultats. Sur notre rapport, le premier segment retourné est bien la section d’ingénierie logicielle, sans qu’aucun mot-clé n’ait été programmé. Prenez l’habitude de lire ces distances comme un indicateur de confiance : un premier résultat nettement détaché du second inspire confiance ; des distances toutes similaires suggèrent que la question ne discrimine pas bien les sections — signal utile pour le débogage du pipeline.
Pourquoi stocker le texte avec les embeddings
Revenons sur la décision de conception cruciale de l’étape 3, car elle conditionne l’usage final. Sans le texte original, vous ne récupéreriez que des tableaux de nombres inutilisables — aucun humain ni aucun prompt ne consomme un vecteur. En incluant le texte source, vous pouvez immédiatement utiliser les chunks récupérés pour fournir du contexte à votre modèle de langage : ce sont ces extraits, insérés dans le prompt, qui permettront à Claude de répondre à partir du document.
Cela complète le workflow RAG de base — découper, vectoriser, stocker, vectoriser la question, rechercher. Des optimisations substantielles restent possibles (recherche hybride, reranking, retrieval contextuel), et ce sont précisément les prochaines leçons.
Points clés à retenir
- Cinq étapes : découpage, embeddings, stockage, embedding de la question, recherche
- L’indexation (étapes 1-3) s’exécute une fois par document ; la question (4-5) à chaque interaction
- Toujours stocker le texte avec son vecteur — les métadonnées voyagent avec chaque résultat
- Question et chunks doivent passer par le même modèle d’embedding
- Distances faibles = pertinence ; des écarts nets entre résultats sont un signe de bonne discrimination