Skip to main content
claude plugin eval シェルコマンドは プラグイン をテストケースのスイートに対して実行し、結果をスコア化します。各ケースは現実的なプロンプトと 1 つ以上のグレーダーで構成されます。グレーダーは Claude が生成したものに対する合格/不合格チェックで、返信に対する正規表現、特定のツールが呼び出されたかどうか、または第 2 のモデルが返信を判定するルーブリックなどです。 スイートを手動で作成する必要はありません。claude plugin eval init はプラグインについて質問し、ケースとグレーダーを提案し、それらを試し、ファイルを作成します。既に開いているセッションから Claude に同じことを行うよう依頼することもできます。 evals を使用して以下を実行します。
  • プラグインがどの程度確実に Claude を正しい結果に導くかを測定する
  • プラグインを変更したり新しいモデルがリリースされたりしたときの回帰を検出する
  • プラグインなしの場合と比較してプラグインが何を貢献しているかを確認する
このページはプラグインとスキル作成者向けで、動作するプラグインがあり、その動作をテストしたい場合、および CI でプラグイン変更をゲートするチーム向けです。Claude Code 会話内で 1 つのスキルを反復処理する場合、skill-creator プラグイン は独自の evals/evals.json 形式で同様の比較を実行し、どちらのツールも他方のケースファイルを読み込みません。プラグインを作成するには プラグインを作成する を参照してください。プラグインの動作ではなく構文とスキーマエラーをチェックするには、claude plugin validate を使用します。
すべての eval 実行とすべてのジャッジグレーダーは、アカウント上の実際のモデル呼び出しで、プランの使用量または API 請求に対してカウントされます。そのため、最初に 要件 を確認してください。その後、最初の eval スイートを作成 するか、既にスイートがある場合は CI で evals を実行 に進んでください。

要件

プラグイン evals を実行するには、以下が必要です。
  • Claude Code v2.1.269 以降。claude --version で確認し、claude update でアップグレードしてください。
  • Git 2.31 以降(Git がインストールされている場合)。git --version で確認してください。古いバージョンの Git では、claude plugin eval は ケースを実行する前に停止します。Git がない場合は、通常どおり実行されます。
  • plugin.json または .claude-plugin/plugin.json マニフェストを含むプラグインディレクトリ、または skills-directory プラグイン。
  • 通常の Claude Code セッションで使用するのと同じ認証とモデルプロバイダー。Eval 実行、judge-scored graders、および claude plugin eval init はユーザーの認証情報でモデルを呼び出すため、プランの使用制限または API 請求に対してカウントされます。コマンドがコストを報告する場合、その数値はそれらの呼び出しの 定価見積もり です。Amazon Bedrock、Google Cloud の Agent Platform、または Microsoft Foundry で Claude Code を実行している場合は、通常のセッションと同じプロバイダー変数をエクスポートするシェルからスイートを実行してください。env フィールド で説明されているとおり、各実行はそのシェルからこれらの変数を継承するためです。

eval 実行の仕組み

eval スイートはプラグイン内の evals/ というディレクトリに存在し、ケースを作成して改善する に示すようにレイアウトされます。各ケースは プロンプト と 1 つ以上の グレーダー を含む独自のサブディレクトリです。プロンプトは、プラグインを使用している人が入力するようなもので、そのスキルの 1 つが処理すべきリクエストなどです。

実行中に何が起こるか

ケースの各実行について、Claude Code は新しい 分離された 非対話型セッション を開始し、プラグインのみをロードし、プロンプトを送信し、Claude が完了するか、ケースのターン制限または時間制限に達するまで動作させます。その後、各グレーダーは最終的な返信、トランスクリプト、または Claude が作成したファイルをチェックし、合格または不合格を判定します。

ケースのスコア化方法

非決定論的なエージェントの 1 回の実行では、ほとんど情報が得られないため、各ケースはデフォルトで 3 回実行されます。実行のスコアは、重み付けを設定した場合は重み付けされた、合格したグレーダーの割合であり、ケースのスコアは実行全体の平均です。ケースは、そのスコアが --threshold(デフォルトは 1.0)を満たすときに合格します。 モデル呼び出しでは、スイートはおおよそ cases × runs のエージェント実行をプラグインで行い、プラグインなしベースライン でも同じ数だけ行い、さらに実行ごとに llm または baseline グレーダーごとに 3 つの短いジャッジ呼び出しを行います。

プラグインなしベースライン

プラグインなしでも Claude が同じくらい上手くいく可能性があるため、単独のスコアが高いだけではプラグインが役に立ったことを示しません。この 2 つを分離するために、各ケースの実行はプラグインをロードせずに繰り返され、2 つのスコア WITH と W/OUT が得られます。その差 Δ は、プラグインが貢献したものです。ケースがプラグインの有無にかかわらず 1.0 でスコアされた場合、プラグインはそれが合格した理由ではありません。 2 つの実行セットは with-arm と without-arm と呼ばれます。プラグインなしベースラインに対してスコアを付ける では、どのケースが with-arm のみを実行するか、およびグレーダーが 2 つの arm にわたってどのようにスコア化されるかについて説明します。

最初の eval スイートを作成する

このチュートリアルは、独自のプラグイン用に 1 つのケースを作成し、実行し、結果を読みます。開始する前に、以下があることを確認してください。
  • Claude Code v2.1.269 以降およびその他の 要件
  • プラグインのルートディレクトリで開いているターミナル(plugin.json または .claude-plugin/plugin.json を含むディレクトリ)
  • テストしたいプラグイン内の 1 つのスキルと、ユーザーが入力すべきリクエスト(それがスキルをトリガーすべき)
1

ケースを作成する

