J'ai cru que RAG allait tout résoudre
J'ai cru que RAG allait tout résoudre. J'ai passé des semaines à débugger des hallucinations. Voici ce que j'ai appris.
Quand j'ai découvert le RAG, j'ai pensé avoir trouvé la solution magique. Mon agent allait enfin pouvoir répondre sur nos données internes. Fini les hallucinations.
J'ai implémenté un système "propre". Embeddings, base vectorielle, chunking optimisé.
Et puis les utilisateurs ont commencé à tester. Le résultat ? Des réponses à côté de la plaque, des documents ignorés, et des hallucinations encore plus confiantes qu'avant.
Voici ce que j'aurais aimé qu'on me dise dès le début.
RAG ne résout pas les hallucinations
C'est le truc qui m'a pris le plus de temps à accepter.
Je pensais : "Si je donne les bons documents au LLM, il va forcément bien répondre." Faux.
Le LLM peut avoir le bon document sous les yeux et quand même inventer. Pourquoi ? Parce qu'il prédit toujours le texte le plus probable. Si ta question ressemble à quelque chose qu'il a vu pendant l'entraînement, il va parfois ignorer ton contexte et répondre "de mémoire".
J'ai vu Claude citer correctement un de nos documents... puis ajouter une fonctionnalité qui n'existe pas. Le document était là, dans le contexte. Il l'a juste... ignoré pour la fin de sa réponse.
Le chunking, c'est 80% du travail
Au début, j'ai fait comme tout le monde : chunks de 500 tokens, overlap de 50. "C'est ce que tout le monde utilise."
Résultat : des réponses incohérentes parce que le contexte était coupé au mauvais endroit.
Un exemple concret : notre doc expliquait une procédure en 3 étapes. Mon chunking coupait entre l'étape 2 et 3. Le LLM récupérait le chunk avec les étapes 1 et 2, et inventait une étape 3 "logique" mais fausse.
J'ai revu tout le découpage. Chunks par section logique, pas par nombre de tokens. C'est moins "propre" mathématiquement, mais ça marche.
La recherche vectorielle a des angles morts
Les embeddings capturent le sens sémantique. Super pour "Comment créer un compte" qui matche avec "Inscription nouvel utilisateur".
Mais pour les questions factuelles précises ? C'est la galère.
"Quel est le prix du plan Pro ?" Un humain irait chercher la page pricing. Mon RAG retournait des articles de blog qui mentionnaient vaguement les tarifs. Sémantiquement proche, factuellement inutile.
Google DeepMind a montré qu'il existe un "plafond mathématique" sur ce que les embeddings peuvent capturer. Certaines relations entre questions et documents sont juste trop complexes.
Ma solution ? Hybrid search. Recherche vectorielle + recherche par mots-clés (BM25). Quand quelqu'un cherche "prix plan Pro", la recherche exacte trouve la bonne page.
Plus de contexte n'est pas toujours mieux
J'ai fait l'erreur classique : "Si 5 chunks c'est bien, 10 c'est mieux."
Non.
Plus tu injectes de contexte, plus le LLM peut se perdre. Il y a même un phénomène documenté : le "lost in the middle". Les LLMs ont tendance à mieux retenir le début et la fin du contexte, et à "oublier" le milieu.
Ethan Mollick conseille de traiter les LLMs comme des "stagiaires brillants mais distraits". Tu ne donnes pas 50 pages à un stagiaire en lui demandant de tout retenir.
Maintenant je limite à 3-5 chunks max, et je m'assure que le plus pertinent soit en premier.
Les coûts s'accumulent vite
Personne ne m'avait prévenu pour les coûts cachés.
L'indexation initiale ? OK, c'est un one-shot. Mais ensuite :
- Chaque mise à jour de doc = re-génération d'embeddings
- Chaque requête = appel au modèle d'embedding + appel au LLM
- La base vectorielle = hébergement permanent
Sur un mois de prod chez Geta.Team, les coûts d'embeddings représentaient presque autant que les appels LLM. Je ne m'y attendais pas.
Parfois, RAG n'est pas la réponse
Le plus dur à admettre : j'aurais pu éviter tout ça.
Notre base documentaire ? 50 pages. Ça tenait dans le contexte de Claude (200k tokens). J'aurais pu juste... tout mettre dans le prompt.
J'ai construit une usine à gaz pour un problème qui n'existait pas.
Simon Willison a cette règle : "Commence toujours par la solution la plus simple qui pourrait marcher." Pour moins de 100 pages, un prompt avec le contexte complet est souvent suffisant.
Ce qui a changé ma façon d'implémenter
Après ces galères, voici mes réflexes :
Je commence sans RAG. Si le contexte tient dans le prompt, je n'ajoute pas de complexité. Je passe au RAG seulement quand c'est nécessaire.
Je chunk par logique, pas par tokens. Sections, paragraphes complets, procédures entières. Tant pis si les tailles varient.
J'utilise hybrid search par défaut. Vectoriel + BM25. Ça couvre les deux types de requêtes.
Je limite le contexte injecté. 3-5 chunks max. Le plus pertinent en premier.
Je teste avec des questions pièges. Questions factuelles précises, questions qui nécessitent plusieurs sources, questions hors sujet. Si ça passe ces tests, c'est bon.
RAG n'est pas magique. C'est un outil avec des cas d'usage précis et des limites réelles.
Comprendre ça m'a fait passer de "pourquoi mon RAG hallucine encore" à "je sais quand RAG est la bonne solution et quand c'est overkill".
Sources :