Тестирование plugins с помощью evals
Напишите eval-кейсы для вашего Claude Code plugin, запустите их с помощью claude plugin eval, оцените результаты, сравните с базовым вариантом без plugin и установите ограничение CI на основе оценки.
Команда claude plugin eval запускает ваш plugin на наборе тестовых кейсов и оценивает результаты. Каждый кейс — это реалистичный запрос плюс один или несколько graders. Grader — это проверка pass/fail того, что произвел Claude, например регулярное выражение для ответа, был ли вызван конкретный инструмент или рубрика, которую вторая модель оценивает в ответе.
Вам не нужно писать набор вручную; claude plugin eval init спрашивает вас о вашем plugin, предлагает кейсы и graders, пробует их и записывает файлы, и вы можете попросить Claude сделать то же самое из уже открытой сессии.
Используйте evals для:
- Измерения того, насколько надежно ваш plugin направляет Claude к правильному результату
- Выявления регрессий при изменении plugin или выпуске новой модели
- Определения того, что plugin вносит в сравнении с отсутствием plugin
Эта страница предназначена для авторов plugin и skills, у которых есть работающий plugin и которые хотят протестировать его поведение, а также для команд, которые ограничивают изменения plugin в CI. Для итерации над одним skill внутри разговора Claude Code skill-creator plugin запускает аналогичное сравнение с собственным форматом evals/evals.json, и ни один инструмент не читает файлы кейсов другого. Чтобы создать plugin, см. Create a plugin; чтобы проверить файлы plugin на синтаксические и схемные ошибки, а не его поведение, используйте claude plugin validate.
Каждый запуск eval и каждый judge grader — это реальный вызов модели на вашем аккаунте, учитываемый в использовании вашего плана или счете API, поэтому сначала проверьте требования. Затем создайте свой первый eval suite или перейдите к Run evals in CI, если у вас уже есть один.
Требования
Для запуска plugin evals вам нужно:
- Claude Code v2.1.269 или позже. Запустите
claude --versionдля проверки иclaude updateдля обновления. - Git 2.31 или позже, если git установлен. Запустите
git --versionдля проверки. Со старой версией git,claude plugin evalостанавливается перед запуском любого случая. Без git он работает нормально. - Директория plugin с манифестом
plugin.jsonили.claude-plugin/plugin.json, или skills-directory plugin. - Та же аутентификация и поставщик модели, которые используют ваши обычные сессии Claude Code. Запуски eval, graders с оценкой judge и
claude plugin eval initвызывают модель с вашими учётными данными, поэтому они расходуют лимиты использования вашего плана или учитываются в вашем счёте за API. Когда команда сообщает стоимость, эта цифра — оценка по прейскуранту этих вызовов. Если вы запускаете Claude Code в Amazon Bedrock, Google Cloud's Agent Platform или Microsoft Foundry, запускайте набор тестов из оболочки, которая экспортирует те же переменные поставщика, что и ваши обычные сессии, поскольку каждый запуск наследует их от этой оболочки, как описано в разделе о полеenv.
Как работает запуск eval
Eval suite находится в директории под названием evals/ внутри вашего plugin, расположенной так, как показано в Write and refine cases. Каждый case — это собственная поддиректория с prompt и одним или несколькими graders. Prompt — это что-то, что может напечатать человек, использующий ваш plugin, например запрос, который должен обработать один из его skills.
Что происходит во время запуска
Для каждого запуска case Claude Code запускает свежую, изолированную неинтерактивную сессию только с вашим plugin, отправляет prompt и позволяет Claude работать, пока он не закончит или не достигнет лимита turn или времени case. Затем каждый grader проверяет финальный ответ, полный транскрипт или файл, созданный Claude, и проходит или не проходит.
Как оценивается case
Один запуск недетерминированного агента говорит вам мало, поэтому каждый case по умолчанию запускается три раза. Оценка запуска — это доля его graders, которые прошли, взвешенная, если вы установили веса, и оценка case — это среднее значение по его запускам. Case проходит, когда его оценка соответствует --threshold, по умолчанию 1.0. При вызовах модели suite создает примерно cases × runs запусков агента с plugin и столько же для no-plugin baseline, плюс три коротких вызова judge на llm или baseline grader на запуск.
The no-plugin baseline
Высокая оценка сама по себе не говорит вам, что plugin помог, потому что Claude может работать так же хорошо без него. Чтобы разделить эти два, запуски каждого case повторяются без загруженного plugin, и вы получаете две оценки, WITH и W/OUT. Их разница, Δ, — это то, что внес plugin. Если case оценивается в 1.0 как с plugin, так и без него, plugin не является тем, что заставило его пройти.
Два набора запусков называются with-arm и without-arm; Score against the no-plugin baseline охватывает, какие case запускают only with-arm и как graders оцениваются в обоих arms.
Создайте свой первый eval suite
Это пошаговое руководство написания одного кейса для вашего собственного plugin, его запуска и чтения результата. Перед началом убедитесь, что у вас есть:
- Claude Code v2.1.269 или позже и другие требования
- Терминал, открытый в корневой директории вашего plugin, той, которая содержит
plugin.jsonили.claude-plugin/plugin.json - Один skill в plugin, который вы хотите протестировать, и запрос, который пользователь должен напечатать, чтобы его запустить
Создайте кейсы
Из корня plugin запустите:
claude plugin eval init
Если Claude Code еще не доверяет этой директории, он сначала спрашивает Trust this plugin directory?; ответьте y. Затем открывается интерактивная Claude Code сессия. Claude читает ваш plugin и спрашивает вас, как должен выглядеть хороший результат, предлагает prompts, которые должны и не должны запускать plugin, разрабатывает graders для каждого, пилотирует их один раз, чтобы проверить их поведение, и записывает одну директорию кейса на prompt под evals/, каждую названную в честь своего prompt. Когда Claude скажет вам, что suite готов, выйдите из этой сессии с /exit или Ctrl+D, чтобы вернуться в shell.
Если у вас уже есть Claude Code сессия, открытая в корне plugin, вы можете вместо этого попросить Claude там запустить claude plugin eval init. Claude запускает команду и затем задает вам те же вопросы в этом разговоре.
Если вы предпочитаете написать кейс самостоятельно, чтобы увидеть ровно то, что содержат файлы, следуйте Write a case manually и вернитесь сюда, чтобы запустить его.
Запустите suite
Вернитесь в shell в корне plugin и запустите каждый кейс под evals/:
claude plugin eval .
Вы уже доверяли этой директории на шаге 1, поэтому запуск начинается немедленно. Если вы написали кейс вручную, запуск сначала спрашивает Trust this plugin directory? [y/N]; ответьте y. What a run can access объясняет, на что вы соглашаетесь.
Каждый кейс запускается три раза с вашим plugin и три раза без него, поэтому один кейс — это шесть запусков. Строка прогресса печатается по мере завершения каждого запуска с оценкой этого запуска и вердиктом каждого grader.
Прочитайте сводку
Когда suite завершится, вы увидите таблицу сводки, за которой следует, где был записан отчет:
CASE WITH W/OUT Δ RUNS COST NOTES
first-case 1.00 0.33 +0.67 6 $0.41
1 case(s) · mean Δ +0.67 · 74s · $0.41
Report: /Users/you/my-plugin/evals/results/2026-09-10T17-02-11-482Z/report.html
Published: https://claude.ai/... · keep local next time with --no-publish
WITH — это оценка кейса с загруженным вашим plugin, W/OUT — это оценка без него, и положительное Δ означает, что plugin повысил оценку. COST — это оценка по прейскуранту вызовов модели, и NOTES показывает объяснение самого высокого веса неудачного grader или ошибку запуска из with-arm.
Откройте отчет и повторяйте
Откройте URL Published: или путь Report:, когда нет строки Published:, чтобы увидеть вердикт каждого grader и объяснение для каждого запуска, и для llm graders голоса judge и отрывок, который он оценивал. Строка Published: появляется только, когда ваш аккаунт может публиковать отчеты.
Наиболее частое первое открытие — это Δ близко к нулю с неудачным grader tool_used: Skill кейса, что означает, что Claude не выбирает ваш skill при естественной формулировке. Отрегулируйте description skill, запустите claude plugin eval . снова и сравните.
Чтобы повторять один кейс дешево, запустите один arm один раз. Один запуск шумный, поэтому подтвердите любое изменение при трех запусках по умолчанию, прежде чем доверять ему. С одним arm таблица показывает столбцы SCORE и PASS% вместо WITH, W/OUT и Δ:
claude plugin eval . --case <case-name> --runs 1 --ablation none
Замените <case-name> на одно из имен директорий под evals/.
Написание и уточнение кейсов
Кейсы, которые пишет claude plugin eval init, — это простые файлы, которые вы можете открыть, изменить и дополнить. Кейс — это каталог внутри каталога eval плагина, который содержит prompt.md, case.yaml или оба файла. Добавьте каждому кейсу хотя бы один grader в виде файла graders/<name>.md или записи graders: в case.yaml, потому что кейс без него не загружается. Чтобы сгруппировать кейсы, вложите их в каталог, который сам не является кейсом; все, что находится внутри каталога кейса, например graders/ и файлы fixtures, принадлежит этому кейсу.
Это структура, которую создает claude plugin eval init, и именно ее следует использовать для новых suites. В справочнике по eval suite приведено полное дерево, включая mocks и результаты:
my-plugin/
├── .claude-plugin/plugin.json
├── skills/...
└── evals/
├── first-case/
│ ├── prompt.md # frontmatter: case fields; body: the prompt
│ ├── graders/
│ │ ├── criteria.md # frontmatter: type + options; body: rubric or pattern
│ │ └── skill-fired.md
│ └── case.yaml # optional: only for context.* fields
├── ignores-unrelated-request/
│ └── ...
└── results/ # written by each run; add to .gitignore
Напишите кейс вручную
Рекомендуемый путь — поручить Claude написание кейсов с помощью claude plugin eval init. Чтобы вместо этого написать кейс самостоятельно, начните с пустого шаблона. Следующая команда создает кейс с именем first-case с заготовкой prompt.md и одним grader-заготовкой и ничего не запускает:
claude plugin eval init --bare first-case
evals/first-case/
├── prompt.md # the prompt sent to Claude, plus run limits
└── graders/
└── criteria.md # one grader: how to score the result
В prompt.md вы пишете сообщение, которое Claude получает в каждом запуске, а в его frontmatter задаете лимиты запуска и инструменты, которые может использовать кейс. Откройте evals/first-case/prompt.md и замените текст-заготовку на задачу, которую должен обработать один из ваших скиллов, сформулированную так, как ее напечатал бы пользователь, а не с указанием названия скилла. Этот пример предназначен для скилла, который составляет сообщения коммитов; используйте собственную задачу:
---
max_turns: 10
allowed_tools: [Read, Glob, Grep, Skill]
---
Write me a commit message for this change: I renamed getUser to fetchUser and updated the three call sites.
Каждый запуск начинается в пустом рабочем каталоге, поэтому поместите все, что нужно для задачи, в сам промпт или сначала подготовьте рабочее пространство.
Полный список полей frontmatter охватывает модель, таймаут, теги и переменные окружения.
Каждый файл в graders/ — это одна проверка, применяемая после запуска. Откройте evals/first-case/graders/criteria.md и замените заготовку на рубрику для модели-судьи, написанную в виде конкретных условий PASS и FAIL:
---
type: llm
---
PASS if <what a correct response contains>.
FAIL if <what a wrong or missing response looks like>.
Затем добавьте второй grader, который проверяет, что ответ был получен именно благодаря вашему скиллу. Создайте evals/first-case/graders/skill-fired.md, заменив your-skill-name на имя каталога скилла в skills/ — это имя, по которому Claude его вызывает:
---
type: tool_used
tool: Skill
input_match: '"skill"\s*:\s*"(?:[\w-]+:)?your-skill-name"'
---
Эта проверка проходит, если Claude вызвал этот скилл хотя бы один раз во время запуска, в том числе в форме с пространством имен plugin-name:skill-name.
В разделе Типы graders перечислены другие доступные проверки, например сопоставление с регулярным выражением или подтверждение создания файла.
Сохранив оба файла, запустите кейс так же, как в быстром старте, командой claude plugin eval . из корня плагина.
Задайте лимиты запуска и инструменты в prompt.md
Задайте max_turns, timeout_seconds, model, tags кейса и allowed_tools, которые он может использовать, во frontmatter prompt.md; в справочнике frontmatter prompt.md перечислены все поля и их значения по умолчанию.
Claude получает текст ровно так, как вы его написали. Упоминания @path в нем не разворачиваются во вложения файлов, поэтому если Claude нужно прочитать файл, предоставьте для этого инструмент в allowed_tools.
Выберите graders и задайте их вес
Frontmatter grader задает его type и, опционально, weight, который увеличивает его вклад в оценку запуска, а также arm, который определяет, как он оценивается относительно базового варианта. Из шести типов regex, tool_used, tool_order и file_exists вычисляются по транскрипту и файлам и ничего не стоят, а llm и baseline вызывают модель-судью и увеличивают стоимость запуска.
Graders с пользовательским кодом не поддерживаются.
В разделе Типы graders перечислены опции и условие прохождения для каждого типа, а в разделе что может проверять grader — значения, которые принимают target и focus.
По умолчанию судьей для graders llm и baseline является модель, которую Claude Code использует для фоновых задач. Передайте --judge-model sonnet или полный ID модели, чтобы выбрать судью самостоятельно.
Выбирайте graders, которые дают стабильный сигнал
Grader llm запрашивает вердикт у модели, поэтому его ответ может различаться между запусками, и тем сильнее, чем длиннее текст, который ему нужно прочитать. Следующие привычки помогают сохранять оценки suite достаточно стабильными, чтобы им можно было доверять:
- Длинный вывод, например сгенерированный файл, оценивайте с помощью grader
regexпо содержимому файла: он каждый раз проверяет весь файл одинаково. Используйте gradersllmдля коротких выводов, с рубриками в виде конкретных условий PASS и FAIL. - Дайте каждому кейсу один grader на результат, например финальное сообщение или созданный файл, и один на шаги, которые Claude предпринял для его получения, например
tool_usedилиtool_order. Вместе они показывают, был ли ответ правильным и был ли он получен благодаря вашему плагину. - Если grader
tool_used: Skillкейса проходит, ноΔотрицательная, сначала подозревайте судью, а не плагин. Небольшая модель-судья может пометить правильный ответ как неправильный, потому что он отформатирован иначе, чем описано в рубрике. Перезапустите с--judge-model sonnetи уточните рубрику, чтобы форматирование не определяло вердикт. - Чтобы проверить, что сборка или тест прошли внутри запуска, сделайте так, чтобы промпт просил Claude выполнить их и записать результат в файл, оцените этот файл и убедитесь, что команда была выполнена, с помощью grader
tool_used, чейinput_matchуказывает эту команду.
Оценка относительно базового варианта без плагина
Когда тестируется плагин, кейс обычно запускается в двух arms. With-arm — это запуски с загруженным плагином, а without-arm — то же количество запусков вообще без плагина. Сводка и отчет показывают обе оценки и Δ — оценку with-arm минус оценку without-arm.
В следующих ситуациях кейс запускает только with-arm, поэтому не получает оценку W/OUT или Δ:
- Вы передаете
--ablation none: каждый кейс запускает один arm, что вдвое снижает стоимость, когда сравнение не нужно, например при доработке graders. - Кейс возобновляет транскрипт, а целевой объект — это путь: если целевой объект — например,
., а не имя установленного плагина, кейс сcontext.history_fileпо умолчанию запускает один arm, исходя из предположения, что записанный диалог уже отражает работу плагина. Запуск выводит в stderr уведомлениеsingle-arm (no Δ)с перечнем таких кейсов. Чтобы сравнить возобновленный ход с плагином и без него, передайте--ablation with-without. - Для кейса не найден плагин: когда целевой объект — это путь, кейс, плагин которого Claude Code не смог найти, также по умолчанию запускает один arm. Чтобы исправить это, см. раздел базовый arm не показывает плагин.
В запуске с двумя arms некоторые graders отображаются с scored: false. Проверка вроде «скилл был вызван» никогда не может пройти без плагина, поэтому ее учет приблизил бы without-arm к нулю и завысил бы Δ. Чтобы два arms оставались сопоставимыми, Claude Code исключает такие graders из оценки в обоих arms и показывает их в with-arm только как индикаторы pass/fail. К ним относятся:
- Каждый grader
tool_used, у которогоtool— этоSkill - Каждый grader
regexсtarget: mock_callsи каждый graderllmсfocus: mock_calls, если каждый mock-сервер в кейсе объявлен вашим плагином - Любой grader, который вы пометили
arm: with-only
Три настройки изменяют это исключение:
- Исключены все graders: если все graders в кейсе входят в исключаемый набор, они вместо этого оцениваются обычным образом, так как иначе оценивать было бы нечего.
arm: both: задайтеarm: bothдля grader, чтобы в любом случае оценивать его в обоих arms; это нужно для проверки «не должен вызывать скилл» сmin: 0иmax: 0.--ablation none: при--ablation noneничего не исключается, поэтому один и тот же suite может давать разную абсолютную оценку в двух режимах.
Использование другого каталога eval
Если evals/ уже занят другим инструментом, храните suite в другом каталоге. Вы можете указать этот каталог в plugin.json плагина, чтобы его использовали все запуски и все участники, или передать его в командной строке для одного запуска:
- В
plugin.json: добавьте"experimental": { "evals": "quality/evals" }. - В командной строке: передайте
--eval-dir quality/evalsи вclaude plugin eval, и вclaude plugin eval init.
Если заданы оба варианта, используется каталог из флага. Указывайте относительный путь из простых имен каталогов, например qa или quality/evals. Абсолютный путь или путь, содержащий .., не принимается: в качестве значения флага это ошибка, а непригодное значение в манифесте приводит к выводу строки Warning:, и запуск использует evals/. Кейсы, результаты и вывод init перемещаются в этот каталог.
Установите fixtures и mocks
Кейс может нуждаться в большем, чем prompt: файлы или git репозиторий в workspace, более ранний разговор для продолжения или ответы от MCP серверов, с которыми разговаривает ваш plugin. Каждый из них установлен рядом с кейсом, чтобы запуски оставались повторяемыми.
Заполните workspace или разговор
Каждый запуск начинается в пустом workspace. Когда кейс нуждается в большем, чем prompt, добавьте case.yaml рядом с prompt.md с блоком context:
- Файлы fixtures или git репозиторий: напишите Bash скрипт в директории кейса и назовите его в
context.scaffold_script. Скрипт запускается как вы, вне sandbox агента, и только когда вы передаете--scaffold, поэтому передавайте этот флаг только для suites, которые вы или ваша организация написали. - Более ранний разговор для продолжения: сохраните транскрипт как файл
.jsonlи назовите его вcontext.history_file, и prompt кейса становится следующим ходом пользователя. Когда целевой объект является путем, такой кейс запускается без baseline arm по умолчанию. - Директории fixtures, которые Claude может читать во время запуска: перечислите их в
context.add_dirs.
case.yaml также нуждается в schema_version: "1.1" и name; справочник case.yaml fields содержит полный список.
Этот case.yaml заполняет workspace из скрипта и позволяет Claude читать fixtures из директории resources/:
schema_version: "1.1"
name: changelog-from-diff
tags: [smoke]
context:
scaffold_script: fixture.sh
add_dirs: [resources]
Scaffold скрипт начинается в пустом workspace с небольшой фиксированной окружением: PATH вашей оболочки, HOME установлен на временный домашний каталог запуска, TMPDIR и несколько констант, таких как TERM=dumb. Ничего больше из вашей оболочки не достигает его, и переменные EVAL_* кейса тоже не достигают. Если скрипт завершается с ненулевым кодом или работает дольше 120 секунд, этот запуск получает оценку 0 с ошибкой scaffold failed. Используйте скрипт только для файлов и состояния git, так как конфигурация проекта, которую он записывает, не загружается.
Mock MCP серверы
Вы можете оценить plugin, чьи skills вызывают MCP инструменты без реального сервиса позади них. Поместите один Markdown файл на инструмент под evals/mocks/<server>/<tool>.md для всей suite или под собственную директорию mocks/ кейса для одного кейса, где <server> — это имя сервера в MCP конфигурации вашего plugin.
Запуск никогда не запускает реальные MCP серверы вашего plugin, если вы не попросите. Claude Code регистрирует substitute server под каждым именем сервера. Инструменты с файлом mock отвечают из него и разрешены без гранта --allow-tools, и инструмент без файла mock недоступен Claude. Сервер без mocks вообще появляется в строке прогресса кейса как plugin_<plugin>_<server>[not started: no mock].
Body файла — это то, что инструмент возвращает Claude. Этот mock стоит на месте инструмента create_issue на сервере с именем tracker, проверяет input, который Claude отправляет, и эхо-возвращает заголовок. Сохраните его как evals/mocks/tracker/create_issue.md:
---
expect:
title: string
priority: [low, medium, high]
---
Created issue #4821: {{input.title}}
Body файла mock и frontmatter принимают эти опции:
- Подстановки: вставьте поля из input вызова с
{{input.<field>}}и содержимое файла fixture рядом с mock с{{file:fixtures/{input.<field>}.json}}. expect:: блокexpect:охраняет input. Если вызов нарушает его, запуск прерывается с оценкой 0 и записывает почему, поэтому кейс может утверждать, что ваш plugin попросил сервер сделать.error: true: установитеerror: true, чтобы вернуть body как ошибку инструмента вместо этого.type: agent: задайтеtype: agent, чтобы модель-судья отвечала от имени сервера по инструкциям из тела.
Справочник mock file reference перечисляет каждый ключ и файлы _server.md и _tools.json.
Чтобы оценить сами вызовы, укажите grader на target: mock_calls.
Чтобы запустить против реальных MCP серверов plugin вместо этого, передайте один из этих флагов. В любом случае эти процессы запускаются как вы, вне sandbox запуска, и их инструменты нуждаются в гранте --allow-tools:
--allow-real-servers: запустите реальный процесс для каждого сервера, который вы не замокировали, и продолжайте отвечать замокированные инструменты из их файлов--mocks off: игнорируйтеmocks/полностью и запустите каждый сервер, который объявляет plugin
Воспроизведите ответы agent mock
type: agent mock отвечает с вызовом --judge-model, поэтому его вывод варьируется между запусками и изменяется, если вы измените judge. Когда запуск завершается без ошибки или прерывания, Claude Code сохраняет каждый ответ, который дал agent mock, под директорией результатов в mock-recordings/.
Откройте ADOPT.txt там, чтобы увидеть каждую запись и директорию .replay/<server>/, чтобы скопировать ее в, рядом с mock, который ее произвел. После того как вы скопируете запись туда, более поздние запуски отвечают на идентичный вызов из нее без вызова модели. Зафиксируйте mocks/.replay/ вместе с остальной частью mocks/, чтобы запуски CI были повторяемыми.
Запустите evals
Как только suite существует, claude plugin eval запускает его. Вы выбираете, какой plugin и кейсы запускаются с аргументом target, предоставляете любые инструменты, которые кейсы нуждаются за пределами набора только для чтения с --allow-tools, и контролируете количество запусков, модели, стоимость и вывод с другими опциями.
Выберите, что оценивать
Большую часть времени вы запускаете claude plugin eval . из корня plugin, который запускает каждый кейс в suite с загруженным plugin, который вы разрабатываете. Чтобы запустить один файл кейса или оценить установленный plugin вместо того, который вы разрабатываете, передайте другой target:
| Target | Что запускается |
|---|---|
Корневая директория plugin, такая как . |
Каждый кейс под его директорией eval с этим plugin загруженным |
Один файл prompt.md или case.yaml |
Этот кейс с его заключающим plugin загруженным |
Установленный plugin по имени, name или name@marketplace |
Кейсы в копии установленного plugin директории eval с установленной копией загруженной. Результаты записываются под ./evals/results/ в вашей текущей директории или ./<dir>/results/ с --eval-dir |
name@skills-dir |
То же самое для skills-directory plugin |
| Опущено | Текущая директория как путь |
Добавьте --case <glob> для фильтрации по имени кейса и --tag <tag> для сохранения кейсов с любыми из данных тегов.
Поместите target перед --tag, --allow-tools и --json. Первые два принимают список и --json принимает опциональный путь, поэтому каждый из них читает target, который следует как его собственное значение.
Предоставьте инструменты
Запуски никогда не останавливаются, чтобы попросить разрешение. Встроенные инструменты, которые нуждаются в гранте, который вы не дали, такие как Bash, Write, Edit, WebFetch и WebSearch, удаляются из сессии, поэтому Claude не может их вызывать вообще.
Запуск позволяет только инструменты только для чтения, которые кейс перечисляет в allowed_tools, из Read, Glob, Grep, NotebookRead, Skill, AskUserQuestion, Agent, TodoWrite и инструменты задач TaskCreate, TaskGet, TaskList, TaskUpdate и TaskStop, плюс все, что вы предоставляете с --allow-tools. Этот грант применяется к каждому кейсу в запуске. Чтобы позволить кейсам использовать Bash, Write, Edit, WebFetch или WebSearch, предоставьте их сами:
claude plugin eval . --allow-tools Write Edit "Bash(npm test *)"
Когда кейс попросил инструмент, который вы не предоставили, вывод прогресса перечисляет его как not granted. Инструменты на замокированном MCP сервере не нуждаются в гранте. Инструменты на реальном plugin MCP сервере нуждаются как в запущенном сервере, с --allow-real-servers или --mocks off, так и в гранте по имени, такой как --allow-tools "mcp__plugin_my-plugin_github__*"; инструменты MCP plugin названы mcp__plugin_<plugin>_<server>__<tool>.
Когда вы предоставляете Bash в любой форме, каждая команда запускается под Claude Code OS-level sandbox. Записи ограничены workspace запуска, ваша домашняя директория и конфигурация Claude Code нечитаемы, и доступ в сеть ограничен доменами, которые вы предоставляете с --allow-tools "WebFetch(domain:example.com)". Если вы предоставляете Bash или PowerShell на машине без backend sandbox, Claude Code отказывает каждому запуску вместо его запуска без ограничений, и кейс показывает ошибку запуска и обычно оценивается в 0. Native Windows не имеет backend, поэтому запустите suites, предоставляющие shell, под WSL2; на Linux сначала установите bubblewrap и socat. См. sandboxing prerequisites.
Опции команды
Эта таблица охватывает опции для количества запусков, моделей, оценки, стоимости, грантов инструментов, mocks и вывода. Запустите claude plugin eval --help для полного списка, который также включает --case, --tag, --eval-dir, --no-scaffold, --report и --verbose.
| Опция | По умолчанию | Эффект |
|---|---|---|
--runs <n> |
runs каждого кейса, иначе 3 |
Запусков на кейс на arm |
-j, --concurrency <n> |
1 |
Запустите до этого количества запусков агента одновременно, от 1 до 8. Они делят лимит скорости вашего аккаунта, поэтому это сокращает wall-clock время, а не повышает пропускную способность за этот лимит. Результаты сохраняют порядок кейса |
--model <model> |
model каждого кейса, иначе ANTHROPIC_MODEL, если установлено, иначе default Claude Code |
Модель для агента под тестом. Закрепите ее в CI, чтобы rollout модели не был ошибочно принят за регрессию plugin |
--judge-model <model> |
Модель для фоновых задач | Модель для graders llm и baseline |
--ablation <mode> |
Решено для каждого кейса; см. Score against the no-plugin baseline | Запускать ли также каждый кейс без plugin для измерения того, что он добавляет. none запускает один arm; with-without добавляет базовый вариант без plugin |
--threshold <0..1> |
1.0 |
Кейс проходит, когда его оценка with-arm по крайней мере это. Любой кейс ниже него заставляет команду выйти 1 |
--max-cost-usd <usd> |
Нет потолка | Потолок на оценку стоимости по прейскуранту запуска, не на использование плана. Проверяется перед каждым запуском. Один раз потрачено, ничего дальше не начинается; запуски уже в полете завершаются, поэтому расход может пройти потолок этими запусками. Если какой-либо запуск остается незапущенным, команда выходит 2 с частичными результатами |
--allow-tools <tools...> |
Нет | Предоставьте инструменты за пределами набора только для чтения. См. Grant tools |
--scaffold |
Выключено | Запустите scaffold_script каждого кейса |
--trust-plugin |
Выключено | Пропустите первый запрос доверия для plugin, чей код и suite вы запустили бы сами. Передайте его в CI, чтобы работа никогда не была отказана или не осталась ожидающей на запросе. См. What a run can access |
--mocks <mode> |
record |
record отвечает вызовам инструментов MCP из mocks, не запускает реальные серверы plugin и сохраняет ответы agent-mock для воспроизведения. off игнорирует mocks и запускает реальные MCP серверы plugin |
--allow-real-servers |
Выключено | С --mocks record также запустите реальные MCP серверы plugin для серверов, которые не имеют mock |
--json [path] |
Выключено | Напечатайте result document на stdout или запишите его на путь, заканчивающийся на .json. Запуск молчит: нет строк прогресса или таблицы сводки |
--output-dir <dir> |
<eval dir>/results/<timestamp>/ |
Где идут aggregate-result.json и report.html |
--no-publish |
Держите HTML отчет локально. См. HTML report | |
--publish-report |
Опубликуйте отчет даже там, где он остался бы локально по умолчанию, такой как запуск, который Claude Code сессия запустила | |
--keep-temp |
Выключено | Держите директорию sandbox каждого запуска и напечатайте его путь для отладки того, что произвел Claude |
Запустите evals в CI
В вашей CI работе запустите suite с --json, чтобы написать результат для архивирования, и не пройдите сборку на exit коде. Передайте --trust-plugin, чтобы работа никогда не ждала на первом запросе доверия, закрепите обе модели, чтобы оценки были сравнимы со временем, держите отчет локально и установите потолок стоимости как верхний лимит:
claude plugin eval . \
--trust-plugin \
--json results.json \
--threshold 0.8 \
--model claude-sonnet-5 \
--judge-model claude-haiku-4-5 \
--no-publish \
--max-cost-usd 20
Exit код работы говорит вам, что произошло:
| Exit код | Значение |
|---|---|
| 0 | Каждый кейс оценен на или выше --threshold и каждый файл кейса загружен |
| 1 | Кейс оценен ниже порога, файл кейса не загружен, кейсы не найдены, запуск не может быть запущен, директория plugin не доверена и --trust-plugin не был передан, или опция была неправильной |
| 2 | Частичный запуск: потолок --max-cost-usd был достигнут или ваши учетные данные были отклонены перед или на первом запуске. results.json все еще написан с partial: true и причиной |
| 130 | Прервано. Частичные результаты написаны |
| 143 | Завершено, такое как timeout CI |
Дельта with-minus-without сообщается, но никогда не изменяет exit код, и проблемы с написанием или публикацией HTML отчета тоже не изменяют.
Чтобы увидеть, почему кейс оценен низко, запустите его локально без --json, чтобы строки прогресса per-run и grader печатались.
CI runner также нуждается в этом на месте:
- Установка и учётные данные: раннеру CI нужна установка Claude Code и учётные данные в окружении, например
ANTHROPIC_API_KEYили переменные вашего облачного провайдера. - Доверие: без
--trust-plugin, работа, чья директория checkout Claude Code еще не доверяет, нуждается в первом запросе доверия, и запуск, который не может спросить, отказан с exit 1. initв CI:claude plugin eval initнуждается в терминале, чтобы задать вам его вопросы; в CI запуститеclaude plugin eval init --bare <name>, чтобы получить пустой шаблон.
Чтобы держать стоимости предсказуемыми, дайте быстрым every-change suites только graders, которые не вызывают judge, используйте --ablation none, где вам не нужно Δ, и оставьте partial: true документы и запуски с skippedPaidGraders вне любого тренда, который вы составляете.
Прочитайте результаты
Каждый запуск с по крайней мере одним кейсом пишет директорию results/<timestamp>/ внутри директории eval, содержащую aggregate-result.json и report.html. Для path target, который находится под plugin; для plugin, который вы назвали, это под вашей текущей директорией, как показывает target table. Таблица сводки, JSON и отчет все отображают одни и те же данные результата.
HTML отчет
report.html — это один самодостаточный файл, который не делает внешних запросов, поэтому вы можете прикрепить его к CI работе или открыть его с диска. Это пример верхней части отчета для запуска трёхкейсного набора с --threshold 0.8; показанная стоимость — это оценка по прейскуранту и варьируется в зависимости от модели и количества кейсов:
Читайте его сверху вниз:
- Строка вердикта и плитки отвечают на вопрос, помог ли plugin по всему набору. Suite score — это среднее значение per-case with-plugin оценок, Ablation Δ — это то, насколько это находится выше или ниже baseline score, и Cases считает, сколько соответствовали threshold. Perfect runs — это доля with-plugin запусков, где каждый grader прошёл.
- Каждая карточка кейса показывает собственный
Δкейса и with-plugin оценку, с отметкой на полосе в threshold. Кейс, чейΔотрицательный, получает красный левый край, поэтому регрессии выделяются при прокрутке. - Внутри кейса with-plugin запуски идут первыми, а baseline запуски после. Каждый запуск перечисляет своих graders с чипом pass или fail. Неудачный grader уже развёрнут с его объяснением, и
llmgrader также показывает голоса судьи и доказательства, которые ему были показаны, что является местом, где вы узнаёте, почему запуск получил низкую оценку. Graders, которые не учитываются в оценке, такие какtool_used: Skill, несутplugin-fired indicatorзначок. - Prompt и Graders, ниже запусков, показывают prompt кейса и rubric или pattern каждого grader, поэтому кто-то, читающий отчет без набора, может увидеть, что было запрошено и что считалось хорошим.
Если вы вошли с подпиской claude.ai и artifacts доступны для вашего аккаунта, Claude Code также публикует отчет как приватный artifact и печатает Published: <url>. Передайте --no-publish, чтобы держать его локально. Если нет строки Published:, такой как с API-key аутентификацией, локальный файл — это отчет.
Запуск, который Claude Code сессия запустила, такой как когда вы просите Claude запустить suite для вас, также остается локально, и его строка Report: говорит kept local. Добавьте --publish-report к этой команде, чтобы опубликовать его.
JSON результат
aggregate-result.json и --json вывод — это версионированный документ с schemaVersion: 1 для CI скриптов для парсинга. Имена полей — это camelCase и новые поля добавляются без переименования существующих, поэтому напишите ваш скрипт, чтобы игнорировать поля, которые он не признает.
Это поля, которые скрипт gating обычно читает. Документ также несет конфигурацию suite, каждое определение grader и результаты grader на запуск с объяснениями и доказательствами:
| Поле | Значение |
|---|---|
partial, partialReason |
true с cost_ceiling, interrupted или auth_failed, когда suite не завершилась. Оставьте частичные результаты вне трендовых диаграмм |
aggregates.overallScore |
Средняя оценка кейса по suite |
aggregates.casesPassed, aggregates.casesTotal |
Кейсы на или выше --threshold и всего |
aggregates.meanDelta |
Среднее Δ по кейсам в двухarm режиме |
cases[].name |
Имя кейса |
cases[].aggregates.score |
Средняя оценка запуска with-arm для кейса |
cases[].aggregates.delta |
Оценка with-arm минус оценка without-arm. Опущено, когда кейс запустил одну arm или arms не сравнимы |
cases[].arms.with[].error |
null или почему запуск закончился ненормально, такой как timed out after 300s. Запуск, который начался, но закончился плохо, все еще оценивается на том, что он произвел, поэтому non-null ошибка не подразумевает оценку 0 |
cases[].arms.with[].aborted |
Присутствует, когда mock expect: или abort_when остановил запуск, с server, tool и reason. Запуск оценивается в 0 и error остается null |
cases[].arms.with[].skippedPaidGraders |
true, когда потолок стоимости пропустил judge graders этого запуска, поэтому его оценка не сравнима |
costUsd, durationSeconds, claudeVersion |
Оценка стоимости по прейскуранту, включая judge вызовы, wall-clock секунды и версия Claude Code, которая запустила suite |
Что может получить доступ запуск
claude plugin eval загружает skills, hooks и agents целевого плагина и запускает его набор тестов на вашей машине от вашего имени. Указание на плагин — это то же самое решение о доверии, что и claude --plugin-dir, поэтому оценивайте только плагины, которым вы доверяете.
Изоляция, описанная в этом разделе, ограничивает то, что может достичь тестируемый агент; это не граница против собственного кода плагина, и набор, который проходит, ничего не говорит о том, безопасен ли плагин.
Доверяйте директории плагина
При первом запуске claude plugin eval для директории Claude Code спрашивает Trust this plugin directory? перед загрузкой чего-либо из неё, если вы уже не приняли приглашение доверия там в интерактивном сеансе claude. Внутри репозитория git ответ «да» доверяет всему репозиторию, также для интерактивных сеансов. Когда stdin или stdout не является терминалом, или под --json, запуск не может спросить и отказывается с выходом 1; передайте --trust-plugin, чтобы утвердить доверие самостоятельно, только для плагина, который вы бы запустили на своей машине. Цель, которую вы называете, а не даёте как путь, то есть установленный плагин или плагин из директории skills, пропускает приглашение.
Некоторые части плагина и набора запускаются только при передаче их флага для этого запуска:
scaffold_scriptслучая с--scaffold- Tools за пределами набора только для чтения с
--allow-tools - Реальные MCP серверы плагина с
--allow-real-serversили--mocks off
allowed_tools случая и собственный frontmatter allowed-tools skill не могут расширить ни один из них.
Когда плагин поставляется с hooks, которые вы не писали, или вы запускаете его реальные MCP серверы, рассматривайте его оценки как рекомендательные, если вы не запустили его в изолированной среде, такой как контейнер или CI runner, поскольку hooks и серверы работают вне sandbox агента и могут изменять файлы, которые читают грейдеры.
Как запуски изолированы
Каждый запуск получает одноразовую домашнюю директорию, рабочую директорию и конфигурацию Claude Code, и тестируемый агент работает там как дочерний процесс claude -p с загруженным только вашим плагином. Помните об этих последствиях при написании случаев:
- Ничего личного или на уровне проекта не загружается. Ваши пользовательские настройки, hooks, файлы
CLAUDE.md, MCP серверы, другие установленные плагины, память и skills отсутствуют. Конфигурация на уровне проекта не читается нигде: никакая директория.claude/,CLAUDE.mdили.mcp.jsonне загружается выше рабочей области или внутри неё, даже та, которую написалscaffold_script, и директорииadd_dirsпредоставляют доступ только для чтения. Большая часть вашей shell среды также скрывается; только allowlist и переменныеEVAL_*достигают запуска. Поставляйте любые skills, agents, hooks или MCP серверы, от которых зависит случай, в плагине под тестом, посколькуscaffold_scriptможет предоставить только файлы и состояние git. - Управляемая политика всё ещё может ограничить запуск. Ограничения в управляемых настройках, которые администратор развернул на машине, применяются внутри запуска, поэтому результаты на управляемой машине могут отличаться от неуправляемой на эту политику.
- Инструмент Artifact отключён. Skill, который публикует artifact, может быть оценён только на основе того, что он производит до этого шага.
- Определения случаев скрыты от агента. Запуск не может читать директорию eval, поэтому Claude не может видеть приглашение случая, его грейдеры или соседние случаи.
- Нет сетевого sandbox вне shell команд. Shell команды, которые вы предоставляете, работают под правилами сети sandbox. Грант
WebFetch(domain:…)достигает этого домена напрямую, и собственные hooks плагина и любые реальные MCP серверы, которые вы запускаете, могут достичь любого хоста.
Справочник набора тестов
Всё, что может содержать набор тестов, находится в директории evals/ плагина, если вы не настроили другую. Директория считается случаем, когда она содержит prompt.md или case.yaml, и случай без хотя бы одного оценщика не загружается с ошибкой invalid case.yaml, которая называет graders. Это дерево показывает каждый файл, который claude plugin eval читает или записывает в директории eval:
evals/
├── <case>/ # одна директория на случай; вложите в директорию без случаев для группировки
│ ├── prompt.md # frontmatter: поля case и run; тело: подсказка
│ ├── case.yaml # опционально: поля context.*, или весь случай в одном файле
│ ├── graders/
│ │ └── <name>.md # один оценщик на файл; frontmatter: тип и опции; тело: рубрика
│ ├── mocks/ # опционально: мокирование только для этого случая, такой же макет как ниже
│ └── <fixtures, scripts, transcripts referenced by case.yaml>
├── mocks/ # опционально: мокирование на уровне набора тестов для MCP
│ ├── <server>/
│ │ ├── <tool>.md # один мокированный инструмент; тело: результат инструмента
│ │ ├── _server.md # опционально: один агент, который отвечает на несколько инструментов
│ │ ├── _tools.json # опционально: сохранённый ответ tools/list для реальных описаний и схем
│ │ └── fixtures/ # файлы, вставленные с {{file:fixtures/...}}
│ └── .replay/<server>/ # принятые записи agent-mock, отвеченные без вызова модели
└── results/<timestamp>/ # записано каждым запуском; добавьте results/ в .gitignore
├── aggregate-result.json
├── report.html
└── mock-recordings/ # ответы agent-mock из чистых запусков, с ADOPT.txt
prompt.md frontmatter
prompt.md frontmatter принимает эти поля. Неизвестный ключ является ошибкой:
| Поле | По умолчанию | Назначение |
|---|---|---|
schema_version |
"1.1", установлено для вас |
Версия формата случая. Случаи, написанные как prompt.md, получают её автоматически, поэтому вы редко устанавливаете её |
name |
Имя директории | Имя случая. Глобы --case совпадают с ним и отчёт использует его в качестве ключа |
description |
Для людей. Не используется во время запуска | |
tags |
[] |
Метки для фильтрации --tag. Случай запускается, если любой из его тегов совпадает |
plugins |
Ближайший охватывающий плагин | Директории плагинов под тестом, относительно директории случая. Установите plugins: ["../.."], когда автоматическое обнаружение не находит ваш плагин; см. плагин не загрузился |
runs |
3 |
Запусков на ветвь, от 1 до 50. --runs переопределяет это |
expected_outcome |
Для людей. Не используется во время запуска | |
model |
По умолчанию дочерней сессии | Модель для тестируемого агента. --model переопределяет это |
max_turns |
10 |
Ограничение ходов, до 200. Его достижение записывается как ошибка запуска и обычно снижает оценку, поэтому установите его щедро |
timeout_seconds |
300 |
Ограничение по времени на запуск, до 3600 |
allowed_tools |
[] |
Инструменты, которые нужны случаю, такие как [Read, Glob, Grep, Skill]. Инструменты только для чтения предоставляются при указании здесь; для всего остального см. Предоставление инструментов |
append_system_prompt |
Текст, добавленный к системной подсказке дочерней сессии | |
env |
{} |
Дополнительные переменные окружения для дочерней сессии. Ключи должны соответствовать EVAL_[A-Z0-9_]*; любой другой ключ приводит к сбою запуска. Запуск наследует только список разрешённых переменных из вашей оболочки: основные переменные, такие как PATH и локаль, параметры прокси и сертификата, переменные, которые выбирают и аутентифицируют вашего поставщика модели, большинство конфигурации ANTHROPIC_* и CLAUDE_CODE_*, и EVAL_*. Чтобы передать плагину что-то ещё, например параметр цепочки инструментов, экспортируйте его как переменную EVAL_* |
case.yaml поля
case.yaml описывает тот же случай в YAML и добавляет поля, которые указывают на другие файлы. Требуется schema_version: "1.1" и name. Поля prompt.md description, tags, plugins, runs и expected_outcome находятся на верхнем уровне; model, max_turns, timeout_seconds, allowed_tools, append_system_prompt и env находятся под execution:. Когда оба файла существуют, frontmatter prompt.md переопределяет совпадающие поля case.yaml, тело prompt.md является подсказкой, и graders/*.md добавляются после любых оценщиков, указанных в case.yaml.
Эти поля существуют только в case.yaml:
| Поле | Назначение |
|---|---|
context.scaffold_script |
Bash-скрипт в директории случая, который запускается в пустом рабочем пространстве перед началом Claude, для создания файлов фиксур или репозитория git. Запускается только при передаче --scaffold, с минимальным окружением и ограничением в 120 секунд, и ненулевой выход приводит к сбою запуска |
context.history_file |
Транскрипт .jsonl в директории случая для возобновления. Подсказка случая становится следующим ходом пользователя |
context.add_dirs |
Директории внутри директории случая, которые Claude может читать во время запуска, предоставлены только для чтения |
execution.prompt |
Подсказка, когда вы сохраняете весь случай в case.yaml и опускаете prompt.md |
graders |
Список оценщиков, каждый с name плюс те же ключи, которые файл graders/*.md принимает в frontmatter. Для оценщиков llm поместите рубрику в criteria |
Frontmatter оценщика
Каждый файл оценщика под graders/ принимает эти ключи в frontmatter, плюс опции для его типа. Имя оценщика — это имя файла без .md:
| Ключ | По умолчанию | Назначение |
|---|---|---|
type |
требуется | Один из типов оценщиков |
weight |
1 |
Относительный вес в оценке запуска. Любое положительное число |
arm |
не установлено | with-only исключает оценщика из оценки в двухветвевом запуске; both заставляет оценщика Claude Code, который иначе исключил бы, оцениваться в обеих ветвях |
Что может видеть оценщик
Оценщики regex принимают target и оценщики llm принимают focus. Оба принимают одни и те же значения:
| Значение | Что видит оценщик |
|---|---|
last_message |
Финальный текст ответа Claude. Это значение по умолчанию |
trace |
Вся сессия как JSON, одно сообщение на строку. Оценщик regex видит каждое сообщение; судья llm видит первые 12 и последние 12. Кавычки и переводы строк внутри неё экранированы JSON, поэтому регулярное выражение совпадает с \" вместо " |
files |
Список путей, которые Claude создал во время запуска, по одному на строку. Не их содержимое и не файлы, которые создала фиксура или которые Claude только изменил |
{ source: file, path: <path> } |
Содержимое одного файла в рабочем пространстве после запуска. Используйте это для оценки того, что произвёл плагин. Файл PNG, JPEG, GIF или WebP показывается судье llm как изображение. Судья llm отказывает в других двоичных файлах, таких как .pptx или PDF; отрендерьте их в изображение или выведите как текст и оцените это |
mock_calls |
Каждый вызов, который Claude сделал к мокированному инструменту MCP, с его входом и ответом мока |
Типы оценщиков
Каждый тип оценщика ниже перечисляет его опции и когда он проходит:
| Тип | Опции | Проходит когда |
|---|---|---|
regex |
pattern, flags, match, target |
JavaScript регулярное выражение pattern найдено в целевом объекте. Установите match: not_contains для требования отсутствия или match: "count:N" для требования ровно N совпадений. Поместите нечувствительность к регистру в flags: i; встроенный (?i) не поддерживается |
tool_used |
tool, input_match, min, max |
Количество вызовов tool, чей JSON-кодированный вход совпадает с опциональным регулярным выражением input_match, находится между min, по умолчанию 1, и max, по умолчанию неограниченно. Чтобы утверждать, что инструмент никогда не вызывался, установите оба min: 0 и max: 0 |
tool_order |
before, after |
Оба инструмента были вызваны и первый совпадающий вызов before предшествует первому совпадающему вызову after. Каждый — это имя инструмента или { tool, input_match } |
file_exists |
path, exists |
Файл, созданный Claude, совпадает с глобом path, или ни один не совпадает с exists: false. Считаются только файлы, созданные во время запуска |
llm |
criteria, focus |
Судья модель голосует PASS по рубрике по крайней мере в двух из трёх голосов. В макете .md тело файла — это критерии |
baseline |
baseline_file, criteria |
Судья находит, что запуск удовлетворяет критериям по крайней мере так же хорошо, как эталонный транскрипт в baseline_file, .jsonl в директории случая |
Файлы мока
Файл <tool>.md под mocks/<server>/ отвечает на один инструмент. Его тело — это результат инструмента, с подстановками {{input.<field>}} и {{file:fixtures/<name>}}. Его frontmatter принимает эти ключи:
| Ключ | По умолчанию | Назначение |
|---|---|---|
type |
fixed |
fixed возвращает тело как написано. agent рассматривает тело как инструкции для модели-судьи, которая играет роль сервера для запуска и видит более ранние вызовы как историю |
expect |
не установлено | Карта от точечных путей входа к имени типа, такому как string, number, boolean, array или object, /regex/, литерал или список разрешённых литералов. Вызов, который нарушает это, прерывает запуск с оценкой 0 и сообщается как aborted с сервером, инструментом и причиной |
error |
false |
Только fixed. Верните тело как ошибку инструмента |
abort_when |
не установлено | Только agent. Проза, перечисляющая единственные условия, при которых агент может прервать запуск |
Два опциональных файла находятся рядом с файлами инструментов в директории сервера:
_server.md: один мокtype: agent, который отвечает на несколько инструментов, перечисленных в его ключе frontmattertools:.<tool>.mdдля того же инструмента имеет приоритет. Поместите охрануexpect:на отдельный<tool>.md, а не здесь_tools.json: сохранённый ответtools/listот реального сервера, поэтому мокированные инструменты несут свои реальные описания и входные схемы вместо разрешающего заполнителя
Собственная директория mocks/ случая использует тот же макет и переопределяет файлы мока набора тестов файл за файлом.
Troubleshooting
Это проблемы, которые авторы встречают чаще всего, ключевые на том, что вы видите.
"plugin eval is currently in early access"
Ваша сборка предшествует общей доступности команды. Запустите claude update, затем запустите команду снова в свежей сессии.
"plugin eval is currently unavailable"
Anthropic переключила команду выключенной на стороне сервера. Ничто на вашей машине не включает ее обратно; запустите claude update и попробуйте снова в свежей сессии позже.
"is not a trusted plugin directory, and this run cannot stop to ask you about it"
Это первый запуск против директории, которой Claude Code еще не доверяет, и он не может спросить, потому что stdin или stdout не является терминалом, или вы передали --json. Запустите claude plugin eval <dir> один раз в терминале и ответьте на запрос, или передайте --trust-plugin, если вы доверяете коду plugin и suite. См. What a run can access.
"is too old for claude plugin eval"
git на вашем PATH старше версии 2.31, поэтому claude plugin eval остановился перед запуском любого кейса и вышел с кодом 1 с сообщением, называющим вашу версию:
git 2.30 is too old for claude plugin eval: it ignores the environment configuration (GIT_CONFIG_COUNT, added in git 2.31) that switches off the repository's git hooks and helper programs for the run. Install git 2.31 or newer.
Для каждого запуска Claude Code отключает git hooks, credential helpers и другие программы, которые конфигурация git репозитория может запустить. Это делается через конфигурацию окружения, которую git читает только из версии 2.31. Более старый git игнорирует эту конфигурацию, поэтому suite останавливается, а не оценивает запуски, где эти программы могли бы выполняться. Установите git 2.31 или позже и запустите suite снова.
До версии v2.1.283 claude plugin eval не проверял версию git, и на более старом git suite запускался с этими программами оставленными включенными.
"No eval cases found"
Никакой <case>/prompt.md или <case>/case.yaml не существует под директорией eval в действии, или ваши фильтры --case и --tag не соответствовали никакому кейсу. Запустите из корня plugin или запустите claude plugin eval init, чтобы создать suite.
The baseline arm shows no plugin, or delta is zero
Если сводка не имеет столбца W/OUT, или кейс не пройдет с "ablation requested but no plugin resolved", обычная причина в том, что никакой plugin не был найден для кейса. Если каждый кейс возобновляет транскрипт через context.history_file, отсутствующий столбец ожидается вместо этого, потому что эти кейсы запускаются одной веткой по умолчанию. В противном случае добавьте plugins: ["../.."] к кейсу, давая путь от директории кейса к директории plugin.
Если plugin действительно загружен и Δ все еще близко к нулю с неудачным grader tool_used: Skill, это обычно реальное открытие, означающее, что description skill не запускается на формулировке prompt. Отрегулируйте описание и перезапустите ту же suite.
"Agent type '...' not found" for one of your plugin's agents
По умолчанию каждый кейс запускается как с вашим plugin, так и без него, и запуски без него являются базовым запуском без plugin. Когда Claude отправляет одного из агентов вашего plugin в базовом запуске, вызов инструмента Agent не удается с Agent type '<plugin>:<agent-name>' not found. Available agents: .... Список называет только агентов, которые существуют без plugin, такие как встроенные подагенты.
Ошибка ожидается, так как Δ сравнивает запуски вашего plugin с базовым. В результате JSON базовые запуски находятся под cases[].arms.without.
В запусках с загруженным вашим plugin, кейс, который перечисляет Agent в allowed_tools, может отправить одного из агентов вашего plugin по его пространственному имени, такому как my-plugin:code-reviewer для агента code-reviewer в plugin с именем my-plugin. Чтобы пропустить базовые запуски, передайте --ablation none.
Everything scores zero although the right files were produced
Ваши graders нацелены на files, список созданных путей, когда вы имели в виду содержимое файла. Используйте { source: file, path: <path> } как target или focus.
Отдельно, file_exists считает только файлы, созданные во время запуска, поэтому файл, который scaffold создал или который Claude только отредактировал, невидим для него; оцените его содержимое или используйте tool_used на Edit.
A regex over the trace doesn't match text I can see
- Wrong target: default
target— этоlast_message, не trace. - JSON escaping: когда вы действительно нацеливаетесь на
trace, это JSON на строку, поэтому кавычки появляются как\". - Regex syntax: regexes используют JavaScript синтаксис, поэтому поместите
iвflagsвместо написания(?i).
Tools are denied, MCP tools are missing, or Bash won't run
Все, что за пределами набора только для чтения, нуждается в вашем гранте, такой как --allow-tools Bash Write. Ваши личные MCP серверы никогда не загружаются в запуск. Собственные серверы plugin не запускаются, если вы не opt in, и их инструменты затем также нуждаются в гранте --allow-tools "mcp__plugin_<plugin>_<server>__*"; замокированный инструмент не нуждается ни в чем.
The run exits 1 but the results look fine
Default --threshold — это 1.0, поэтому команда выходит 1, когда любой кейс оценен ниже совершенства. Установите порог, который соответствует требуемой оценке. Exit 1 также охватывает файл кейса, который не загружен, который сообщается на stderr выше таблицы.
`--json output path must end in .json`
Вы поместили target после --json, поэтому он был прочитан как путь вывода. Поместите target первым, как в claude plugin eval . --json, или дайте --json явный путь .json.
A grader shows passed: false under a run that scored 1.0
Этот grader исключен из оценки по дизайну в двухarm запуске, и его поле scored — это false. См. Score against the no-plugin baseline.
Runs fail with a usage-limit or rate-limit error partway through
Если ваш аккаунт достигает лимита использования плана или API лимита скорости, пока suite запускается, каждый более поздний запуск заканчивается этой ошибкой, оценивается на том, что он произвел, и обычно оценивается в 0. Suite все еще завершается и не отмечена partial, поэтому результат может выглядеть как регрессия. Проверьте столбец NOTES или cases[].arms.with[].error в JSON для сообщения лимита перед тем как доверять оценкам, затем перезапустите после того как лимит сбросится, с --runs 1 или фильтром --case, если вам нужно остаться под ним.
Runs time out or hit the turn cap
Defaults — это 10 turns и 300 секунд. Поднимите max_turns и timeout_seconds в кейсе для задач, которые нуждаются в большем, и используйте --max-cost-usd как потолок стоимости вместо плотных per-run лимитов.
См. также
- Создание плагина: создайте плагин, который вы тестируете, и загрузите его с помощью
--plugin-dirво время разработки - Справочник команд плагинов: записи команд
plugin evalиplugin eval init. Ключexperimental.evalsманифеста находится в справочнике манифеста - Skills: как описание skill решает, когда Claude его вызывает, что измеряет случай, проверяющий, срабатывает ли skill
- Sandboxing: изолированная среда на уровне ОС, которая применяется при предоставлении Bash для запуска
- Публикация плагина: опубликуйте плагин после того, как его набор тестов пройдёт
- Измерение стоимости и использования плагина: что плагин добавляет к контексту каждой сессии и используют ли его люди