Méthodologie d'Évaluation
Ce document est la référence officielle pour comprendre comment PluginEval mesure la qualité des plugins et des skills. Il couvre les trois couches d'évaluation, les dix dimensions de notation, la formule composite, les seuils de badges, les signaleurs d'anti-patterns, le classement Elo, et des conseils d'amélioration exploitables.
Voir aussi : Anchors complets du rubric
Les Trois Couches d'Évaluation
PluginEval empile trois couches complémentaires. Chaque couche produit une note entre 0,0 et 1,0 pour chaque dimension applicable, et les couches ultérieures remplacent ou se mélangent aux précédentes selon les poids de fusion spécifiques à chaque dimension.
Couche 1 — Analyse Statique
Vitesse : < 2 secondes. Aucun appel LLM. Déterministe.
L'analyseur statique (layers/static.py) exécute six sous-contrôles directement sur le SKILL.md analysé :
| Sous-contrôle | Ce qu'il mesure |
|---|---|
frontmatter_quality |
Présence du nom, longueur de la description, qualité des phrases déclencheur |
orchestration_wiring |
Documentation des sorties/entrées, nombre de blocs de code, anti-pattern orchestrateur |
progressive_disclosure |
Nombre de lignes vs zone optimale (200–600 lignes), bonus references/ et assets/ |
structural_completeness |
Densité des titres, blocs de code, section exemples, section dépannage |
token_efficiency |
Densité MUST/NEVER/ALWAYS, ratio de répétition des lignes dupliquées |
ecosystem_coherence |
Références croisées vers d'autres skills/agents, mentions « related »/« see also » |
Ces six sous-contrôles alimentent directement six des dix dimensions finales (via le mapping STATIC_TO_DIMENSION). Les quatre dimensions restantes — output_quality, scope_calibration,
robustness, et une partie de triggering_accuracy — ne reçoivent aucune contribution statique et s'appuient
entièrement sur la Couche 2 et/ou la Couche 3.
La pénalité anti-pattern s'applique de manière multiplicative au score de la Couche 1 :
penalty = max(0.5, 1.0 − 0.05 × anti_pattern_count)
Chaque anti-pattern détecté supplémentaire réduit le score de 5 %, avec un plancher de 50 %.
Couche 2 — Juge LLM
Vitesse : 30–90 secondes. Un ou plusieurs appels LLM (Sonnet par défaut). Non-déterministe.
L'agent eval-judge lit le SKILL.md et tous les fichiers references/, puis note quatre
dimensions avec des rubrics ancrés (voir references/rubrics.md) :
- Précision du déclenchement — Score F1 dérivé de 10 prompts mentaux de test
- Ajustement d'orchestration — Évaluation de la pureté du worker (rubric 0–1)
- Qualité de la sortie — Simule 3 tâches réalistes ; évalue la qualité des instructions
- Calibrage du scope — Juge la profondeur et l'étendue par rapport à la catégorie du skill
Le juge retourne un objet JSON structuré (sans fences markdown) que le moteur d'évaluation fusionne
dans le composite. Quand judges > 1, les scores sont moyennés et le kappa de Cohen est rapporté comme
métrique d'accord inter-juges.
Couche 3 — Simulation Monte Carlo
Vitesse : 5–20 minutes. N=50 invocations Agent SDK simulées (défaut). Statistique.
Monte Carlo exécute N prompts réels à travers le skill et enregistre :
- Taux d'activation — Fraction de prompts qui ont déclenché le skill
- Cohérence de sortie — Coefficient de variation (CV) sur les scores de qualité
- Taux d'échec — Fraction erreur/crash avec IC exact Clopper-Pearson
- Efficacité tokens — Nombre médian de tokens, IQR, nombre de valeurs aberrantes
La formule composite de la Couche 3 :
mc_score = 0.40 × activation_rate
+ 0.30 × (1 − min(1.0, CV))
+ 0.20 × (1 − failure_rate)
+ 0.10 × efficiency_norm
où efficiency_norm = max(0, 1 − median_tokens / 8000).
Formule de Notation Composite
Le score final est un mélange pondéré sur les trois couches pour chaque dimension, puis sommé :
composite = Σ(dimension_weight × blended_dimension_score) × 100 × anti_pattern_penalty
Poids des Dimensions
| Dimension | Poids | Pourquoi c'est important |
|---|---|---|
triggering_accuracy |
0,25 | Un skill qui ne s'active jamais — ou s'active incorrectement — n'a aucune valeur |
orchestration_fitness |
0,20 | Les skills doivent être des workers purs ; la logique superviseur appartient aux agents |
output_quality |
0,15 | Une sortie correcte et complète est le livrable principal |
scope_calibration |
0,12 | Ni une esquisse ni un monstre gonflé |
progressive_disclosure |
0,10 | SKILL.md est épuré ; les détails vivent dans references/ |
token_efficiency |
0,06 | Gaspillage minimal de contexte par invocation |
robustness |
0,05 | Gère les cas limites sans crash |
structural_completeness |
0,03 | Sections correctes dans le bon ordre |
code_template_quality |
0,02 | Exemples fonctionnels, prêts à copier-coller |
ecosystem_coherence |
0,02 | Références croisées ; pas de duplication avec les siblings |
Poids de Fusion des Couches
Chaque dimension puise dans différentes couches à différents ratios. Avec les trois couches actives
(--depth deep ou certify) :
| Dimension | Statique | Juge | Monte Carlo |
|---|---|---|---|
triggering_accuracy |
0,15 | 0,25 | 0,60 |
orchestration_fitness |
0,10 | 0,70 | 0,20 |
output_quality |
0,00 | 0,40 | 0,60 |
scope_calibration |
0,30 | 0,55 | 0,15 |
progressive_disclosure |
0,80 | 0,20 | 0,00 |
token_efficiency |
0,40 | 0,10 | 0,50 |
robustness |
0,00 | 0,20 | 0,80 |
structural_completeness |
0,90 | 0,10 | 0,00 |
code_template_quality |
0,30 | 0,70 | 0,00 |
ecosystem_coherence |
0,85 | 0,15 | 0,00 |
À --depth standard (statique + juge uniquement), les fusions sont renormalisées pour supprimer la colonne Monte Carlo. À --depth quick (statique uniquement), tous les poids vont à la Couche 1.
Calcul du Score Fusionné
Pour une profondeur donnée, le score fusionné pour la dimension d est :
blended[d] = Σ( layer_weight[d][layer] × layer_score[d][layer] )
─────────────────────────────────────────────────────
Σ( layer_weight[d][layer] for available layers )
Cette normalisation garantit que l'omission de Monte Carlo à profondeur standard ne dégonfle pas artificiellement les scores.
Interprétation des Scores de Dimension
Chaque score de dimension est un flottant dans [0,0, 1,0]. La CLI le convertit en note littérale :
| Note | Plage de score | Signification |
|---|---|---|
| A | 0,90 – 1,00 | Excellent — aucune amélioration significative nécessaire |
| B | 0,80 – 0,89 | Bon — seules des lacunes mineures |
| C | 0,70 – 0,79 | Adéquat — une ou deux zones d'amélioration claires |
| D | 0,60 – 0,69 | Marginal — nécessite un travail ciblé |
| F | < 0,60 | Défaillant — amélioration significative requise |
Lors de la lecture d'un rapport, concentrez-vous d'abord sur la dimension la plus mal notée qui a le poids le plus élevé.
Une D en triggering_accuracy (poids 0,25) coûte bien plus qu'une D en ecosystem_coherence
(poids 0,02).
Les intervalles de confiance apparaissent dans le rapport quand la Couche 2 ou la Couche 3 ont été exécutées. Les IC étroites (± < 5 points) indiquent des scores stables. Les IC larges suggèrent une incohérence — souvent causée par une description ambiguë ou des instructions qui fonctionnent pour certains styles de prompts mais pas d'autres.
Badges de Qualité
Les badges nécessitent à la fois un seuil de score composite ET un seuil Elo (quand Elo est disponible).
La logique Badge.from_scores() vérifie d'abord le composite, puis Elo si fourni :
| Badge | Composite | Elo | Signification |
|---|---|---|---|
| Platinum ★★★★★ | ≥ 90 | ≥ 1600 | Qualité de référence — approprié pour corpus or |
| Gold ★★★★ | ≥ 80 | ≥ 1500 | Prêt pour la production |
| Silver ★★★ | ≥ 70 | ≥ 1400 | Fonctionnel, a des opportunités d'amélioration |
| Bronze ★★ | ≥ 60 | ≥ 1300 | Minimum viable — pas encore recommandé pour les utilisateurs |
| — | < 60 | tout | Ne respecte pas le seuil minimum |
Le seuil Elo est ignoré quand Elo n'a pas été calculé (c'est-à-dire à profondeur quick ou standard sans certify). Un skill peut gagner un badge sur score composite seul dans ces cas.
Signaleurs d'Anti-Pattern
L'analyseur statique détecte cinq anti-patterns. Chacun porte un multiplicateur de sévérité qui alimente la formule de pénalité.
OVER_CONSTRAINED
Déclencheur : Plus de 15 occurrences de MUST, ALWAYS, ou NEVER dans le SKILL.md.
Problème : Des instructions trop prescriptives réduisent la flexibilité du modèle, augmentent les frais généraux tokens, et signalent que l'auteur essaie de contrôler chaque sortie plutôt que de fournir des conseils principes.
Correctif : Auditez chaque MUST/ALWAYS/NEVER. Remplacez le langage directif par un cadrage explicatif quand c'est possible. Réservez les contraintes dures aux vrais besoins de sécurité ou de correction. Visez moins de 10 telles directives par 100 lignes.
EMPTY_DESCRIPTION
Déclencheur : Le champ frontmatter description contient moins de 20 caractères après nettoyage.
Problème : Sans une description significative, le système plugin Claude Code ne peut pas déterminer quand invoquer le skill. Le skill devient invisible pour l'invocation autonome.
Correctif : Écrivez une description d'au moins 60–120 caractères qui inclut :
- Une clause « Use this skill when... » ou « Use when... »
- Deux contextes concrets ou plus séparés par des virgules ou « or »
MISSING_TRIGGER
Déclencheur : La description ne contient pas « use when », « use this skill when », « use proactively », ou « trigger when » (insensible à la casse).
Problème : Même une longue description est inutile pour l'invocation autonome si elle n'inclut pas une signal de déclenchement clair. Le modèle de routage du système a besoin d'une indication explicite.
Correctif : Commencez par « Use this skill when... » la description, suivi de scénarios spécifiques. Exemple : « Use this skill when measuring plugin quality, interpreting score reports, or explaining badge thresholds to a team. »
BLOATED_SKILL
Déclencheur : SKILL.md dépasse 800 lignes ET le skill n'a pas de répertoire references/.
Problème : Un SKILL.md monolithique force l'intégralité du document en contexte à chaque invocation, gaspillant des tokens sur du contenu seulement nécessaire dans les cas limites.
Correctif : Créez un répertoire references/ et déplacez-y le matériel de soutien :
- Rubrics détaillés →
references/rubrics.md - Exemples étendus →
references/examples.md - Référence de configuration →
references/config.md
Le SKILL.md doit lier vers ces fichiers avec [text](references/filename.md) pour que le modèle
puisse les récupérer à la demande.
ORPHAN_REFERENCE
Déclencheur : SKILL.md contient un lien markdown [text](references/filename) où
filename n'existe pas dans le répertoire references/.
Problème : Les liens morts gaspillent des tokens sur du contexte qui ne se résoudra jamais et confondent le modèle.
Correctif : Soit créez le fichier de référence manquant, soit supprimez le lien mort.
DEAD_CROSS_REF
Déclencheur : SKILL.md référence un autre skill ou agent par chemin relatif et ce chemin ne peut pas être résolu depuis le répertoire skills/.
Problème : Les liens d'écosystème cassés minent le score de cohérence du plugin et peuvent amener le modèle à tenter de naviguer vers des fichiers inexistants.
Correctif : Vérifiez que le skill référencé existe. Mettez à jour le chemin ou supprimez la référence.
Classement Elo
PluginEval utilise un système de notation Elo/Bradley-Terry pour classer un skill par rapport au corpus gold.
Note de départ : 1500 (la médiane du corpus par convention).
Facteur K : 32 (standard pour les notations de enjeux modérés).
Formule de score attendu (Elo standard) :
E(A vs B) = 1 / (1 + 10^((B_rating − A_rating) / 400))
Mise à jour de la note après chaque appairage :
new_rating = old_rating + 32 × (actual_score − expected_score)
où actual_score est 1,0 pour une victoire, 0,5 pour un match nul, 0,0 pour une défaite.
Les intervalles de confiance sont calculés via bootstrap de 500 échantillons, rapportés comme IC à 95 %. Le percentile du corpus reflète le taux de victoire par paires contre le corpus gold. Vérification du biais de position : Les paires sont évaluées dans les deux ordres ; les désaccords sont signalés.
La commande plugin-eval init construit l'index du corpus à partir d'un répertoire de plugins :
plugin-eval init ./plugins --corpus-dir ~/.plugineval/corpus
Référence CLI
Noter un skill (analyse statique rapide uniquement)
plugin-eval score ./path/to/skill --depth quick
Retourne les résultats de la Couche 1 en < 2 secondes. Utile pour un retour rapide lors de la création.
Noter avec juge LLM (défaut)
plugin-eval score ./path/to/skill
Exécute analyse statique + juge LLM (profondeur standard). Prend 30–90 secondes.
Noter avec sortie complète en JSON
plugin-eval score ./path/to/skill --output json
Émet du JSON structuré incluant composite.score, composite.dimensions, et
layers[0].anti_patterns. Approprié pour intégration CI :
plugin-eval score ./path/to/skill --depth quick --output json --threshold 70
# quitte avec code 1 si score < 70
Certification complète (les trois couches + Elo)
plugin-eval certify ./path/to/skill
Exécute analyse statique + juge LLM + Monte Carlo (50 simulations) + classement Elo. Prend 15–20 minutes. Assigne un badge de qualité. Utilisez avant de publier un skill sur la marketplace.
Comparaison tête-à-tête
plugin-eval compare ./skill-a ./skill-b
Évalue les deux skills à profondeur quick et imprime un tableau de comparaison dimension par dimension. Utile pour décider entre deux implémentations ou mesurer l'amélioration avant/après une réécriture.
Initialiser le corpus pour Elo
plugin-eval init ./plugins
Construit l'index du corpus local à ~/.plugineval/corpus. Requis avant que le classement Elo ne fonctionne.
Scripting de la Formule Composite
Reproduisez le score composite hors ligne (pre-commit hook, porte CI) :
def composite_score(dimension_scores: dict, anti_pattern_count: int = 0) -> float:
"""Répliquez la formule composite PluginEval."""
WEIGHTS = {
"triggering_accuracy": 0.25,
"orchestration_fitness": 0.20,
"output_quality": 0.15,
"scope_calibration": 0.12,
"progressive_disclosure": 0.10,
"token_efficiency": 0.06,
"robustness": 0.05,
"structural_completeness":0.03,
"code_template_quality": 0.02,
"ecosystem_coherence": 0.02,
}
raw = sum(WEIGHTS[d] * s for d, s in dimension_scores.items())
penalty = max(0.5, 1.0 - 0.05 * anti_pattern_count)
return round(raw * 100 * penalty, 2)
# Exemple : un skill avec une note de déclenchement faible
scores = {
"triggering_accuracy": 0.65, # D — nécessite du travail sur la description
"orchestration_fitness": 0.85,
"output_quality": 0.80,
# … remplissez les 7 dimensions restantes …
}
# composite_score(scores, anti_pattern_count=1) → ~76.5
Format de Sortie JSON
Forme de haut niveau de --output json :
{
"composite": { "score": 76.5, "badge": "Silver", "elo": null },
"dimensions": {
"triggering_accuracy": { "score": 0.65, "grade": "D", "ci_low": 0.60, "ci_high": 0.70 },
"orchestration_fitness": { "score": 0.85, "grade": "B", "ci_low": 0.80, "ci_high": 0.90 }
},
"layers": [
{ "name": "static", "duration_ms": 1243, "anti_patterns": ["OVER_CONSTRAINED"] },
{ "name": "judge", "duration_ms": 48200, "judges": 1, "kappa": null }
]
}
Analysez composite.score en CI pour verrouiller les déploiements :
score=$(plugin-eval score ./my-skill --output json | python3 -c "import sys,json; print(json.load(sys.stdin)['composite']['score'])")
if (( $(echo "$score < 70" | bc -l) )); then
echo "Quality gate failed: score $score < 70"
exit 1
fi
Conseils pour Améliorer le Score d'un Skill
Travaillez les dimensions dans l'ordre des poids. Les gains les plus importants proviennent de la correction des dimensions les plus pondérées en premier.
Quelle Dimension Améliorer en Premier
Utilisez ce tableau quand un rapport de score affiche plusieurs notes D/F et que vous devez prioriser l'effort.
| Dimension | Poids | Effort de correction typique | Impact score / heure | Corriger en premier si… |
|---|---|---|---|---|
triggering_accuracy |
0,25 | Bas — réécriture description | Élevé | Score < 70 global |
orchestration_fitness |
0,20 | Moyen — restructurer sections | Élevé | Skill mélange logique worker + supervisor |
output_quality |
0,15 | Moyen — ajouter exemples | Moyen | Score juge < 0,70 |
scope_calibration |
0,12 | Bas — déplacer contenu vers references/ | Moyen | Fichier < 100 ou > 800 lignes |
progressive_disclosure |
0,10 | Bas — créer répertoire references/ | Moyen | Répertoire references/ n'existe pas |
token_efficiency |
0,06 | Bas — réduire MUST/ALWAYS/NEVER | Bas | Anti-pattern count ≥ 3 |
robustness |
0,05 | Bas — ajouter section Troubleshooting | Bas | Pas de gestion de cas limites documentée |
structural_completeness |
0,03 | Très bas — ajouter titres/blocs de code | Bas | Moins de 4 titres H2 |
code_template_quality |
0,02 | Très bas — ajouter tags de langue | Très bas | Blocs de code sans tags de langue |
ecosystem_coherence |
0,02 | Très bas — ajouter section Related | Très bas | Pas de références croisées du tout |
Règle générale : Corrigez triggering_accuracy avant tout — avec un poids de 0,25 il fournit
plus de gain de score composite par heure que toutes les dimensions de faible poids combinées.
Précision du Déclenchement (poids 0,25)
- Incluez « Use this skill when... » suivi de 3–4 contextes spécifiques séparés par des virgules.
- Ajoutez « proactively » si le skill doit s'auto-activer sans demande explicite de l'utilisateur.
- Test mental : écrivez 5 prompts qui devraient le déclencher et 5 qui ne devraient pas — votre description discrimine-t-elle ? Si non, ajoutez ou resserrez les phrases de contexte.
Ajustement d'Orchestration (poids 0,20)
- Documentez ce que le skill reçoit et ce qu'il retourne — pas ce qu'il orchestre.
- Évitez « orchestrate », « coordinate », « dispatch », « manage workflow » dans SKILL.md.
- Incluez une section « Output format » et 2+ blocs de code montrant un comportement worker concret.
Qualité de Sortie (poids 0,15)
- Donnez des instructions spécifiques et exploitables — pas seulement des objectifs.
- Couvrez au moins un cas limites explicitement (entrée vide, données malformées, etc.).
- Incluez une section d'exemples montrant des entrées représentatives et les sorties attendues.
- Plus les instructions sont concrètes, plus le juge notera cette dimension.
Calibrage du Scope (poids 0,12)
- Visez 200–600 lignes. Moins de 100 est une esquisse ; plus de 800 sans
references/est du gaspillage. - Déplacez la lecture de base, les exemples étendus, et les tableaux de référence vers
references/. - Les skills très étroits doivent être fusionnés avec un sibling ; les très larges doivent être divisés.
Divulgation Progressive (poids 0,10)
- Ajoutez un répertoire
references/(gagne un bonus 0,15–0,25) et gardez SKILL.md focalisé sur le chemin d'exécution. Un répertoireassets/ajoute un bonus supplémentaire.
Efficacité Token (poids 0,06)
- Auditez le nombre MUST/ALWAYS/NEVER. Visez < 1 par 10 lignes.
- Consolidez les points de balle presque dupliqués et les tableaux à structure répétée.
Robustesse (poids 0,05)
- Ajoutez une section « Troubleshooting » ou « Edge Cases » couvrant au moins 3 modes d'échec.
- Déclarez ce que le skill retourne quand il ne peut pas compléter sa tâche.
Complétude Structurelle (poids 0,03)
- Assurez-vous d'au moins 4 titres H2/H3, 3 blocs de code, une section Examples, et une section Troubleshooting.
Qualité du Modèle de Code (poids 0,02)
- Tous les blocs de code doivent être syntaxiquement valides et prêts à copier-coller avec des tags de langue.
Cohérence d'Écosystème (poids 0,02)
- Ajoutez une section « ## Related » listant les skills ou agents siblings avec des chemins relatifs.
- Évitez de dupliquer du contenu qui existe déjà dans un autre skill — liez-y plutôt.
Dépannage
« Le score est bien plus bas que prévu après avoir ajouté du contenu »
La pénalité anti-pattern s'aggrave. Exécutez avec --output json et inspectez
layers[0].anti_patterns. Si vous avez 5+ anti-patterns, le multiplicateur peut réduire votre
score à 75 % de sa valeur brute peu importe la qualité du contenu. Corrigez d'abord les signaleurs.
« triggering_accuracy est bas malgré une description détaillée »
Le scorer _description_pushiness cherche des patterns syntaxiques spécifiques, pas seulement la longueur.
Vérifiez que votre description contient la phrase « Use this skill when » ou « Use when » (l'exactitude
du libellé importe — c'est une correspondance regex). Vérifiez aussi que vous avez plusieurs cas d'usage séparés
par des virgules ou « or » pour gagner le bonus spécificité.
« Les scores du juge LLM varient significativement entre les exécutions »
C'est attendu pour les skills ambigus. Le juge génère 10 prompts de test mentaux
de manière non-déterministe. Améliorez la stabilité du score en resserrant la description et en ajoutant
des exemples concrets. Quand judges > 1, les scores moyennés seront plus stables. Utilisez
--depth deep avec certify qui exécute Monte Carlo pour obtenir des scores statistiquement bornés.
« Le score progressive_disclosure est bas même si le fichier est de la bonne longueur »
Vérifiez si le fichier se situe dans la zone optimale 200–600 lignes. Les fichiers de moins de 100 lignes
ne marquent que 0,20 sur ce sous-contrôle. Confirm aussi que les fichiers references/ ne sont pas vides —
le scorer vérifie les fichiers de référence non-vides, pas seulement le répertoire.
« compare affiche que ma réécriture marque plus bas que l'original »
La profondeur quick (--depth quick) exécute seulement l'analyse statique. Si la réécriture a déplacé du contenu vers
references/ et a significativement raccourci SKILL.md, les scores statiques pour la complétude structurelle
peuvent chuter même si la qualité globale s'est améliorée. Exécutez --depth standard pour une comparaison plus juste
qui inclut l'évaluation du juge LLM sur la qualité du contenu.
Références
Agents Liés
- eval-judge (
../../agents/eval-judge.md) — le juge LLM qui note les dimensions de la Couche 2 (triggering_accuracy,orchestration_fitness,output_quality,scope_calibration). Invoquez directement quand vous devez relancer seulement la couche juge ou inspecter son raisonnement. - eval-orchestrator (
../../agents/eval-orchestrator.md) — l'orchestrateur de haut niveau qui séquence les trois couches, fusionne les résultats, assigne les badges, et écrit le rapport final. Invoquez lors d'une passe de certification complète ou lors de la comparaison de deux skills tête-à-tête.