Skip to main content
claude plugin eval exécute votre plugin par rapport à une suite de cas de test et note les résultats. Chaque cas est une invite réaliste plus un ou plusieurs évaluateurs. Un évaluateur est une vérification réussi/échoué sur ce que Claude a produit, comme une regex sur la réponse, si un outil particulier a été appelé, ou une rubrique qu’un deuxième modèle juge sur la réponse. Vous n’avez pas à écrire la suite à la main ; claude plugin eval init vous pose des questions sur votre plugin, propose les cas et les évaluateurs, les essaie, et écrit les fichiers. Vous pouvez aussi demander à Claude de faire la même chose à partir d’une session que vous avez déjà ouverte. Utilisez les evals pour mesurer la fiabilité avec laquelle votre plugin oriente Claude vers le bon résultat, pour détecter les régressions lorsque vous modifiez le plugin ou qu’un nouveau modèle est lancé, et pour voir ce que le plugin contribue par rapport à aucun plugin du tout. Cette page est destinée aux auteurs de plugins et de skills qui ont un plugin fonctionnel et qui veulent tester son comportement, et aux équipes qui contrôlent les modifications de plugins dans CI. Son format de cas est séparé du fichier evals/evals.json que le plugin skill-creator utilise. Pour créer un plugin, voir Créer des plugins ; pour vérifier les fichiers d’un plugin pour les erreurs de syntaxe et de schéma plutôt que son comportement, utilisez claude plugin validate.
Chaque exécution d’eval et chaque évaluateur de juge est un vrai appel de modèle sur votre compte, compté par rapport à l’utilisation de votre plan ou votre facture API, alors vérifiez d’abord les exigences. Ensuite créez votre première suite d’eval, ou allez à Exécuter les evals dans CI si vous en avez déjà une.

Exigences

Pour exécuter les evals de plugin, vous avez besoin de :
  • Claude Code v2.1.269 ou ultérieur. Exécutez claude --version pour vérifier et claude update pour mettre à jour.
  • Un répertoire de plugin avec un manifeste plugin.json ou .claude-plugin/plugin.json, ou un plugin de répertoire de skills.
  • La même authentification et le même fournisseur de modèle que vos sessions Claude Code normales. Les exécutions d’eval, les évaluateurs notés par le juge, et claude plugin eval init appellent le modèle avec vos identifiants, donc ils comptent par rapport à vos limites d’utilisation du plan ou votre facture API. Lorsque la commande rapporte un coût, le chiffre est une estimation du prix catalogue de ces appels.

Comment fonctionne une exécution d’eval

Une suite d’eval vit dans un répertoire appelé evals/ à l’intérieur de votre plugin, disposé comme Écrire et affiner les cas le montre. Chaque cas est son propre sous-répertoire avec une invite et un ou plusieurs évaluateurs. L’invite est quelque chose qu’une personne utilisant votre plugin pourrait taper, comme une demande que l’une de ses skills devrait gérer.

Ce qui se passe dans une exécution

Pour chaque exécution d’un cas, Claude Code démarre une nouvelle session isolée non-interactive avec seulement votre plugin chargé, envoie l’invite, et laisse Claude travailler jusqu’à ce qu’il finisse ou atteigne la limite de tour ou de temps du cas. Chaque évaluateur vérifie ensuite la réponse finale, la transcription, ou un fichier que Claude a créé, et réussit ou échoue.

Comment un cas est noté

Une exécution d’un agent non-déterministe vous dit peu de choses, donc chaque cas s’exécute trois fois par défaut. Le score d’une exécution est la fraction de ses évaluateurs qui ont réussi, pondérée si vous définissez des poids, et le score du cas est la moyenne sur ses exécutions. Un cas réussit lorsque son score atteint le --threshold, 1.0 par défaut. Dans les appels de modèle, une suite fait environ cas × exécutions appels d’agent avec le plugin et autant à nouveau pour la base de référence sans plugin, plus trois appels de juge courts par évaluateur llm ou baseline par exécution.

La base de référence sans plugin

Un score élevé en soi ne vous dit pas si le plugin a aidé, car Claude pourrait faire aussi bien sans lui. Pour séparer les deux, les exécutions de chaque cas sont répétées sans plugin chargé par défaut, et vous obtenez deux scores, WITH et W/OUT. Leur différence, Δ, est ce que le plugin a contribué. Si un cas marque 1.0 à la fois avec et sans le plugin, le plugin n’est pas ce qui l’a fait réussir. Les deux ensembles d’exécutions sont appelés le bras with et le bras without ; Comparer avec une base de référence sans plugin couvre comment les évaluateurs sont notés sur les deux bras et comment désactiver la base de référence.

Créez votre première suite d’eval

Cette procédure écrit un cas pour votre propre plugin, l’exécute, et lit le résultat. Avant de commencer, assurez-vous que vous avez :
  • Claude Code v2.1.269 ou ultérieur et les autres exigences
  • Un terminal ouvert au répertoire racine de votre plugin, celui contenant plugin.json ou .claude-plugin/plugin.json
  • Une skill dans le plugin que vous voulez tester, et une demande qu’un utilisateur taperait qui devrait la déclencher
1

Créer les cas

