Apogée Consult
Retour au blog
Jules Ginhac
Jules GinhacCo-Founder & ingénieur IA

Je suis Jules Ginhac, Co-Founder & ingénieur IA chez Apogée Consult à Lyon. Je conçois et déploie des architectures IA génératives (RAG, agents, LLMOps) pour des PME, startups et organisations publiques.

LLMOps : ce qu'on monitore vraiment après 18 mois de produit IA en prod

  • ia-produit

Après 18 mois de produits IA en production, voici ce qu'on trace vraiment, ce qu'on a arrêté de mesurer, et pourquoi l'observabilité LLM est différente de l'observabilité classique.

LLMOps : ce qu'on monitore vraiment après 18 mois de produit IA en prod

Les premiers dashboards qu'on a construits mesuraient tout. Latence, coût par requête, nombre de tokens, taux d'erreur API, longueur des réponses. Six semaines plus tard, personne ne regardait la moitié de ces métriques. Certaines étaient du bruit. D'autres pointaient vers de vrais problèmes mais on n'avait pas les outils pour y répondre.

Ce texte documente ce qu'on a gardé, ce qu'on a jeté, et pourquoi l'observabilité LLM n'est pas une observabilité applicative avec du texte en plus.

Ce qui rend le monitoring LLM fondamentalement différent

Dans une API REST classique, une réponse est correcte ou incorrecte. La vérité terrain est binaire et souvent vérifiable automatiquement : code HTTP, schema de réponse, temps de traitement.

Avec un LLM, la réponse peut être grammaticalement parfaite, formatée correctement, et factuellement erronée. Elle peut répondre à la question posée tout en manquant l'intention réelle de l'utilisateur. Elle peut être "bonne" sur un jeu d'exemples de référence et dériver progressivement sur le trafic réel sans déclencher aucune alerte.

C'est ce qu'on appelle le drift silencieux : la qualité se dégrade sans que les métriques d'infrastructure bougent. Pas de 500, pas d'augmentation de latence, pas de spike de coût. Juste des réponses qui empirent.

Les métriques qu'on trace en permanence

Coût par conversation, pas par requête

La métrique coût par requête est trompeuse sur un produit conversationnel. Une conversation en 3 tours coûte 3 fois plus qu'une requête single-shot, mais elle représente peut-être 10 fois plus de valeur. On a remplacé cette métrique par le coût moyen par conversation complète, segmenté par type d'usage.

Ça permet de détecter des comportements anormaux : si le coût moyen par conversation monte de 30 % sur deux semaines, c'est souvent le signe que les utilisateurs reformulent beaucoup (prompts qui ne répondent pas) ou que le contexte s'accumule inutilement.

Taux de refus et taux de repromptage

On appelle repromptage le fait qu'un utilisateur envoie un message immédiatement après une réponse du modèle, dans les 5 secondes, avec un message qui commence par "non", "ce n'est pas", "tu n'as pas compris", ou similaire. C'est un proxy imparfait mais mesurable de l'insatisfaction.