プラグインルートから、以下を実行します。
Claude Code がこのディレクトリをまだ信頼していない場合、最初に Trust this plugin directory? と尋ねます。y で答えてください。その後、対話型 Claude Code セッションが開きます。Claude はプラグインを読み、良い結果がどのようなものかを尋ね、プラグインをトリガーすべき、またはトリガーすべきでないプロンプトを提案し、各プロンプト用のグレーダーを設計し、それらを試行として 1 回実行して動作を確認し、evals/ の下にプロンプトごとに 1 つのケースディレクトリを作成します。各ディレクトリにはそのプロンプトに基づいた名前が付けられます。Claude がスイートの準備ができたことを伝えたら、/exit または Ctrl+D でそのセッションを終了してシェルに戻ります。プラグインルートで既に Claude Code セッションが開いている場合は、代わりにそこで Claude に claude plugin eval init を実行するよう依頼できます。Claude はコマンドを実行し、その会話で同じ質問をします。ケースを自分で作成して、ファイルが正確に何を含むかを確認したい場合は、ケースを手動で作成する に従い、ここに戻ってそれを実行します。
2

スイートを実行する

プラグインルートのシェルに戻り、evals/ の下のすべてのケースを実行します。
ステップ 1 でこのディレクトリを既に信頼しているため、実行はすぐに開始されます。代わりにケースを手動で作成した場合、実行は最初に Trust this plugin directory? [y/N] と尋ねます。y で答えてください。実行がアクセスできるもの は、同意していることを説明します。各ケースはプラグイン付きで 3 回、プラグインなしで 3 回実行されるため、1 つのケースは 6 回の実行です。各実行が完了すると、その実行のスコアと各グレーダーの判定を含む進捗行が出力されます。
3

サマリーを読む

スイートが完了すると、サマリーテーブルが表示され、その後にレポートの場所が表示されます。
WITH はプラグインをロードしたケースのスコア、W/OUT はロードしないでのスコア、正の Δ はプラグインがスコアを上げたことを意味します。COST はモデル呼び出しの定価見積もりで、NOTES は最も高い重みの失敗したグレーダーの説明、または with-arm の実行エラーを示します。
4

レポートを開いて反復する

Published: URL、または Published: 行が表示されない場合は Report: パスを開いて、すべての実行のすべてのグレーダーの判定と説明を確認し、llm グレーダーについてはジャッジの投票と判定した抜粋を確認します。Published: 行は、アカウントが レポートを公開 できる場合にのみ表示されます。最初の一般的な発見は、ケースの tool_used: Skill グレーダーが失敗している Δ がほぼゼロで、Claude が自然な表現でスキルを選択していないことを意味します。スキルの description を調整し、claude plugin eval . を再度実行し、比較します。実行回数を減らして 1 つのケースを反復するには、1 つの arm を 1 回実行します。1 回の実行はノイズが多いため、信頼する前にデフォルトの 3 回で変更を確認してください。1 つの arm では、テーブルは WITH、W/OUT、Δ の列の代わりに SCORE と PASS% の列を表示します。
<case-name> を evals/ の下のディレクトリ名の 1 つに置き換えます。

ケースを作成して改善する

claude plugin eval init が作成するケースは、開いて変更し、追加できるプレーンファイルです。ケースはプラグインの eval ディレクトリの下のディレクトリで、prompt.md、case.yaml、またはその両方を含みます。グレーダーのないケースは読み込みに失敗するため、各ケースには graders/<name>.md ファイルまたは case.yaml の graders: エントリとして、少なくとも 1 つのグレーダーを付与してください。ケースをグループ化するには、それ自体がケースではないディレクトリの下にネストします。graders/ やフィクスチャファイルなど、ケースディレクトリ内のすべてはそのケースに属します。 これは claude plugin eval init が作成するレイアウトで、新しいスイートに使用するレイアウトです。eval スイートリファレンス には、モックと結果を含む完全なツリーがあります。

ケースを手動で作成する

Claude にケースを claude plugin eval init で作成させることが推奨パスです。代わりに自分で作成するには、空のテンプレートから開始します。次のコマンドは、プレースホルダー prompt.md と 1 つのプレースホルダーグレーダーを含む first-case という名前のケースを作成し、何も実行しません。
prompt.md では、各実行で Claude が受け取るメッセージを作成し、フロントマターで実行の制限とケースが使用できるツールを設定します。evals/first-case/prompt.md を開き、プレースホルダー本文をスキルの 1 つが処理すべきリクエストに置き換えます。スキル名を挙げるのではなく、ユーザーが入力するであろう表現で記述してください。この例はコミットメッセージを作成するスキル用です。独自のリクエストを使用してください。
各実行は空の作業ディレクトリで開始されるため、タスクに必要なものをプロンプト自体に含めるか、先に ワークスペースをセットアップ してください。 フロントマターフィールドの完全なリスト は、モデル、タイムアウト、タグ、および環境変数をカバーしています。 graders/ の下の各ファイルは、実行後に適用される 1 つのチェックです。evals/first-case/graders/criteria.md を開き、プレースホルダーをジャッジモデル用のルーブリックに置き換えます。具体的な PASS および FAIL 条件として作成されます。
その後、スキルが答えを生成したかどうかをチェックする 2 番目のグレーダーを追加します。evals/first-case/graders/skill-fired.md を作成し、your-skill-name をスキルのディレクトリ名(skills/ の下)に置き換えます。これは Claude が呼び出す名前です。
これは Claude がその実行中にそのスキルを少なくとも 1 回呼び出した場合に合格します。これには、その名前空間付き plugin-name:skill-name 形式も含まれます。 グレーダータイプ は、正規表現のマッチングやファイルが作成されたことの確認など、利用可能な他のチェックをリストします。 両方のファイルを保存したら、クイックスタート が行うように、プラグインルートから claude plugin eval . でケースを実行します。

