Québec, Canada

403-1381 1re Avenue

+1 581.849.27.96

bdgouthiere@gmail.com

RAG (Retrieval-Augmented Generation) : donner des sources à l'IA avant qu'elle invente

Ou : Pourquoi les LLM mentent moins quand on leur file les réponses à l’avance


Vous connaissez la différence entre un examen à livre fermé et un examen à livre ouvert. À livre fermé, vous récitez ce que vous avez mémorisé — et si votre mémoire est floue, vous improvisez avec une assurance que votre professeur qualifierait de « créative ». À livre ouvert, vous cherchez la réponse dans vos notes, vous la trouvez (ou pas), et vous reformulez. Le résultat est radicalement différent. Pas parce que vous êtes plus intelligent avec vos notes. Parce que vous inventez moins.

Les LLM passent leur vie à passer des examens à livre fermé. Ils ont « lu » Internet pendant leur entraînement, ils en ont retenu une version compressée et statistique, et quand vous leur posez une question, ils reconstruisent une réponse à partir de cette mémoire floue. Parfois c’est brillant. Parfois c’est une hallucination parfaitement formulée.

Le RAGRetrieval-Augmented Generation, littéralement « génération augmentée par récupération » — c’est l’idée de leur donner un livre ouvert. Avant de répondre, le système va chercher des documents pertinents dans une base de connaissances et les injecte dans le prompt. Le modèle génère alors sa réponse en s’appuyant sur ces documents. Il a des sources. Il peut les citer. Et il invente beaucoup moins.

C’est simple sur le papier. En pratique, chaque étape du pipeline peut mal tourner de façons créatives et surprenantes.

Le pipeline RAG, étape par étape — de la question à la réponse sourcée

L’architecture en cinq temps

Un pipeline RAG classique se déroule en cinq étapes. Cinq étapes qui ont l’air simples quand on les dessine sur un tableau blanc, et qui deviennent un projet d’ingénierie complet quand on essaie de les faire fonctionner en production.

1. Ingestion — On prend les documents de la base de connaissances (PDF, pages web, fichiers Markdown, base de données, emails, tickets Jira, tout ce qui contient du texte) et on les découpe en chunks — des morceaux de taille gérable. C’est la première décision non triviale du pipeline, et on y reviendra.

2. Embedding — Chaque chunk est converti en un vecteur numérique — une liste de centaines ou milliers de nombres qui encode le sens du texte dans un espace géométrique. Deux chunks qui parlent du même sujet se retrouvent proches dans cet espace, même s’ils utilisent des mots différents. C’est ce qui permet la recherche sémantique : chercher par sens, pas par mots-clés.

3. Indexation — Les vecteurs sont stockés dans une base de données vectorielle — un système optimisé pour retrouver rapidement les vecteurs les plus proches d’un vecteur donné. C’est le cœur technique du RAG. Sans recherche vectorielle rapide, le reste s’écroule.

4. Retrieval — L’utilisateur pose une question. La question est elle-même convertie en vecteur (avec le même modèle d’embedding), puis on cherche dans la base les chunks dont les vecteurs sont les plus proches. On en récupère typiquement 3 à 10, selon le budget de tokens disponible.

5. Generation — Les chunks récupérés sont injectés dans le prompt du LLM, avec la question de l’utilisateur et une instruction du type « Réponds en te basant uniquement sur les documents fournis. Si l’information n’est pas dans les documents, dis-le. » Le modèle génère sa réponse. Avec des sources. En théorie.

Le chunking, ou l’art de découper du texte sans le massacrer

Le chunking est le problème le plus sous-estimé du RAG. Vous avez un document de 50 pages. Vous ne pouvez pas l’envoyer en entier au modèle à chaque requête — ça coûterait une fortune en tokens et ça noierait l’information pertinente dans du bruit. Donc vous découpez.

Mais comment ?

