10. Report

Rôle de l’étape

report génère un rapport HTML auto-contenu (Quarto + Python) à la fin du pipeline. Il décrit la campagne de codification réalisée et ne suppose aucune vérité terrain : il ne note pas le pipeline, il dit ce qu’il a produit.

Mesurer la qualité est le travail d’une autre étape, facultative : evaluate.

  • Code : report/ — entrée report/main.py
  • Sortie : …/{run}/report/report.html
  • Activé par défaut (skip-report vaut "false" dans argo/codif-pipeline.yaml) ; désactivable avec -p skip-report=true.
NoteIl y avait ici une détection de mode

report/main.py testait bool_and(code IS NULL) sur la sortie de conciliation et choisissait entre deux gabarits. Un seul code non nul dans un fichier de production suffisait à faire basculer tout le rapport en mode évaluation. Le second gabarit est parti dans evaluate, déclenché par un paramètre explicite ; il ne reste qu’un rapport, rendu sans condition.

Contenu

Sections réelles du gabarit prediction_report.qmd, et la question à laquelle chacune répond :

Section du rapport Question
Métadonnées du run quel run, quel fichier d’entrée, quels modèles, quelles durées d’étapes ?
Distribution des prédictions par niveau COICOP quels postes ressortent, à chaque profondeur de code ?
Source des prédictions combien de lignes codées par regex / consensus / LLM, et avec quelle confiance ?
Accord entre les classifieurs sur combien de lignes les classifieurs amont s’accordaient-ils (et le consensus a-t-il joué) ?
Accord de chaque classifieur avec le juge LLM (+ détail par groupe COICOP L2 sur les cas arbitrés) quel modèle amont le juge suit-il le plus souvent ?
Décisions du juge hors des prédictions des classifieurs sur quelles lignes le LLM a-t-il choisi un code qu’aucun modèle n’avait proposé ?

Les classifieurs amont sont détectés dynamiquement (jusqu’à 4 : LCS, RAG notices, RAG annotations, TTC) — le bloc RAG-annotations n’est inclus que s’il est présent dans les données.

Le rapport décrit la campagne de codification réalisée, sans calcul d’exactitude :

  • Répartition par source de prédiction : nombre de lignes codées par regex, par consensus, par llm, et nombre d’erreurs LLM (llm_error).

    n_regex     = (df["prediction_source"] == "regex").sum()
    n_consensus = (df["prediction_source"] == "consensus").sum()
    n_llm       = (df["prediction_source"] == "llm").sum()
  • Distribution par niveau COICOP : comptage des predicted_code tronqués à chaque niveau, enrichi du libellé (llm_libelle).

  • Calibration : répartition des décisions LLM par score de llm_confiance (1 à 5).

  • Consensus vs désaccord : pour les cas arbitrés par le LLM, comparaison de llm_code avec lcs_code / rag_code / ragann_code / ttc_code_1 — mesure l’apport de l’arbitrage par rapport à chaque modèle amont.

Les lignes sans code (prediction_source vide) et les erreurs LLM (llm_error) ressortent ici : leur nombre signale la part de produits non codés automatiquement. Voir l’éventail des valeurs possibles de predicted_code sur la page 9. Final output.

Rendre le rapport à la main

Les gabarits lisent leurs entrées via des variables d’environnement plutôt que des paramètres Quarto : REPORT_INPUT_PATH (fichier de prédictions), REPORT_DECIDE_PATH (sortie de conciliation), REPORT_RUN_ID, REPORT_RUN_DATE. C’est report/main.py qui les positionne avant d’appeler quarto render ; pour itérer sur le gabarit en local, il suffit de les exporter soi-même puis de rendre le .qmd directement.

Traçabilité MLflow

En plus du HTML, l’étape loggue le run dans MLflow (log_to_mlflow() dans report/main.py, expérience réglée par report-experiment). C’est facultatif et sans effet de bord : si MLFLOW_TRACKING_URI n’est pas défini, l’étape passe l’enregistrement.

Sont enregistrés notamment :

  • Paramètres du pipeline pour rejouer/comparer un run : run_id, run_date, bucket, sample_size, classify_rag_model (LLM des RAG), reconcile_llm_model, reconcile_llm_concurrency, classify_ttc_model_uri (URI du modèle utilisé par classify-ttc), les deux noms de collections Qdrant (classify_rag_notices_collection, classify_rag_annotations_collection), skip_report, l’emplacement S3 de sortie — et surtout reconciliation et reconcile_sirus_model_uri : sans eux, deux runs aux métriques différentes seraient indistinguables, puisqu’on ne saurait pas laquelle des deux conciliations a tranché.
  • Tags : commit et branche git.
  • Métriques : durées des étapes Argo, nombre d’observations, distribution des codes prédits par niveau. Aucune accuracy : elles sont loguées par evaluate, dans sa propre expérience.
  • Artefacts : le report.html et prediction_distribution.json.

Logguer ttc_model_uri permet de savoir, pour chaque run, quel modèle TTC a produit les prédictions — utile pour comparer deux versions du classifieur.

Sortie

Fichier Contenu
…/{run}/report/report.html rapport HTML auto-contenu

➡️ Étape suivante, facultative : 11. Evaluate

Retour à l’accueil