eval-harness-first

Par wshobson · agents

Construisez le dispositif d'évaluation qui conditionne chaque cycle de fine-tuning — golden sets, évaluateurs par mode d'échec, calibration du juge et baselines sur le modèle de base. À utiliser au démarrage d'un effort de fine-tuning, lors de la conversion de traces en ensemble d'évaluation, ou lors de la calibration d'un juge par rapport à des labels humains.

npx skills add https://github.com/wshobson/agents --skill eval-harness-first

Eval Harness En Premier

La gate Phase 0 pour l'ensemble du plugin : finetuning-method-selection et chaque skill en aval supposent que ce harness existe avant qu'une config d'entraînement ne soit écrite. Le harness n'est pas un artefact de fin de run — c'est le moteur de curation de données. Les mêmes traces annotées qui construisent les goldens alimentent les données d'entraînement, moins une holdout explicite.

Input : production/agent traces si elles existent, ou une task spec sinon, plus des labelers disposés à noter ≥100 exemples. Output format : le répertoire eval/ ci-dessous — goldens, graders, drift suite, et la baseline du modèle de base sur laquelle les phases ultérieures s'appuient.

La Gate

Pas de eval harness, pas de fine-tune. Sautez à une training config et il n'y a rien à mesurer, rien pour attraper les régressions, et pas de données annotées pour l'entraînement. Le flywheel :

  1. Collecter les traces — production/agent spans, ou tâches synthétiques si aucune n'existe encore.
  2. Analyse d'erreurs — open coding sur ≥100 traces, axial coding en 4–8 buckets d'échec.
  3. Un grader par bucket — déterministe en premier ; LLM-judge calibré seulement pour les critères véritablement subjectifs.
  4. Prioriser par fréquence × sévérité × valeur.
  5. Les traces annotées alimentent la curation de dataset, moins une holdout explicite. Chaque ID eval/goldens.jsonl reste exclu des données d'entraînement par ID.
  6. Entraîner.
  7. Réexécuter le même harness sur le checkpoint — pas un différent, plus lâche.
  8. La détection de drift remonte à l'étape 2 — les nouveaux modes d'échec en production rouvrent l'analyse d'erreurs.

Les étapes 2–4 construisent le harness ; les étapes 5–8 sont pourquoi il doit exister en premier — c'est à la fois la source de données d'entraînement et la gate de sortie du checkpoint.

Construire des Goldens

  • À partir de traces, quand elles existent : exécuter une analyse d'erreurs — open coding sur ≥100 traces réelles (les lire, taguer les échecs en vos propres termes, pas de taxonomie fixe encore), puis axial coding pour réduire ces tags en 4–8 buckets d'échec nommés. Moins de 4 signifie que la passe de coding était trop superficielle ; plus de 8 signifie que les buckets ont besoin de fusion. Exception : les tâches avec surface d'échec unique (p. ex. extraction de schéma strict) peuvent atterrir à 1–2 buckets avec des sous-métriques par champ à l'intérieur d'un grader — n'inventez pas de divisions artificielles sans preuve derrière elles.
  • Synthétique, quand les traces n'existent pas encore : génération basée sur les dimensions — énumérer les axes qui importent (type de tâche, difficulté, cas limite, persona) et échantillonner le produit cartésien ; les prompts librement générés se regroupent autour de ce qui est plus facile à écrire.
  • Les goldens sont versionnés comme du code — committer eval/goldens.jsonl, le diff en revue, le tagger par version. Il sert aussi de suite de régression CI.

Graders

Un grader par bucket d'échec de l'analyse d'erreurs — pas un pour l'ensemble de l'eval set. Un seul score mixte cache quel bucket a régressé.

  • Déterministe en premier. Les regex, la validation de schéma, ou les vérifications d'exécution sont moins coûteux, reproductibles, et ne nécessitent pas de calibrage.
  • LLM-judge seulement pour les critères véritablement subjectifs — ton, fidélité, « quelle réponse est meilleure » — où aucune vérification déterministe ne peut l'exprimer.
  • Pass/fail binaire sur Likert. Une échelle 1–5 ou 1–10 est plus bruyante à calibrer et plus difficile à appliquer de façon cohérente ; réduire à pass/fail.
  • Drift-suite MMLU-style scoring : préférer logprob à generate-and-extract — un budget token serré rend generate-and-extract fragile à l'analyse pour les modèles qui préambulent, conflant la conformité de format avec la connaissance mesurée. Templates pour les quatre formes de grader et cette note scoring : references/grader-templates.md.

