claude plugin eval запускает ваш plugin на наборе тестовых кейсов и оценивает результаты. Каждый кейс — это реалистичный запрос плюс один или несколько graders. Grader — это проверка pass/fail того, что произвел Claude, например регулярное выражение для ответа, был ли вызван конкретный инструмент или рубрика, которую вторая модель оценивает в ответе.
Вам не нужно писать набор вручную; claude plugin eval init спрашивает вас о вашем plugin, предлагает кейсы и graders, пробует их и записывает файлы, и вы можете попросить Claude сделать то же самое из уже открытой сессии.
Используйте evals для:
- Измерения того, насколько надежно ваш plugin направляет Claude к правильному результату
- Выявления регрессий при изменении plugin или выпуске новой модели
- Определения того, что plugin вносит в сравнении с отсутствием 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
Это пошаговое руководство по написанию одного кейса для вашего собственного плагина, его запуску и чтению результата. Перед началом убедитесь, что у вас есть:- Claude Code v2.1.269 или новее и другие требования
- Терминал, открытый в корневой директории вашего плагина, той, которая содержит
plugin.jsonили.claude-plugin/plugin.json - Один скилл в плагине, который вы хотите протестировать, и просьба, которую ввел бы пользователь и которая должна его вызвать
1
Создайте кейсы
Из корня плагина запустите:Если Claude Code еще не доверяет этой директории, он сначала спрашивает
Trust this plugin directory?; ответьте y.Затем открывается интерактивная сессия Claude Code. Claude читает ваш плагин и спрашивает вас, как должен выглядеть хороший результат, предлагает промпты, которые должны и не должны вызывать плагин, разрабатывает graders для каждого, один раз пробно запускает их, чтобы проверить их поведение, и записывает одну директорию кейса на каждый промпт в evals/, каждую названную по своему промпту.Когда Claude сообщит вам, что suite готов, выйдите из этой сессии с помощью /exit или Ctrl+D, чтобы вернуться в оболочку.Если у вас уже есть сессия Claude Code, открытая в корне плагина, вы можете вместо этого попросить Claude там запустить claude plugin eval init. Claude запускает команду и затем задает вам те же вопросы в этом диалоге.Если вы предпочитаете написать кейс самостоятельно, чтобы увидеть, что именно содержат файлы, следуйте разделу Написание кейса вручную и вернитесь сюда, чтобы запустить его.2
Запустите suite
Вернитесь в оболочку в корне плагина и запустите каждый кейс в Вы уже доверились этой директории на шаге 1, поэтому запуск начинается немедленно. Если вы вместо этого написали кейс вручную, запуск сначала спрашивает
evals/:Trust this plugin directory? [y/N]; ответьте y. Раздел К чему имеет доступ запуск объясняет, на что вы соглашаетесь.Каждый кейс запускается три раза с вашим плагином и три раза без него, поэтому один кейс — это шесть запусков. По мере завершения каждого запуска печатается строка прогресса с оценкой этого запуска и вердиктом каждого grader.3
Прочитайте сводку
Когда suite завершится, вы увидите таблицу сводки, за которой следует информация о том, куда был записан отчет:
WITH — это оценка кейса с загруженным вашим плагином, W/OUT — это оценка без него, а положительное Δ означает, что плагин повысил оценку. COST — это оценка стоимости вызовов модели по прейскуранту, а NOTES показывает объяснение неудачного grader с наибольшим весом или ошибку запуска из with-arm.4
Откройте отчет и повторяйте
Откройте URL Замените
Published: или путь Report:, если строки Published: нет, чтобы увидеть вердикт и объяснение каждого grader для каждого запуска, а для llm graders — голоса judge и отрывок, который он оценивал. Строка Published: появляется, только когда ваш аккаунт может публиковать отчеты.Наиболее частое первое открытие — это Δ близко к нулю с неудачным grader tool_used: Skill кейса, что означает, что Claude не выбирает ваш скилл при естественной формулировке. Отрегулируйте description скилла, снова запустите claude plugin eval . и сравните.Чтобы повторять итерации по одному кейсу с меньшим числом запусков, запустите один arm один раз. Один запуск шумный, поэтому подтвердите любое изменение при трех запусках по умолчанию, прежде чем доверять ему. С одним arm таблица показывает столбцы SCORE и PASS% вместо WITH, W/OUT и Δ:<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 и результаты:
Напишите кейс вручную
Рекомендуемый путь — поручить Claude написание кейсов с помощьюclaude plugin eval init. Чтобы вместо этого написать кейс самостоятельно, начните с пустого шаблона. Следующая команда создает кейс с именем first-case с заготовкой prompt.md и одним grader-заготовкой и ничего не запускает:
prompt.md вы пишете сообщение, которое Claude получает в каждом запуске, а в его frontmatter задаете лимиты запуска и инструменты, которые может использовать кейс. Откройте evals/first-case/prompt.md и замените текст-заготовку на задачу, которую должен обработать один из ваших скиллов, сформулированную так, как ее напечатал бы пользователь, а не с указанием названия скилла. Этот пример предназначен для скилла, который составляет сообщения коммитов; используйте собственную задачу:
graders/ — это одна проверка, применяемая после запуска. Откройте evals/first-case/graders/criteria.md и замените заготовку на рубрику для модели-судьи, написанную в виде конкретных условий PASS и FAIL:
evals/first-case/graders/skill-fired.md, заменив your-skill-name на имя каталога скилла в skills/ — это имя, по которому 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, которые дают стабильный сигнал
Graderllm запрашивает вердикт у модели, поэтому его ответ может различаться между запусками, и тем сильнее, чем длиннее текст, который ему нужно прочитать. Следующие привычки помогают сохранять оценки 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 не показывает плагин.
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/:
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:
- Подстановки: вставьте поля из input вызова с
{{input.<field>}}и содержимое файла fixture рядом с mock с{{file:fixtures/{input.<field>}.json}}. expect:: блокexpect:охраняет input. Если вызов нарушает его, запуск прерывается с оценкой 0 и записывает почему, поэтому кейс может утверждать, что ваш plugin попросил сервер сделать.error: true: установитеerror: true, чтобы вернуть body как ошибку инструмента вместо этого.type: agent: задайтеtype: agent, чтобы модель-судья отвечала от имени сервера по инструкциям из тела. Вызовы agent mock используют общий бюджет на запуск, равный четырёхкратному значениюmax_turnsкейса, и вызов сверх него прерывает запуск с оценкой 0.
_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:
Добавьте
--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, предоставьте их сами:
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.
Запустите evals в CI
В вашей CI работе запустите suite с--json, чтобы написать результат для архивирования, и не пройдите сборку на exit коде. Передайте --trust-plugin, чтобы работа никогда не ждала на первом запросе доверия, закрепите обе модели, чтобы оценки были сравнимы со временем, держите отчет локально и установите потолок стоимости как верхний лимит:
Дельта 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>, чтобы получить пустой шаблон.
--ablation none, где вам не нужно Δ, и оставьте partial: true документы и запуски с skippedPaidGraders вне любого тренда, который вы составляете.
Чтение результатов
Каждый запуск, в котором есть хотя бы один кейс, создаёт внутри каталога eval каталогresults/<timestamp>/, содержащий aggregate-result.json и report.html. Для цели, заданной путём, он находится внутри плагина; для плагина, указанного по имени, — в вашем текущем каталоге, как показано в таблице целей. Сводная таблица, JSON и отчёт отображают одни и те же данные результатов.
HTML-отчёт
report.html — это единый самодостаточный файл, который не выполняет внешних запросов, поэтому его можно прикрепить к задаче CI или открыть с диска. В этом примере показано начало отчёта для набора из трёх кейсов, запущенного с --threshold 0.8; указанная стоимость является оценкой по прейскурантным ценам и зависит от модели и количества кейсов:

