Aller au contenu principal
Retour au journal
IA26 avril 202610 min de lecture

Eval de LLM en prod : détecter la dérive d'un agent sans surveiller à la main

Un agent LLM dérive en silence pendant des semaines. Voici la stack d'observabilité minimale pour le voir avant que le NPS ne chute.

ParPatrice Huetz

Un client SaaS B2B nous appelle un lundi matin. Leur agent commercial conversationnel — déployé depuis 4 mois, considéré comme stable — vient de leur faire perdre un deal à 280 000 €. Le prospect a cité une phrase de l'agent : « Notre tarif standard pour ce volume est de 2 400 €/mois. » Sauf que le vrai tarif, validé par la direction commerciale, est de 4 800 €/mois pour ce volume. L'agent disait n'importe quoi depuis trois semaines. Personne ne s'en était rendu compte parce que personne ne lisait les conversations. Pas d'eval, pas d'alerte, pas de dashboard. Voici la stack d'observabilité qu'on déploie chez nos clients, et les quatre métriques qui vous évitent ce scénario.

Pourquoi un agent LLM dérive sans qu'on le voie

Un agent en production peut dégrader sa qualité pour cinq raisons, et aucune n'est détectable à l'œil :

  1. Le modèle sous-jacent change. Vous appelez claude-sonnet-4-6 mais Anthropic met à jour le modèle silencieusement. Comportement légèrement différent — pas d'annonce.
  2. Le contexte évolue. Vos données RAG s'enrichissent, des documents contradictoires apparaissent, des chunks sont réindexés différemment.
  3. Les utilisateurs changent leurs questions. Au lancement, ils posent des questions simples. Trois mois plus tard, ils testent les limites — et l'agent improvise.
  4. Les tools se modifient. Une API métier renvoie un nouveau format, l'agent l'interprète mal, mais répond quand même.
  5. Le system prompt vieillit. Une règle métier change, personne ne pense à mettre à jour le prompt.

Sans observabilité, vous découvrez le problème quand un client se plaint. C'est-à-dire jamais — la plupart des utilisateurs frustrés se taisent et désinstallent.

Les chiffres que nous mesurons en audit sur des agents « stables » :

Mois en productionPrécision agentHallucination rate
Lancement89 %4 %
+3 mois81 %9 %
+6 mois73 %16 %
+12 mois64 %24 %

La pente moyenne, sans intervention : -2 points de précision par mois. C'est lent, c'est silencieux, c'est mortel pour le ROI.

Le drift d'un agent n'est jamais brutal. C'est une accumulation : un peu de drift contexte + un peu de drift modèle + un peu de drift utilisateur. Aucun n'est catastrophique seul. Combinés, ils détruisent la qualité.

La stack minimale qui marche : 3 jours de setup

Voici l'architecture que nous déployons en première itération chez 100 % de nos clients ayant un agent en production.

# 1. Instrumenter — 5 minutes, une fois
from langfuse import observe, get_client
langfuse = get_client()

@observe()
async def agent_response(question: str, user_id: str):
    trace = langfuse.get_current_trace_id()
    langfuse.update_current_trace(
        user_id=user_id,
        tags=["prod", "agent-commercial"]
    )

    # Votre logique d'agent existante
    response = await llm.chat(question)

    # Score utilisateur (👍/👎 dans l'UI)
    return {"response": response, "trace_id": trace}

# 2. Évaluer (asynchrone, toutes les 15 minutes)
async def run_eval_batch():
    traces = await langfuse.get_traces(since="15 min ago", limit=200)
    for trace in traces:
        scores = await asyncio.gather(
            judge_hallucination(trace),    # LLM-as-judge
            check_format(trace),            # heuristique
            measure_drift(trace),           # cosine similarity vs baseline
        )
        await langfuse.score_trace(trace.id, scores)

# 3. Alerter (Slack si dépassement de seuil)
if hallucination_rate_24h > 0.10:
    slack_alert(f"Hallucination rate à {hallucination_rate_24h:.1%}")

Trois composants : capture (LangFuse SDK), eval asynchrone (LLM-as-judge + heuristiques), alertes (Slack/PagerDuty). Total : 200 lignes, 3 jours de setup, 0 € si on auto-héberge LangFuse.