Judge Calibration Est un Prérequis

N'importe quel bucket routé à un LLM-judge a besoin de calibrage avant que ses verdicts comptent pour quoi que ce soit au-delà de l'exploration — un prérequis dur, pas un nice-to-have. N/A quand aucun bucket ne route vers un judge — un harness tout déterministe n'a rien à calibrer ; exposez-le plutôt que de laisser cette section sans réponse.

  • Annoter ≥100 éléments, scinder train/dev/ sealed test (rapporter une fois, sans retouche après).
  • Rapporter TPR et TNR, pas un seul nombre de précision mixte — un judge peut frapper 90 % en disant toujours « pass » sur un ensemble biaisé.
  • Épingler le judge à un snapshot de modèle fixe et recalibrer lors du changement de judge-model, trimestriellement sans faute.
  • Le judge doit provenir d'une famille de modèles différente du modèle testé.
  • Un judge qui manque la barre TPR/TNR convenue livre advisory-only — flags pour revue humaine, jamais gate une promotion. Protocole complet, correction de biais, et checklist de recalibrage : references/judge-calibration.md.

La Baseline

Avant que Phase 1 (sélection de méthode) ne commence, exécuter le harness complet — goldens plus la drift-suite capability — sur le modèle de base non modifié. C'est le nombre contre lequel tous les checkpoints ultérieurs sont comparés.

eval/baseline-<model>.json est le gate token. Pas de fichier baseline, pas de base de comparaison pour checkpoint-promotion — un checkpoint qui « semble meilleur » contre rien de mesuré n'est pas une découverte.

Contrat du Répertoire

eval/
├── goldens.jsonl          # traces annotées + goldens synthétiques, versionnés
├── graders/                # un module par bucket d'échec
│   ├── schema_compliance.py
│   ├── exact_match.py
│   └── rubric_judge.py
├── drift-suite.yaml        # benchmarks figés + 200-500 éléments adjacents au domaine
└── baseline-<model>.json   # gate token : harness + drift suite vs le modèle de base
runs/
└── <run-id>/
    └── results.json         # output harness par run, un par checkpoint

eval/ persiste à travers les runs et vit en dehors de runs/ — la mesure fixe, pas un artefact de run. runs/ est jetable ; eval/ ne l'est pas. Ne laissez jamais un script de run écrire dans eval/. Emplacement canonique : chaque results.json par trace — la baseline Phase 0 incluse — vit à runs/<run-id>/results.json, jamais sous eval/runs/... ; une instruction demandant ce dernier est incorrecte, pas ce contrat.

Phase 0 Exit Checklist

Avant finetuning-method-selection, confirmez :

  1. ≥100 traces open-codées ; 4–8 buckets d'échec (N/A plancher pour goldens synthétiques sur une tâche surface d'échec unique — voir l'exception Building Goldens ; le compte de buckets provient alors de l'analyse d'erreurs post-baseline).
  2. eval/goldens.jsonl committée et versionnée.
  3. Un grader par bucket, déterministe en premier.
  4. Judges calibrés — TPR/TNR, snapshot épinglé, famille différente (N/A quand aucun bucket ne route vers un LLM-judge ; l'exposer explicitement).
  5. eval/drift-suite.yaml gelée.
  6. eval/baseline-<model>.json écrit.

Manquer l'un des six (ou son N/A exposé) ? Phase 0 non complète — /finetune vérifie le fichier baseline avant un run.

Skills Connexes

L'orientation générale d'évaluation (dashboards, A/B testing, harnesses sans fine-tuning) vit dans la skill llm-evaluation du plugin llm-application-dev — cette skill couvre seulement le couplage fine-tuning : goldens qui doublent de données d'entraînement, et la baseline qui gate un checkpoint.

  • finetuning-method-selection — route ici en premier.
  • dataset-curation — formate ces traces en lignes d'entraînement.
  • trace-to-training-data — transforme les traces notées en exemples d'entraînement.
  • checkpoint-promotion — consomme baseline-<model>.json, réexécute ce harness sur chaque checkpoint candidat.

Références

  • references/grader-templates.md — exemples de grader exécutables par forme, plus un exemple drift-suite.yaml et note MMLU logprob-scoring.
  • references/judge-calibration.md — le protocole de calibrage, y compris le chemin N/A tout déterministe.

Skills similaires