· Hernán Pérez Rodal · Engineering  · 6 min read

LLM evaluation dans les domaines régulés : au-delà de l'accuracy

Quand une réponse incorrecte de votre LLM impacte un audit FDA, l'accuracy ne suffit pas. Nous racontons comment nous évaluons les LLMs et agents chez Darwin — golden sets, LLM-as-judge, regression detection et guardrails numériques.

Quand une réponse incorrecte de votre LLM impacte un audit FDA, l'accuracy ne suffit pas. Nous racontons comment nous évaluons les LLMs et agents chez Darwin — golden sets, LLM-as-judge, regression detection et guardrails numériques.

TL;DR — “Accuracy” est une métrique insuffisante quand l’output de votre LLM influence des décisions réglementaires. Chez Darwin nous combinons golden sets + LLM-as-judge + regression detection + guardrails numériques. Ce post raconte comment nous l’avons monté et ce que nous avons appris en production avec des milliers de cas par jour.

Le problème : l’accuracy ne suffit pas

Quand vous évaluez un classifieur traditionnel, accuracy + confusion matrix vous disent pas mal. Quand vous évaluez un LLM dans un domaine régulé :

  • L’accuracy a l’air haute sur des benchmarks génériques mais échoue sur les cas edge du domaine
  • Les cas critiques pèsent différemment — une erreur sur un cas “routinier” vs. un cas “haut risque”, ce n’est pas pareil
  • Les outputs sont du texte libre — il n’y a pas de réponse unique correcte
  • Les modèles changent sans prévenir — OpenAI/Anthropic mettent à jour les modèles, votre eval du jour 1 ne vaut rien au jour 90
  • Les hallucinations numériques sont des silent killers — le modèle invente une donnée et la présente avec une confiance totale

Chez Darwin, quand le système dit “ce lot a 3 gaps de compliance FSMA 204”, cette réponse va à un audit. Se tromper là, c’est de la legal liability. Nous avons besoin d’une evaluation qui capture ça.

Les 4 niveaux d’evaluation que nous utilisons

Niveau 1 : Golden sets curés manuellement

Un set de 300-500 cas représentatifs avec des réponses ground truth curées par des experts humains (compliance officers internes + advisors externes).

Couvre :

  • Cas routiniers — la majorité, que le modèle devrait résoudre sans problème
  • Cas edge connus — situations ambiguës, règles qui se contredisent, lots incomplets
  • Cas adversariaux — tentatives de faire échouer le modèle (trick questions, data contradictoire)

Metrics à ce niveau :

  • Exact match — pour les réponses structurées (JSON, enum values)
  • Semantic similarity — pour les réponses text-based (BERTScore, embeddings)
  • Fact extraction recall — est-ce qu’il a extrait tous les facts pertinents ?

Fréquence : nous faisons tourner ce set en CI avant chaque deploy. Ça casse le deploy si ça descend en dessous du threshold.

Niveau 2 : LLM-as-judge pour les text outputs

Pour les réponses longues (reports, gap analyses, explications) il n’y a pas un seul “correct”. Nous utilisons un autre LLM comme juge — avec un prompt spécifique qui évalue :

  • Factualité — les claims sont-ils vérifiables avec l’évidence montrée ?
  • Completeness — couvre-t-il tous les aspects qu’il devrait ?
  • Citation correcte — cite-t-il les bonnes réglementations/sources ?
  • Tone/style — est-ce professionnel, précis, non-alarmiste ?

Le point clé : le judge LLM utilise un autre modèle (ex : modèle A génère, modèle B juge). Ça évite le biais du “modèle qui se juge lui-même”.

Pitfalls : LLM-as-judge a ses propres biais. Nous le calibrons avec des échantillons où des experts humains ont aussi évalué, et ajustons le prompt du judge itérativement.

Niveau 3 : Regression detection en production

Entre les evals de golden sets, le modèle en production traite des milliers de cas par jour. Nous ne pouvons pas tous les curer — mais nous pouvons détecter les régressions.

Techniques :

  • Score distributions over time — si la confidence moyenne, les scores par dimension d’eval, ou les patterns d’outputs changent d’un coup, alerte
  • Shadow mode pour les deploys — le nouveau modèle tourne en parallèle, nous comparons ses outputs au courant sur des cas réels
  • Sampling + human review — 1-2 % des outputs sont samplés chaque semaine et un compliance officer humain les revoit
  • Feedback from operators — chaque fois qu’un opérateur corrige une réponse du système, c’est un data point

