Tout le monde écrit sur le RAG, et les tutoriels donnent l'impression que c'est simple : vous embarquez vos documents, vous les jetez dans une base vectorielle, vous branchez un LLM, terminé. Livrez.
Je l'ai cru aussi, jusqu'au jour où il a fallu construire des systèmes RAG qui tiennent vraiment en production. Pas des démos. Pas des notebooks. Des systèmes où de vrais utilisateurs posent des questions imprévisibles, où une mauvaise réponse a des conséquences, et où « ça marche la plupart du temps » ne suffit pas.
Ces deux dernières années, j'ai construit et livré trois systèmes RAG en production : un assistant de documentation piloté par IA déployé sur AWS avec Kubernetes, une plateforme d'analyse de discours parlementaires traitant plus de 100 000 documents, et un assistant IA QHSE construit avec Spring AI et MCP. Chacun m'a appris des choses qu'aucun tutoriel n'a jamais mentionnées.
Voici ce que j'aurais aimé qu'on me dise avant de commencer.
Le piège de l'ingestion des documents
Le premier système que j'ai construit était un assistant de documentation : un chatbot capable de répondre à des questions sur la documentation projet interne. La stack était Python, Weaviate comme base vectorielle, et AWS SageMaker pour le LLM. Le déploiement tournait sur EKS avec des conteneurs Docker, orchestré par un pipeline CI/CD.
Le prototype a pris deux semaines. Le rendre prêt pour la production a pris trois mois.
La première leçon est tombée tout de suite : le composant le plus important, c'est votre pipeline d'ingestion. Pas le LLM. Pas le prompt. La façon dont vous traitez, découpez et embarquez les documents décide de 80 % de la qualité finale.
Découper n'est pas fractionner
Tous les tutoriels répètent « découpez vos documents en morceaux d'environ 500 tokens ». Un conseil techniquement exact et parfaitement inutile.
Dans l'assistant de documentation, les docs projet étaient profondément imbriquées : des spécifications dont les sous-sections renvoyaient à d'autres sous-sections, des tableaux qui n'avaient de sens qu'avec leur en-tête, des blocs de code qui ne voulaient plus rien dire coupés en deux. Un découpeur de texte récursif basique rasait tout ce contexte.
Ce qui a réellement marché :
- Un découpage attentif à la structure : analyser d'abord le format du document (titres Markdown, sections HTML, mise en page PDF) et découper le long des frontières sémantiques, pas des comptes de tokens
- Des fenêtres chevauchantes avec métadonnées : 15 à 20 % de chevauchement entre morceaux, avec les titres de section parents injectés en métadonnées pour que le retriever puisse évaluer la pertinence au regard du contexte plus large
- La préservation des tableaux : les tableaux étaient extraits entiers et stockés comme morceaux distincts avec un indicateur de type « table », jamais coupés entre les lignes
- Petits morceaux pour la récupération, grands morceaux pour la génération : le motif « parent-enfant », où l'on embarque de petits morceaux granulaires mais où l'on récupère le parent plus large quand une correspondance est trouvée
Si votre précision de récupération est mauvaise, n'ajustez pas votre prompt et ne changez pas de LLM. Corrigez d'abord votre découpage. J'ai vu des gains de précision de 20 à 30 % rien qu'avec un meilleur découpage : plus que tout ce que l'ingénierie de prompt m'a jamais apporté.
Le problème de la qualité de récupération
Le deuxième système, une plateforme RAG parlementaire, m'a obligé à affronter la qualité de récupération à l'échelle. Nous avions plus de 100 000 discours parlementaires que les citoyens pouvaient interroger en langage naturel. Le pipeline de classification thématique atteignait 95 % de précision, mais le composant RAG a d'abord peiné.
Le problème était d'une simplicité trompeuse : la similarité sémantique n'est pas la pertinence.
Un citoyen demandant « qu'a dit le parlement sur la réforme de la santé en 2023 ? » obtenait des résultats sémantiquement proches (des discours qui mentionnaient la santé) mais pas les plus pertinents. Les vrais débats de politique publique, les votes clés, les discours charnières étaient enfouis sous des dizaines de mentions accessoires.
La recherche hybride nous a sauvés
La recherche vectorielle seule ne suffisait pas. La recherche par mots-clés seule (BM25) non plus. Le déclic est venu de la combinaison des deux :
- La recherche vectorielle saisissait l'intention sémantique : comprendre que « réforme de la santé » se rapporte à « changements de politique médicale »
- La recherche par mots-clés BM25 saisissait la terminologie exacte : numéros de projets de loi, noms de responsables politiques, termes juridiques que les embeddings brouillent souvent
- La fusion par rang réciproque fusionnait les deux jeux de résultats, avec un rappel nettement meilleur que l'une ou l'autre approche seule
À l'échelle de plus de 100 000 documents, j'ai aussi appris que le filtrage par métadonnées n'est pas optionnel. Plages de dates, types de documents, rôles des intervenants, sessions parlementaires : ces filtres s'appliquent avant la recherche vectorielle, réduisant énormément l'espace de recherche et améliorant à la fois la vitesse et la pertinence.
Le re-ranking : le multiplicateur caché
Voilà une chose que presque aucun tutoriel n'aborde : vos premiers résultats de recherche ne sont que des candidats. Ce n'est pas le contexte final à donner à votre LLM.
Dans l'assistant de documentation, j'ai ajouté une étape de re-ranking par cross-encoder après la récupération. Le processus :
- Récupérer les 20 meilleurs morceaux depuis Weaviate par recherche hybride
- Reclasser ces 20 morceaux avec un modèle cross-encoder qui note chaque paire (requête, morceau)
- Ne transmettre au LLM que les 5 meilleurs morceaux reclassés
Le cross-encoder est plus lent que la similarité d'embeddings — il traite chaque paire une par une — mais nettement plus juste, parce qu'il voit la requête et le document ensemble, et non comme deux vecteurs indépendants.
La récupération vous amène dans le quartier. Le re-ranking vous amène à la bonne porte.
Le gain de précision était frappant. Sur notre jeu d'évaluation interne, le re-ranking a fait passer la qualité des réponses d'environ 72 % à 89 %, mesurée par évaluation humaine du critère « cette réponse répond-elle correctement et complètement à la question ».
Les défaillances dont personne ne parle
En production, les systèmes RAG échouent d'une manière qu'aucune démo ne montre. Voici les modes de défaillance croisés sur les trois systèmes :
1. La réponse fausse et assurée
Le LLM tombe sur un contexte à peu près pertinent et produit une réponse fluide, assurée, et subtilement fausse. L'utilisateur n'a aucun moyen de s'en apercevoir. C'est pire que pas de réponse du tout.
Mon correctif : toujours faire remonter les morceaux sources à côté de la réponse. Dans le système parlementaire, chaque réponse incluait des références cliquables vers les discours d'origine. Dans la plateforme QHSE, les réponses renvoyaient à la réglementation ou au document d'audit précis. Cela n'empêche pas l'hallucination, mais cela la rend vérifiable.
2. La question sans réponse
Les utilisateurs posent des questions auxquelles votre base ne peut tout simplement pas répondre. Un système RAG naïf remontera les morceaux « les moins hors sujet » et hallucinera quand même une réponse.
La solution qui a marché : un seuil de pertinence sur les scores de récupération. Si le meilleur morceau note en dessous d'un seuil calibré, le système répond « je n'ai pas assez d'informations pour répondre » au lieu de deviner. Calibrer ce seuil pour chaque domaine demande du tâtonnement : trop haut, vous rejetez des questions valides ; trop bas, vous laissez passer n'importe quoi.
3. Le problème des connaissances périmées
Les documents sont mis à jour. Les réglementations changent. De nouveaux discours sont publiés. Votre base vectorielle ne le sait pas, sauf si vous le lui dites.
Dans la plateforme QHSE (construite avec Spring AI, MCP et Groq), j'ai mis en place un pipeline d'ingestion incrémentale : les documents étaient versionnés, et les mises à jour ne déclenchaient le ré-embedding que des sections modifiées. Les suppressions étaient gérées par invalidation à base de métadonnées, pas par réindexation complète.
4. La question multi-sauts
« Comment le budget santé de 2022 se compare-t-il à celui de 2023 ? » Il faut aller chercher sur deux périodes distinctes, puis synthétiser. Une recherche en un seul coup se casse les dents.
L'approche qui a marché : la décomposition de requête. Le LLM commence par découper la question en sous-requêtes (« budget santé 2022 » et « budget santé 2023 »), récupère séparément pour chacune, puis synthétise. C'est plus lent mais nettement plus précis pour les questions comparatives ou en plusieurs étapes.
Leçons d'infrastructure tirées d'AWS
L'assistant de documentation tournait sur AWS EKS : des conteneurs gérés par Kubernetes avec des endpoints SageMaker pour le LLM. Voici ce que j'ai appris sur l'exécution d'un RAG dans le cloud :
- Séparez votre service d'embedding de votre service de génération : ils ont des profils de montée en charge complètement différents. L'embedding est limité par le CPU/GPU et arrive par à-coups pendant l'ingestion. La génération est sensible à la latence et suit le trafic utilisateur
- Le dimensionnement de la base vectorielle compte plus qu'on ne le croit : l'empreinte mémoire de Weaviate croît linéairement avec le nombre de vecteurs. Nous l'avions sous-estimée, et la production nous l'a fait payer en OOM kills. Prévoyez 2 à 3 fois la taille d'index attendue
- Mettez en cache sans complexe : les requêtes identiques ou presque sont bien plus fréquentes qu'on ne l'imagine. Un simple cache par hachage de requête, TTL d'une heure, a nettement allégé notre facture d'inférence SageMaker
- S3 comme source de vérité : les documents bruts vivaient dans S3, les morceaux traités dans la base vectorielle. Si la base vectorielle se corrompait ou devait être réindexée, nous pouvions toujours reconstruire depuis S3. Ça nous a sauvés deux fois
Votre base vectorielle est un stockage dérivé, pas un stockage primaire. Traitez-la comme un cache reconstructible. Gardez vos documents bruts et vos métadonnées de traitement dans un endroit durable. Quand (et non si) vous devrez réindexer avec un nouveau modèle d'embedding ou une autre stratégie de découpage, vous serez content de l'avoir fait.
L'évaluation : la partie la plus dure
Comment savoir si votre système RAG est réellement bon ? C'est la question sur laquelle je bute encore, après trois systèmes en production.
Ce à quoi je me suis arrêté, c'est une évaluation à trois couches :
- Qualité de récupération : pour une question donnée, les bons morceaux sont-ils dans le top 5 ? Mesurée par le rappel@5 sur un jeu de test constitué à la main. C'est la métrique la plus importante et celle que la plupart des gens sautent
- Qualité de réponse : avec les bons morceaux, le LLM produit-il une réponse correcte ? Cela isole la génération de la récupération. Mesurée par évaluation humaine sur un échantillon
- Qualité de bout en bout : pour une question donnée, la réponse finale est-elle correcte ? C'est ce que vivent les utilisateurs. Mesurée par une combinaison de contrôles automatisés et de revues humaines périodiques
L'idée décisive : si la recherche est cassée, rien en aval ne la réparera. J'ai vu des équipes passer des semaines à retoucher des prompts alors que le vrai problème était que les bons documents ne remontaient jamais. Déboguez toujours en partant de la recherche.
Ce que je ferais autrement
Si je démarrais un nouveau système RAG demain, voici ce que je changerais :
- Commencer par l'évaluation, pas par la construction : constituez votre jeu de test de 50 à 100 paires question/réponse avant d'écrire une ligne de pipeline. Chaque décision de conception se mesure ensuite contre lui
- Investir tôt dans le découpage : passez une semaine sur la stratégie de découpage avant de toucher à la récupération ou à la génération. Le retour sur investissement est énorme
- La recherche hybride dès le premier jour : ne partez pas sur du vectoriel pur en vous disant que vous « ajouterez BM25 plus tard ». Ce ne sont pas les mêmes hypothèses d'architecture
- Construire la boucle de retour en premier : instrumentez votre système pour capter quelles réponses les utilisateurs ont trouvées utiles et lesquelles non. Ces données valent de l'or pour itérer
- Garder votre LLM interchangeable : j'ai changé de LLM en cours de projet deux fois. Abstrayez la couche de génération pour pouvoir changer de modèle sans recâbler votre pipeline
Le RAG n'est pas un problème résolu. C'est une discipline d'ingénierie, qui réclame autant d'attention à la qualité des données, à l'infrastructure et à l'évaluation qu'à l'IA elle-même. Les tutoriels vous emmènent à 20 % du chemin. Les 80 % restants, c'est ce qui arrive quand de vrais utilisateurs rencontrent de vrais documents en production.
Ces 80 %, c'est là que vivent le vrai travail et la vraie valeur.
Commentaires
Pas de connexion, pas de pistage. Écrivez juste votre nom et votre avis. Restez courtois.