À partir de la racine du plugin, exécutez :
Si Claude Code ne fait pas déjà confiance à ce répertoire, il demande d’abord Trust this plugin directory? ; répondez y. Une session Claude Code interactive s’ouvre ensuite. Claude lit votre plugin et vous demande à quoi ressemble un bon résultat, propose des invites qui devraient et ne devraient pas déclencher le plugin, conçoit des évaluateurs pour chacun, les teste une fois pour vérifier qu’ils se comportent, et écrit un répertoire de cas par invite sous evals/, chacun nommé d’après son invite. Lorsque Claude vous dit que la suite est prête, quittez cette session avec /exit ou Ctrl+D pour revenir à votre shell.Si vous avez déjà une session Claude Code ouverte à la racine du plugin, vous pouvez plutôt demander à Claude d’exécuter claude plugin eval init. Claude exécute la commande et vous pose ensuite les mêmes questions dans cette conversation.Si vous préférez écrire un cas vous-même pour voir exactement ce que contiennent les fichiers, suivez Écrire un cas à la main et revenez ici pour l’exécuter.
2

Exécuter la suite

De retour à votre shell à la racine du plugin, exécutez chaque cas sous evals/ :
Vous avez déjà fait confiance à ce répertoire lors de l’étape 1, donc l’exécution commence immédiatement. Si vous avez écrit le cas à la main à la place, l’exécution demande d’abord Trust this plugin directory? [y/N] ; répondez y. Ce qu’une exécution peut accéder explique à quoi vous acceptez.Chaque cas s’exécute trois fois avec votre plugin et trois fois sans lui, donc un cas est six exécutions. Une ligne de progression s’affiche à la fin de chaque exécution, avec le score de cette exécution et le verdict de chaque évaluateur.
3

Lire le résumé

Lorsque la suite se termine, vous voyez un tableau récapitulatif, suivi de l’endroit où le rapport est allé :
WITH est le score du cas avec votre plugin chargé, W/OUT est le score sans lui, et un Δ positif signifie que le plugin a augmenté le score. COST est une estimation du prix catalogue des appels de modèle, et NOTES affiche l’explication de l’évaluateur défaillant de poids le plus élevé, ou l’erreur de l’exécution, du bras with.
4

Ouvrir le rapport et itérer

Ouvrez l’URL Published:, ou le chemin Report: lorsqu’aucune ligne Published: n’apparaît, pour voir le verdict de chaque évaluateur et l’explication pour chaque exécution, et pour les évaluateurs llm les votes du juge et l’extrait qu’il a jugé. La ligne Published: n’apparaît que lorsque votre compte peut publier des rapports.La découverte la plus courante au premier abord est un Δ proche de zéro avec l’évaluateur tool_used: Skill du cas échouant, ce qui signifie que Claude ne choisit pas votre skill sur une formulation naturelle. Ajustez la description de la skill, exécutez claude plugin eval . à nouveau, et comparez.Pour itérer sur un cas à moindre coût, exécutez un seul bras une fois. Une seule exécution est bruyante, donc confirmez tout changement aux trois exécutions par défaut avant de lui faire confiance. Avec un seul bras, le tableau affiche les colonnes SCORE et PASS% au lieu de WITH, W/OUT, et Δ :
Remplacez <case-name> par l’un des noms de répertoire sous evals/.

Écrire et affiner les cas

Les cas que claude plugin eval init écrit sont des fichiers simples que vous pouvez ouvrir, modifier et ajouter. Un cas est un répertoire sous le répertoire eval du plugin qui contient un prompt.md, un case.yaml, ou les deux. Pour regrouper les cas, imbriquez-les sous un répertoire qui n’est pas lui-même un cas ; tout ce qui se trouve à l’intérieur d’un répertoire de cas, comme graders/ et les fichiers de fixture, appartient à ce cas. Ceci est la disposition que claude plugin eval init écrit et celle à utiliser pour les nouvelles suites. La référence de la suite d’eval a l’arborescence complète, y compris les mocks et les résultats :

Écrire un cas à la main

Faire écrire les cas par Claude avec claude plugin eval init est le chemin recommandé. Pour en écrire un vous-même à la place, commencez par un modèle vierge. La commande suivante écrit un cas nommé first-case avec un prompt.md d’espace réservé et un évaluateur d’espace réservé, et n’exécute rien :
Dans prompt.md, vous écrivez le message que Claude reçoit dans chaque exécution, et définissez les limites de l’exécution et les outils que le cas peut utiliser dans son frontmatter. Ouvrez evals/first-case/prompt.md et remplacez le corps d’espace réservé par une demande que l’une de vos skills devrait traiter, formulée de la manière qu’un utilisateur la taperait plutôt que de nommer la skill. Cet exemple concerne une skill qui rédige des messages de commit ; utilisez votre propre demande :
Chaque exécution commence dans un répertoire de travail vide, donc mettez tout ce dont la tâche a besoin dans l’invite elle-même, ou configurez l’espace de travail d’abord. La liste complète des champs frontmatter couvre le modèle, le délai d’expiration, les balises et les variables d’environnement. Chaque fichier sous graders/ est une vérification appliquée après l’exécution. Ouvrez evals/first-case/graders/criteria.md et remplacez l’espace réservé par une rubrique pour le modèle juge, écrite comme des conditions PASS et FAIL concrètes :
Ensuite, ajoutez un deuxième évaluateur qui vérifie si votre skill est ce qui a produit la réponse. Créez evals/first-case/graders/skill-fired.md, en remplaçant your-skill-name par le name du SKILL.md de votre skill :
Cela réussit lorsque Claude a invoqué cette skill au moins une fois pendant l’exécution, y compris par sa forme plugin-name:skill-name avec espace de noms. Types d’évaluateurs énumère les autres vérifications disponibles, comme la correspondance d’une regex ou la confirmation qu’un fichier a été créé. Avec les deux fichiers enregistrés, exécutez le cas de la manière que le démarrage rapide le fait, avec claude plugin eval . à partir de la racine du plugin.