prompt.md で実行制限とツールを設定する

prompt.md フロントマターでケースの max_turns、timeout_seconds、model、tags、および使用可能な allowed_tools を設定します。prompt.md フロントマター リファレンスはすべてのフィールドとそのデフォルトをリストします。 Claude は本文を正確に作成したとおりに受け取ります。その中の @path メンションはファイル添付に展開されないため、Claude がファイルを読む必要がある場合は、allowed_tools でツールを付与します。

グレーダーを選択して重み付けする

グレーダーのフロントマターはその type を設定し、オプションで実行のスコアでより多くをカウントする weight と、ベースラインに対してどのようにスコア化されるかを制御する arm を設定します。6 つのタイプのうち、regex、tool_used、tool_order、file_exists はトランスクリプトとファイルから計算され、コストはかかりませんが、llm と baseline はジャッジモデルを呼び出し、実行のコストに追加されます。 カスタムコードグレーダーはありません。 グレーダータイプ は各タイプのオプションと合格条件をリストし、グレーダーが見ることができるもの は target と focus が受け入れる値をリストします。 デフォルトでは、llm および baseline グレーダーのジャッジは、Claude Code がバックグラウンドタスクに使用するモデルです。ジャッジを自分で選択するには、--judge-model sonnet または完全なモデル ID を渡します。

安定した信号を与えるグレーダーを選択する

llm グレーダーはモデルに判定を求めるため、その答えは実行間で異なる可能性があり、読む必要があるテキストが長いほど異なります。これらの習慣はスイートのスコアを十分に安定させて信頼できるようにします。
  • 生成されたファイルなどの長い出力については、ファイルの内容に対する regex グレーダーでグレード化します。これは毎回同じ方法でファイル全体をチェックします。短い出力には llm グレーダーを保持し、ルーブリックを具体的な PASS および FAIL 条件として作成します。
  • 各ケースに、最終メッセージや生成されたファイルなどの結果に対する 1 つのグレーダーと、tool_used や tool_order など Claude がそれを生成するためにたどった手順に対する 1 つのグレーダーを付与します。一緒に、答えが正しかったかどうかと、プラグインがそれを生成したかどうかの両方を示します。
  • ケースの tool_used: Skill グレーダーが合格しているが Δ が負の場合、プラグインの前にジャッジを疑います。小さいジャッジモデルは、ルーブリックが説明する内容と異なる形式であるため、正しい答えを間違いとマークできます。--judge-model sonnet で再実行し、形式が判定を決定しないようにルーブリックを厳しくします。
  • ビルドまたはテストが実行内で合格したことを確認するには、プロンプトで Claude にそれを実行し、結果をファイルに書き込むよう依頼し、そのファイルをグレード化し、コマンドが tool_used グレーダーで実行されたことを主張します。その input_match はコマンドに名前を付けます。

プラグインなしベースラインに対してスコア化する

プラグインがテスト対象の場合、ケースは通常 2 つの arm で実行されます。with-arm はプラグインをロードした実行で、without-arm はプラグインをまったくロードせずに同じ回数行う実行です。サマリーとレポートは両方のスコアと Δ(with-arm スコアから without-arm スコアを引いたもの)を表示します。 次の状況では、ケースは with-arm のみで実行されるため、W/OUT スコアや Δ は得られません。
  • --ablation none を渡した場合: すべてのケースが 1 つの arm で実行されます。グレーダーを反復改善している間など、比較が不要な場合にコストを半減できます。
  • ケースがトランスクリプトを再開し、ターゲットがパスである場合: インストール済みプラグインの名前ではなく . などの ターゲット を指定すると、context.history_file ケースは、記録された会話にすでにプラグインが反映されているという前提のもと、デフォルトで 1 つの arm で実行されます。実行時には、これらのケースを示す single-arm (no Δ) 通知が stderr に出力されます。再開したターンをプラグインありとなしで比較するには、--ablation with-without を渡します。
  • ケースのプラグインが見つからなかった場合: ターゲットがパスのとき、Claude Code がプラグインを特定できなかったケースもデフォルトで 1 つの arm で実行されます。修正方法は ベースライン arm にプラグインが表示されない を参照してください。
2 つの arm 実行では、一部のグレーダーは scored: false で報告されます。「スキルが呼び出された」などのチェックはプラグインなしでは決して合格できないため、カウントすると without-arm がゼロに向かい、Δ を膨らませます。2 つの arm を比較可能に保つために、Claude Code はそのようなグレーダーを両方の arm のスコアから除外し、with-arm でそれらを合格/不合格インジケーターのみとして報告します。これには以下が含まれます。
  • tool が Skill である各 tool_used グレーダー
  • target: mock_calls を持つ各 regex グレーダーと、各 モック化されたサーバー がケース内にあり、プラグインが宣言するものである場合の focus: mock_calls を持つ各 llm グレーダー
  • arm: with-only でマークするグレーダー
3 つの設定がその除外を変更します。
  • すべてのグレーダーが除外される: ケース内のすべてのグレーダーが除外対象に含まれる場合、スコア化するものが何も残らないため、代わりに通常スコア化されます。
  • arm: both: グレーダーに arm: both を設定して、それに関わらず両方の arm でスコア化します。これは「スキルを呼び出してはいけない」チェックに min: 0 と max: 0 を使用する場合に必要です。
  • --ablation none: --ablation none の下では何も除外されないため、同じスイートは 2 つのモードで異なる絶対スコアを生成できます。

別の eval ディレクトリを使用する

