Skill Auditor — Évaluation de la dépréciation et de l'adéquation des capacités des agents
Aperçu
Un skill est un actif qui se déprécie. Les versions de modèles sont publiées tous les quelques mois. Un skill qui passait les tests le trimestre dernier peut régresser silencieusement — forme de sortie incorrecte, appels d'outils cassés, déclencheurs manqués — et personne ne prévient l'utilisateur que son agent est devenu moins intelligent.
Ce skill est la méthodologie d'évaluation. Il répond à trois questions :
- Un skill se dégrade-t-il ? — régression de capacité entre versions de modèle.
- Un nouveau skill est-il réellement bon ? — efficacité vs coût.
- Un skill convient-il à CET utilisateur ? — précision des déclencheurs + environnement + style.
Il embarque cinq points d'entrée exécutables :
scripts/console.py— la console résidente (couche de données) : maintientregistry.<host>.jsonpar hôte, détecte les changements de version de modèle (bump/check) et émet le panneau de recommandation/élimination. VoirUSAGE.mdpour la liste complète des commandes.scripts/regress.py— à partir des résultats de rejeu d'un golden set, calcule la matrice de taux de réussite, signale la dégradation (seuil + direction) et signaleFINGERPRINT-DRIFTlorsqu'un actif a été modifié au lieu de cela.scripts/baseline.py— génère une liste de contrôle de rejeu, puis fusionne les verdicts enregistrés dansbaseline-results.json(par actif ;--replacepour un remplacement complet). Les cas golden en brouillon sont ignorés sauf si--allow-draft.scripts/fingerprint.py— CLI de rapport autonome ; une fine surcouche du même code de hachage utilisé parscan. Il écrit uniquementfingerprint-report.*; il n'écrit pas le registre.scripts/install.py— installe ce skill dans chaque hôte d'agent sur la machine (~/.workbuddy-ai/skills,~/.claude/skills,~/.agents/skills,~/.dsh/skills,~/.codex/skills). Vérifie après l'installation ; ne laisse jamais de répertoire vide derrière lui ; ne copie jamais de données personnelles.
Principe fondamental : pas de mesure sans référence (baseline). Dégradation = baisse significative du taux de réussite sous une empreinte inchangée — jamais "j'ai l'impression que c'est moins intelligent".
Architecture Multi-Hôte (skills vs plugins)
Un moteur central, des adaptateurs par hôte. La même logique d'empreinte / référence / régression / recommandation / suggestion de besoin s'exécute partout ; un adaptateur sait seulement où se trouvent les actifs et comment lire leur manifeste.
| hôte | type | racine par défaut | manifeste |
|---|---|---|---|
| workbuddy | skill | racine des skills qui contient ce skill | SKILL.md |
| claude-code | skill | ~/.claude/skills | SKILL.md |
| deepseek | plugin | ~/.dsh/profiles/desktop (lit les dépendances package.json) | package.json / plugin.json |
| generic | actif | passer --root | plugin.json / manifest.json / SKILL.md / package.json |
- Chaque hôte conserve son propre registre :
registry.<host>.json— pas d'écrasement entre hôtes. - Les résultats de référence + les golden sets sont partagés, clés par nom d'actif.
- Exécutez avec
--host <name> --root <path>; ajoutez des hôtes personnalisés danshosts.json. console.py hostsaffiche chaque profil, sa racine résolue et le nombre d'actifs détectés.
Ainsi, dans WorkBuddy vous évaluez des skills ; dans DeepSeek harness vous évaluez des plugins — mêmes commandes, adaptateur différent. Ajouter un nouvel hôte est une simple entrée dans hosts.json (type + racine + noms de manifeste), sans modification de code.
Quand l'utiliser
- Avant de déployer un nouveau skill ou plugin ("fais un skill, suis le processus d'évaluation").
- Après une mise à jour de version de modèle, pour vérifier si les skills existants ont régressé.
- Quand un skill "semble bizarre" — confirmez avec des données, pas des impressions.
- Pour décider de conserver / réécrire / retirer un skill.
- Pour recommander un skill ou un plugin à un utilisateur (adéquation + preuves).
Quand NE PAS l'utiliser : tâches ponctuelles sans skill réutilisable ; documents purement narratifs.
Concept Clé : L'Empreinte de Version (Fingerprint)
L'empreinte est la ligne de la matrice de dépréciation.
fingerprint = hash(contenu des fichiers de surface de capacité + chemin relatif) # mesure v2-surface-de-capacité
Ce qui constitue la surface de capacité (les fichiers dont le changement modifie réellement le comportement) :
- inclus :
SKILL.md,scripts/*,lib/*,dist/*,package.json,plugin.json,cordis.patch.yml, templates - exclus :
README*,CHANGELOG*,LICENSE*, images/audio/fonts,*.map, lockfiles,node_modules/,test*/,docs/
Pourquoi exclure : une modification du README ne change pas la capacité, mais son hachage ferait bouger l'empreinte et produirait un faux FINGERPRINT-DRIFT ("l'actif a été modifié") alors que rien de fonctionnel n'a changé. Les plugins empirent ce problème — un plugin installé peut contenir 16 Mo de sortie groupée plus un README de 57 Ko.
Règles :
- Empreinte inchangée ⇒ la ligne persiste ; une baisse du taux de réussite est une régression du modèle.
- Empreinte modifiée ⇒ le changement est de la responsabilité du skill, pas du modèle. Les anciennes et nouvelles lignes coexistent, donc les modifications de skill ne sont jamais attribuées à tort à une dérive du modèle.
Exécutez python scripts/console.py scan pour calculer les empreintes et les stocker dans le registre. fingerprint.py est une surcouche de rapport autonome ; il ne touche pas au registre.
Surface de Capacité (pourquoi les plugins ont besoin d'un second axe)
L'empreinte dit "les fichiers ont-ils changé ?". Elle ne peut pas dire "offre-t-il toujours la même chose ?".
scan enregistre donc également une surface de capacité par actif et la compare avec l'analyse précédente :
| Type d'actif | Ce que la surface enregistre |
|---|---|
| plugin | patch (dsh.bundle.patch), main/module, bin, exports, deps, skills, mcp, hooks, insert (lignes cordis), scripts |
| skill | tools (nombre d'outils autorisés), scripts |
Lorsqu'elle change, scan l'affiche explicitement :
[caps] 1 actif a changé de surface de capacité (cela signifie que « ce qu'il offre à l'extérieur a changé », sans lien avec le taux de réussite) :
plug-a +bin
Pourquoi c'est important pour les plugins : un plugin se dégrade en n'enregistrant pas ses outils / en retournant des 404 sur ses routes / en n'exécutant pas ses hooks — pas en "répondant moins bien". Un golden set de prompts mesure la mauvaise chose pour un plugin. Le diff de surface détecte "la v1.1.0 a supprimé un point d'entrée" sans avoir besoin de démarrer l'hôte.
Limite connue (ne pas la masquer) : la surface est une capacité déclarée, pas une capacité observée. Pour un plugin dont le manifeste ment (déclare un patch qui échoue à charger), cela ne peut pas être détecté.
Preuves d'Exécution (le troisième axe, et ce qu'il ne peut pas faire)
Il existe deux choses très différentes appelées "sonde d'exécution". Ne les confondez pas :
| Sonde active (active probe) | Preuve passive (passive evidence) — implémentée | |
|---|---|---|
| ce qu'elle fait | démarre l'hôte, demande "quels outils as-tu réellement enregistrés" | lit le journal que l'hôte écrit déjà |
| coût | Le profil desktop de DSH est exclusif à Electron — dsh --profile desktop --dump-config est refusé ; pas d'entrée headless → rétro-ingénierie de l'IPC ou pilotage de l'interface utilisateur | une lecture de fichier, ~10 ms |
| détecte | tout, y compris un plugin dont le manifeste ment | tout ce que le plugin a journalisé |
| statut | non construit | console.py probe / skill_audit_probe |
probe lit ~/.dsh/logs/*.log (configurable par hôte via "logs" dans hosts.json), analyse <iso> [niveau] [source] message, attribue les lignes dont la source correspond au nom d'un actif installé, et signale les lignes correspondant à un vocabulaire d'échec (fail|error|ENOENT|unavailable|timeout|…).
Exemple réel, sur cette machine :
@wxg-prc-cpg/browser-skill-dsh-plugin 2 indices de défaillance
échec de la sonde bsk (spawn bsk ENOENT) ; les outils du navigateur signaleront des conseils d'installation…
Fichiers présents, manifeste valide, caps=4 — toutes les vérifications statiques réussissent. Le plugin est chargé et ses outils sont enregistrés, mais ils ne peuvent pas fonctionner : le CLI bsk auquel il délègue n'est pas dans le PATH. Aucun hachage de fichier ne trouve cela.
Angles morts (énoncez-les, ne les cachez jamais) : un plugin qui ne journalise rien est invisible ; la rotation des journaux efface les anciennes défaillances ; un plugin que personne n'a utilisé n'a aucune preuve ; les défaillances de niveau info sont détectées par correspondance de mots-clés, donc les oublis et les faux positifs sont possibles. L'absence de preuve n'est pas une preuve de bon fonctionnement — probe affiche cette phrase elle-même plutôt qu'une coche verte.
Implémenté vs Méthodologie Seule (ne pas brouiller cette distinction)
La méthodologie ci-dessous est plus large que le code. Les utilisateurs doivent savoir quelle moitié ils tiennent :
| Domaine | Statut |
|---|---|
Empreinte sur la surface de capacité, scan/status, diff de capacité | implémenté |
| Génération de golden set + ingestion de référence (fusion par actif, protection des brouillons) | implémenté (baseline.py) |
Matrice de taux de réussite, seuil ≥20pp + direction, FINGERPRINT-DRIFT | implémenté (regress.py) |
Détection de changement de modèle (bump/check), tampons par hôte | implémenté — mais la source d'événement est manuelle ; une check planifiée reste verte jusqu'à ce que quelqu'un fasse bump |
| Panneau de recommandation/élimination, suggestion de besoin, brouillons issus de l'historique | implémenté (heuristique ; les suggestions ne sont pas des preuves) |
| Preuves d'exécution à partir des journaux hôte | implémenté (passif ; seulement ce que le plugin a journalisé) |
| Ablation, taux d'adoption en mode furtif, valeur nette / télémétrie de tokens | méthodologie seulement — aucun code |
| Précision/rappel des déclencheurs, réconciliation d'environnement, référence de style | méthodologie seulement — aucun code |
| Rejeux K≥3, validation croisée par LLM-juge | non implémenté ; les verdicts actuels sont une auto-évaluation K=1 |
Colonne risque | proxy de surface de maintenance — pas la valeur |
Si une affirmation dans ce fichier ne peut être attribuée à une ligne marquée "implémenté", traitez-la comme un conseil pour l'humain qui réalise l'audit, pas comme quelque chose que l'outil fera pour lui.
Jugement 1 — Dégradation de Capacité
Quatre étapes :
- Construire le golden set à partir de l'historique, pas à la main. Extraire les sessions passées : utilisateur a adopté sans opposition → rejeu positif ; utilisateur s'est opposé / a demandé une réécriture → négatif. Le rejeu EST la régression. L'historique d'utilisation de l'utilisateur lui-même est le corpus — pas d'ensemble de test inventé.
- Exécuter les deux modèles sur le même golden set, K≥3 (cas notés par LLM-juge : K≥5, car le juge est bruyant). Enregistrer le taux de réussite par (empreinte, version du modèle).
- Règle de décision : baisse ≥20pp ET cohérente directionnellement → signaler une dégradation ; en dessous du seuil → "surveillance de volatilité". Cela transforme "cette sortie est bizarre" en un critère reproductible.
- Attribuer, ne pas seulement signaler. Inspecter les artefacts intermédiaires :
- Erreur d'appel d'outil / format modifié → corriger la description de l'outil.
- Structure de sortie correcte, contenu faux → réécrire les instructions.
- Aurait dû se déclencher mais ne l'a pas fait → corriger la description du déclencheur.
- Tous les intermédiaires corrects, seul le résultat final est erroné → régression interne du modèle ; marquer le skill comme "dépendant d'un seul modèle", attendre la correction du modèle.
La ligne "7 dégradés, 2 recommandés pour réécriture" est le sous-ensemble attribuable de la sortie de l'étape 4 — c'est ce qui rend le rapport exploitable.
Jugement 2 — Un Nouveau Skill est-il Bon ?
Divisé en deux axes mesurables : efficacité (meilleurs résultats) et économie (coût réduit).
- Ablation pré-déploiement. Même lot de tâches, deux bras : A sans skill, B avec skill. Enregistrer le taux de réussite, le nombre de corrections humaines, le coût en tokens.
bénéfice net = augmentation_du_taux_de_réussite × fréquence_de_la_tâche − coût_marginalUn skill qui augmente le succès de 30 % mais se déclenche 3×/an à +50k tokens chacun est un passif, pas un actif. - Mode furtif post-déploiement. Le nouveau skill s'exécute en silence : produit des suggestions mais ne les exécute pas automatiquement ; journalise "ce qui se serait passé". Surveiller le taux d'adoption (accepté vs ignoré). Le taux d'adoption est le juge ultime du "bon", plus honnête que n'importe quelle métrique hors ligne. Limite : les skills d'opérations d'écriture (supprimer un fichier, envoyer un mail) ne peuvent que simuler/annoter en mode furtif, jamais vraiment s'exécuter.
- Carte de valeur nette. Un tableau de bord par skill : nombre d'appels, taux de réussite, taux d'adoption, tokens moyens, bénéfice net cumulé. 90 jours nets négatifs → suggérer réécriture ou retrait. C'est le versant consommateur de la table de dépréciation.
Jugement 3 — Convient-il à CET Utilisateur ?
"Vous convient" = déclencheurs précis + hypothèses tenues + style correspondant. Le tout automatisable :
- Précision des déclencheurs (affecte le plus la sensation, est le plus souvent ignorée). Échantillonner les positifs historiques (devrait se déclencher) et les négatifs (similaires, ne devrait pas — "corriger ce bug" vs "expliquer ce qu'est un bug"). Rejouer → précision/rappel. Faible précision = ennuyeux (trop de déclenchements) ; faible rappel = installation inutile. D'abord 10–20 étiquettes manuelles, puis semi-auto, zéro coût LLM.
- Réconciliation d'environnement (installé ≠ fonctionne). Les métadonnées du skill déclarent les dépendances : quels outils / MCP / permissions / habitudes de chemin / langage, plus les hypothèses implicites de capacité du modèle (contexte long, exécution de code, multimodal). Reconcilier avec l'environnement réel de l'utilisateur ; manquant → drapeau rouge. "Suppose macOS", "produit du japonais", "nécessite 200k de contexte" — les hypothèses invisibles sont la raison n°1 pour laquelle un skill reste inutilisé. Cela alimente également le Jugement 1 : une hypothèse de capacité non satisfaite = dégradation silencieuse.
- Référence de style (poids le plus faible). Utiliser la sortie historique de l'utilisateur + USER.md comme référence ; le LLM-juge compare le format, la langue, la verbosité. Utilisé uniquement pour départager des skills à score égal.
Workflow Intégré (pour "créer un nouveau skill")
Lorsque l'utilisateur demande de créer un skill, exécuter le protocole en ligne avant de livrer :
- Réconciliation d'environnement — l'environnement de l'utilisateur satisfait-il les dépendances déclarées + les hypothèses de capacité du skill ?
- Rejeu des déclencheurs — rejouer 10–20 cas échantillonnés ; rapporter précision/rappel.
- Ablation — sur un petit lot de tâches, mesurer l'amélioration vs le coût.
- Entrer en surveillance — en cas de succès, enregistrer l'empreinte + le golden set ; la console résidente réexécute à chaque mise à jour de modèle.
Suggestion Basée sur le Besoin (quand aucun skill ne correspond)
C'est le comportement "étagère vide" : un utilisateur (surtout celui qui n'a zero skill/plugin) demande quelque chose qu'aucun skill installé ne couvre. Ne dites pas simplement "je ne peux pas" — mettez en évidence le manque et proposez de le combler.
- Détecter le besoin à partir de la conversation : type de tâche + domaine (ex. "rapport financier trimestriel" → finance/analyse ; "supprimer le ton IA" → humaniseur ; "créer un tableau de bord" → frontend/graphique).
- Consulter d'abord le registre —
python scripts/console.py suggest --need "<besoin>". Il renvoie soit :✓ Vous avez déjà un skill/plugin utilisable : <nom>→ utilisez-le, n'installez rien ; soit💡 Suggestion d'ajout : [install:<slug>] <titre>→ aucune couverture, recommandez la catégorie.
- Si non couvert, rechercher sur le marketplace des candidats réels (skills/plugins/experts) et présenter une fiche avec preuves : ce qu'il fait, pourquoi il correspond à ce besoin, source. Ne jamais auto-installer — l'utilisateur choisit.
- En cas d'échec, construire un nouveau skill — comme décrit dans le Workflow Intégré ci-dessus — et entrer en surveillance.
Flux de Travail en Console (l'utilisateur tape, l'agent orchestre)
console.py est conçu pour être appelé par un agent, pas tapé directement par un humain. Les résultats sont écrits dans registry.<host>.json (et imprimés sur la sortie standard pour que l'agent les voie).
exemples de séquences d'utilisation agent → console :
| Déclencheur de l'utilisateur | L'agent exécute |
|---|---|
| "évalue ce skill" | console.py status (vérifie d'abord si quelqu'un a modifié des fichiers) ; console.py scan si l'empreinte a changé ; regress.py s'il existe une baseline |
| "le skill est-il encore bon après la mise à jour du modèle ?" | console.py check (voir si la version du modèle a changé depuis la dernière analyse) ; si oui, console.py bump <version> puis regress.py |
| "ce nouveau skill est-il bon ?" | baseline.py génère la baseline depuis l'historique ; regress.py sur la sortie |
| "ce skill me convient-il ?" | console.py status (montre la stabilité des déclencheurs et de la surface de capacité) ; suggest --need ; note : la réconciliation d'environnement et la précision/rappel ne sont pas automatisés — l'agent doit les orchestrer via le protocole |
| "que dois-je installer ?" | suggest --need "<dérivé de la conversation>" |
La console est l'intermédiaire de données de l'agent. Elle exécute l'outil. L'agent exécute le protocole.
Pré-requis
- Python ≥ 3.10 installé.
- Les hôtes cibles (WorkBuddy, DeepSeek, etc.) installés et leurs répertoires de skills accessibles.
- Droits en écriture sur les répertoires de registre.
Installation
Exécutez python scripts/install.py pour installer ce skill dans tous les hôtes d'agent configurés. L'installateur vérifie chaque cible après copie et ne laisse jamais de répertoire vide.
Utilisation
Consultez le fichier USAGE.md joint pour la documentation complète des commandes de console.py, y compris scan, status, check, bump, probe, suggest, hosts, et leurs options.