Définir les limites d’exécution et les outils dans prompt.md

Définissez max_turns, timeout_seconds, model, tags d’un cas, et les allowed_tools qu’il peut utiliser dans le frontmatter de prompt.md ; la référence frontmatter de prompt.md énumère chaque champ et sa valeur par défaut. Claude reçoit le corps exactement comme vous l’avez écrit. Les mentions @path dedans ne sont pas développées en pièces jointes de fichier, donc si Claude a besoin de lire un fichier, accordez un outil pour cela dans allowed_tools.

Choisir et pondérer les évaluateurs

Le frontmatter d’un évaluateur définit son type, et optionnellement un weight qui le fait compter pour plus du score de l’exécution et un arm qui contrôle comment il est noté par rapport à la base de référence. Des six types, regex, tool_used, tool_order, et file_exists sont calculés à partir de la transcription et des fichiers et ne coûtent rien, tandis que llm et baseline appellent un modèle juge et s’ajoutent au coût de l’exécution. Il n’y a pas d’évaluateurs de code personnalisé. Types d’évaluateurs énumère les options de chaque type et la condition de réussite, et ce qu’un évaluateur peut regarder énumère les valeurs que target et focus acceptent. Le juge pour les évaluateurs llm et baseline est un petit modèle rapide par défaut. Passez --judge-model sonnet ou un ID de modèle complet pour en utiliser un plus fort pour les rubriques nuancées.

Choisir des évaluateurs qui donnent un signal stable

Un évaluateur llm demande à un modèle un verdict, donc sa réponse peut différer entre les exécutions, et elle diffère plus le plus long le texte qu’il doit lire. Ces habitudes gardent les scores d’une suite assez stables pour être dignes de confiance :
  • Pour une sortie longue comme un fichier généré, notez-la avec un évaluateur regex sur le contenu du fichier, qui vérifie le fichier entier de la même manière à chaque fois. Gardez les évaluateurs llm pour les sorties courtes, avec des rubriques écrites comme des conditions PASS et FAIL concrètes.
  • Donnez à chaque cas un évaluateur sur le résultat, comme le message final ou un fichier produit, et un sur la façon dont Claude y est arrivé, comme tool_used ou tool_order. Ensemble, ils vous disent à la fois si la réponse était correcte et si votre plugin l’a produite.
  • Si l’évaluateur tool_used: Skill d’un cas réussit mais Δ est négatif, soupçonnez le juge avant le plugin. Un petit modèle juge peut marquer une réponse correcte comme fausse parce qu’elle est formatée différemment de ce que la rubrique décrit. Réexécutez avec --judge-model sonnet, et resserrez la rubrique pour que le formatage ne décide pas du verdict.
  • Pour vérifier qu’une construction ou un test a réussi à l’intérieur de l’exécution, demandez à Claude de l’exécuter et d’écrire le résultat dans un fichier, notez ce fichier, et affirmez que la commande a été exécutée avec un évaluateur tool_used dont input_match nomme la commande.

Noter par rapport à la base de référence sans plugin

Lorsqu’un plugin est en test, chaque cas s’exécute dans deux bras par défaut. Le bras with est ses exécutions avec le plugin chargé, et le bras without est le même nombre d’exécutions sans aucun plugin. Le résumé et le rapport affichent les deux scores et Δ, le score du bras with moins le score du bras without. Passez --ablation none pour exécuter seulement le bras with, ce qui réduit de moitié le coût lorsque vous n’avez pas besoin de la comparaison, comme lors de l’itération sur les évaluateurs. Dans une exécution à deux bras, certains évaluateurs sont rapportés avec scored: false. Une vérification comme « la skill a été invoquée » ne peut jamais réussir sans le plugin, donc la compter pousserait le bras without vers zéro et gonflerait Δ. Pour garder les deux bras comparables, Claude Code exclut ces évaluateurs du score dans les deux bras et les rapporte dans le bras with comme des indicateurs réussi/échoué uniquement. Cela inclut :
  • Chaque évaluateur tool_used dont tool est Skill
  • Tout évaluateur que vous marquez arm: with-only
Si chaque évaluateur dans un cas en est un, ils sont notés normalement à la place, puisqu’il n’y aurait rien d’autre à noter. Définissez arm: both sur un évaluateur pour le noter dans les deux bras indépendamment, ce que vous voulez pour une vérification « ne doit pas invoquer la skill » avec min: 0 et max: 0. Sous --ablation none, rien n’est exclu, donc la même suite peut produire un score absolu différent dans les deux modes.

Utiliser un répertoire d’eval différent

