claude plugin eval: test skills and plugins like you test code
TL;DR
claude plugin eval runs a skill or plugin on real cases, three times each, against a no-plugin arm to measure its real contribution. Write prompts like users, give each case a result grader and a process grader, and rerun when the model changes.
You write a skill, try it a few times, it works, and you ship it to the team. A week later a new model comes out, or someone edits the description, and the skill silently stops being invoked. Nobody notices until someone complains. Claude Code now has a claude plugin eval command to test plugins and skills against real test cases, score them, and compare with a no-plugin run so you know what the plugin actually contributes.
How an eval run works
- The suite lives in your plugin's
evals/directory; each case is a subdirectory with aprompt.md(what a user would type) and one or more graders. - Each run opens an isolated non-interactive session with only your plugin loaded, sends the prompt and lets Claude work until it finishes.
- Each case runs 3 times by default because agents are non-deterministic; the case score is the mean across runs.
- By default a no-plugin arm runs too: a positive
Δmeans the plugin improved the result.
Getting started
claude plugin eval init # Claude interviews you, proposes cases and graders, trials them, writes files
claude plugin eval . # run every case
claude plugin eval . --case <name> --runs 1 --ablation none # iterate fast on one case
The output shows WITH, W/OUT, Δ and COST columns and produces an HTML report with every grader's verdict for every run.
Six grader types
| Type | Checks | Cost |
|---|---|---|
regex | A pattern in the reply or a file | Free |
tool_used | Whether a tool (e.g. Skill) was called | Free |
tool_order | The order of tool calls | Free |
file_exists | A file was created | Free |
llm | A judge model grades against a rubric | Model calls |
baseline | Compares with the no-plugin arm | Model calls |
There are no custom-code graders. Each grader can have a weight; a case passes when its score is ≥ --threshold (default 1.0).
Tips for a stable signal
- Write prompts like real users: don't name the skill, so you test whether Claude picks it from its description.
- Two graders per case: one on the result (reply, file) and one on the process (
tool_used,tool_order). - Use regex for long output: keep
llmgraders for short outputs, with rubrics written as concrete PASS/FAIL conditions. - Include cases that shouldn't trigger: a "must not invoke the skill" grader with
arm: bothcatches false triggering. - The most common finding:
Δnear zero withtool_used: Skillfailing means Claude doesn't pick the skill on natural phrasing; fix thedescriptionand rerun.
Risks and caveats
- It costs real money: every run and every
llmgrader is a model call against your plan or bill. Calls are roughly cases × runs × 2 arms, plus judge calls. Use--ablation nonewhile you're only tuning graders. - Small judges can misgrade: if the skill fires correctly but
Δis negative, suspect the judge first; try--judge-model sonnet. - Early access: the feature may not be enabled on every account yet.
- Different from skill-creator: the skill-creator plugin has its own
evals/evals.jsonformat; the two tools don't read each other's files.
How to apply it
- Dev: Run
claude plugin eval initon the skill you use most; tune its description until thetool_used: Skillgrader passes consistently. - Tech Lead: Put evals into CI for your internal plugin repo; rerun whenever a new model ships.
- PM: Use the
Δcolumn to decide which skills are worth maintaining; skills that don't improve results should go, to keep context lean.
Sources & references
- Test plugins with evals — Claude Code Docs