Par taille fixe : découper tous les 512 tokens, avec un chevauchement de 50-100 tokens entre les chunks. C’est la méthode la plus courante. C’est aussi la plus bête. Imaginez découper un roman tous les 500 mots : vous allez couper des phrases en deux, séparer une question de sa réponse, isoler un paragraphe de conclusion de l’argument qu’il conclut.

Par structure : respecter les frontières naturelles du document — sections, paragraphes, titres. Si votre document est bien structuré (avec des headings, des sections claires), c’est nettement mieux. Si votre document est un PDF scanné de 1997 sans aucune structure… bon courage.

Par sémantique : utiliser un modèle pour détecter les ruptures de sujet et découper aux changements de thème. C’est la méthode la plus intelligente et la plus coûteuse. En pratique, c’est souvent un luxe réservé aux pipelines les plus sophistiqués.

La taille idéale des chunks fait l’objet d’un débat quasi-religieux dans la communauté. Trop petits (128 tokens), et ils manquent de contexte — le chunk contient un fait mais pas l’explication qui le rend compréhensible. Trop grands (2 048 tokens), et la recherche perd en précision — vous ramenez du bruit avec le signal. La fourchette courante se situe entre 256 et 1 024 tokens, avec un chevauchement de 10 à 20%1.

Les embeddings : transformer le sens en géométrie

Les embeddings sont la colle qui tient le RAG ensemble. L’idée : projeter chaque morceau de texte dans un espace à haute dimension (768, 1 024, voire 3 072 dimensions) de sorte que des textes sémantiquement proches se retrouvent géométriquement proches.

Concrètement, « Comment nourrir un chat ? » et « Alimentation féline : guide pratique » seraient représentés par des vecteurs très proches, même s’ils ne partagent presque aucun mot. C’est la différence fondamentale avec une recherche par mots-clés : la recherche sémantique comprend le sens, pas juste la surface.

Les modèles d’embedding populaires incluent text-embedding-3 d’OpenAI, les modèles embed de Cohere, et côté open source, les familles BGE (BAAI) et E5 (Microsoft). Le choix du modèle d’embedding est, contrairement à ce qu’on pourrait croire, au moins aussi important que le choix du LLM lui-même. Un mauvais modèle d’embedding signifie que votre recherche ramène les mauvais documents, et à ce moment-là, peu importe la qualité du modèle de génération — garbage in, garbage out.

La métrique standard pour mesurer la proximité entre vecteurs est la similarité cosinus — l’angle entre deux vecteurs, indépendamment de leur longueur. Deux vecteurs qui pointent dans la même direction ont une similarité de 1. Deux vecteurs perpendiculaires, 0. Deux vecteurs opposés, -1.

Les bases de données vectorielles : le nouveau jouet de l’infrastructure

Stocker des vecteurs dans une base relationnelle classique est possible. Les retrouver rapidement, c’est une autre histoire. Les bases de données vectorielles sont des systèmes spécialisés dans la recherche de voisins les plus proches (nearest neighbor search) — trouver, parmi des millions de vecteurs, les k plus similaires à un vecteur donné.

Les noms à connaître :

BaseTypeParticularité
PineconeCloud managéPlug-and-play, pas d’infra à gérer
WeaviateOpen sourceRecherche hybride (vecteurs + mots-clés) native
ChromaOpen sourceLégère, idéale pour le prototypage
QdrantOpen sourceÉcrite en Rust, performances brutes
MilvusOpen sourceConçue pour le passage à l’échelle (milliards de vecteurs)
pgvectorExtension PostgreSQLRAG sans nouvelle base — si vous avez déjà Postgres

Le choix dépend de votre contexte. Si vous prototypez, Chroma ou pgvector suffisent. Si vous avez 50 millions de documents et des exigences de latence à la milliseconde, vous êtes dans le territoire de Milvus ou Pinecone. Et si vous ne voulez pas gérer d’infrastructure supplémentaire, pgvector a l’avantage de transformer votre PostgreSQL existant en base vectorielle — c’est le genre de solution pragmatique qui ne gagne pas de concours de beauté mais qui fait le travail.

La recherche hybride : le meilleur des deux mondes