Si evals/ est déjà pris par un autre outil, gardez la suite dans un répertoire différent. Vous pouvez enregistrer ce répertoire dans le plugin.json du plugin pour que chaque exécution et chaque collaborateur l’utilise, ou le passer sur la ligne de commande pour une seule exécution :
  • Dans plugin.json : ajoutez "experimental": { "evals": "quality/evals" }.
  • Sur la ligne de commande : passez --eval-dir quality/evals à la fois à claude plugin eval et claude plugin eval init.
Si vous définissez les deux, le répertoire du drapeau est utilisé. Donnez un chemin relatif de noms de répertoire simples comme qa ou quality/evals. Un chemin absolu ou contenant .. n’est pas accepté : comme valeur de drapeau c’est une erreur, tandis qu’une valeur de manifeste inutilisable imprime une ligne Warning: et l’exécution utilise evals/ à la place. Les cas, les résultats, et la sortie init se déplacent tous vers ce répertoire.

Configurer les fixtures et les mocks

Un cas peut avoir besoin de plus qu’une invite : des fichiers ou un référentiel git dans l’espace de travail, une conversation antérieure à continuer, ou des réponses des serveurs MCP avec lesquels votre plugin communique. Chacun d’eux est configuré à côté du cas pour que les exécutions restent reproductibles.

Ensemencer l’espace de travail ou la conversation

Chaque exécution commence dans un espace de travail vide. Lorsqu’un cas a besoin de plus que l’invite, ajoutez un case.yaml à côté de prompt.md avec un bloc context. Pour créer d’abord des fichiers de fixture ou un référentiel git, écrivez un script Bash dans le répertoire de cas et nommez-le dans context.scaffold_script. Le script s’exécute en tant que vous, en dehors du sandbox de l’agent, et seulement lorsque vous passez --scaffold, donc passez ce drapeau seulement pour les suites que vous ou votre organisation avez écrites. Pour continuer une conversation antérieure, enregistrez la transcription en tant que fichier .jsonl et nommez-la dans context.history_file, et l’invite du cas devient le prochain tour utilisateur. Pour laisser Claude lire les répertoires de fixture pendant l’exécution, énumérez-les dans context.add_dirs. Un case.yaml a également besoin de schema_version: "1.1" et name ; la référence champs case.yaml a la liste complète. Ce case.yaml ensemence un espace de travail à partir d’un script et laisse Claude lire les fixtures à partir d’un répertoire resources/ :

Serveurs MCP fictifs

Vous pouvez évaluer un plugin dont les skills appellent des outils MCP sans le vrai service derrière eux. Mettez un fichier Markdown par outil sous evals/mocks/<server>/<tool>.md pour la suite entière, ou sous le répertoire mocks/ propre d’un cas pour un cas, où <server> est le nom du serveur dans la configuration MCP de votre plugin. Une exécution ne démarre jamais les vrais serveurs MCP de votre plugin à moins que vous le demandiez. Claude Code enregistre un remplaçant sous le nom propre de chaque serveur. Les outils avec un fichier mock répondent à partir de celui-ci et sont autorisés sans une concession --allow-tools, et un outil sans fichier mock n’est pas disponible pour Claude. Un serveur sans aucun mock du tout apparaît dans la ligne de progression mocked: du cas comme plugin_<plugin>_<server>[not started: no mock]. Le corps du fichier est ce que l’outil retourne à Claude. Ce mock se substitue à un outil create_issue sur un serveur nommé tracker, vérifie l’entrée que Claude envoie, et renvoie le titre. Enregistrez-le en tant que evals/mocks/tracker/create_issue.md :
Insérez les champs de l’entrée de l’appel avec {{input.<field>}}, et le contenu d’un fichier de fixture à côté du mock avec {{file:fixtures/{input.<field>}.json}}. Le bloc expect: protège l’entrée. Si un appel le viole, l’exécution s’arrête avec un score de 0 et enregistre pourquoi, donc un cas peut affirmer ce que votre plugin a demandé au serveur de faire. Définissez error: true pour retourner le corps comme une erreur d’outil à la place, ou type: agent pour avoir un petit modèle répondre en tant que serveur à partir d’instructions dans le corps. La référence du fichier mock énumère chaque clé et les fichiers _server.md et _tools.json. Pour noter les appels eux-mêmes, pointez un évaluateur vers target: mock_calls. Pour exécuter contre les vrais serveurs MCP du plugin à la place, passez l’un de ces drapeaux. De toute façon, ces processus s’exécutent en tant que vous, en dehors du sandbox de l’exécution, et leurs outils ont besoin d’une concession --allow-tools :
  • --allow-real-servers : démarrez le processus réel pour chaque serveur que vous n’avez pas mocké, et continuez à répondre aux outils mockés à partir de leurs fichiers
  • --mocks off : ignorez mocks/ entièrement et démarrez chaque serveur que le plugin déclare

Rejouer les réponses mock d’agent

Un mock type: agent répond avec un appel au --judge-model, donc sa sortie varie entre les exécutions et change si vous changez le juge. Lorsqu’une exécution se termine sans erreur ou abandon, Claude Code enregistre chaque réponse qu’un mock d’agent a donnée sous le répertoire des résultats dans mock-recordings/. Ouvrez ADOPT.txt là pour voir chaque enregistrement et le répertoire .replay/<server>/ pour le copier dedans, à côté du mock qui l’a produit. Après avoir copié un enregistrement là, les exécutions ultérieures répondent à l’appel identique à partir de celui-ci sans appel de modèle. Validez mocks/.replay/ avec le reste de mocks/ pour que les exécutions CI soient reproductibles.

