درس 8 — Fiabiliser en production

Observabilité : traces, logs, tableaux de bord et retours utilisateurs

5 دقائق قراءة

هذا المحتوى غير مترجم بعد. تُعرض النسخة الأصلية.

Trois niveaux d'observation

NiveauQuestionOutil type sur GCP
TraceQue s'est-il passé pour cette requête ?Cloud Trace (OpenTelemetry)
Log structuréQuelles données pour analyser après coup ?Cloud Logging, export BigQuery
Métrique / tableau de bordComment va le système dans son ensemble ?Cloud Monitoring, Looker Studio sur BigQuery
flowchart TD
  Q["Requête utilisateur"] --> T1["span : garde-fous entrée"]
  T1 --> T2["span : recherche (k, scores, ids)"]
  T2 --> T3["span : appel LLM (modèle, tokens, latence)"]
  T3 --> T4["span : validation + garde-fous sortie"]
  T4 --> L["Log structuré (trace_id, statut, coût)"]
  L --> BQ["BigQuery"]
  F["Retour utilisateur (pouce, commentaire)"] --> BQ
  BQ --> D["Tableau de bord + file de revue"]

Que journaliser ?

Un log par requête, structuré en JSON, relié à la trace par un identifiant :

journal.py
import json, logging, time, uuid

log = logging.getLogger("assistant")

def journaliser(question, resultat, docs, usage, debut, versions):
    log.info(json.dumps({
        "trace_id": str(uuid.uuid4()),
        "versions": versions,                       # prompt, index, modèle
        "question_longueur": len(question),         # pas la question brute si sensible
        "docs_retrouves": [d["id"] for d in docs],
        "scores": [round(d["score"], 3) for d in docs],
        "statut": resultat["statut"],               # ok, repli:..., refus_entree
        "sources_citees": resultat["sources"],
        "tokens_entree": usage["entree"],
        "tokens_sortie": usage["sortie"],
        "latence_ms": int((time.perf_counter() - debut) * 1000),
    }, ensure_ascii=False))

Un utilisateur signale une mauvaise réponse hier à 14 h. Quel champ de log permet le plus vite de savoir si la recherche ou la génération est en cause ?

Le tableau de bord minimal

IndicateurPourquoiAlerte suggérée (à adapter)
Taux de repli et de refusHausse = recherche dégradée ou prompt trop strictÉcart marqué par rapport à la moyenne des 7 derniers jours
Score de recherche moyen du top-1Baisse = questions hors base ou index casséBaisse durable
Latence p50 / p95Expérience utilisateurp95 au-dessus de l'objectif fixé avec le métier
Tokens et coût par jourBudgetSeuil de budget Cloud Billing
Taux de pouces vers le basQualité perçueHausse sur 3 jours consécutifs
Erreurs 429 / 5xx du fournisseurRésiliencePic
taux_repli_par_version.sql
-- BigQuery : taux de repli par version de prompt sur 7 jours
SELECT
  JSON_VALUE(payload, '$.versions.prompt') AS version_prompt,
  COUNTIF(STARTS_WITH(JSON_VALUE(payload, '$.statut'), 'repli')) / COUNT(*) AS taux_repli,
  COUNT(*) AS requetes
FROM `mon_projet.logs_assistant.requetes`
WHERE horodatage >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
GROUP BY version_prompt
ORDER BY requetes DESC;

Les retours utilisateurs

Un pouce haut/bas est peu coûteux à ajouter et très utile, à condition de :

  1. le relier à la trace (trace_id) pour retrouver le contexte exact ;
  2. proposer un motif facultatif en un clic : « faux », « incomplet », « pas de source », « hors sujet » ;
  3. ne pas le confondre avec une mesure de justesse : un utilisateur peut aimer une réponse fausse mais confiante.

Pourquoi le taux de pouces vers le haut ne suffit-il pas à mesurer la justesse des réponses ?

Exercice : diagnostiquer une alerte

Lundi, le taux de repli passe d'environ 4 % à environ 15 %. Les logs montrent : version du prompt inchangée, version de l'index passée de 2026-09-01 à 2026-10-01, score top-1 moyen en baisse, latence stable. Que s'est-il probablement passé et que faites-vous ?

Voir la solution

Le changement coïncide avec la nouvelle version de l'index, et le score de recherche baisse : la cause probable est côté recherche (documents mal découpés, documents manquants, changement de modèle d'embedding sans réindexation complète, filtre de métadonnées erroné).

Actions :

  1. Relancer le jeu doré contre l'index 2026-10-01 et regarder le rappel moyen : s'il chute, c'est confirmé.
  2. Si nécessaire, revenir à l'index précédent (d'où l'intérêt de versionner les index).
  3. Ajouter au jeu doré quelques questions de production qui ont déclenché un repli, pour qu'une telle régression soit bloquée en CI la prochaine fois (module 4).

Je sais faire

  • Instrumenter une requête RAG en spans : garde-fous, recherche, LLM, validation.
  • Écrire un log structuré qui inclut versions, documents, statut, tokens et latence.
  • Définir les indicateurs et alertes d'un tableau de bord minimal.
  • Collecter des retours utilisateurs reliés aux traces et les transformer en cas de test.
  • Respecter la confidentialité des données dans les logs.
التالي