Déboguez le pipeline, pas le LLM : un modèle mental pour les échecs RAG en environnement de production
Lorsqu’un bot RAG donne une mauvaise réponse, le LLM est rarement la cause. Suivez les échecs depuis l’ingestion, la récupération, la génération, l’évaluation jusqu’au cycle pour identifier le niveau problématique.
Sources: RAG Is Not Just Vector Search
Imaginez un bot d’assistance dans une entreprise SaaS de taille moyenne qui, un jour, répond différemment à deux clients qui posent tous deux des questions sur la période de remboursement.
Un incident est ouvert, et la première pensée de l’ingénieur de garde est que le LLM hallucine et qu’un modèle différent est nécessaire. C’est le diagnostic de base : on considère RAG comme une boîte noire, on change de modèle en espérant que les symptômes disparaîtront.
Un ingénieur expérimenté commence par une autre approche en se demandant à quel stade du processus quelque chose a échoué. Dire que le modèle hallucine des noms n’est qu’un symptôme et n’explique rien.
Deux jours plus tard, le véritable problème apparaît. La politique de remboursement avait été modifiée, mais personne n’a supprimé le PDF obsolète du corpus de récupération, de sorte que les deux versions continuaient d’apparaître avec des scores de pertinence similaires, et le modèle résumait fidèlement des contextes contradictoires. Il ne hallucinait pas du tout. (Il s’agit d’un scénario composite à des fins illustratives, mais des variantes de celui-ci sont courantes.)
Voici la différence entre la version théorique du RAG et la manière dont le RAG en usage réel échoue. Les tutoriels le résument généralement en une seule ligne :
Embed → Search → Generate
Cela suffit pour une démonstration mais pas pour un environnement de production. Un système réel dispose de plusieurs limites de défaillance. La question d’ingénierie importante n’est pas seulement de savoir si le LLM peut produire une bonne réponse, mais aussi si chaque couche qui alimente cette réponse fonctionne correctement.
Ingestion : la qualité est déterminée avant même le début de la récupération
La plupart des débogages liés aux systèmes RAG commencent par le mauvais bout. Les gens ajustent les prompts, changent de modèles d’incorporation et modifient les paramètres top-k, alors que la véritable erreur a été introduite des semaines auparavant lors de l’ingestion.
Analyse par structure
Les tableaux, les blocs de code, les titres et les listes transmettent du sens grâce à leur structure. Si l’on transforme un tableau de prix en prose simple, le lien entre une ligne et son en-tête de colonne peut disparaître. Un pipeline d’ingestion doit conserver cette structure et choisir une représentation adaptée à la récupération des informations, plutôt que de traiter chaque document comme un bloc de texte indifférencié.
La méthode appropriée dépend du contenu. Un tableau peut nécessiter une extraction structurée, une sérialisation de texte, des métadonnées, ou une combinaison de récupération lexicale et sémantique.
Chunkage par sens
La méthode simple divise le texte en tronçons tous les 512 tokens. Cependant, le nombre de tokens et le sens ne coïncident pas, de sorte qu’un tronçon peut commencer par une introduction et s’arrêter en cours de route, avant d’atteindre l’objectif visé.
Le chunkage sémantique vise à diviser le texte en fonction des changements de sujet plutôt qu’en fonction du nombre de tokens. Ce n’est pas une amélioration universelle et il entraîne des coûts plus élevés lors de l’ingestion. Pour des documents longs tels que des politiques, des contrats ou de la documentation technique, conserver l’intégrité des idées améliore souvent les résultats de la récupération.
Fournir un contexte à chaque tronçon avant l’embedding
Un extrait tiré de la page 40 d’un document de 60 pages peut être un texte parfaitement valide, mais rester ambigu en dehors de son contexte d’origine. Prenons une phrase indiquant qu’une limite s’applique uniquement aux clients Enterprise. Sans la section qui l’entoure, rien ne permet à l’outil de savoir à quoi fait référence cette « limite ».
La récupération contextuelle résout ce problème en ajoutant en tête de l’extrait le contexte au niveau du document : le titre, le chemin de la section, le produit, la version, ou une brève note indiquant l’endroit où se trouve l’extrait. L’objectif est que chaque extrait conserve le contexte que la segmentation aurait sinon supprimé.
Joindre des métadonnées
Considérez les métadonnées comme des données fonctionnelles. Les étapes ultérieures ont besoin de l’origine, de la date, du type de document, du propriétaire, des permissions et de la version afin de filtrer, de contrôler l’accès, de vérifier la fraîcheur des données et de diagnostiquer les problèmes.
Cela soulève l’une des questions les plus importantes en matière de production lors de l’ingestion : que se passe-t-il si un document source change demain ? Si le pipeline ne peut que réindexer tout le contenu, une petite modification devient un fardeau opérationnel. L’ingestion devrait idéalement être incrémentale et idempotente, afin qu’une mise à jour soit détectée, traitée et diffusée sans devoir reconstruire l’ensemble du corpus.
Dans l’histoire présentée au début, l’ancienne politique de remboursement n’était jamais due à une erreur du LLM. La cause résidait plutôt dans la manière dont l’ingestion et le corpus étaient gérés.
La récupération est un pipeline et non une recherche
Le terme suggère une seule étape. En pratique, la récupération est une série de choix, et l’ordre de ces choix a des conséquences.
1. Réécrire
Les gens n’écrivent pas naturellement des requêtes de recherche. Ils posent des questions du type savoir si un remboursement a été envoyé. Un LLM peut transformer cela en quelque chose de plus utile pour la récupération des informations, en intégrant peut-être l’historique de la conversation ou en divisant une question complexe en questions plus ciblées. Cependant, la réécriture n’est pas gratuite : une mauvaise réécriture peut omettre des détails importants ou ajouter des suppositions. Considérez-la comme un élément supplémentaire à évaluer et non comme de la magie.
2. Définir la portée avant la recherche
C’est l’un des détails les plus importants en environnement de production. Si le système est multi-locataire ou gère les permissions, l’espace de recherche doit respecter ces limites. Le locataire, les permissions, la visibilité, la date et la source doivent être pris en compte lors de l’opération de récupération, là où le système sous-jacent le permet.
Le filtrage après un top-k global pose deux problèmes. Premièrement, des documents utiles peuvent déjà avoir été éliminés du top-k par des documents que l’utilisateur n’a pas le droit de voir. Deuxièmement, la logique d’autorisation finit par être dangereusement séparée de la récupération des données. En termes simples, ne recherchez pas tout d’abord pour ensuite déterminer ce que l’utilisateur peut voir ; restreignez d’abord la recherche.
3. Recherche de deux manières
La recherche vectorielle dense gère bien la proximité sémantique. Une personne qui demande comment annuler peut être associée à un texte indiquant que les clients peuvent résilier leur forfait à tout moment, même en l’absence de mots en commun.
Cependant, les embeddings sont moins efficaces avec des identifiants exacts. Pensez à des chaînes de caractères comme celles-ci :
ERR_CONNECTION_RESET
SKU-48392
API-v3-beta
Pour de telles requêtes, le token littéral constitue le signal, et c’est là que la récupération lexicale comme BM25 trouve son utilité. La récupération de production associe souvent une recherche dense axée sur le sens à une recherche lexicale pour des chaînes de caractères exactes.
4. Fusionner
On dispose désormais de deux listes classées. La recherche dense a son propre ordre, BM25 en a un autre, et leurs scores bruts ne sont pas nécessairement comparables. La Fusion de rangs réciproques (RRF) propose une méthode simple pour les fusionner en utilisant la position dans le classement :
RRF_score(d) = Σ 1 / (k + rank_i(d))
Chaque liste contribue en fonction de la position d’un document à l’intérieur d’elle, ce qui évite de devoir calibrer les distributions de scores de deux systèmes non liés entre eux.
5. Réclasser
La fusion fournit un ensemble de candidats, qui n’est pas nécessairement le contexte final. Un réclasseur à codeur croisé lit la requête ainsi que chacun des candidats et génère un score de pertinence pour cette paire spécifique. Cela diffère fondamentalement de l’approche où la requête et le document sont encodés indépendamment avant comparaison des vecteurs.
Le coût réside dans les calculs, c’est pourquoi on n’applique pas un codeur croisé sur l’ensemble du corpus. La récupération peut retourner les 20 ou 50 meilleurs candidats, et le réclasseur choisit alors le contexte le plus pertinent parmi eux.
Le modèle mental de fonctionnement est donc : récupération dense, puis récupération lexicale, puis fusion, enfin réclassement. Ce n’est pas simplement « base de données vectorielle, terminé ».
Génération : un bon contexte ne garantit pas pour autant une bonne réponse
Il est nécessaire de trouver les documents appropriés, mais cela ne suffit pas. Le LLM doit encore les utiliser correctement.
Gestion de la fenêtre de contexte
Un plus grand contexte ne conduit pas automatiquement à une meilleure réponse. Les modèles n’utilisent pas de manière égale les contextes longs. Des recherches ont montré que les informations situées au milieu d’un contexte long peuvent être mémorisées avec moins de fiabilité que celles situées au début ou à la fin. Intégrer les 20 premiers extraits dans la demande peut donc nuire à la qualité de la réponse. L’objectif est un contexte utile au maximum, et non un contexte maximal.
Limites de la demande et attribution
Précisez dans la demande comment les extraits obtenus doivent être utilisés. Le modèle doit les traiter comme des preuves à citer, et jamais comme des instructions à suivre.
Les citations aident également à renforcer la confiance et à diagnostiquer les problèmes. Lorsqu’une réponse indique que les clients Enterprise disposent de 30 jours pour annuler, il est nécessaire de pouvoir retracer cette affirmation à une source fiable.
Abstention
L’abstention marque une différence majeure entre un système de démonstration et un système fiable. Même si la recherche ne donne aucun résultat, un modèle essaiera quand même d’aider, à moins que le refus ne soit une option autorisée. Un système de production devrait être capable de répondre que les preuves ne sont pas suffisantes. C’est souvent la bonne décision et non un défaut.
En l’absence d’abstention, chaque échec de recherche peut se transformer en hallucination. Le LLM prend la responsabilité de fournir une réponse erronée, alors que l’échec réel a pu survenir à plusieurs niveaux antérieurs.
L’évaluation précède toute correction
RAG présente une propriété délicate : la qualité peut diminuer même si le code d’application reste inchangé. Un nouveau modèle d’incorporation, une méthode de segmentation différente, l’ajout ou la suppression de documents, des ajustements des paramètres de récupération ou une modification de la prompt peuvent chacun changer les réponses, même lorsque le code déployé hier est identique mot pour mot. Par conséquent, le RAG en environnement de production doit être évalué à plusieurs niveaux.
Qualité de la récupération. La précision du contexte porte sur la part du contexte récupéré qui était pertinent. Le rappel du contexte concerne la part des informations pertinentes disponibles que la récupération a réellement trouvées. Ensemble, ils permettent de distinguer le cas où « nous ne l’avons jamais trouvé » de celui où « nous l’avons trouvé mais l’avons perdu dans le bruit ».
Qualité de la génération. La fidélité (également appelée ancrage) vérifie que la réponse découle des preuves obtenues, tandis que la précision des citations s’assure que les sources citées soutiennent chaque affirmation. Une réponse bien rédigée peut néanmoins manquer d’ancrage.
Santé du système. Les métriques opérationnelles sont également importantes : latence p95, coût par requête et taux d’abstention. Il ne s’agit pas seulement de problèmes d’infrastructure. Si la latence double parce qu’un agent commence à exécuter plusieurs boucles de récupération, cela fait partie de la qualité du système. Une augmentation soudaine du taux d’abstention peut indiquer une dégradation de la récupération des informations. Une hausse du coût par requête peut signifier qu’un changement apparemment inoffensif a introduit une méthode coûteuse.
La séparation des mesures s’avère utile pour le diagnostic. Un rappel sain associé à une diminution du niveau de connexion vers le réel indique une génération de résultats. Une baisse de la précision pointe vers des problèmes liés à l’ingestion, aux filtres, au retraitement ou au classement. Si l’on ne suit que la qualité globale des réponses, chaque régression semble identique et ne fournit aucun élément concret pour agir.
De la chaîne de traitement à la boucle de retours
La chaîne de traitement de base reste simple :
Ingestion → Retrieval → Generation → Evaluation
De nombreux systèmes n’ont besoin de rien de plus. Une base de connaissances bien indexée et des questions claires nécessitent rarement qu’un agent choisisse la prochaine étape. Cependant, des questions plus complexes existent bel et bien.
Prenons par exemple une demande visant à comparer les chiffres des revenus du deuxième trimestre avec ceux indiqués dans la présentation destinée au conseil d’administration, puis à expliquer la différence. La réponse peut exiger les chiffres du Q2, la présentation du conseil, les sections pertinentes de chacune, une comparaison, et éventuellement une consultation d’une autre source de données. Une seule recherche peut ne pas suffire, et c’est là que l’approche agentic RAG devient utile. Au lieu d’une simple étape de récupération suivie de génération, on peut mettre en œuvre une boucle :
Retrieve
↓
Evaluate
↓
Enough evidence?
↓ no
Retrieve again
↓
Generate
Un tel système peut conclure que les preuves actuelles sont insuffisantes, reformuler la requête, effectuer une nouvelle recherche, ou transmettre une sous-question à une base de données SQL, un graphe de connaissances ou une API en temps réel. La récupération des informations devient itérative et n’est plus une action unique.
Cependant, le RAG agentique n’est pas automatiquement meilleur. Chaque boucle supplémentaire augmente la latence, le coût en tokens et les risques d’échec, et peut déclencher des recherches inutiles lorsque l’agent n’a aucune raison claire de continuer. Sa complexité s’avère utile lorsque les questions sont ambiguës, nécessitent plusieurs étapes ou plusieurs sources. Une question concernant la politique de remboursement devrait probablement être répondue en une seule passe par un pipeline statique bien conçu. La comparaison entre les jeux de cartes pourrait justifier une itération.
La question pertinente est de savoir si le système a une raison mesurable de chercher à nouveau, et non de savoir s’il devrait disposer d’un agent. Itérer sans règle claire de sortie ne fait qu’augmenter les délais et les coûts.
Un modèle mental pour la production
Partir du LLM est l’erreur de débogage la plus courante. Une mauvaise réponse n’est que le dernier symptôme visible, tandis que la cause peut se trouver bien plus en amont. Des documents obsolètes ressemblent à des hallucinations, un mauvais découpage des données ressemble à une erreur de récupération, une récupération insuffisante ressemble à une faille de génération, et l’absence d’évaluation cache toutes ces problématiques jusqu’à ce que les clients se plaignent.
Ne demandez donc pas quel modèle utiliser. Demandez plutôt quelle couche est défaillante.
INGESTION
↓
RETRIEVAL
↓
GENERATION
↓
EVALUATION
↖
└── feedback loop / Agentic RAG
Des données obsolètes signifient qu’il faut corriger le processus d’ingestion. Un document manquant signifie qu’il faut corriger le mécanisme de récupération. Un document trouvé mais classé en bas signifie qu’il faut améliorer le système de classement. Un contexte correct associé à une réponse erronée indique qu’il faut examiner le processus de génération. Si vous ne pouvez pas déterminer lequel des problèmes s’applique, construisez d’abord un système d’évaluation plus fiable. Et lorsque une seule passe ne suffit jamais, envisagez un cycle agentiel.
Commencez par le pipeline et laissez le modèle pour la fin.
D’où viennent ces idées
Pour en savoir plus, l’article original sur la génération améliorée par la récupération de Lewis et ses collaborateurs (NeurIPS 2020) définit le modèle de base. L’étude d’Anthropic de 2024 sur la récupération contextuelle indique une forte réduction des échecs de récupération grâce aux embeddings contextuels, au BM25 contextuel et au reranking, bien que ce soient des mesures effectuées par le fournisseur lui-même. Cormack, Clarke et Büttcher (SIGIR 2009) ont introduit la Fusion de rangs réciproques. L’article « Lost in the Middle » de Liu et ses collaborateurs étudie la manière dont les modèles utilisent des contextes longs, l’article RAGAs décrit l’évaluation automatisée de RAG, et l’article Self-RAG d’Asai et ses collaborateurs aborde la récupération auto-réflexive et agente.
Lectures complémentaires
- Notes pratiques : Les limites de la recherche vectorielle dans RAG — Similarité cosinus et autres aspects — Guide pas à pas des Notes pratiques : Les limites de la recherche vectorielle dans RAG — Similarité cosinus et autres aspects : contrats, vérifications et espaces de code prêts à l’emploi pour les équipes qui implémentent ce modèle.
- Le sens en tant que coordonnées : Des embeddings aux bases de données vectorielles et au RAG — Explication simple des embeddings de phrases, de la similarité cosinus, des bases de données vectorielles et du cycle RAG, avec quatre petites phrases sur les chiens, les chats et Paris pour montrer comment fonctionne la recherche sémantique.