Exécuter les evals

Une fois qu’une suite existe, claude plugin eval l’exécute. Vous choisissez quel plugin et quels cas exécuter avec l’argument cible, accordez tous les outils que les cas ont besoin au-delà de l’ensemble en lecture seule avec --allow-tools, et contrôlez le nombre d’exécutions, les modèles, le coût et la sortie avec les autres options.

Choisir ce qu’il faut évaluer

La plupart du temps, vous exécutez claude plugin eval . à partir de la racine du plugin, ce qui exécute chaque cas de la suite avec le plugin dans lequel vous vous tenez chargé. Pour exécuter un fichier de cas unique, ou pour évaluer un plugin que vous avez installé plutôt qu’un que vous développez, passez une cible différente : Ajoutez --case <glob> pour filtrer par nom de cas et --tag <tag> pour garder les cas avec l’une des balises données. Mettez la cible avant --tag, --allow-tools, et --json. Les deux premiers prennent une liste et --json prend un chemin optionnel, donc chacun d’eux lit une cible qui suit comme sa propre valeur.

Accorder les outils

Les exécutions ne s’arrêtent jamais pour demander la permission. Les outils intégrés qui ont besoin d’une concession que vous n’avez pas donnée, comme Bash, Write, Edit, WebFetch, et WebSearch, sont supprimés de la session, donc Claude ne peut pas les appeler du tout. La liste d’autorisation est les outils en lecture seule que le cas énumère dans allowed_tools, à partir de Read, Glob, Grep, NotebookRead, Skill, Agent, TodoWrite, et les outils de tâche TaskCreate, TaskGet, TaskList, TaskUpdate, TaskStop, et TaskOutput, plus tout ce que vous accordez avec --allow-tools, qui s’applique à chaque cas de l’exécution. Pour laisser les cas utiliser Bash, Write, Edit, WebFetch, ou WebSearch, accordez-les vous-même :
Lorsqu’un cas a demandé un outil que vous n’avez pas accordé, l’exécution le énumère sur stderr comme not granted. Les outils sur un serveur MCP mocké n’ont besoin d’aucune concession. Les outils sur un vrai serveur MCP de plugin ont besoin à la fois du serveur démarré, avec --allow-real-servers ou --mocks off, et d’une concession par nom, comme --allow-tools "mcp__plugin_my-plugin_github__*" ; les outils MCP d’un plugin sont nommés mcp__plugin_<plugin>_<server>__<tool>. Lorsque vous accordez Bash sous n’importe quelle forme, chaque commande s’exécute sous le sandbox au niveau du système d’exploitation de Claude Code. Les écritures sont confinées à l’espace de travail de l’exécution, votre répertoire personnel et la configuration de Claude Code sont illisibles, et l’accès réseau est limité aux domaines que vous accordez avec --allow-tools "WebFetch(domain:example.com)". Si vous accordez Bash ou PowerShell sur une machine sans backend de sandbox, Claude Code refuse chaque exécution plutôt que de l’exécuter sans confinement, et le cas affiche une erreur d’exécution et marque généralement 0. Windows natif n’a pas de backend, donc exécutez les suites accordant le shell sous WSL2 ; sur Linux, installez d’abord bubblewrap et socat. Voir les prérequis du sandboxing.

Options de commande

Ce tableau couvre les options pour le nombre d’exécutions, les modèles, la notation, le coût, les concessions d’outils, les mocks et la sortie. Exécutez claude plugin eval --help pour la liste complète, qui inclut également --case, --tag, --eval-dir, --no-scaffold, --report, et --verbose.

Exécuter les evals dans CI

Dans votre travail CI, exécutez la suite avec --json pour écrire le résultat pour l’archivage, et échouez la construction sur le code de sortie. Passez --trust-plugin pour que le travail n’attende jamais à l’invite de confiance à la première exécution, épinglez les deux modèles pour que les scores soient comparables au fil du temps, gardez le rapport local, et définissez un plafond de coût comme limite supérieure :
Le code de sortie du travail vous dit ce qui s’est passé : Les problèmes d’écriture ou de publication du rapport HTML ne changent jamais le code de sortie. Pour voir pourquoi un cas a marqué bas, exécutez-le localement sans --json pour que les lignes de progression par exécution et d’évaluateur s’impriment. Un exécuteur CI a besoin d’une installation Claude Code et de identifiants dans l’environnement comme ANTHROPIC_API_KEY. Sans --trust-plugin, un travail dont le répertoire de checkout Claude Code ne fait pas déjà confiance est refusé avec la sortie 1 lorsqu’il n’a pas de terminal, ou attend à l’invite lorsque le coureur en alloue un. claude plugin eval init a besoin d’un terminal pour vous poser ses questions ; dans CI, exécutez claude plugin eval init --bare <name> pour obtenir le modèle vierge. Pour garder les coûts prévisibles, donnez aux suites rapides à chaque changement seulement des évaluateurs qui n’appellent pas un juge, utilisez --ablation none où vous n’avez pas besoin de Δ, et laissez les documents partial: true et les exécutions avec skippedPaidGraders en dehors de toute tendance que vous tracez.

Lire les résultats