- Строка вердикта и плитки отвечают на вопрос, помог ли плагин в масштабе всего набора. Suite score — это среднее оценок по кейсам с плагином, Ablation Δ показывает, насколько оно выше или ниже базовой оценки, а Cases подсчитывает, сколько кейсов достигли порога. Perfect runs — это доля запусков с плагином, в которых прошли все грейдеры.
- Каждая карточка кейса показывает собственную
Δкейса и оценку с плагином, с отметкой порога на шкале. Кейс с отрицательнойΔполучает красную левую границу, поэтому регрессии заметны при прокрутке. - Внутри кейса сначала идут запуски с плагином, а затем базовые запуски. Для каждого запуска перечислены его грейдеры с меткой pass или fail. Не прошедший грейдер уже развёрнут с пояснением, а грейдер
llmтакже показывает голоса судьи и доказательства, которые ему были показаны, — именно здесь можно выяснить, почему запуск получил низкую оценку. Грейдеры, которые не учитываются в оценке, напримерtool_used: Skill, помечены значкомplugin-fired indicator. - Prompt и Graders под запусками показывают промпт кейса и рубрику или шаблон каждого грейдера, чтобы тот, кто читает отчёт без набора, мог увидеть, что было запрошено и что считалось хорошим результатом.
Published: <url>. Передайте --no-publish, чтобы оставить его локальным. Если строка Published: не появляется, например при аутентификации с помощью API-ключа, отчётом является локальный файл.
Запуск, начатый сессией Claude Code, например когда вы просите Claude запустить набор за вас, также остаётся локальным, а его строка Report: содержит kept local. Добавьте --publish-report к этой команде, чтобы опубликовать его.
Результат в JSON
aggregate-result.json, как и вывод --json, — это версионированный документ с schemaVersion: 1, предназначенный для разбора скриптами CI. Имена полей записываются в camelCase, а новые поля добавляются без переименования существующих, поэтому пишите скрипт так, чтобы он игнорировал нераспознанные поля.
Ниже перечислены поля, которые обычно читает скрипт-шлюз. Документ также содержит конфигурацию набора, определения всех грейдеров и результаты грейдеров по каждому запуску с пояснениями и доказательствами:
Что может получить доступ запуск
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:
prompt.md frontmatter
prompt.md frontmatter принимает эти поля. Неизвестный ключ является ошибкой:
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:
Frontmatter оценщика
Каждый файл оценщика подgraders/ принимает эти ключи в frontmatter, плюс опции для его типа. Имя оценщика — это имя файла без .md:
Что может видеть оценщик
Оценщикиregex принимают target и оценщики llm принимают focus. Оба принимают одни и те же значения:
Типы оценщиков
Каждый тип оценщика ниже перечисляет его опции и когда он проходит:Файлы мока
Файл<tool>.md под mocks/<server>/ отвечает на один инструмент. Его тело — это результат инструмента, с подстановками {{input.<field>}} и {{file:fixtures/<name>}}. Его frontmatter принимает эти ключи:
Два опциональных файла находятся рядом с файлами инструментов в директории сервера:
_server.md: один мокtype: agent, который отвечает на несколько инструментов, перечисленных в его ключе frontmattertools:.<tool>.mdдля того же инструмента имеет приоритет. Охранаexpect:здесь вызывает ошибку загрузки, если толькоtools:не перечисляет единственный инструмент, поэтому поместите охрану на отдельный<tool>.md_tools.json: сохранённый ответtools/listот реального сервера, поэтому мокированные инструменты несут свои реальные описания и входные схемы вместо разрешающего заполнителя
mocks/ случая использует тот же макет и переопределяет файлы мока набора тестов файл за файлом.
Шаблоны регулярных выражений в expect
Значение/regex/ в expect: использует небольшой диалект, который Claude Code проверяет при загрузке набора тестов:
- Литеральные символы,
., экранированные последовательности, такие как\d, и классы символов, такие как[a-z] - Квантификаторы
*,+,?и формы{m,n}, каждый применительно к одному символу, экранированной последовательности или классу - Необязательный
^в начале и$в конце - Только флаги
iиs
^ увеличивает её, поэтому привязывайте шаблоны с помощью ^ и используйте как можно меньше квантификаторов.
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 с сообщением, называющим вашу версию:
claude plugin eval не проверял версию git, и на более старом git suite запускался с этими программами оставленными включенными.
“cannot be evaluated where sessions load it”
Вы запустилиclaude plugin eval в своей оболочке с именем плагина, установленного из маркетплейса, который вы добавили по локальному пути. Сейчас ни одна сессия не смогла бы загрузить плагин из этого маркетплейса, поэтому команда отказывает с этим сообщением и завершается с кодом 1.
no session could load it now. указывает, что именно не удалось.
Выполните claude plugin marketplace list в своей оболочке и исправьте то, что указано в сообщении. Например, восстановите каталог маркетплейса или верните запись плагина в его каталог. Чтобы оценить исходный код плагина без маркетплейса, передайте его каталог в качестве цели, например claude plugin eval ./plugins/formatter.
“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
Если каждый кейс получил оценку не ниже--threshold, а команда всё равно завершается с кодом 1, причина указывается в строке в stderr, даже при --json. Например, файл кейса не загрузился или запуски завершились ошибкой API. Другие причины см. в разделе коды выхода.
Значение --threshold по умолчанию — 1.0, поэтому команда завершается с кодом 1, если любой кейс получил оценку ниже идеальной. Задайте порог, соответствующий требуемой вами оценке.
--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.
“ended on an API error and scored 0 without grading”
Это предупреждение в stderr означает, что API ответил на последний запрос как минимум одного запуска HTTP-ошибкой, например из-за ограничения частоты запросов или лимита использования плана. Такой запуск получает оценку 0 без результатов грейдеров, а команда завершается с ненулевым кодом независимо от оценок и--threshold.
Чтобы исправить это, найдите ошибку каждого затронутого запуска и устраните указанную в ней причину, затем снова запустите набор тестов:
- Без
--json: ошибка находится в конце строки прогресса запуска, послеerror: - С
--json: ошибка находится в JSON-результате, вcases[].arms.with[].errorилиcases[].arms.without[].error
W/OUT и Δ затронутого кейса выводятся как —. О лимите использования или ограничении частоты запросов см. Запуски завершаются ошибкой лимита использования или ограничения частоты запросов на полпути.
До версии v2.1.299 такой запуск оценивался по тому, что он успел создать.
Runs fail with a usage-limit or rate-limit error partway through
Запуски, завершившиеся ошибкой лимита использования или ограничения частоты запросов, получают оценку 0 без проверки грейдерами, а команда завершается с ненулевым кодом. Набор тестов всё равно доходит до конца и не помечается какpartial. Перезапустите его после сброса лимита, с --runs 1 или фильтром --case, если нужно уложиться в лимит.
“mock call budget exceeded”
Все моки сtype: agent в запуске расходуют общий бюджет вызовов, равный четырёхкратному значению max_turns кейса, то есть 40 вызовов при значении по умолчанию 10. Вызовы, на которые отвечают записи из .replay/, тоже учитываются, а строка прогресса mock budget кейса выводит бюджет. Вызов сверх него прерывает запуск с оценкой 0 и этой причиной, поэтому для скилла, который делает много вызовов к мокам агентов, увеличьте max_turns в кейсе.
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 для запуска
- Публикация плагина: опубликуйте плагин после того, как его набор тестов пройдёт
- Измерение стоимости и использования плагина: что плагин добавляет к контексту каждой сессии и используют ли его люди