evals/ が既に別のツールで使用されている場合は、スイートを別のディレクトリに保持します。プラグインの plugin.json にそのディレクトリを記録して、すべての実行とすべての共同作業者がそれを使用するようにするか、単一の実行のためにコマンドラインで渡すことができます。
  • plugin.json で: "experimental": { "evals": "quality/evals" } を追加します。
  • コマンドラインで: claude plugin eval と claude plugin eval init の両方に --eval-dir quality/evals を渡します。
両方を設定した場合、フラグのディレクトリが使用されます。qa または quality/evals などのプレーンディレクトリ名の相対パスを指定します。絶対パスまたは .. を含むパスは受け入れられません。フラグ値としてはエラーで、マニフェスト値として使用できない場合は Warning: 行が出力され、実行は evals/ を使用します。ケース、結果、および init 出力はすべてそのディレクトリに移動します。

フィクスチャとモックをセットアップする

ケースはプロンプト以上のものが必要な場合があります。ワークスペース内のファイルまたは git リポジトリ、続行する以前の会話、またはプラグインが通信する MCP サーバーからの回答。これらのそれぞれはケースの横にセットアップされるため、実行は繰り返し可能なままです。

ワークスペースまたは会話をシードする

各実行は空のワークスペースで開始されます。ケースがプロンプト以上のものが必要な場合は、context ブロックを含む case.yaml を prompt.md の横に追加します。
  • フィクスチャファイルまたは git リポジトリ: ケースディレクトリに Bash スクリプトを作成し、context.scaffold_script で名前を付けます。スクリプトはエージェントのサンドボックスの外でユーザー自身として実行され、--scaffold を渡したときのみ実行されるため、そのフラグはユーザー自身またはユーザーの組織が作成したスイートに対してのみ渡してください。
  • 以前の会話を続行する: トランスクリプトを .jsonl ファイルとして保存し、context.history_file で名前を付けます。ケースのプロンプトは次のユーザーターンになります。ターゲットがパスの場合、このようなケースはデフォルトでベースラインアームなしで実行されます。
  • 実行中に Claude が読むことができるフィクスチャディレクトリ: context.add_dirs にそれらをリストします。
case.yaml には schema_version: "1.1" と name も必要です。case.yaml フィールド リファレンスには完全なリストがあります。 この case.yaml はスクリプトからワークスペースをシードし、Claude が resources/ ディレクトリからフィクスチャを読むことができるようにします。
スキャフォールドスクリプトは、小さな固定環境を持つ空のワークスペースで開始されます。この環境には、シェルの PATH、実行の一時ホームディレクトリに設定された HOME、TMPDIR、および TERM=dumb などのいくつかの定数が含まれます。シェルのそれ以外のものはスクリプトに渡されず、ケースの EVAL_* 変数も渡されません。スクリプトが 0 以外で終了するか、120 秒より長く実行された場合、その実行は scaffold failed エラーでスコア 0 になります。スクリプトが書き込むプロジェクト設定は読み込まれないため、スクリプトはファイルと git の状態のためだけに使用してください。

MCP サーバーをモックする

スキルが MCP ツールを呼び出すプラグインを評価できます。その背後にある実際のサービスなしで。スイート全体の場合は evals/mocks/<server>/<tool>.md の下に 1 つのツールごとに 1 つの Markdown ファイルを配置するか、1 つのケースの場合はケース独自の mocks/ ディレクトリの下に配置します。<server> はプラグインの MCP 設定 のサーバーの名前です。 実行は、要求しない限り、プラグインの実際の MCP サーバーを開始しません。Claude Code は各サーバー独自の名前で代替サーバーを登録します。モックファイルを持つツールはそのファイルから回答し、--allow-tools 付与なしで許可されます。モックファイルを持たないツールは Claude で利用できません。モックがまったくないサーバーは、ケースの mocked: 進捗行に plugin_<plugin>_<server>[not started: no mock] として表示されます。 ファイルの本文は、ツールが Claude に返すものです。このモックは tracker という名前のサーバー上の create_issue ツールの代わりになり、Claude が送信する入力をチェックし、タイトルをエコーバックします。evals/mocks/tracker/create_issue.md として保存します。
モックファイルの本文とフロントマターは、これらのオプションを受け入れます。
  • 置換: {{input.<field>}} で呼び出しの入力からフィールドを挿入し、{{file:fixtures/{input.<field>}.json}} でモックの横のフィクスチャファイルの内容を挿入します。
  • expect:: expect: ブロックは入力を保護します。呼び出しがそれに違反する場合、実行はスコア 0 で中止され、理由が記録されます。そのため、ケースはプラグインがサーバーに何を求めたかを主張できます。
  • error: true: error: true を設定して本文をツールエラーとして返します。
  • type: agent: type: agent を設定してジャッジモデルが本文の指示からサーバーとして答えるようにします。エージェントモックへの呼び出しは、ケースの max_turns の 4 倍となる実行ごとの 1 つの予算を共有し、それを超えた呼び出しは実行をスコア 0 で中止します。
モックファイルリファレンス はすべてのキーと _server.md および _tools.json ファイルをリストします。 呼び出し自体をグレード化するには、グレーダーを target: mock_calls に指します。 プラグインの実際の MCP サーバーに対して実行するには、これらのフラグの 1 つを渡します。どちらの方法でも、これらのプロセスは実行のサンドボックスの外でユーザー自身として実行され、それらのツールには --allow-tools 付与 が必要です。
  • --allow-real-servers: モックしていない各サーバーの実際のプロセスを開始し、モックしたツールには引き続きそれぞれのファイルから回答します。
  • --mocks off: mocks/ を完全に無視し、プラグインが宣言するすべてのサーバーを開始します。

エージェントモック回答を再生する