Chaque exécution avec au moins un cas écrit un répertoire results/<timestamp>/ à l’intérieur du répertoire d’eval, contenant aggregate-result.json et report.html. Pour une cible de chemin qui est sous le plugin ; pour un plugin que vous avez nommé, c’est sous votre répertoire courant, comme le tableau cible le montre. Le tableau récapitulatif, le JSON, et le rapport rendent tous les mêmes données de résultat.

Rapport HTML

report.html est un fichier unique autonome qui ne fait aucune demande externe, donc vous pouvez le joindre à un travail CI ou l’ouvrir à partir du disque. Cet exemple est le haut d’un rapport pour une exécution de suite à trois cas avec --threshold 0.8 ; le coût affiché est une estimation au prix catalogue et varie selon le modèle et le nombre de cas : Haut d'un rapport d'eval : une ligne de verdict lisant « Plugin effect: +33.3 pts vs baseline, improved 2, flat 1, regressed 0 of 3 cases », cinq tuiles récapitulatives pour le score de la suite, le delta d'ablation, le score de base, les cas passant le seuil, et les exécutions parfaites, puis le premier cas avec son delta, sa barre de score, et une exécution dont les deux évaluateurs affichent tous deux un passage Lisez-le de haut en bas :
  • La ligne de verdict et les tuiles répondent à la question de savoir si le plugin a aidé sur l’ensemble de la suite. Le score de la suite est la moyenne des scores avec-plugin par cas, Ablation Δ est la distance à laquelle cela se situe au-dessus ou au-dessous du score de base, et Cases compte combien ont atteint le seuil. Perfect runs est la part des exécutions avec-plugin où chaque évaluateur a réussi.
  • Chaque carte de cas affiche le propre Δ du cas et le score avec-plugin, avec une coche sur la barre au seuil. Un cas dont le Δ est négatif obtient un bord gauche rouge, donc les régressions se démarquent lorsque vous faites défiler.
  • À l’intérieur d’un cas, les exécutions avec-plugin viennent en premier et les exécutions de base après. Chaque exécution énumère ses évaluateurs avec une puce de passage ou d’échec. Un évaluateur échoué est déjà développé avec son explication, et un évaluateur llm affiche également les votes du juge et la preuve qui lui a été montrée, ce qui est l’endroit où vous découvrez pourquoi une exécution a obtenu un score faible. Les évaluateurs qui ne comptent pas vers le score, comme tool_used: Skill, portent un badge plugin-fired indicator.
  • Prompt et Graders, sous les exécutions, affichent l’invite du cas et la rubrique ou le motif de chaque évaluateur, afin que quelqu’un lisant le rapport sans la suite puisse voir ce qui a été demandé et ce qui comptait comme bon.
Si vous êtes connecté avec un abonnement claude.ai et que les artifacts sont disponibles pour votre compte, Claude Code publie également le rapport en tant qu’artifact privé et imprime Published: <url>. Passez --no-publish pour le garder local. Si aucune ligne Published: n’apparaît, comme avec l’authentification par clé API, le fichier local est le rapport. Une exécution qu’une session Claude Code a démarrée, comme lorsque vous demandez à Claude d’exécuter la suite pour vous, reste également locale, et sa ligne Report: dit kept local. Ajoutez --publish-report à cette commande pour la publier.

Résultat JSON

aggregate-result.json, et la sortie --json, est un document versionné avec schemaVersion: 1 pour que les scripts CI l’analysent. Les noms de champs sont camelCase et les nouveaux champs sont ajoutés sans renommer les existants, donc écrivez votre script pour ignorer les champs qu’il ne reconnaît pas. Ce sont les champs qu’un script de gating lit généralement. Le document porte également la configuration de la suite, chaque définition d’évaluateur, et les résultats d’évaluateur par exécution avec explications et preuves :

Ce qu’une exécution peut accéder

claude plugin eval charge les skills et hooks du plugin cible et exécute sa suite d’eval sur votre machine, en tant que vous. Le pointer vers un plugin est la même décision de confiance que claude --plugin-dir, donc n’évaluez que les plugins en lesquels vous avez confiance. L’isolation décrite dans cette section limite ce que l’agent en test peut atteindre ; ce n’est pas une limite contre le code du plugin lui-même, et une suite qui réussit ne dit rien sur la sécurité du plugin.

Faire confiance au répertoire du plugin

La première fois que vous exécutez claude plugin eval contre un répertoire, Claude Code demande Trust this plugin directory? avant de charger quoi que ce soit à partir de celui-ci, à moins que vous ayez déjà accepté l’invite de confiance là dans une session claude interactive. À l’intérieur d’un référentiel git, répondre oui fait confiance au référentiel entier, pour les sessions interactives aussi. Lorsque stdin ou stdout n’est pas un terminal, ou sous --json, l’exécution ne peut pas demander et est refusée avec la sortie 1 ; passez --trust-plugin pour affirmer la confiance vous-même, seulement pour un plugin que vous exécuteriez sur votre propre machine. Une cible que vous nommez plutôt que de donner en tant que chemin, signifiant un plugin installé ou un plugin de répertoire de skills, ignore l’invite. Certaines parties du plugin et de la suite s’exécutent seulement lorsque vous passez leur drapeau pour cette exécution : un scaffold_script de cas avec --scaffold, outils au-delà de l’ensemble en lecture seule avec --allow-tools, et les vrais serveurs MCP du plugin avec --allow-real-servers ou --mocks off. Un allowed_tools de cas et un frontmatter allowed-tools propre d’une skill ne peuvent pas élargir aucun d’eux. Lorsque le plugin expédie des hooks que vous n’avez pas écrits, ou que vous démarrez ses vrais serveurs MCP, traitez ses scores comme consultatifs à moins que vous ne l’ayez exécuté dans un environnement isolé comme un conteneur ou un coureur CI, puisque les hooks et les serveurs s’exécutent en dehors du sandbox de l’agent et pourraient toucher les fichiers que les évaluateurs lisent.