ComposantChoix par défautCoût mensuel
Trace captureLangFuse self-hosted0 € (VPS 20 €)
LLM-as-judgeClaude Haiku 4.530–150 € selon volume
Drift detectorsentence-transformers local0 €
AlertingSlack webhook + PagerDuty0–40 €
Si vous démarrez et n'avez pas le temps d'auto-héberger : LangFuse Cloud à 49 $/mois est un excellent investissement pour 3–6 mois, le temps de prouver la valeur. Migrer vers le self-hosted prend ensuite 2 jours.

Le dataset de régression : votre filet de sécurité

Avant même de parler métriques live, construisez un dataset de régression : 100 à 300 paires (question, réponse attendue) couvrant les cas critiques de votre métier. C'est votre ceinture et bretelles pour les déploiements.

Chaque modification du system prompt, du RAG, ou du modèle déclenche le dataset. Si la précision baisse de plus de 2 points, le déploiement est bloqué. Coût : 2 jours pour constituer le dataset initial, 50 €/mois pour le faire tourner via Claude Haiku 4.5 en CI.

Comment constituer ce dataset rapidement :

  1. Extraire 100 conversations réelles des logs des 30 derniers jours
  2. Faire valider la bonne réponse par un expert métier (1 jour)
  3. Catégoriser par type de question (FAQ, calcul, recherche, génération)
  4. Itérer : ajouter chaque mois 10 cas nouveaux, retirer ceux devenus obsolètes

Sans ce dataset, vous découvrez les régressions en production. Avec, vous les attrapez en CI avant déploiement.

Pourquoi ce pipeline marche : les 4 métriques qui comptent

Pipeline d'observabilité LLM

L'erreur classique : tracker 30 métriques. Vous regardez le dashboard une semaine, plus jamais ensuite. Quatre métriques bien calibrées battent trente métriques jamais lues.

Métrique 1 — Taux d'hallucination (LLM-as-judge)

La plus importante, et celle que tout le monde évite parce qu'elle est « subjective ». Solution : un LLM-as-judge avec un prompt strict, qui note chaque réponse asynchrone.

JUDGE_PROMPT = """Tu es un évaluateur. Question : {question}
Réponse de l'agent : {response}
Sources fournies à l'agent : {context}

Note : la réponse est-elle entièrement supportée par les sources ?
- 1.0 si toutes les affirmations sont dans les sources
- 0.5 si certaines sont déduites raisonnablement
- 0.0 si l'agent invente des faits non présents

Réponds uniquement par un JSON {{"score": 0.0|0.5|1.0, "reason": "..."}}."""

Tournez ce judge sur 10 % du trafic (sampling) avec Claude Haiku 4.5 — coût marginal. Le score moyen sur 24 h est votre KPI principal. Seuil d'alerte : < 0,85.

Métrique 2 — Drift sémantique (cosine similarity)

Calculez l'embedding moyen des réponses de l'agent par jour. Comparez à l'embedding moyen de référence (semaine de lancement, validée manuellement). Quand la cosine similarity descend sous 0,82, votre agent répond « différemment » qu'au lancement — ça mérite une investigation manuelle.

C'est le détecteur le plus simple, le moins cher, et celui qui a sauvé le projet du client SaaS de l'intro. Drift détecté à J+18, alerte Slack envoyée, lecture des traces, problème identifié : le system prompt avait perdu l'instruction « consulte toujours la grille tarifaire avant de citer un prix » lors d'un refactor.

Métrique 3 — Latence p50/p95 + coût/requête

Métriques techniques, pas de qualité — mais critiques. Une dérive de latence est souvent le signal d'un problème en amont :

  • Latence ↑ 30 % → un tool API est lent ou timeout
  • Coût/requête ↑ 50 % → le RAG remonte trop de chunks ou le contexte gonfle
  • Tokens output ↑ → l'agent se met à raconter sa vie au lieu de répondre court

Seuils typiques pour un agent web : p95 < 4 s, coût moyen < 0,02 €/requête.

Métrique 4 — Feedback utilisateur (binaire)

Un simple 👍/👎 sur chaque réponse, stocké dans la trace. Volume de signal très faible (5–15 % des utilisateurs cliquent), mais le ratio 👎/total est un indicateur en or. Quand il dépasse 8 %, vous avez un problème observable côté utilisateur.

C'est le seul signal de vérité terrain que vous obtenez gratuitement. Ne le négligez pas sous prétexte qu'il est bruité.

MétriqueSourceCoûtLatence détection
Hallucination rateLLM-as-judge30–150 €/mois15 minutes
Drift sémantiqueEmbeddings local0 €1 heure
Latence/coûtLangFuse natif0 €Temps réel
Feedback 👎UI0 €Temps réel