type: agent モックは --judge-model への呼び出しで答えるため、その出力は実行間で異なり、ジャッジを変更すると変わります。実行がエラーまたは中止なしで完了すると、Claude Code はエージェントモックが返した各回答を、結果ディレクトリ内の mock-recordings/ の下に保存します。 そこにある ADOPT.txt を開くと、各記録と、その記録のコピー先となる .replay/<server>/ ディレクトリ(記録を生成したモックの横)を確認できます。記録をそこにコピーした後は、以降の実行で同一の呼び出しに対してモデル呼び出しなしでその記録から回答します。mocks/.replay/ を mocks/ の残りと一緒にコミットして、CI 実行が繰り返し可能になるようにします。

evals を実行する

スイートが存在すると、claude plugin eval はそれを実行します。ターゲット引数でどのプラグインとケースを実行するかを選択し、--allow-tools でケースが読み取り専用セット以上に必要とするツールを付与し、他のオプションで実行数、モデル、コスト、出力を制御します。

評価対象を選択する

ほとんどの場合、プラグインルートから claude plugin eval . を実行します。これはスイート内のすべてのケースをロードされたプラグインで実行します。単一のケースファイルを実行するか、開発中のプラグインではなくインストール済みのプラグインを評価するには、別のターゲットを渡します。 --case <glob> を追加してケース名でフィルタリングし、--tag <tag> を使用して指定されたタグのいずれかを持つケースを保持します。 ターゲットを --tag、--allow-tools、--json の前に配置します。最初の 2 つはリストを取り、--json はオプションのパスを取るため、それぞれは後に続くターゲットを独自の値として読み取ります。

ツールを付与する

