Chapitre 10 · RAG · 9 min
Lire tes documents
Comment un LLM accède à des milliers de pages sans les mémoriser. Embeddings, recherche sémantique, contexte injecté.
La limite que le contexte ne peut pas résoudre
Imagine que tu veuilles construire un assistant capable de répondre à des questions sur l'ensemble de la documentation interne de ton entreprise — 50 000 pages, mises à jour chaque semaine.
Même avec une fenêtre de 1 million de tokens, tu ne peux pas tout mettre dedans. Et si tu pouvais, le coût serait prohibitif et la qualité des réponses se dégraderait : les modèles ont du mal à extraire des informations précises dans des contextes très longs.
Il faut une autre approche. C'est le RAG — Retrieval-Augmented Generation.
L'idée fondamentale
Plutôt que de donner tout le document au modèle, tu lui donnes uniquement les passages pertinents pour sa question. Pour faire ça, tu as besoin de deux choses :
- Un index : une représentation vectorielle de tous tes documents, stockée à l'avance.
- Un moteur de recherche sémantique : quand une question arrive, il trouve les passages les plus proches sémantiquement.
Les passages trouvés sont ensuite injectés dans le contexte du LLM avec la question. Le modèle répond en s'appuyant sur ces extraits.
C'est exactement ce que fait la recherche sémantique avec les embeddings que tu connais déjà depuis le chapitre 03 — mais appliquée à des documents réels.
Le pipeline en trois étapes
1. L'indexation (une seule fois)
On découpe le document en chunks — des extraits de quelques centaines de tokens (avec un léger chevauchement entre eux pour ne pas couper le sens à la frontière).
Chaque chunk est ensuite converti en vecteur par un modèle d'embedding. Ces vecteurs sont stockés dans une base de données vectorielle (Pinecone, Chroma, pgvector…).
Cette étape se fait une seule fois, ou à chaque mise à jour du document.
2. La recherche (à chaque question)
Quand une question arrive, on la convertit en vecteur avec le même modèle d'embedding.
On calcule la similarité cosinus entre ce vecteur-question et les vecteurs-chunks de la base. Les k chunks les plus proches sont récupérés — en général 3 à 5. (En vrai, on ne compare pas à tous les chunks : passé quelques dizaines de milliers de vecteurs, les bases vectorielles utilisent des index approximatifs — HNSW, IVF — qui trouvent les plus proches voisins sans tout parcourir. C'est même leur raison d'être.)
C'est la recherche sémantique : "proche" ne veut pas dire "qui contient les mêmes mots", mais "qui exprime un sens similaire".
3. La génération
Les chunks récupérés sont assemblés dans un prompt :
Extraits du document :
[Extrait 1 — ...]
[Extrait 2 — ...]
[Extrait 3 — ...]
Question : {question de l'utilisateur}
Ce prompt est envoyé au LLM, qui génère une réponse en s'appuyant sur les extraits. Le modèle n'a pas mémorisé le document — il le lit au moment où on lui pose la question.
Visualisation du pipeline
Voici le système en action sur un mini-corpus de planétologie. Choisis une question — observe quels chunks sont récupérés dans l'espace vectoriel et comment ils sont assemblés en contexte.
Choisis une question : elle est embedded, comparée aux chunks du corpus, et les plus pertinents sont injectés dans le prompt avant la génération. C'est ce détour qui permet à un LLM de répondre sur des documents qu'il n'a jamais vus pendant son entraînement.
Deux choses à retenir de cette manipulation. D'abord, les chunks récupérés ne sont pas ceux qui contiennent les mots de la question — demande "quelle est la plus grande planète ?" et tu obtiens les géantes gazeuses, alors que le mot "grande" n'apparaît nulle part dans ces extraits. C'est la proximité dans l'espace vectoriel qui décide, pas le vocabulaire. Ensuite, le modèle ne voit jamais le corpus entier : il ne reçoit que la poignée d'extraits sélectionnés. Toute la qualité d'un RAG se joue donc avant la génération. Si le bon chunk n'est pas récupéré, aucune finesse de prompt ne le rattrapera — c'est pour ça que le reste de ce chapitre parle surtout de découpage et de recherche.
La taille des chunks : un vrai choix d'ingénierie
Le découpage en chunks n'est pas anodin. C'est souvent la première source de problèmes dans un système RAG.
Chunks trop petits : chaque chunk est trop peu informatif. On récupère des fragments qui, sortis de contexte, ne permettent pas au modèle de répondre correctement.
Chunks trop grands : on dépasse la précision de l'embedding. Un vecteur qui représente 2 000 tokens est une moyenne floue — il sera récupéré pour certaines questions mais le contenu pertinent sera noyé dans le texte.
Une règle pratique : des chunks de 200 à 500 tokens, avec un overlap de 10-15 %. Le bon paramètre dépend de la structure de tes documents.
Quel modèle d'embedding utiliser ?
Toutes les questions ne mènent pas aux bons chunks avec le même embedding. Un modèle entraîné sur du français généraliste retrouvera mal du code Python ; un modèle entraîné sur du code retrouvera mal des échanges médicaux.
Les choix qui reviennent en pratique :
text-embedding-3-small/-large(OpenAI) — qualité solide, généraliste, multilingue. Longtemps le défaut quand on commençait ; aujourd'hui dépassé sur les benchmarks, mais toujours parfaitement utilisable.bge-large/bge-m3(BAAI) — open-source, excellent en multilingue. Ils dominaient les benchmarks MTEB en 2024.- Gemini Embedding (Google) — en tête du MTEB anglais.
- Qwen3-Embedding (Alibaba) — le meilleur des modèles à poids ouverts, que tu peux héberger toi-même.
- Voyage 3.x, Cohere
embed-v4, Jina v4 — les références commerciales du moment, la dernière étant multimodale (texte et images dans le même espace). all-MiniLM-L6-v2(Sentence-Transformers) — petit, rapide, déployable localement. Bon rapport qualité/coût pour des cas d'usage simples.- Modèles spécialisés par domaine (code, biomédical, juridique) — toujours meilleurs sur leur niche, plus faibles ailleurs.
Ce classement bouge tous les six mois. Et attention en le lisant : les scores MTEB v2 ne se comparent pas à ceux de la v1, les tâches ont changé entre les deux.
Une règle pratique : tester deux ou trois modèles sur tes données et tes questions. Le classement MTEB ne dit pas grand-chose de ton cas d'usage particulier.
Le reranker : la deuxième passe
La recherche vectorielle a un défaut : elle est rapide mais grossière. Un embedding de quelques centaines de dimensions est une moyenne floue d'un texte. Beaucoup de chunks "à peu près pertinents" surnagent, et les vrais bons sont parfois noyés.
D'où une étape devenue standard dans les systèmes RAG sérieux : le reranker.
L'idée en deux temps :
- Première passe (recherche vectorielle) — récupère les 50 ou 100 chunks les plus proches. Rapide.
- Deuxième passe (reranking) — un petit modèle (souvent un cross-encoder) évalue chaque paire
(question, chunk)ensemble, donne un score précis, et garde le top 5–10. Lent par chunk, mais on ne le fait que sur les 50 candidats de la première passe.
Le reranker voit la question et le chunk en même temps, ce que l'embedding ne fait pas. Il capte des subtilités sémantiques que la recherche vectorielle rate. Cohere, Jina AI, BAAI proposent des rerankers prêts à l'emploi.
Sans reranker, ton RAG plafonne. Avec, la qualité saute d'un cran sans changer le reste du pipeline.
Pourquoi pas du full-text search ?
Une question légitime : pourquoi ne pas simplement faire une recherche par mots-clés, comme un moteur de recherche classique ?
La recherche vectorielle est complémentaire, pas un remplacement. Elle trouve des passages sémantiquement proches, même si la formulation est différente. "Quelle planète tourne le plus lentement ?" peut retrouver un chunk qui parle de "période orbitale" sans que ces mots soient dans la question.
En pratique, les meilleurs systèmes combinent les deux : hybrid search — un score combinant similarité vectorielle et correspondance de mots-clés (BM25).
Les limites du RAG
Le RAG n'est pas magique. Voici les problèmes les plus fréquents :
Le chunk mal découpé. Si une réponse s'étale sur deux chunks et que la frontière de découpage tombe au mauvais endroit, aucun des deux chunks n'est suffisant seul.
Le "lost in the middle" à l'intérieur du chunk. Si le chunk est trop long, les informations importantes peuvent se retrouver au milieu et être ignorées par le modèle.
La question ambiguë. Si la question est vague, l'embedding-question sera loin de la plupart des chunks pertinents. Solution : reformuler la question, ou en générer plusieurs variantes.
Les hallucinations sur les extraits. Le LLM peut extrapoler au-delà de ce que disent les chunks. Le RAG réduit les hallucinations, il ne les élimine pas.
Ce que le RAG change en pratique
Le RAG est aujourd'hui la technique de référence pour connecter un LLM à des données privées ou récentes. Presque tous les chatbots d'entreprise, les assistants de documentation, les outils de veille s'appuient dessus.
Mais le pipeline classique — embed, retrieve, generate — est une architecture "passive" : le modèle reçoit une question, cherche des chunks, répond. Depuis 2025, il est concurrencé sur beaucoup de cas d'usage par la recherche agentique : on donne au modèle un outil de recherche et on le laisse chercher en boucle, reformuler, creuser jusqu'à avoir ce qu'il lui faut. Pour des tâches plus complexes — rechercher, puis agir en fonction du résultat, puis chercher encore — il faut aller un cran plus loin.
Mis à jour le