Évaluer un Système RAG avec Ragas
Comment savoir si votre RAG fonctionne vraiment ? Découvrez Ragas, le framework d'évaluation standard, et apprenez à mesurer faithfulness, relevancy et recall.
Le Problème des Hallucinations Silencieuses
Un RAG mal configuré peut sembler fonctionner parfaitement… jusqu'au jour où un utilisateur pose une question critique et reçoit une réponse inventée présentée avec la même assurance qu'une réponse correcte.
C'est le problème des hallucinations silencieuses : le LLM génère une réponse plausible, confiante, bien formulée : mais fausse ou non ancrée dans vos documents. Sans évaluation systématique, vous ne pouvez pas détecter ce problème avant qu'il cause des dommages.
Pourquoi l'Évaluation Manuelle ne Suffit Pas
- Vous ne pouvez pas tester des milliers de questions à la main
- Votre jugement est biaisé (vous connaissez les documents)
- L'évaluation manuelle ne s'intègre pas dans un pipeline CI/CD
- Une modification du chunking ou du modèle peut dégrader subtilement la qualité sans que vous le remarquiez
La solution : Ragas, un framework d'évaluation automatique spécialement conçu pour les systèmes RAG.
Un RAG non évalué est un RAG non fiable. Avant de déployer en production, définissez des seuils de qualité minimum et automatisez les tests. Traitez l'évaluation RAG comme vous traitez les tests unitaires : indispensable, pas optionnel.
Les 4 Métriques Ragas
Ragas mesure la qualité de votre RAG selon 4 dimensions complémentaires. Chaque métrique a un score entre 0 et 1.
1. Faithfulness (Fidélité)
Question : La réponse générée est-elle entièrement basée sur les documents récupérés ?
Intuition : Si votre RAG récupère des documents sur Python et génère une réponse mentionnant Java, la faithfulness est basse. Le LLM a ajouté des informations qui ne viennent pas des documents.
Calcul : Ragas décompose la réponse en affirmations atomiques, puis vérifie que chaque affirmation peut être déduite des documents contextuels.
Exemple :
Documents : "Python est créé par Guido van Rossum en 1991."
Réponse : "Python est un langage créé en 1991 par Guido van Rossum,
très populaire en data science."
Affirmation 1 : "Python créé en 1991" → Vérifiable ✓
Affirmation 2 : "Par Guido van Rossum" → Vérifiable ✓
Affirmation 3 : "Très populaire en data science" → NON dans les docs ✗
Faithfulness = 2/3 = 0.67
Seuil recommandé : > 0.85
2. Answer Relevancy (Pertinence de la Réponse)
Question : La réponse répond-elle réellement à la question posée ?
Intuition : Si l'utilisateur demande "Comment installer Python ?" et que la réponse parle de l'historique de Python, l'answer relevancy est basse. La réponse est vraie mais ne répond pas à la question.
Calcul : Ragas génère des questions synthétiques à partir de la réponse, puis mesure leur similarité avec la question originale. Si les questions générées correspondent à la question initiale, la réponse y répondait bien.
Seuil recommandé : > 0.80
3. Context Recall (Rappel du Contexte)
Question : Le système a-t-il récupéré tous les documents nécessaires pour répondre ?
Intuition : Si la bonne réponse nécessite 3 informations et que votre RAG n'en a récupéré que 2, le context recall est bas. C'est un problème de retrieval, pas de génération.
Calcul : Compare les documents récupérés avec la ground truth (la réponse de référence). Mesure quelle fraction des informations nécessaires était présente dans le contexte.
Seuil recommandé : > 0.75
4. Context Precision (Précision du Contexte)
Question : Les documents récupérés sont-ils tous utiles, ou y a-t-il du bruit ?
Intuition : Si votre RAG récupère 10 documents mais que seulement 2 sont vraiment pertinents pour la question, la context precision est basse. Le LLM doit filtrer beaucoup de bruit pour trouver l'information utile.
Calcul : Mesure le rang des documents pertinents dans la liste des résultats. Un document pertinent en position 1 est mieux qu'en position 10.
Seuil recommandé : > 0.70
Vue d'ensemble
| Métrique | Ce qu'elle détecte | Cause probable si basse |
|---|---|---|
| Faithfulness | Hallucinations du LLM | Instructions du prompt trop laxistes, contexte insuffisant |
| Answer Relevancy | Réponses hors sujet | Prompt mal formulé, top-k trop élevé |
| Context Recall | Documents manquants | Chunking trop fin, embedding inadapté |
| Context Precision | Bruit dans le contexte | Chunking trop grossier, top-k trop élevé |
Pipeline d'Évaluation Ragas
Micro-exercice : Scorer un RAG Agno avec Ragas
Installation
Code Complet
# eval_rag.py
import os
from agno.agent import Agent
from agno.knowledge.embedder.openai import OpenAIEmbedder
from agno.knowledge.knowledge import Knowledge
from agno.models.openai import OpenAIResponses
from agno.vectordb.lancedb import LanceDb, SearchType
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import (
answer_relevancy,
context_precision,
context_recall,
faithfulness,
)
os.environ["OPENAI_API_KEY"] = "sk-..."
# --- 1. Construire le RAG ---
knowledge = Knowledge(
vector_db=LanceDb(
uri="tmp/lancedb_eval",
table_name="docs_eval",
search_type=SearchType.hybrid,
embedder=OpenAIEmbedder(id="text-embedding-3-small"),
),
)
knowledge.insert(
url="https://agno-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf"
)
agent = Agent(
model=OpenAIResponses(id="gpt-4o-mini"),
knowledge=knowledge,
instructions=[
"Réponds uniquement avec les informations de ta base de connaissances.",
"Si tu ne sais pas, dis-le clairement.",
],
markdown=False, # Désactiver le markdown pour l'évaluation
)
# --- 2. Dataset d'évaluation (golden dataset) ---
test_questions = [
"Quels sont les ingrédients principaux du Pad Thai ?",
"Comment préparer une soupe Tom Yum ?",
"Qu'est-ce que le lait de coco apporte dans la cuisine thaï ?",
]
ground_truths = [
"Le Pad Thai contient des nouilles de riz, des œufs, des crevettes ou du tofu, de la sauce de poisson, du tamarin, des cacahuètes et des germes de soja.",
"La soupe Tom Yum se prépare avec un bouillon de citronnelle, galanga, feuilles de kaffir, champignons, crevettes, sauce de poisson et jus de citron vert.",
"Le lait de coco apporte de la richesse, de la douceur et une texture crémeuse aux currys et soupes thaïs.",
]
# --- 3. Faire tourner le RAG et collecter les données ---
questions_list = []
answers_list = []
contexts_list = []
for question in test_questions:
# Obtenir la réponse de l'agent
response = agent.run(question)
answer = response.content
# Obtenir les documents récupérés
docs = knowledge.search(question, num_documents=5)
contexts = [doc.content for doc in docs]
questions_list.append(question)
answers_list.append(answer)
contexts_list.append(contexts)
print(f"Q: {question}")
print(f"A: {answer[:100]}...")
print(f"Contexts récupérés: {len(contexts)}")
print()
# --- 4. Créer le dataset Ragas ---
data = {
"question": questions_list,
"answer": answers_list,
"contexts": contexts_list,
"ground_truth": ground_truths,
}
dataset = Dataset.from_dict(data)
# --- 5. Évaluer avec Ragas ---
result = evaluate(
dataset,
metrics=[
faithfulness,
answer_relevancy,
context_recall,
context_precision,
],
)
print("\n=== Résultats Ragas ===")
print(result)
print(f"\nFaithfulness : {result['faithfulness']:.3f}")
print(f"Answer Relevancy : {result['answer_relevancy']:.3f}")
print(f"Context Recall : {result['context_recall']:.3f}")
print(f"Context Precision: {result['context_precision']:.3f}")
Exemple de sortie attendue
=== Résultats Ragas ===
{'faithfulness': 0.892, 'answer_relevancy': 0.841,
'context_recall': 0.783, 'context_precision': 0.756}
Faithfulness : 0.892 ✓ (seuil : 0.85)
Answer Relevancy : 0.841 ✓ (seuil : 0.80)
Context Recall : 0.783 ✓ (seuil : 0.75)
Context Precision: 0.756 ✓ (seuil : 0.70)
Créer un Golden Dataset pour le CI/CD
Un golden dataset est un ensemble fixe de questions avec les réponses de référence attendues. Il sert de benchmark pour comparer les versions de votre RAG.
Structure d'un Golden Dataset
# golden_dataset.py
golden_dataset = [
{
"id": "Q001",
"question": "Quelle est la politique de remboursement ?",
"ground_truth": "Les remboursements sont effectués sous 5 jours ouvrés. "
"Les articles personnalisés ne sont pas remboursables.",
"source_document": "politique-retours-v3.pdf",
"category": "politique_commerciale",
},
{
"id": "Q002",
"question": "Comment contacter le support technique ?",
"ground_truth": "Le support technique est disponible par email (support@example.com) "
"et par téléphone au +33 1 23 45 67 89, du lundi au vendredi de 9h à 18h.",
"source_document": "guide-support.pdf",
"category": "support",
},
# ... 50 à 100 questions couvrant tous vos cas d'usage
]
Intégration dans un Pipeline CI/CD
# ci_eval.py : À exécuter dans votre pipeline GitHub Actions / GitLab CI
import sys
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_recall
# Seuils minimum acceptables
THRESHOLDS = {
"faithfulness": 0.85,
"answer_relevancy": 0.80,
"context_recall": 0.75,
}
# ... (construire dataset à partir du golden dataset)
result = evaluate(dataset, metrics=[faithfulness, answer_relevancy, context_recall])
# Vérifier les seuils
failed = []
for metric, threshold in THRESHOLDS.items():
if result[metric] < threshold:
failed.append(f"{metric}: {result[metric]:.3f} < {threshold}")
if failed:
print("ÉCHEC : Métriques en dessous des seuils :")
for f in failed:
print(f" - {f}")
sys.exit(1) # Arrête le déploiement
else:
print("SUCCÈS : Toutes les métriques sont au-dessus des seuils.")
sys.exit(0)
# .github/workflows/rag-eval.yml
name: RAG Evaluation
on: [push, pull_request]
jobs:
evaluate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: pip install ragas datasets agno openai lancedb
- name: Run RAG evaluation
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: python ci_eval.py
Avec ce pipeline, chaque modification de votre chunking, de votre prompt ou de votre modèle d'embedding sera automatiquement évaluée. Si les métriques chutent, le déploiement est bloqué.
TruLens : Une Alternative à Ragas
TruLens est un autre framework d'évaluation RAG, développé par TruEra. Ses points forts :
- Interface web pour explorer les résultats visuellement
- Intégration native avec LangChain, LlamaIndex, et autres
- Métriques similaires à Ragas (groundedness, context relevance, answer relevance)
- Dashboard interactif pour analyser les cas d'échec
from trulens.apps.custom import TruCustomApp
from trulens.core import TruSession
from trulens.providers.openai import OpenAI as TruOpenAI
tru_session = TruSession()
tru_session.reset_database()
provider = TruOpenAI(model_engine="gpt-4o-mini")
# Définir les feedbacks
from trulens.core import Feedback
import numpy as np
f_groundedness = (
Feedback(provider.groundedness_measure_with_cot_reasons, name="Groundedness")
.on_input_output()
)
# Wrapper votre RAG avec TruLens
tru_rag = TruCustomApp(
mon_agent_rag,
app_id="RAG v1",
feedbacks=[f_groundedness],
)
# Lancer le dashboard
tru_session.run_dashboard() # http://localhost:8501
| Critère | Ragas | TruLens |
|---|---|---|
| Facilité de prise en main | Très facile | Facile |
| Métriques disponibles | 10+ | 15+ |
| Dashboard visuel | Non (CSV/dict) | Oui (Streamlit) |
| CI/CD | Natif | Possible |
| Frameworks supportés | Tous | LangChain, LlamaIndex, custom |
| Documentation | Excellente | Bonne |
Commencez avec Ragas pour sa simplicité et son intégration CI/CD. Passez à TruLens si vous avez besoin d'un dashboard d'analyse pour votre équipe ou si vous voulez explorer visuellement les cas d'échec.
Specialiste IA — Master Intelligence Artificielle
Diplome d'un Master en Intelligence Artificielle, je travaille au quotidien sur des projets IA en entreprise. J'ai cree IwanttolearnAI pour rendre l'apprentissage de l'IA accessible a tous, gratuitement.
Continuer a apprendre
Stratégies de Chunking et Indexation pour le RAG
La qualité d'un RAG repose à 80% sur le chunking. Découvrez comment découper vos documents pour maximiser la pertinence des réponses de votre agent IA.
GraphRAG et Hybrid Search : BM25 + Vecteur
Le RAG vectoriel pur a ses limites. Hybrid search (BM25 + embedding) et GraphRAG résolvent les cas complexes — apprenez à les implémenter avec Agno et LanceDB.
Vector Databases : pgvector vs Pinecone vs Weaviate : Comparatif Complet
pgvector, Pinecone, Weaviate, LanceDB, Qdrant… comment choisir sa vector database ? Comparatif complet avec intégration Agno et cas pratique Supabase.