Comment les exécutions sont isolées

Chaque exécution obtient un répertoire personnel jetable, un répertoire de travail, et une configuration Claude Code, et l’agent en test s’exécute là en tant que processus enfant claude -p avec seulement votre plugin chargé. Gardez ces conséquences à l’esprit lorsque vous écrivez des cas :
  • Rien de personnel ou au niveau du projet ne charge. Vos paramètres utilisateur, hooks, fichiers CLAUDE.md, serveurs MCP, autres plugins installés, mémoire, et skills sont absents, et aucun .claude/ ou .mcp.json au niveau du projet au-dessus du sandbox n’est lu. La plupart de votre environnement shell est également retenu ; seulement une liste d’autorisation et les variables EVAL_* atteignent l’exécution. Si le plugin a besoin de configuration, livrez-la dans le plugin, créez-la dans un scaffold_script, ou passez les variables EVAL_*.
  • La politique gérée peut toujours restreindre une exécution. Les restrictions dans les paramètres gérés qu’un administrateur a déployés sur la machine s’appliquent à l’intérieur d’une exécution, donc les résultats sur une machine gérée peuvent différer d’une machine non gérée par cette politique.
  • L’outil Artifact est désactivé. Une skill qui publie un artifact ne peut être notée que sur ce qu’elle produit avant cette étape.
  • Les définitions de cas sont cachées à l’agent. Une exécution ne peut pas lire le répertoire d’eval, donc Claude ne peut pas voir l’invite du cas, ses évaluateurs, ou les cas frères.
  • Pas de sandbox réseau en dehors des commandes shell. Les commandes shell que vous accordez s’exécutent sous les règles de sandbox du réseau. Une concession WebFetch(domain:…) atteint ce domaine directement, et les hooks propres du plugin et tous les vrais serveurs MCP que vous démarrez peuvent atteindre n’importe quel hôte.

Référence de la suite d’eval

Tout ce qu’une suite d’eval peut contenir vit sous le répertoire d’eval du plugin, evals/ à moins que vous ayez configuré un autre. Cet arborescence montre chaque fichier que claude plugin eval lit ou écrit là ; seulement prompt.md ou case.yaml est requis pour qu’un cas existe :

Frontmatter de prompt.md

Le frontmatter de prompt.md accepte ces champs. Une clé inconnue est une erreur :

Champs case.yaml