La recherche purement sémantique a un défaut gênant : elle est mauvaise pour les correspondances exactes. Si quelqu’un cherche « erreur 403 API v2.3 », la recherche sémantique va comprendre « problème d’accès API » — ce qui est correct mais imprécis. Elle risque de remonter des documents sur les erreurs 401 ou 500, parce que sémantiquement, c’est proche.

La recherche hybride combine la recherche vectorielle (sémantique) avec une recherche par mots-clés classique (typiquement BM25, l’algorithme derrière la plupart des moteurs de recherche textuels). Les résultats des deux sont fusionnés et re-classés. Vous obtenez la compréhension du sens et la précision lexicale.

En pratique, la recherche hybride surpasse presque systématiquement la recherche purement vectorielle. C’est devenu le standard de facto dans les pipelines RAG sérieux2.

Le débat : RAG vs contexte long — faut-il encore découper ?

Avec des fenêtres de contexte qui atteignent maintenant un million de tokens, une question légitime se pose : pourquoi ne pas simplement tout mettre dans le prompt ? Pourquoi s’embêter avec le chunking, les embeddings, les bases vectorielles, quand on peut balancer 500 pages de documentation directement dans le contexte du modèle ?

La réponse tient en trois mots : coût, vitesse, précision.

Coût : envoyer un million de tokens à chaque requête, c’est cher. Le RAG n’envoie que les chunks pertinents — typiquement quelques milliers de tokens. La différence sur la facture est d’un ou deux ordres de grandeur.

Vitesse : plus le prompt est long, plus l’inférence est lente. Le premier token met plus de temps à arriver, et l’utilisateur attend.

Précision : paradoxalement, les modèles sont moins performants quand on leur donne trop de contexte. L’information pertinente se noie dans le bruit. Plusieurs études ont montré que les LLM ont du mal à utiliser l’information située au milieu d’un contexte très long — un phénomène surnommé « lost in the middle »3.

Le contexte long n’élimine pas le RAG. Il le complète. On peut utiliser le RAG pour sélectionner les documents pertinents, puis les injecter dans un contexte long pour que le modèle ait plus de marge de manœuvre. Les deux approches ne sont pas en compétition — elles sont complémentaires.

Les modes d’échec du RAG (parce qu’il faut en parler)

Le RAG n’est pas magique. Voici les façons dont il peut mal tourner, classées par fréquence :

Le retrieval ramène les mauvais documents. C’est le problème numéro un. Si votre question est ambiguë, si vos embeddings sont de mauvaise qualité, si vos chunks sont mal découpés, le système va remonter des documents non pertinents. Et le LLM, fidèle à lui-même, va quand même générer une réponse confiante basée sur ces mauvais documents. C’est pire qu’une hallucination classique, parce que le système a l’air de citer des sources — sauf que ce sont les mauvaises.

Le document pertinent existe mais n’est pas trouvé. La base contient la réponse, mais le modèle d’embedding ne fait pas le lien entre la question et le chunk pertinent. Le modèle répond alors « je n’ai pas trouvé l’information » (dans le meilleur cas) ou invente (dans le pire).

Le LLM ignore les documents fournis. On lui dit « base-toi sur les documents », et il répond de mémoire. Ça arrive, surtout quand le contenu des documents contredit ce que le modèle « sait » de son entraînement. Le modèle a tendance à faire confiance à sa mémoire statistique plutôt qu’au document qu’on vient de lui donner.

L’information est là mais mal formatée. Le chunk contient un tableau, et le modèle n’arrive pas à l’interpréter. Ou le chunk est une image avec du texte (un scan), et le pipeline d’ingestion n’a pas fait d’OCR. Ou le chunk contient une formule mathématique en LaTeX, et le modèle fait n’importe quoi avec.

Le dialogue du pipeline cassé

DevOps Dave : Le chatbot RAG est en prod. Les utilisateurs adorent.

Security Sarah : Ils trouvent les bonnes réponses ?

