watch·ia
AccueilActusTutosGlossaireCette semaineTendancesSources
/
À chaud

Évaluer et fiabiliser un système LLM : évals et garde-fous

mercredi 17 juin 202607:135 min de lecture
L'essentiel — 3 points
  • 01"Ça a l'air de marcher" n'est pas une métrique : sans jeu d'évaluation, tu pilotes à l'instinct.
  • 02Combine trois niveaux de mesure : vérifications automatiques, LLM-as-judge calibré, et revue humaine sur un échantillon.
  • 03Les garde-fous d'exécution (validation des sorties, détection d'hallucination, fallback) complètent l'éval : l'une mesure avant, les autres protègent en direct.
AVANCÉ

À la fin de ce tuto, tu auras un harnais d'évaluation qui tourne : un dataset de cas de référence, des vérifications automatiques, un juge LLM, et un score chiffré qui te dit si un changement de prompt ou de modèle améliore ou dégrade ton système. Tu sauras transformer « ça a l'air de marcher » en décisions mesurées.

Durée : 35 min. Prérequis : un système LLM existant à évaluer (chatbot, RAG, extraction…), Python, une clé API.

Pourquoi l'éval est non négociable

Un système LLM qui « a l'air de marcher » en démo échoue souvent en production, sur les cas que tu n'avais pas testés. Les LLM sont non déterministes : la même entrée peut donner des sorties différentes. « Je l'ai testé trois fois, c'était bon » ne prouve rien. Sans mesure systématique, chaque changement de prompt ou de modèle est un pari. Une suite d'évals transforme ces paris en décisions chiffrées.

Étape 1 — Construire un jeu d'évaluation

Commence tôt, même petit :

  1. Rassemble des cas réels : 30 à 100 entrées représentatives, incluant les cas limites et ceux qui ont déjà échoué.
  2. Définis le résultat attendu pour chacun (réponse de référence, ou critères de réussite).
  3. Versionne ce dataset (un simple fichier JSON dans ton dépôt) : il devient ta référence pour comparer modèles, prompts et versions.

Un dataset de 50 cas bien choisis vaut mieux que 1000 cas génériques.

# eval_dataset.json — versionné dans ton dépôt
[
  {"input": "Combien de jours de congés ?", "expect_contains": "25"},
  {"input": "Politique animaux au bureau ?", "expect_contains": "ne sais pas"},
  {"input": "Télétravail possible ?", "expect_contains": "3 jours"}
]

Étape 2 — Les trois niveaux de mesure

Niveau 1 — Vérifications automatiques (rapides, gratuites)

Pour tout ce qui est objectif : format JSON valide, présence d'un champ, longueur, absence de mots interdits, correspondance attendue.

def check_auto(output: str, case: dict) -> bool:
    return case["expect_contains"].lower() in output.lower()

Niveau 2 — LLM-as-judge (souple, pour le subjectif)

Un second LLM note la sortie selon une grille : pertinence, fidélité aux sources, ton. Pratique pour évaluer à grande échelle ce qu'une règle ne peut juger.

from openai import OpenAI
client = OpenAI()

def judge(question: str, answer: str) -> int:
    prompt = f"""Note de 1 à 5 la qualité de cette réponse à la question.
Critères : exactitude, clarté, absence d'invention.
Réponds UNIQUEMENT par le chiffre.

Question : {question}
Réponse : {answer}"""
    r = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
    )
    try:
        return int(r.choices[0].message.content.strip()[0])
    except Exception:
        return 0

⚠️ Le juge a ses biais. Calibre-le : fais-lui noter 5 à 10 cas que tu as toi-même notés à la main, et vérifie qu'il est d'accord avec toi avant de lui faire confiance à l'échelle.

Niveau 3 — Revue humaine (l'étalon-or, coûteux)

Sur un échantillon, un humain tranche. À réserver aux décisions importantes et au calibrage du juge automatique.

Étape 3 — Le harnais qui fait tourner tout ça

import json

def run_system(question: str) -> str:
    # ← ton système réel (RAG, agent, simple appel…)
    r = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": question}],
    )
    return r.choices[0].message.content

def run_evals(dataset_path: str):
    dataset = json.load(open(dataset_path, encoding="utf-8"))
    auto_pass, judge_total = 0, 0
    for case in dataset:
        out = run_system(case["input"])
        ok = check_auto(out, case)
        score = judge(case["input"], out)
        auto_pass += int(ok)
        judge_total += score
        flag = "✅" if ok else "❌"
        print(f"{flag} [juge {score}/5] {case['input'][:40]}")
    n = len(dataset)
    print(f"\nVérifs auto : {auto_pass}/{n} ({auto_pass/n:.0%})")
    print(f"Score juge moyen : {judge_total/n:.2f}/5")

run_evals("eval_dataset.json")

Lance-le avant et après chaque changement (nouveau prompt, autre modèle, RAG modifié). Si le score baisse, tu le sais immédiatement — au lieu de le découvrir en production.

Étape 4 — Les garde-fous à l'exécution

L'éval mesure avant le déploiement ; les garde-fous protègent en direct :

  • Validation de sortie : rejette ou réessaie si la réponse ne respecte pas le format attendu.
  • Détection d'hallucination : en RAG, vérifie que la réponse s'appuie sur les sources fournies ; sinon, signale ou refuse.
  • Filtres d'entrée et de sortie : bloque les contenus interdits dans les deux sens.
  • Fallback : prévois un comportement sûr quand le modèle échoue (réponse par défaut, escalade humaine) plutôt qu'un plantage.
  • Limites : timeout, nombre de tentatives, budget de tokens.

Étape 5 — Boucler avec la production

Les vrais cas limites viennent des utilisateurs. Journalise les échecs et les retours négatifs, et réinjecte-les dans ton dataset d'éval. Ta suite de tests s'enrichit ainsi des cas qui comptent vraiment, et chaque incident renforce le système.

À retenir

« Ça a l'air de marcher » n'est pas une métrique. Construis tôt un jeu d'évaluation de cas réels, mesure à trois niveaux (vérifs automatiques, LLM-juge calibré, revue humaine), et fais tourner le harnais à chaque changement. Double l'éval de garde-fous d'exécution : validation des sorties, détection d'hallucination, fallback sûr. Enfin, boucle : chaque échec en production devient un nouveau cas de test. C'est cette discipline qui rend un système LLM fiable.

Réagir :
Partager —XLinkedIn