Aller au contenu
Retour au blog

RAG en production : les leçons que personne ne vous donne

6 min de lecture
RAGLLMProductionArchitecture

Tout le monde sait construire un prototype RAG en un après-midi. La vraie question, c'est ce qui se passe quand vous mettez ce prototype face à de vrais utilisateurs, de vrais documents, et de vraies contraintes de coût.

Produit fictif. Patterns d'ingénierie réels.

Le fossé entre démo et production

Sur AuditLens — une plateforme d'analyse de conformité réglementaire — le prototype initial était séduisant. Un pipeline synchrone simple : l'utilisateur télécharge un document, Elasticsearch retrouve les passages réglementaires pertinents, le LLM produit une analyse structurée. En démo, c'était magique. Les responsables conformité regardaient le système disséquer un document de 200 pages et retourner des constats structurés avec citations réglementaires. On avait le buy-in en quelques semaines.

En production, la réalité a frappé vite. Les documents réglementaires font parfois plusieurs centaines de pages. Les timeouts HTTP sont devenus la norme — pas l'exception. Un crash du service ML en cours d'analyse signifiait une perte silencieuse du travail, sans possibilité de récupérer le traitement partiel. Et quand plusieurs analystes lançaient des vérifications simultanées avant une échéance réglementaire, les pics de charge étaient totalement imprévisibles. Le pipeline qui paraissait blindé en démo échouait plusieurs fois par jour.

La couche de retrieval avait ses propres problèmes. Une recherche par mots-clés naïve sur plus de 50 000 provisions réglementaires indexées ramenait trop de bruit. Le LLM dépensait des tokens à analyser des passages non pertinents, ce qui gonflait les coûts et dégradait la qualité des résultats. Il fallait une stratégie de retrieval plus intelligente avant de scaler quoi que ce soit.

Du synchrone à l'asynchrone — la migration qui a tout changé

La solution n'était pas incrémentale. On a reconstruit le modèle d'exécution, passant d'appels HTTP synchrones à une architecture entièrement asynchrone basée sur des files de messages.

Loading diagram…

Les files SQS avec retry en backoff exponentiel géraient les erreurs transitoires. Les Dead Letter Queues capturaient les messages en échec répété — cela seul a permis d'atteindre un taux de récupération de 99.7% sur des cas limites qui auraient été silencieusement perdus dans le modèle synchrone. Le statut des jobs était suivi en PostgreSQL pour que le frontend puisse interroger toutes les quelques secondes et afficher une barre de progression.

La migration n'était pas triviale. Chaque contrat d'API entre frontend et backend a changé. Le frontend est passé de "envoyer et attendre la réponse" à "envoyer, recevoir un job ID, poller le statut." Il a fallu repenser le workflow des analystes autour de ce nouveau modèle mental.

Le résultat inattendu : les utilisateurs préféraient le modèle asynchrone. Ils pouvaient lancer plusieurs analyses en parallèle et continuer à travailler en attendant — une capacité que le système synchrone n'offrait pas. Un analyste préparant un audit pouvait lancer cinq documents d'un coup, puis consulter les résultats au fil de leur arrivée. La latence P95 pour une analyse complète s'est stabilisée sous les 45 secondes, avec plus de 200 analyses simultanées supportées sans dégradation.

Un pipeline de retrieval en quatre étapes

Le problème de qualité du retrieval exigeait une approche multi-étapes, pas une correction de requête unique. Au départ, on a essayé de tuner le scoring de pertinence Elasticsearch seul — ajuster les facteurs de boost, ajouter des dictionnaires de synonymes pour la terminologie réglementaire. L'amélioration était marginale, car le vrai problème restait entier : le matching par mots-clés ne distingue pas une provision qui définit une exigence d'une autre qui la mentionne en passant.

D'abord, Elasticsearch effectuait une recherche par mots-clés sur le corpus réglementaire, en ratissant large. Ensuite, un passage de filtrage LLM éliminait le bruit — des passages correspondant aux mots-clés mais contextuellement hors sujet. Cette étape seule réduisait l'ensemble candidat d'environ 60%. Troisièmement, un reclassement sémantique par embeddings et similarité cosinus faisait remonter les passages les plus pertinents. Enfin, une sélection fine des chunks extrayait les passages exacts nécessaires à l'analyse.

Ce pipeline en quatre étapes signifiait que le LLM ne traitait que du contenu pré-validé et hautement pertinent. La réduction de consommation de tokens inutiles était spectaculaire — et elle se composait avec la stratégie de tiering de coûts, car moins de tokens en entrée signifiait que des modèles moins chers pouvaient prendre en charge une plus grande part du travail.

Contrôler les coûts sans sacrifier la qualité

Un pipeline RAG en production, c'est aussi un problème de coûts. Les documents réglementaires sont longs, et une seule analyse de conformité peut consommer des milliers de tokens à travers de multiples appels LLM. Sans contrôle, les coûts scaleraient linéairement avec l'usage.

L'approche était multi-couches. Toutes les tâches ne nécessitaient pas le modèle le plus puissant. Les vérifications de cohérence simples — vérifier que les définitions concordent entre sections, contrôler les références croisées — utilisaient des modèles plus légers et moins chers. Le raisonnement réglementaire complexe — interpréter des provisions ambiguës, identifier des risques subtils de non-conformité — faisait appel aux modèles plus capables.

Le pré-filtrage Elasticsearch signifiait que le LLM ne voyait jamais le corpus réglementaire complet, uniquement la tranche pertinente. Un chunking intelligent garantissait que les documents n'étaient jamais envoyés en entier — chaque chunk était dimensionné pour tenir dans la fenêtre de contexte du modèle avec de la place pour le prompt système et le format de sortie structurée. Un système de cache basé sur le hashing détectait les analyses répétées de sections similaires — fréquent quand plusieurs versions d'une même politique étaient téléchargées pendant un cycle d'audit. Des dashboards Datadog suivaient le coût par fonctionnalité et par tier client en temps réel, avec des alertes sur les anomalies de dépense. La combinaison du tiering, du pré-filtrage et du caching a ramené le coût par analyse à un niveau où une tarification à l'usage devenait viable — quelque chose qui n'était même pas envisageable avec l'architecture synchrone originale.

Ce que j'en retiens

Le RAG en production n'est pas un problème d'IA — c'est un problème d'ingénierie système. La qualité du retrieval compte plus que la puissance du modèle : un pipeline en quatre étapes avec du pré-filtrage peu coûteux surpasse l'injection massive de tokens coûteux sur du contenu bruité. L'architecture asynchrone n'est pas un compromis, c'est un avantage que les utilisateurs préfèrent activement. Et les coûts LLM se contrôlent par le design — modèles tiered, pré-filtrage agressif, caching — pas par l'optimisation après coup.

Le prototype décroche le rendez-vous. Le système de production décroche le contrat.