DevOps Dave : Oui ! Enfin… surtout. Il y a un ticket qui dit que le bot a répondu « notre politique de remboursement est de 30 jours » alors qu’on l’a changée à 14 jours en janvier.

Security Sarah : Le document mis à jour est dans la base vectorielle ?

DevOps Dave : Oui. Les deux versions, en fait. L’ancienne et la nouvelle.

Security Sarah : Et tu t’étonnes que le modèle cite parfois l’ancienne ?

DevOps Dave : Je pensais qu’il prendrait la plus récente automatiquement.

Security Sarah : Le retriever cherche la similarité sémantique, pas la date. « Politique de remboursement : 30 jours » et « politique de remboursement : 14 jours » ont exactement le même score de similarité par rapport à la question « quel est le délai de remboursement ? ». Pile ou face.

DevOps Dave : … Je vais ajouter un filtre de date.

Security Sarah : Tu vois, le RAG, c’est pas juste « je branche une base vectorielle et c’est parti ».

Tableau récapitulatif

ConceptEn une phrase
RAGDonner des documents au LLM avant qu’il réponde pour qu’il invente moins.
ChunkingDécouper les documents en morceaux de taille gérable (256-1 024 tokens).
EmbeddingConvertir du texte en vecteur numérique qui encode le sens.
Base vectorielleBase de données spécialisée dans la recherche de vecteurs similaires.
Similarité cosinusMesure de proximité entre deux vecteurs (angle, pas distance).
Recherche hybrideCombiner recherche sémantique (vecteurs) et lexicale (BM25).
RetrievalL’étape où on va chercher les chunks pertinents dans la base.
Lost in the middleLes LLM peinent à utiliser l’info au milieu d’un contexte très long.

Le mot de la fin

Le RAG est né d’une observation simple : un modèle de langage qui a accès à ses notes donne de meilleures réponses qu’un modèle qui improvise. L’article fondateur de Lewis et al. (Facebook AI Research, 2020) a posé les bases, et depuis, toute une industrie s’est construite autour de cette idée — bases vectorielles, modèles d’embedding, frameworks d’orchestration, startups de « RAG-as-a-service ».

Ce qui est ironique, c’est que le RAG est fondamentalement un aveu d’humilité. On ne fait pas confiance au modèle pour se souvenir de tout. On ne fait pas confiance à sa mémoire statistique pour être exacte. Alors on lui donne des documents, comme un professeur qui accepte que ses étudiants viennent avec leurs notes à l’examen, parce qu’il sait que ce qui compte, ce n’est pas la mémorisation — c’est la capacité à trouver la bonne information et à l’utiliser intelligemment.

Les LLM sont remarquablement bons pour la seconde partie. Le RAG s’occupe de la première.



  1. Le chevauchement (overlap) entre chunks existe pour éviter de perdre du contexte aux frontières. Si un fait important est à cheval entre deux chunks, le chevauchement garantit qu’au moins un des deux le contient en entier. C’est un filet de sécurité. Il coûte un peu d’espace de stockage et de calcul, mais l’alternative — perdre des informations aux coutures — est pire. ↩︎

  2. L’algorithme BM25 (Best Matching 25) date de 1994 — la même année que le BPE de Philip Gage, décidément une bonne année pour les algorithmes qui refusent de prendre leur retraite. BM25 est une fonction de scoring basée sur la fréquence des termes et la longueur du document, et il est encore utilisé par Elasticsearch et la plupart des moteurs de recherche textuels. Le combiner avec des embeddings modernes, c’est marier trente ans de recherche d’information classique avec cinq ans de deep learning↩︎

  3. L’article « Lost in the Middle: How Language Models Use Long Contexts » (Liu et al., 2023) a montré que les LLM ont tendance à mieux utiliser l’information placée au début et à la fin du contexte, et à ignorer ce qui se trouve au milieu. C’est un résultat contre-intuitif — on s’attendrait à ce qu’un modèle avec un million de tokens de contexte utilise toute l’information de façon uniforme. Ce n’est pas le cas. La position dans le prompt influence la qualité de la réponse. ↩︎