case.yaml décrit le même cas en YAML et ajoute les champs qui pointent vers d’autres fichiers. Il nécessite schema_version: "1.1" et name. Les champs prompt.md description, tags, plugins, runs, et expected_outcome vont au niveau supérieur ; model, max_turns, timeout_seconds, allowed_tools, append_system_prompt, et env vont sous execution:. Lorsque les deux fichiers existent, le frontmatter de prompt.md remplace les champs case.yaml correspondants, le corps de prompt.md est l’invite, et graders/*.md sont ajoutés après tous les évaluateurs énumérés dans case.yaml. Ces champs existent seulement dans case.yaml :

Frontmatter d’évaluateur

Chaque fichier d’évaluateur sous graders/ prend ces clés en frontmatter, plus les options pour son type. Le nom de l’évaluateur est le nom du fichier sans .md :

Ce qu’un évaluateur peut regarder

Les évaluateurs regex prennent un target et les évaluateurs llm prennent un focus. Les deux acceptent les mêmes valeurs :

Types d’évaluateurs

Chaque type d’évaluateur ci-dessous énumère ses options et quand il réussit :

Fichiers mock

Un fichier <tool>.md sous mocks/<server>/ répond à un outil. Son corps est le résultat de l’outil, avec les substitutions {{input.<field>}} et {{file:fixtures/<name>}}. Son frontmatter accepte ces clés : Deux fichiers optionnels se trouvent à côté des fichiers d’outil dans le répertoire d’un serveur :
  • _server.md : un seul mock type: agent qui répond à plusieurs outils, énumérés dans sa clé frontmatter tools:. Un <tool>.md pour le même outil a la priorité. Mettez une garde expect: sur le <tool>.md individuel, pas ici
  • _tools.json : une réponse tools/list enregistrée du vrai serveur, pour que les outils mockés portent leurs vraies descriptions et schémas d’entrée au lieu d’un espace réservé permissif
Le répertoire mocks/ propre d’un cas utilise la même disposition et remplace les fichiers mocks de la suite fichier par fichier.

Dépannage

Ce sont les problèmes que les auteurs rencontrent le plus souvent, indexés sur ce que vous voyez.

« plugin eval is currently in early access »

Votre construction précède la disponibilité générale de la commande. Exécutez claude update, puis exécutez la commande à nouveau dans une session fraîche.

« plugin eval is currently unavailable »

Anthropic a désactivé la commande côté serveur. Rien sur votre machine ne la réactive ; exécutez claude update et réessayez dans une session fraîche plus tard.

« is not a trusted plugin directory, and this run cannot stop to ask you about it »

C’est la première exécution contre un répertoire que Claude Code ne fait pas confiance encore, et il ne peut pas demander parce que stdin ou stdout n’est pas un terminal ou vous avez passé --json. Exécutez claude plugin eval <dir> une fois dans un terminal et répondez à l’invite, ou passez --trust-plugin si vous faites confiance au code et à la suite du plugin. Voir Ce qu’une exécution peut accéder.

« No eval cases found »

Aucun <case>/prompt.md ou <case>/case.yaml n’existe sous le répertoire d’eval en vigueur, ou vos filtres --case et --tag n’ont pas correspondu à aucun cas. Exécutez à partir de la racine du plugin, ou exécutez claude plugin eval init pour créer une suite.

Le bras de base de référence n’affiche aucun plugin, ou delta est zéro

Si le résumé n’a pas de colonne W/OUT, ou le cas échoue avec « ablation requested but no plugin resolved », aucun plugin n’a été trouvé pour le cas. Ajoutez plugins: ["../.."] au cas, donnant le chemin du répertoire de cas au répertoire du plugin. Si le plugin a chargé et Δ est toujours proche de zéro avec votre évaluateur tool_used: Skill échouant, c’est généralement une vraie découverte, signifiant que la description de la skill ne déclenche pas sur la formulation de l’invite. Ajustez la description et réexécutez la même suite.

Tout marque zéro bien que les bons fichiers aient été produits

Vos évaluateurs ciblent files, la liste des chemins créés, lorsque vous aviez l’intention du contenu du fichier. Utilisez { source: file, path: <path> } comme target ou focus. Séparément, file_exists compte seulement les fichiers créés pendant l’exécution, donc un fichier que le scaffold a créé ou que Claude a seulement modifié est invisible pour lui ; notez son contenu, ou utilisez tool_used sur Edit.

Une regex sur la trace ne correspond pas au texte que je peux voir

La target par défaut est last_message, pas la trace. Lorsque vous ciblez trace, c’est du JSON par ligne, donc les guillemets apparaissent comme \". Les regexes utilisent la syntaxe JavaScript, donc mettez i dans flags plutôt que d’écrire (?i).

Les outils sont refusés, les outils MCP manquent, ou Bash ne s’exécutera pas

Tout au-delà de l’ensemble en lecture seule a besoin de votre concession, comme --allow-tools Bash Write. Vos serveurs MCP personnels ne chargent jamais dans une exécution. Les serveurs propres du plugin ne démarrent pas à moins que vous optiez pour, et leurs outils ont alors aussi besoin d’une concession --allow-tools "mcp__plugin_<plugin>_<server>__*" ; un outil mocké n’en a besoin d’aucune.

L’exécution quitte 1 mais les résultats semblent bien

La --threshold par défaut est 1.0, donc la commande quitte 1 lorsqu’un cas marque en dessous de parfait. Définissez un seuil qui correspond à votre barre. La sortie 1 couvre également un fichier de cas qui n’a pas pu charger, qui est rapporté sur stderr au-dessus du tableau.

« —json output path must end in .json »

Vous avez mis la cible après --json, donc elle a été lue comme le chemin de sortie. Mettez la cible en premier, comme dans claude plugin eval . --json, ou donnez à --json un chemin .json explicite.

Un évaluateur affiche passed: false sous une exécution qui a marqué 1.0

Cet évaluateur est exclu du score par conception dans une exécution à deux bras, et son champ scored est false. Voir Comparer avec une base de référence sans plugin.

Les exécutions échouent avec une erreur de limite d’utilisation ou de limite de débit à mi-chemin

Si votre compte atteint la limite d’utilisation de son plan ou une limite de débit API pendant qu’une suite s’exécute, chaque exécution ultérieure se termine avec cette erreur, est notée sur ce qu’elle a produit, et marque généralement 0. La suite se termine toujours et n’est pas marquée partial, donc le résultat peut ressembler à une régression. Vérifiez la colonne NOTES ou cases[].arms.with[].error dans le JSON pour le message de limite avant de faire confiance aux scores, puis réexécutez après que la limite se réinitialise, avec --runs 1 ou un filtre --case si vous avez besoin de rester en dessous.

Les exécutions expirent ou atteignent la limite de tour

Les valeurs par défaut sont 10 tours et 300 secondes. Augmentez max_turns et timeout_seconds dans le cas pour les tâches qui en ont besoin, et utilisez --max-cost-usd comme plafond de coût plutôt que des limites serrées par exécution.

Voir aussi

  • Créer des plugins : construisez le plugin que vous testez, et chargez-le avec --plugin-dir pendant le développement
  • Référence des plugins : les entrées de commande plugin eval et plugin eval init et la clé experimental.evals du manifeste
  • Skills : comment la description d’une skill décide quand Claude l’invoque, ce qu’un cas qui vérifie si la skill se déclenche mesure
  • Sandboxing : le sandbox au niveau du système d’exploitation qui s’applique lorsque vous accordez Bash à une exécution
  • Créer et distribuer un marché de plugins : publiez le plugin une fois que sa suite réussit