Tu suis la course aux modèles IA ?
Chaque sortie (GPT, Claude, Gemini, Mistral…) décryptée le soir même, en 5 min. Gratuit.
Inclus dès l'inscription : notre sélection des meilleurs guides & comparatifs IA.
Choisis ton rythme
Gratuit · Pas de spam · Désabonnement en 1 clic
Des fenêtres de contexte plus larges ne corrigent pas RAG
Dans une tentative d'améliorer la précision des réponses fournies par les modèles de langage, j'ai multiplié par cinq la taille de la fenêtre de contexte. Cependant, chaque ajustement a conduit à des résultats inattendus. J'ai conçu un système de questions-réponses basé sur un ensemble de données, mais j'ai constaté que les réponses RAG étaient souvent à peine à moitié correctes.
Un test sur 100 000 lignes
Pour évaluer la performance de RAG, j'ai mesuré ses capacités à travers sept types de requêtes et cinq tailles de contexte, en utilisant un ensemble de 100 000 lignes de données. Ce test visait à déterminer comment le modèle gérait des requêtes d'agrégation complexes.
Une confiance mal placée
Le mois dernier, j'ai travaillé sur une nouvelle fonctionnalité pour EmiTechLogic. Cette fonctionnalité permet aux utilisateurs de télécharger leurs fichiers CSV désordonnés et de poser des questions en anglais simple. Cela semblait idéal pour RAG, donc j'ai investi dans cette technologie, en utilisant des embeddings et des techniques de récupération pour présenter des réponses bien structurées.
Lors des premières démonstrations, les résultats étaient impressionnants : des tableaux bien organisés, des chiffres précis et un formatage professionnel. J'ai même commencé à faire confiance au système lors de nos tests internes. Cependant, lorsque j'ai vérifié un chiffre, les dépenses réelles en épicerie dans l'ensemble de données étaient de 1 140 033,24 $. Le modèle a fourni une répartition par catégorie qui semblait légitime, mais le total était inférieur à la moitié de la dépense réelle.
L'illusion de la précision
Face à cette incohérence, j'ai augmenté la fenêtre de contexte à 4k, puis à 16k, 32k, et enfin 128k tokens. À chaque étape, la réponse devenait plus longue et plus détaillée, mais toujours incorrecte. J'ai compris que le problème ne venait pas de la récupération, mais du fait que je demandais à un système de récupération d'effectuer des calculs complexes sur des données qu'il n'avait vues qu'en partie. Le modèle produisait des réponses polies et structurées qui semblaient correctes, mais qui étaient fondamentalement erronées.
Pourquoi RAG échoue à agréger
Le pipeline RAG ne comprend pas vraiment les données structurées. Il transforme chaque ligne CSV en texte brut, sans véritablement interpréter les données. Pour une requête comme "Quel est le total des dépenses par catégorie ?", le pipeline suit plusieurs étapes :
- Tokenisation : il identifie les mots-clés pertinents.
- Évaluation : il évalue toutes les lignes pour trouver des chevauchements de mots-clés.
- Retourne : il retourne les premières lignes sous forme de texte brut.
- Demande : il demande au modèle de langage de faire la somme et de regrouper les données.
C'est à l'étape finale que le système échoue. Le modèle ne réalise pas une somme réelle, mais imite une agrégation en générant une réponse basée sur des motifs de nombres.
Un benchmark révélateur
Pour mesurer précisément ces défaillances, j'ai construit un benchmark comparant deux pipelines pour chaque requête. Le premier est une simulation RAG, testant cinq tailles de contexte allant de 5 lignes à 8 000, soit de 325 tokens à 500 000. Pour chaque taille, j'ai suivi trois métriques : la quantité de données vue par le modèle, la somme calculée à partir de ce segment, et la capacité d'un lecteur à détecter l'erreur.
Le second pipeline est un moteur sémantique qui exécute la même requête en effectuant un scan complet des 100 000 lignes, retournant une réponse exacte.
Comparaison des flux de traitement
La simulation ne reproduit pas les sorties exactes du modèle de langage, mais elle conserve une propriété structurelle clé : un segment partiel de données est alimenté dans un système qui retourne une réponse complète. C'est cette propriété qui cause le problème, et c'est ce que le benchmark mesure.
J'ai choisi sept types de requêtes pour couvrir chaque modèle d'agrégation que l'on pourrait rencontrer dans un système de données structurées :
- Dépenses totales par catégorie : nécessite de sommer toutes les lignes à travers 14 groupes.
- Transaction moyenne la plus élevée par catégorie : la moyenne change avec chaque ligne manquante.
- Total dépensé sur grocery_pos : le filtre nécessite de voir toutes les lignes correspondantes.
- Combien de clientes féminines ont effectué des transactions : le compte est sans signification sur un scan partiel.
- Dépenses totales où le montant > 500 $ : la logique de seuil nécessite des données complètes.
- État avec les dépenses totales les plus basses : le minimum ne peut être trouvé qu'avec tous les groupes présents.
- Pourcentage de transactions frauduleuses : le ratio est indéfini sur un dénominateur partiel.
Ces requêtes sont standard dans l'analyse de données, ce qui rend cet échec critique.
Effondrement de l'observabilité des erreurs
Voici la sortie complète du benchmark pour la requête qui a tout déclenché. Les chiffres rendent le problème impossible à ignorer.
VÉRITÉ FONDAMENTALE (Moteur Sémantique)
SOMME(amt) GROUPE PAR catégorie → 14 groupes
#1 grocery_pos 1 140 033,24 $
#2 shopping_net 773 527,93 $
#3 shopping_pos 725 766,14 $
#4 gas_transport 648 804,24 $
#5 home 556 526,53 $
Latence : 100,47 ms | Lignes scannées : 100 000
SIMULATION RAG — ce que le LLM reçoit à chaque taille de contexte
- Contexte Lignes Couverture Somme partielle Erreur détectable ?
- petit (~325 tokens) 5 0,0050% 197,73 FACILE
- petit (~3K tokens) 50 0,0500% 2 003,56 MODÉRÉ
- moyen (~32K tokens) 500 0,5000% 31 023,21 DIFFICILE
- grand (~130K tokens) 2 000 2,0000% 140 093,16 TRÈS DIFFICILE
- très grand (~520K tokens) 8 000 8,0000% 569 368,22 PRESQUE IMPOSSIBLE
J'ai observé ces résultats pendant un moment. La partie la plus troublante n'était pas seulement que les réponses étaient fausses, mais à quel point il devenait plus difficile de repérer les erreurs à mesure que la fenêtre de contexte grandissait.
À 8 000 lignes, l'erreur était toujours supérieure à 50 %, mais la réponse ressemblait à un rapport professionnel. Vous auriez besoin de vérifier manuellement les chiffres pour remarquer quelque chose d'anormal. C'est ce que j'ai commencé à appeler Effondrement de l'observabilité des erreurs. Plus je donnais de contexte au modèle, plus la sortie devenait convaincante — mais pas plus précise.
La colonne "Somme partielle" montre le total si le LLM additionnait chaque valeur dans les lignes qu'il a réellement récupérées. La colonne "Erreur détectable ?" évalue la probabilité qu'un lecteur humain repère une erreur.
Avec 5 lignes, la somme partielle est 197,73. Le total correct est 1 140 033,24. C'est évident. La sortie est courte, les chiffres sont faux, et les données manquantes sont claires. L'erreur est instantanée.
À 8 000 lignes, la somme partielle atteint 569 368,22. Le LLM a maintenant vu toutes les 14 catégories. Il génère un rapport de 1 500 mots avec des chiffres spécifiques et un langage confiant. L'erreur est de 50 %, mais elle est cachée dans une prose autoritaire et bien structurée. Sans référence externe, un lecteur n'a aucun moyen de la détecter.
C'est le schéma qui s'est maintenu à travers les sept requêtes :
- Taille de la fenêtre de contexte | Lignes | Couverture de l'ensemble de données | Longueur de la réponse | Erreur détectable ?
- ~325 tokens | 5 | 0,005% | ~50 mots | OUI — évidemment une supposition
- ~3K tokens | 500 | 0,050% | ~150 mots | PEUT-ÊTRE
- ~32K tokens | 500 | 0,500% | ~400 mots | DIFFICILE
- ~130K tokens | 2 000 | 2,000% | ~800 mots | TRÈS DIFFICILE
- ~520K tokens | 8 000 | 8,000% | ~1 500 mots | PRESQUE IMPOSSIBLE
- Moteur Sémantique | 100 000 | 100% | <200 ms | N/A — exact
J'ai appelé cela Effondrement de l'observabilité des erreurs. À mesure que le contexte grandit, la confiance augmente avec lui. La justesse ne suit pas.
L'illusion du contexte
Les modes de défaillance sont asymétriques, ce qui les rend dangereux :
Une réponse RAG incorrecte semble correcte. Elle est formatée, spécifique et confiante. Un calcul échoué génère une erreur explicite. Elle est visible.
Une défaillance est silencieuse. L'autre est bruyante. À mesure que les fenêtres de contexte atteignent des millions de tokens, la défaillance silencieuse devient plus difficile à détecter. Le système ne devient pas plus sûr à mesure qu'il se développe. Il devient juste plus convaincant.
Le Moteur Sémantique : Preuve que la réponse correcte est rapide
Avant de comprendre pleinement le problème, j'avais déjà assemblé un simple moteur sémantique par frustration. Je voulais juste la réponse correcte au moins une fois.
L'approche s'est révélée simple : analyser la requête en opérations appropriées et effectuer un seul passage sur l'ensemble de données. Pas d'embeddings, pas de récupération, pas de devinette.
Voici à quoi cela ressemble en pratique :
La logique est simple. Prenez une requête comme "Quel est le total des dépenses par catégorie ?". Le moteur la mappe à une opération directe : SOMME(amt) GROUPE PAR catégorie. Il traite l'ensemble des 100 000 lignes en un seul passage. Il accumule les totaux regroupés. Il n'y a pas de récupération. Pas d'inférence. Pas de scan partiel. Il visite chaque ligne une fois et retourne le résultat exact.
Cela prouve que la réponse correcte n'est pas coûteuse. Les requêtes de benchmark se terminent en moins de 200 ms. Taille de l'échantillon : 100 000 lignes. L'agrégation est triviale. L'échec se produit lorsque vous dirigez ces requêtes vers un système construit pour les mal comprendre.