実行は権限を求めるために停止することはありません。付与しなかった許可が必要な組み込みツール(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 サーバー上のツールは許可が不要です。実際のプラグイン MCP サーバー上のツールは、サーバーが開始されている必要があります(--allow-real-servers または --mocks off で)、および --allow-tools "mcp__plugin_my-plugin_github__*" などの名前による付与。プラグインの MCP ツールは mcp__plugin_<plugin>_<server>__<tool> という名前です。 任意の形式で Bash を付与すると、すべてのコマンドは Claude Code の OS レベルサンドボックス の下で実行されます。書き込みは実行のワークスペースに限定され、ホームディレクトリと Claude Code 設定は読み取り不可で、ネットワークアクセスは --allow-tools "WebFetch(domain:example.com)" で付与するドメインに限定されます。サンドボックスバックエンドのないマシンで Bash または PowerShell を付与すると、Claude Code は制限なしで実行するのではなく各実行を拒否し、ケースは実行エラーを表示し、通常はスコア 0 になります。ネイティブ Windows にはバックエンドがないため、WSL2 の下でシェル付与スイートを実行します。Linux では、最初に bubblewrap と socat をインストールします。サンドボックスの前提条件 を参照してください。

コマンドオプション

この表は、実行数、モデル、スコアリング、コスト、ツール付与、モック、出力のオプションをカバーしています。claude plugin eval --help を実行して完全なリストを確認します。これには --case、--tag、--eval-dir、--no-scaffold、--report、--verbose も含まれます。

CI で evals を実行する

CI ジョブで、--json でスイートを実行して結果をアーカイブ用に書き込み、終了コードでビルドを失敗させます。ジョブが 最初の実行信頼プロンプト で待機しないように --trust-plugin を渡し、スコアが時間とともに比較可能になるように両方のモデルを固定し、レポートをローカルに保持し、コスト上限を上限として設定します。
ジョブの終了コードは何が起こったかを示します。 with-minus-without デルタは報告されますが、終了コードを変更することはなく、HTML レポートの書き込みまたは公開の問題も同様です。 ケースがなぜ低くスコア化されたかを確認するには、ローカルで --json なしで実行して、実行ごとの進捗とグレーダー行が出力されるようにします。 CI ランナーには、以下も必要です。
  • インストールと認証情報:CI ランナーは Claude Code インストールと 環境の認証情報(ANTHROPIC_API_KEY やクラウドプロバイダーの変数など)が必要です。
  • 信頼:--trust-plugin なしで、チェックアウトディレクトリを Claude Code がまだ信頼していないジョブは、最初の実行信頼プロンプト が必要で、質問できない実行は終了 1 で拒否されます。
  • CI での init:claude plugin eval init は質問をするためにターミナルが必要です。CI では、claude plugin eval init --bare <name> を実行して空のテンプレートを取得します。
コストを予測可能に保つために、クイックな毎変更スイートにはジャッジを呼び出さないグレーダーのみを付与し、Δ が不要な場所で --ablation none を使用し、partial: true ドキュメントと skippedPaidGraders を持つ実行をチャートするトレンドから除外します。

結果を読む

少なくとも 1 つのケースを持つすべての実行は、eval ディレクトリ内に results/<timestamp>/ ディレクトリを書き込み、aggregate-result.json と report.html を含みます。パスターゲットの場合はプラグインの下。プラグインに名前を付けた場合は現在のディレクトリの下。ターゲットテーブル に示すように。サマリーテーブル、JSON、レポートはすべて同じ結果データをレンダリングします。

HTML レポート

report.html は単一の自己完結型ファイルで、外部リクエストを行わないため、CI ジョブに添付したり、ディスクから開いたりできます。この例は、--threshold 0.8 で実行された 3 ケーススイートのレポートの上部です。表示されるコストは定価見積もりで、モデルとケース数によって異なります。 eval レポートの上部。「Plugin effect: +33.3 pts vs baseline, improved 2, flat 1, regressed 0 of 3 cases」と読む判定行、スイートスコア、アブレーション デルタ、ベースラインスコア、閾値を通過するケース、完全な実行の 5 つのサマリータイル、その後、デルタ、スコアバー、2 つのグレーダーが両方とも合格を示す 1 つの実行を持つ最初のケース。 上から下に読みます。
  • 判定行とタイル は、プラグインがスイート全体で役に立ったかどうかに答えます。スイートスコアはケースごとのプラグイン付きスコアの平均、アブレーション Δ はそれがベースラインスコアの上または下にどの程度座っているか、ケースは何が閾値を満たしたかをカウントします。完全な実行はすべてのグレーダーが合格した with-plugin 実行の共有です。
  • 各ケースカード はケース独自の Δ とプラグイン付きスコアを表示し、バーの閾値にティックを付けます。Δ が負のケースは赤い左端を取得するため、スクロール時に回帰が目立ちます。
  • ケース内 では、プラグイン付き実行が最初に来て、ベースライン実行が後に来ます。各実行はグレーダーを合格または不合格チップでリストします。失敗したグレーダーは説明付きで既に展開されており、llm グレーダーはジャッジの投票とジャッジに提示された証拠も表示します。ここで、実行のスコアが低かった理由を確認できます。スコアに算入されないグレーダー(tool_used: Skill など)には plugin-fired indicator バッジが付きます。
  • プロンプトとグレーダー は実行の下に表示され、ケースのプロンプトと各グレーダーのルーブリックまたはパターンを示すため、スイートを持たずにレポートを読む人でも、何が尋ねられ、何が良いとみなされたかを確認できます。
claude.ai サブスクリプションでサインインしており、アーティファクト がアカウントで利用可能な場合、Claude Code はレポートをプライベートアーティファクトとして公開し、Published: <url> を出力します。--no-publish を渡してローカルに保持します。Published: 行が表示されない場合(API キー認証など)、ローカルファイルがレポートです。 Claude Code セッションが開始した実行(Claude にスイートを実行するよう依頼するなど)もローカルに留まり、その Report: 行は kept local と言います。そのコマンドに --publish-report を追加して公開します。

JSON 結果

aggregate-result.json および --json 出力は、CI スクリプトが解析するための schemaVersion: 1 を持つバージョン付きドキュメントです。フィールド名は camelCase で、新しいフィールドは既存のフィールドを名前変更せずに追加されるため、認識しないフィールドを無視するようにスクリプトを作成します。 これらはゲートスクリプトが通常読むフィールドです。ドキュメントはスイート設定、すべてのグレーダー定義、および説明と証拠を持つ実行ごとのグレーダー結果も含みます。

実行がアクセスできるもの

claude plugin eval はターゲットプラグインのスキル、フック、エージェントを読み込み、ユーザーのマシン上で、ユーザーとして eval スイートを実行します。プラグインを指定することは claude --plugin-dir と同じ信頼判断であるため、信頼できるプラグインのみを評価してください。 このセクションで説明する分離は、テスト中のエージェントが到達できるものを制限します。これはプラグイン自体のコードに対する境界ではなく、スイートが合格したことは、プラグインが安全であるかどうかについて何も述べていません。

プラグインディレクトリを信頼する

初めて claude plugin eval をディレクトリに対して実行する場合、Claude Code は何かを読み込む前に Trust this plugin directory? と尋ねます。ただし、インタラクティブな claude セッションでそこで既に信頼プロンプトを受け入れている場合は除きます。Git リポジトリ内では、「はい」と答えるとリポジトリ全体が信頼され、インタラクティブセッションでも同様です。stdin または stdout がターミナルでない場合、または --json の下では、実行は尋ねることができず、終了コード 1 で拒否されます。--trust-plugin を渡して信頼を自分で主張してください。これは自分のマシンで実行するプラグインに対してのみ行ってください。パスとして与えるのではなく名前で指定したターゲット、つまりインストール済みプラグインまたはスキルディレクトリプラグインは、プロンプトをスキップします。 プラグインとスイートの一部は、その実行のためにそのフラグを渡す場合にのみ実行されます。 ケースの allowed_tools とスキル自体の allowed-tools フロントマターは、これらのいずれも拡大することはできません。 自分で作成していないフックがプラグインに含まれている場合、または実際の MCP サーバーを開始する場合は、コンテナや CI ランナーなどの分離された環境で実行しない限り、スコアを参考情報として扱ってください。フックとサーバーはエージェントのサンドボックスの外で実行され、グレーダーが読み取るファイルを変更する可能性があるためです。

実行がどのように分離されるか

各実行は、一時的なホームディレクトリ、作業ディレクトリ、Claude Code 設定を取得し、テスト中のエージェントはそこで claude -p 子プロセスとして実行され、プラグインのみが読み込まれます。ケースを作成する際は、これらの結果を念頭に置いてください。
  • 個人またはプロジェクトレベルのものは読み込まれません。 ユーザー設定、フック、CLAUDE.md ファイル、MCP サーバー、その他のインストール済みプラグイン、メモリ、スキルは存在しません。プロジェクトスコープの設定もどこからも読み取られません。ワークスペースの上位からも内部からも、.claude/ ディレクトリ、CLAUDE.md、.mcp.json は読み込まれず、scaffold_script が書き込んだものであっても同様です。また、add_dirs のディレクトリは読み取りアクセスのみを付与します。シェル環境のほとんども保留されます。許可リストと EVAL_* 変数のみが実行に到達します。scaffold_script が提供できるのはファイルと Git の状態のみであるため、ケースが依存するスキル、エージェント、フック、MCP サーバーはテスト対象のプラグインに含めてください。
  • 管理ポリシーは引き続き実行を制限できます。 管理者がマシンに展開した管理設定の制限は実行内に適用されるため、管理マシン上の結果は、そのポリシーによって管理されていないマシンと異なる場合があります。
  • Artifact ツールはオフです。 アーティファクトを公開するスキルは、そのステップの前に生成するものについてのみグレード可能です。
  • ケース定義はエージェントから隠されています。 実行は eval ディレクトリを読み取ることができないため、Claude はケースのプロンプト、グレーダー、または兄弟ケースを見ることができません。
  • シェルコマンド外のネットワークサンドボックスはありません。 付与するシェルコマンドはサンドボックスのネットワークルールの下で実行されます。WebFetch(domain:…) 付与はそのドメインに直接到達し、プラグイン自体のフックと開始する実際の MCP サーバーは任意のホストに到達できます。

Eval スイートリファレンス

eval スイートに含めることができるものはすべて、プラグインの eval ディレクトリの下に配置されます。このディレクトリは、別のディレクトリを設定していない限り evals/ です。prompt.md または case.yaml を含むディレクトリはケースとみなされます。グレーダーが 1 つもないケースは、graders を示す invalid case.yaml エラーで読み込みに失敗します。このツリーは、claude plugin eval が eval ディレクトリ内で読み書きするすべてのファイルを示しています。

prompt.md フロントマター

prompt.md フロントマターは以下のフィールドを受け入れます。未知のキーはエラーです。

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: の下に配置されます。両方のファイルが存在する場合、prompt.md フロントマターは一致する case.yaml フィールドを上書きし、prompt.md 本文がプロンプトになり、graders/*.md は case.yaml にリストされたグレーダーの後に追加されます。 これらのフィールドは case.yaml にのみ存在します。

グレーダーフロントマター

graders/ の下のすべてのグレーダーファイルは、フロントマターでこれらのキーと、そのタイプのオプションを取得します。グレーダーの名前は .md なしのファイル名です。

グレーダーが見ることができるもの

regex グレーダーは target を取得し、llm グレーダーは focus を取得します。両方とも同じ値を受け入れます。

グレーダータイプ

以下の各グレーダータイプは、そのオプションと合格時を列挙しています。

モックファイル

mocks/<server>/ の下の <tool>.md ファイルは 1 つのツールに答えます。その本文はツール結果で、{{input.<field>}} と {{file:fixtures/<name>}} の置換があります。そのフロントマターは以下のキーを受け入れます。 2 つのオプションファイルがサーバーのディレクトリ内のツールファイルの横に配置されます。
  • _server.md: 複数のツールに答える単一の type: agent モック。その tools: フロントマターキーにリストされています。同じツール用の <tool>.md が優先されます。ここに expect: ガードを置くと、tools: に単一のツールしかリストされていない場合を除いて読み込みエラーになるため、ガードは個別の <tool>.md に配置してください
  • _tools.json: 実際のサーバーから保存された tools/list レスポンス。モック化されたツールが許可的なプレースホルダーの代わりに実際の説明と入力スキーマを持つようにします
ケース独自の mocks/ ディレクトリは同じレイアウトを使用し、スイートのモックをファイルごとに上書きします。

expect での正規表現パターン

expect: 内の /regex/ 値は、Claude Code がスイートの読み込み時にチェックする小さな方言を使用します。
  • リテラル文字、.、\d などのエスケープ、[a-z] などの文字クラス
  • 量指定子 *、+、?、および {m,n} 形式。それぞれ単一の文字、エスケープ、またはクラスに適用します
  • 先頭のオプションの ^ と末尾の $
  • フラグは i と s のみ
グループ、選択、後方参照、先読み・後読み、その他のフラグを含むパターンなど、この方言の範囲外のパターンがあると、ケースは読み込まれません。ケースのスコアは 0 になり、そのエラーにはパターンが示されます。複数の正確な値を許可するには、選択の代わりにリテラルのリストを記述してください。 各パターンは最大長までの値のみをチェックし、それより長い値は違反とみなされます。量指定子はその長さを短くし、先頭の ^ は長くするため、パターンは ^ でアンカーし、量指定子は少なくしてください。

トラブルシューティング

これらは著者が最も頻繁に遭遇する問題であり、表示される内容に基づいてキーが付けられています。

「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 を渡してください。実行がアクセスできるものを参照してください。

「is too old for claude plugin eval」

PATH 上の git が 2.31 より古いため、claude plugin eval はケースを実行する前に停止し、バージョンを名前付けするメッセージで 1 で終了しました。
各実行について、Claude Code は git フック、認証情報ヘルパー、およびリポジトリの git 設定が開始できるその他のプログラムをオフにします。これは git がバージョン 2.31 からのみ読み取る環境設定を通じて行われます。古い git はその設定を無視するため、スイートはそれらのプログラムが実行される可能性のある実行をスコアリングするのではなく停止します。git 2.31 以降をインストールしてスイートを再度実行してください。 v2.1.283 より前では、claude plugin eval は git バージョンをチェックしなかったため、古い git ではスイートはそれらのプログラムがオンのままで実行されました。

“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」

有効な eval ディレクトリの下に <case>/prompt.md または <case>/case.yaml が存在しないか、--case および --tag フィルターがケースと一致しません。プラグインルートから実行するか、claude plugin eval init を実行してスイートを作成してください。

ベースラインアームにプラグインが表示されない、またはデルタがゼロ

サマリーに W/OUT 列がない場合、またはケースが「ablation requested but no plugin resolved」で失敗する場合、通常の原因はケースのプラグインが見つからなかったことです。すべてのケースが context.history_file を通じてトランスクリプトを再開する場合は、列がないことは想定どおりです。これらのケースはデフォルトで 1 つのアームで実行されるためです。それ以外の場合は、plugins: ["../.."] をケースに追加し、ケースディレクトリからプラグインディレクトリへのパスを指定してください。 プラグインが読み込まれたにもかかわらず Δ がゼロに近く、tool_used: Skill グレーダーが失敗している場合、これは通常、スキルの description がプロンプトの表現でトリガーされていないことを意味する実際の発見です。説明を調整して、同じスイートを再度実行してください。

プラグインのエージェントの 1 つに対して「Agent type ’…’ not found」

デフォルトでは、各ケースはプラグインありとプラグインなしの両方で実行され、プラグインなしの実行はプラグインなしベースラインです。Claude がベースライン実行でプラグインのエージェントの 1 つをディスパッチする場合、Agent ツール呼び出しは Agent type '<plugin>:<agent-name>' not found. Available agents: ... で失敗します。リストは、組み込みサブエージェントなど、プラグインなしで存在するエージェントのみを名前付けします。 エラーは予期されています。Δ はプラグインの実行をベースラインと比較するためです。JSON 結果では、ベースライン実行は cases[].arms.without の下にあります。 プラグインが読み込まれた実行では、allowed_tools に Agent をリストするケースは、名前空間付きの名前でプラグインのエージェントの 1 つをディスパッチできます。たとえば、my-plugin という名前のプラグイン内の code-reviewer エージェントであれば my-plugin:code-reviewer です。ベースライン実行をスキップするには、--ablation none を渡してください。

正しいファイルが生成されたにもかかわらず、すべてがゼロスコアになる

グレーダーが files(作成されたパスのリスト)をターゲットにしているが、ファイルの内容を意図していました。{ source: file, path: <path> } を target または focus として使用してください。 別途、file_exists は実行中に作成されたファイルのみをカウントするため、スキャフォルドが作成したファイルまたは Claude が編集のみしたファイルは見えません。その内容をグレードするか、Edit で tool_used を使用してください。

トレース上の正規表現が表示されるテキストと一致しない

  • ターゲットが間違っている: デフォルトの target はトレースではなく last_message です。
  • JSON エスケープ: target を trace にする場合、行ごとに JSON であるため、引用符は \" として表示されます。
  • 正規表現構文: 正規表現は JavaScript 構文を使用するため、(?i) を記述するのではなく、flags に i を入れてください。

ツールが拒否される、MCP ツールが見つからない、または Bash が実行されない

読み取り専用セット以外のすべてのものには、--allow-tools Bash Write などの許可が必要です。個人用 MCP サーバーは実行中に読み込まれません。プラグイン自体のサーバーは、オプトインしない限り開始されず、それらのツールは --allow-tools "mcp__plugin_<plugin>_<server>__*" 許可も必要です。モック化されたツールはどちらも必要ありません。

実行が 1 で終了するが、結果は問題ないように見える

すべてのケースが --threshold 以上のスコアを取得したにもかかわらずコマンドが 1 で終了する場合、--json 指定時でも、stderr の行に原因が示されます。たとえば、ケースファイルの読み込みに失敗した場合や、実行が API エラーで終了した場合です。その他の原因については、終了コードを参照してください。 デフォルトの --threshold は 1.0 であるため、ケースが完璧未満のスコアを取得するとコマンドは 1 で終了します。必要なスコアに一致するしきい値を設定してください。

--json output path must end in .json

--json の後にターゲットを配置したため、出力パスとして読み取られました。claude plugin eval . --json のようにターゲットを最初に配置するか、--json に明示的な .json パスを指定してください。

グレーダーが 1.0 のスコアを取得した実行の下で passed: false を表示する

そのグレーダーは設計上、2 アーム実行でスコアから除外され、その scored フィールドは false です。プラグインなしベースラインと比較を参照してください。

“ended on an API error and scored 0 without grading”

この stderr 警告は、少なくとも 1 つの実行の最後のリクエストに対して、API がレート制限やプランの使用制限などの HTTP エラーで応答したことを意味します。このような実行はグレーダーの結果なしでスコア 0 となり、スコアや --threshold に関係なく、コマンドは 0 以外のコードで終了します。 修正するには、影響を受けた各実行のエラーを見つけ、それが報告する原因を解決してから、スイートを再度実行してください。
  • --json なしの場合: エラーは実行の進行状況の行の末尾、error: の後にあります
  • --json 指定時: エラーは JSON 結果の cases[].arms.with[].error または cases[].arms.without[].error にあります
このカウントにはベースライン実行も含まれます。ベースライン実行のスコアはケースの合否を決定しないため、すべてのケースが合格してもコマンドが失敗することがあります。2 アーム実行では、影響を受けたケースの W/OUT と Δ は — と表示されます。使用制限またはレート制限については、実行がスイートの途中で使用制限またはレート制限エラーで失敗するを参照してください。 v2.1.299 より前では、このような実行は生成されたものに基づいてグレード化されていました。

実行がスイートの途中で使用制限またはレート制限エラーで失敗する

使用制限またはレート制限エラーで終了した実行はグレード化されずにスコア 0 となり、コマンドは 0 以外のコードで終了します。スイートはそれでも完了し、partial としてマークされません。制限がリセットされた後に再度実行してください。制限内に留まる必要がある場合は、--runs 1 または --case フィルターを使用してください。

“mock call budget exceeded”

1 回の実行内のすべての type: agent モックは、ケースの max_turns の 4 倍という 1 つの呼び出し予算を共有します。デフォルトの 10 では 40 回の呼び出しです。.replay/ の記録から応答された呼び出しもカウントされ、ケースの mock budget 進行状況の行に予算が表示されます。予算を超えた呼び出しは、スコア 0 とこの理由で実行を中止させるため、エージェントモックを多数呼び出すスキルについては、ケースの max_turns を上げてください。

実行がタイムアウトするか、ターンキャップに達する

デフォルトは 10 ターンと 300 秒です。より多くを必要とするタスクの場合、ケースで max_turns と timeout_seconds を上げ、厳密な実行ごとの制限ではなく、--max-cost-usd をコスト上限として使用してください。

関連項目も参照