Construire un pipeline de Génération Augmentée par Récupération (RAG) est souvent la première étape pour moderniser une application d'entreprise avec des modèles de langage de grande taille (LLM). Cependant, le parcours qui mène d'un prototype fonctionnel à un système de qualité production est là où la plupart des équipes échouent. Le défi fondamental ne réside pas dans la construction du système, mais dans la mesure de sa qualité. Contrairement aux logiciels traditionnels où nous disposons de tests unitaires déterministes, les systèmes RAG introduisent des éléments probabilistes à chaque étape : récupération, fractionnement du contexte et génération. Cela rend l'évaluation considérablement plus complexe. Dans cet article, nous disséquons l'architecture de l'évaluation du RAG, en allant au-delà des simples métriques de précision pour adopter des cadres robustes et automatisés.
Pourquoi les métriques standards échouent
Pendant des années, nous nous sommes fiés à des métriques comme BLEU ou ROUGE pour évaluer la génération de texte. Ces métriques reposent sur la superposition de n-grammes avec un texte de référence. Dans un contexte RAG, cette approche est fondamentalement erronée. Si un système récupère le bon document mais formule la réponse différemment de la référence, BLEU le pénalisera lourdement, même si la réponse est factuellement correcte. De plus, BLEU ne nous renseigne rien sur la composante de récupération elle-même. Un système peut récupérer des documents parfaitement non pertinents et halluciner tout de même une réponse qui ressemble superficiellement à la vérité terrain, tout en restant inutile pour l'utilisateur.
Pour évaluer correctement le RAG, nous devons décomposer le problème en deux phases distinctes : l'Évaluation de la Récupération et l'Évaluation de la Génération. Chaque phase nécessite des métriques spécifiques qui traitent de ses modes d'échec uniques.
Mesurer la performance de la récupération
Avant de regarder ce que le LLM génère, nous devons nous assurer que la fenêtre de contexte est alimentée par des informations pertinentes. Les deux métriques principales pour cela sont le Recall@K et le MRR (Mean Reciprocal Rank ou Rang Réciproque Moyen). Le Recall@K mesure la fraction de documents pertinents récupérés parmi les K premiers résultats. Si vos réponses de vérité terrain sont situées dans les identifiants de document [101, 102], et que votre récupérateur retourne [101, 50, 99], votre Recall@2 est de 0,5 (50 %).
Cependant, en production, nous manquons souvent d'annotations de vérité terrain pour chaque requête. C'est ici que le Hit Rate (Taux de réussite) devient pratique. Si nous savons que la réponse existe dans la base de connaissances, le récupérateur a-t-il extrait le fragment contenant cette réponse ? De plus, les scores de similarité sémantique utilisant des modèles d'embedding peuvent fournir une heuristique de pertinence lorsque les données étiquetées sont rares.
Évaluer la génération avec LLM-as-a-Judge
Évaluer l'étape de génération est plus délicat car il existe rarement une seule réponse « correcte ». L'essor du paradigme LLM-as-a-Judge (LLM comme juge) a transformé ce paysage. En utilisant un LLM plus puissant (comme GPT-4 ou Claude 3) pour critiquer la sortie du LLM de votre application, nous pouvons automatiser le processus d'évaluation.
Les métriques clés ici incluent :
- Fidélité (Faithfulness) : La réponse générée repose-t-elle uniquement sur le contexte fourni ? Si le modèle ajoute des connaissances externes ou hallucine des faits absents des fragments récupérés, il échoue à cette métrique.
- Pertinence de la réponse (Answer Relevance) : La réponse générée répond-elle réellement à la question de l'utilisateur ?
Mettre en œuvre cela nécessite une ingénierie de prompt soignée pour minimiser les biais du modèle juge. Voici un exemple conceptuel en Python utilisant une structure de bibliothèque d'évaluation standard :
from ragas import evaluate
from datasets import Dataset
# Définir votre jeu de données de test
data_samples = {
'question': ["Quelle est la capitale de la France ?", "Qui a écrit Hamlet ?"],
'answer': ["Paris est la capitale de la France.", "William Shakespeare a écrit Hamlet."],
'contexts': [["Paris est la ville capitale de la France.", "La Tour Eiffel est à Paris."], ["William Shakespeare était un dramaturge anglais.", "Hamlet est une tragédie de Shakespeare."]],
'ground_truth': ["Paris", "William Shakespeare"]
}
# Évaluer en utilisant les métriques par défaut (fidélité, pertinence de la réponse, précision du contexte)
result = evaluate(
dataset,
metrics=[faithfulness, answer_relevance, context_precision]
)
print(result)
Outils pratiques : RAGAS et TruLens
Construire ces évaluateurs à partir de zéro est fastidieux. Des bibliothèques comme RAGAS (Retrieval Augmented Generation Assessment System) et TruLens sont apparues pour résoudre ce problème. RAGAS est particulièrement populaire car il permet une évaluation basée uniquement sur le contexte, ce qui signifie que vous n'avez pas toujours besoin de réponses de vérité terrain pour la phase de génération, seulement pour la phase de récupération. Il calcule un score composite RAGAS qui équilibre la fidélité, la précision du contexte et la pertinence de la réponse, vous offrant un nombre unique pour suivre les améliorations au fil du temps.
Conclusion
Évaluer les systèmes RAG n'est pas une tâche ponctuelle, mais un processus continu. À mesure que votre base de connaissances grandit et que vos requêtes deviennent plus complexes, les benchmarks statiques échoueront à capturer les nuances des performances de votre système. En combinant des métriques de récupération déterministes avec des juges de génération probabilistes basés sur les LLM, vous pouvez créer une boucle de rétroaction robuste. Commencez par mesurer le rappel, puis ajoutez des vérifications de fidélité, et enfin, mettez en œuvre des tests de régression automatisés dans votre pipeline CI/CD pour garantir que votre système RAG évolue de manière responsable.