Le taux de refus (le modèle dit qu'il ne peut pas ou ne veut pas répondre) est distinct. Sur un produit B2B, un refus est presque toujours un bug, soit le guard-railing est trop strict, soit le prompt système est mal calibré.

Longueur de réponse et ratio question/réponse

Une réponse trop longue n'est pas toujours une bonne réponse. Sur nos produits, on a observé une corrélation négative entre la longueur des réponses et les évaluations utilisateur quand la longueur dépasse un certain seuil (variable selon le contexte). On trace la distribution de longueur par catégorie de requête et on alerte quand la médiane dérive de plus de 20 %.

Latence P50 et P95 par type de requête

La latence globale masque des disparités importantes. Une requête de classification prend 800 ms. Une requête de synthèse longue prend 4 secondes. Agréger les deux donne une moyenne inutile. On segmente par type de requête dès le début, même grossièrement.

Ce qu'on a arrêté de mesurer

Le score BLEU/ROUGE. Ces métriques sont conçues pour la traduction et la génération de texte avec une référence fixe. Sur des réponses libres, elles ne corrèlent pas avec la qualité perçue. On les a abandonnées après deux mois.

La "similarité cosinus" entre la réponse et la question. Intuitivement séduisante, inutile en pratique. Une réponse très différente de la question peut être exactement la bonne réponse.

Le taux d'utilisation de l'API. On a des alertes sur les limites de rate, pas sur l'utilisation. L'utilisation est une métrique business, pas une métrique de qualité.

Détecter le drift avant les utilisateurs

Le drift LLM se manifeste généralement de trois façons :

  1. Drift de modèle : le fournisseur met à jour le modèle sous-jacent (GPT-4o "0125" vs "0513") et le comportement change sans que l'API renvoie une erreur. Toujours épingler la version du modèle dans les appels de production.
  1. Drift de données : la distribution des requêtes utilisateur change. Le produit est conçu pour un cas d'usage, les utilisateurs en inventent d'autres. Les prompts qui fonctionnaient bien se retrouvent hors distribution.
  1. Drift de prompt : quelqu'un modifie le prompt système pour corriger un bug et dégrade un autre comportement. Sans golden dataset et test automatisé, c'est invisible.

Pour détecter les deux derniers, on maintient un ensemble de 50-100 paires question/réponse de référence, avec une évaluation LLM-as-judge sur chaque nouvelle version de prompt. Le processus tourne en CI à chaque modification du prompt système.

Notre stack de monitoring : Langfuse en production

On utilise Langfuse comme outil principal d'observabilité LLM. Il capture les traces complètes (prompt, contexte, réponse, métadonnées), calcule les coûts par trace, et permet d'attacher des évaluations humaines ou automatiques.

from langfuse import Langfuse
from langfuse.decorators import observe, langfuse_context

langfuse = Langfuse()

@observe()
def generate_response(user_message: str, session_id: str) -> str:
    langfuse_context.update_current_trace(
        session_id=session_id,
        tags=["production", "chat"],
    )

    response = client.chat.completions.create(
        model="gpt-4o-2024-11-20",  # version épinglée
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_message}
        ]
    )

    output = response.choices[0].message.content

    # Score automatique sur la longueur
    langfuse_context.score_current_observation(
        name="response_length_bucket",
        value=1 if 100 < len(output) < 800 else 0,
    )

    return output

Ce que Langfuse nous donne que les logs applicatifs classiques ne donnent pas : la trace complète d'une session, la possibilité de rejouer une requête avec un prompt modifié, et le coût par trace calculé automatiquement.

Helicone est une alternative plus légère, en mode proxy. On l'utilise sur des projets où l'intégration doit être minimale, c'est un header HTTP supplémentaire sur les appels OpenAI, zéro changement de code.

Les alertes qui ont de la valeur

On a réduit les alertes à cinq :

  1. Coût journalier > 120 % de la moyenne des 7 derniers jours. Détecte les runaway loops et les abus.
  2. Taux de refus > 3 % sur 1 heure. Indique un problème de guard-railing ou un prompt mal calibré.
  3. Latence P95 > 2× la baseline sur 30 minutes. Problème côté fournisseur ou context trop long.
  4. Taux de repromptage immédiat > 15 %. Proxy de qualité dégradée.
  5. Score golden dataset < seuil à chaque déploiement de prompt.

Tout le reste part dans un dashboard qu'on consulte manuellement une fois par semaine.

Ce qu'on n'a pas encore résolu

La vérité terrain reste le problème central. On peut détecter les signaux faibles d'insatisfaction, mais distinguer automatiquement une bonne réponse d'une réponse plausible-mais-fausse reste difficile sans évaluation humaine ou LLM-as-judge bien calibré.

L'évaluation LLM-as-judge (utiliser un LLM pour noter les réponses d'un autre LLM) fonctionne sur des critères structurels, format, longueur, respect des contraintes. Elle est moins fiable sur des critères sémantiques fins, exactitude factuelle, pertinence nuancée, cohérence avec le contexte métier.

La question qu'on n'a pas tranchée : jusqu'où peut-on automatiser l'évaluation qualité sans perdre en fiabilité ? La réponse dépend probablement du domaine, et on n'a pas encore de réponse générale.

Disponible pour de nouveaux projets

Un projet à concrétiser ?
Parlons-en, sans engagement.

Un échange de 30 minutes pour cadrer votre besoin, qualifier la faisabilité et vous proposer une trajectoire claire.

1// kick-off : réponse sous 24h
2const project = await apogee.scope({
3 type: 'web | mobile | IA',
4 timeline: '6 à 16 semaines',
5 approach: 'sur-mesure'
6})
7// → cadrage offert
LLMOps monitoring : 18 mois de prod IA | Apogée Consult