Quand le RAG répond mal, regardez d’abord ce qu’il a trouvé

L’assistant répond avec assurance et cite le mauvais paragraphe. Le grand modèle reçoit immédiatement le blâme. Mon premier diagnostic est plus simple : quels passages la recherche lui a-t-elle réellement remis?

Un système RAG commence bien avant la question. Un pipeline lit les fichiers, extrait texte et structure, choisit des blocs, calcule un embedding pour chacun et les écrit dans un index avec l’identifiant du document, sa version et ses permissions. À la requête, la question reçoit elle aussi un embedding; le moteur cherche les voisins puis combine les meilleurs passages dans le contexte du modèle.

documents -> extraction -> découpage -> embeddings -> index + ACL
question  -> identité -> recherche hybride -> passages autorisés
          -> modèle -> réponse + citations

OpenAI a présenté en janvier une nouvelle génération de modèles d’embeddings. Un embedding représente un texte par un vecteur. La similarité cosinus compare l’angle de deux vecteurs :

similarité(a,b) = (a · b) / (||a|| x ||b||)

Une valeur élevée signifie proximité selon le modèle, pas vérité. Un numéro de pièce, une date ou un acronyme rare se trouve souvent mieux par correspondance lexicale. Je préfère une recherche hybride où mots-clés et vecteurs fournissent des candidats, puis un reclassement combine les scores.

Tester d’abord la récupération

Je construirais 100 questions avec le passage attendu et au moins 30 cas négatifs. Pour chacune :

  1. exécuter la recherche sans appeler le grand modèle;
  2. afficher les dix passages, scores, versions et filtres;
  3. mesurer si le bon passage est dans les trois premiers;
  4. tester noms propres, numéros, synonymes et questions ambiguës;
  5. répéter avec un compte autorisé et un compte refusé;
  6. retirer ou modifier un document et mesurer le délai de l’index.

Le découpage change beaucoup le résultat. Un bloc de deux pages mélange plusieurs règles; une seule phrase peut perdre l’exception juste après. Je garderais titres, numéros de section et chevauchement raisonnable, puis adapterais les limites aux contrats, procédures et tableaux. Un changement de stratégie exige une réindexation versionnée et une comparaison sur le même jeu.

Les permissions doivent filtrer avant l’envoi au modèle. Chaque bloc conserve la référence à la source et à sa liste d’accès, ou le moteur rejoint un service d’autorisation au moment de la requête. Filtrer seulement les citations affichées est trop tard : un passage interdit déjà placé dans le contexte peut influencer ou apparaître dans la réponse.

La fraîcheur exige des événements de création, modification et suppression. Une suppression écrit un marqueur et retire les blocs; une tâche de réconciliation compare périodiquement l’index avec la source pour récupérer les événements manqués. Un index indisponible doit produire une erreur ou un mode de recherche classique, jamais une réponse fondée sur un cache dont l’âge est inconnu.

Je journaliserais identifiants et scores, pas tout le contenu sensible. Les citations pointent vers la version exacte consultée et l’interface indique lorsqu’aucun passage ne soutient la réponse. Un modèle plus puissant ne corrige pas une mauvaise source. Si la récupération n’atteint pas le seuil sur les questions connues, j’améliore extraction, découpage, hybridation et droits avant de changer de modèle.