AvancéRAG
22 min de lecture11 vues

É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étriqueCe qu'elle détecteCause probable si basse
FaithfulnessHallucinations du LLMInstructions du prompt trop laxistes, contexte insuffisant
Answer RelevancyRéponses hors sujetPrompt mal formulé, top-k trop élevé
Context RecallDocuments manquantsChunking trop fin, embedding inadapté
Context PrecisionBruit dans le contexteChunking trop grossier, top-k trop élevé

Pipeline d'Évaluation Ragas


Micro-exercice : Scorer un RAG Agno avec Ragas

Installation

pip install ragas datasets agno openai lancedb tantivy pypdf

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èreRagasTruLens
Facilité de prise en mainTrès facileFacile
Métriques disponibles10+15+
Dashboard visuelNon (CSV/dict)Oui (Streamlit)
CI/CDNatifPossible
Frameworks supportésTousLangChain, LlamaIndex, custom
DocumentationExcellenteBonne

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.