Quand quelque chose change systématiquement (ex : le score de “completeness” baisse de 10 % en une semaine), nous investiguons avant que ça cause un incident.

Niveau 4 : Numerical guardrails

Celui-ci est le plus critique. Les LLMs inventent des nombres quand ils ne les ont pas explicites dans le contexte. J’en avais partiellement parlé dans le post de RAG, mais ça vaut la peine d’approfondir.

Chaque fois que notre système retourne un output qui contient un nombre (quantité de lots, dates, pourcentages, counts), on passe par un guardrail validator :

def validate_numerical_claims(response: str, source_data: dict) -> ValidationResult:
    """Extract numerical claims from LLM response and verify against source data."""
    claims = extract_numbers_from_text(response)

    for claim in claims:
        # Is this number present in our verified data?
        if not verify_claim_in_source(claim, source_data):
            return ValidationResult(
                valid=False,
                reason=f"Claim '{claim}' cannot be verified against source data",
            )
    return ValidationResult(valid=True)

Si un nombre du LLM ne peut pas être vérifié contre la source structurée, nous failons fast — nous retournons une erreur au lieu d’une réponse potentiellement incorrecte. Mieux vaut dire “je ne sais pas” que mentir avec confiance.

Le stack d’eval

  • Pytest + custom fixtures — golden sets comme fichiers YAML, asserts dans les tests
  • LangSmith + OpenTelemetry — tracing de chaque invocation avec input, output, metadata
  • PromptLayer — versioning de prompts + history
  • Custom dashboards — Grafana avec score distributions, drift detection
  • Postgres + dbt — persistance des eval runs, comparaison historique

Ce qui n’a pas marché

V0 : une seule metric globale d‘“accuracy” — ça réduisait les décisions techniques à “a amélioré / a empiré” sans nuance. Nous sommes passés à des dashboards multi-dimensionnels (factualité, completeness, citation, etc.) avec des trade-offs explicites.

Golden set statique sans updates — le set s’est désactualisé avec de nouvelles versions de réglementations. Maintenant nous avons un process mensuel de curation/review.

Eval uniquement en staging avant deploy — certaines régressions n’apparaissaient qu’avec la distribution réelle de production. Nous avons ajouté le niveau 3 (regression detection en prod) pour compenser.

Confier 100 % au LLM-as-judge sans calibration humaine — le judge avait des biais que nous ne voyions pas. Maintenant nous calibrons contre des human-rated samples mensuellement.

Ce qui a marché

Golden sets petits mais bien curés — 300 cas bien pensés > 3000 cas random

Dashboards de trend, pas seulement de snapshot — détecter le drift est plus important que le score absolu

Guardrails numériques comme defensive coding — zero hallucinations numériques qui atteignent l’utilisateur final depuis que nous l’avons implémenté

Feedback loops courts — chaque correction de l’opérateur retourne au système d’eval comme potential golden case

Tracing par chaque LLM call — quand quelque chose va mal en production, nous allons du trace à la cause racine en minutes

Lessons learned

  1. L’accuracy est le plancher, pas le plafond de ce dont votre eval suite a besoin
  2. Multi-dimensional scoring > single score
  3. Regression detection en prod est aussi important que l’eval pré-deploy
  4. Les guardrails numériques sont non-negotiable dans les domaines où les nombres comptent
  5. LLM-as-judge est utile mais a besoin de calibration contre des experts humains périodiquement
  6. L’operator feedback est l’eval set le plus précieux à long terme

Et maintenant ?

Nous explorons automated adversarial testing — génération programmatique de cas edge qui stressent le modèle. Combiné avec fuzz testing d’inputs (données partielles, contradictoires, formats bizarres), ça amplifie notre eval coverage sans exiger de curation manuelle.

Si vous construisez des LLMs en production et que votre eval suite est “faire tourner un eval.py avec 50 exemples”, vous sous-estimez probablement le problème. Ce qui est critique n’est pas le nombre dans le rapport — c’est de capturer les régressions avant qu’elles atteignent l’utilisateur.


Vous montez votre eval suite pour LLMs en production ? Parlons-en — nous pouvons partager des templates, des dashboards et des apprentissages.

Compartir:
Back to Blog

Related Posts

View All Posts »