Pourquoi l'évaluation continue ?
Chaque changement de prompt, de modèle, ou de configuration de retrieval peut introduire des régressions silencieuses. L'évaluation continue intégrée à la CI détecte ces régressions avant qu'elles n'atteignent la production.
Architecture
PR ouverte → CI déclenché → Évaluation sur golden dataset → Score comparé au baseline → Pass/FailImplémentation avec GitHub Actions
# .github/workflows/llm-eval.yml
name: LLM Evaluation
on:
pull_request:
paths:
- 'prompts/**'
- 'src/rag/**'
- 'config/models.yml'
jobs:
evaluate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: pip install -r requirements-eval.txt
- name: Run evaluation
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: python scripts/run_eval.py --dataset eval/golden.json --output results.json
- name: Check regression
run: python scripts/check_regression.py --results results.json --baseline eval/baseline.json --threshold 0.05
- name: Comment PR with results
uses: actions/github-script@v7
with:
script: |
const results = require('./results.json');
const body = `## Eval Results\n| Metric | Score | Baseline | Delta |\n|--------|-------|----------|-------|\n| Faithfulness | ${results.faithfulness} | ... |`;
github.rest.issues.createComment({...context.repo, issue_number: context.issue.number, body});Script d'évaluation
# scripts/run_eval.py
import json
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy
def run_evaluation(dataset_path: str, output_path: str):
dataset = load_dataset(dataset_path)
# Exécuter le pipeline RAG sur chaque question
results = []
for item in dataset:
answer, contexts = rag_pipeline(item["question"])
results.append({
"question": item["question"],
"answer": answer,
"contexts": contexts,
"ground_truth": item["ground_truth"]
})
# Évaluer avec RAGAS
scores = evaluate(results, metrics=[faithfulness, answer_relevancy])
with open(output_path, "w") as f:
json.dump(scores, f)Script de vérification de régression
# scripts/check_regression.py
def check_regression(results, baseline, threshold=0.05):
for metric, score in results.items():
baseline_score = baseline[metric]
if score < baseline_score - threshold:
print(f"REGRESSION: {metric} dropped {baseline_score} -> {score}")
sys.exit(1)
print("All metrics within acceptable range.")Bonnes pratiques
- Exécuter l'évaluation uniquement quand les fichiers pertinents changent
- Garder le golden dataset petit (50-100 exemples) pour des CI rapides
- Sauvegarder les résultats historiques pour tracker les tendances
- Utiliser un seuil de régression adapté (5% est un bon défaut)
- Cacher les embeddings pour accélérer les runs