Edge cases : où l'eval automatique se trompe

Cas 1 : LLM-as-judge biaisé en faveur du même modèle

Si vous évaluez Claude avec Claude, le judge a tendance à valider des réponses problématiques. Mitigation : utilisez un modèle différent pour le judge (GPT-4o-mini si l'agent est Claude, et inversement). Ou validez manuellement 50 jugements par mois pour caler le seuil.

Cas 2 : faux positifs de drift sur sujets saisonniers

Un agent commercial parlera « budget annuel » en novembre, « bilan » en janvier, « relance » en juillet. L'embedding moyen dérive naturellement avec le calendrier. Mitigation : calculez la baseline sur 4 semaines glissantes, pas sur la semaine de lancement figée.

Cas 3 : agent qui s'améliore (drift positif)

Vous mettez à jour votre RAG, l'agent s'améliore — et le drift sémantique alerte. Faux positif. Solution : combinez drift + score judge. Un drift seul est ambigu, un drift + score judge en baisse est un vrai problème.

SituationDrift sémantiqueScore judgeAction
Tout normal< 0,18> 0,85Rien
Saisonnalité> 0,18> 0,85Mettre à jour la baseline
Vraie dérive> 0,18< 0,85Investigation manuelle
Bug silencieux< 0,18< 0,85Investigation prompt/tools
Ne déployez jamais un agent sans au moins ces 4 métriques actives. Sans eval, votre agent perd 2 points de précision par mois. Avec eval, vous détectez la dérive en moins de 24 heures et vous corrigez en moins d'une semaine.

LangFuse, Langsmith ou maison : comment choisir

Trois options viables en 2026, selon votre contexte :

CritèreLangFuseLangsmithMaison
Self-hosting✅ Open-source❌ Cloud uniquement
Setup30 min10 min5–10 jours
Coût mensuel0 € (VPS) à 199 € (cloud)39 € à 999 €infra interne
Intégration frameworkTous (SDK Python/TS)Optimisé LangChainÀ écrire
Qualité de l'UI⭐⭐⭐⭐⭐⭐⭐⭐⭐dépend de vous
Souveraineté données✅ self-hosted❌ US

Notre choix par défaut chez les clients : LangFuse self-hosted. Open-source, souverain, intégrations larges, communauté active. On ne recommande Langsmith que si le client est déjà sur LangChain et veut zéro setup. On ne recommande la solution maison que pour les clients avec des contraintes réglementaires extrêmes (santé, défense) qui ne peuvent pas dépendre d'un projet open-source tiers.

Anti-pattern : le dashboard que personne ne regarde

L'erreur classique : on déploie LangFuse, on configure 12 dashboards, on est fier. Trois mois plus tard, plus personne ne les regarde. Le seul mécanisme qui marche durablement : les alertes proactives. Une alerte Slack quand l'hallucination rate dépasse 10 %, une alerte PagerDuty quand l'agent devient inutilisable. C'est le push qui crée l'action, pas le pull.

Règle simple : si une métrique ne déclenche pas d'alerte sur seuil, elle ne sert à rien dans votre stack. Soit vous la calibrez et la branchez, soit vous la retirez.

Ce qu'il faut retenir

Trois règles, dans cet ordre :

  1. Tracez 100 % du trafic, évaluez 10 %. Le coût d'eval est négligeable comparé au coût d'un agent qui dérive sans surveillance.
  2. Quatre métriques suffisent. Hallucination, drift, latence, feedback. Au-delà, vous noyez le signal.
  3. Croisez les signaux avant d'alerter. Drift seul = saisonnalité. Drift + score judge en baisse = vraie dérive.

Pour aller plus loin :

  • LangFuse documentation : intégration en 5 minutes avec n'importe quel SDK Python/TS
  • Article DeepEval sur les patterns LLM-as-judge sans biais
  • OpenTelemetry GenAI semantic conventions (standard émergent pour l'instrumentation LLM)

Conclusion

L'eval LLM en production n'est pas du nice-to-have, c'est du minimum vital. Un agent sans observabilité est un missile aveugle : il marche tant qu'il marche, et le jour où il dévie, vous l'apprenez par un client mécontent ou un revenu perdu. Trois jours de setup pour éviter ce scénario, c'est le meilleur ratio bénéfice/effort qu'on connaisse en MLOps LLM.

Patrice Huetz
Auteur

Patrice Huetz

Co-fondateur — IA & Logiciel

Site auteur
XLinkedIn