evalsmith-mcp について
evalsmith-mcpは、決定論的な指標で検索、エージェントのツール呼び出し、プロンプト変更を評価します。MCPクライアントのほか、コマンドライン、CI、GitHub Actionのワークフローにも対応します。
主な機能
- 01検索ランキング指標
- 02シード固定の設定比較
- 03エージェントのツール呼び出しトレース検査
- 04ゴールデンセットによるプロンプト回帰テスト
- 05複数形式のレポート
活用シーン
- 01検索設定の比較
- 02エージェントのトレースと期待する呼び出しの照合
- 03候補プロンプトのベースラインとのテスト
- 04評価しきい値によるCI変更のゲート
MCP 対応
MCP stdioまたはStreamable HTTPで、評価、設定比較、トレース検査、回帰検出、レポート生成のツールを提供します。MCPクライアントはリソースとしてサンプルデータセットを参照でき、用意されたプロンプトも利用できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y evalsmith-mcpEVALSMITH_JUDGE_BASE_URLOpenAI-compatible endpoint for the optional LLM judge (default: Ollama on localhost)EVALSMITH_JUDGE_MODELModel used by the optional LLM judgeEVALSMITH_JUDGE_API_KEYシークレットAPI key for the judge endpoint, if it needs oneLOG_LEVELpino log level; logs go to stderrローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
evalsmith は、検索器、プロンプト、エージェントを変更するたびに浮かぶ、次の4つの疑問に答えます。
- 検索の品質は十分ですか? qrels とランキング済みの実行結果から、recall@k、precision@k、nDCG@k、ヒット率、MRR を算出します。
- どの設定が優れていて、その差は実際に意味がありますか? シード付きのペア・ブートストラップ信頼区間を使って、2~3個の設定を順位付けします。
- エージェントは適切なツールを呼び出しましたか? トレースと期待される呼び出しを照合し、厳密または緩やかな順序指定や、引数マッチャーに対応します。
- プロンプトの変更で何かが壊れましたか? ベースラインと候補の出力をゴールデンセットでチェックします。
すべて決定論的に動作し、オフラインで実行できます。セカンドオピニオンとして LLM による判定機能もありますが、デフォルトでは無効で、判定を左右することはありません。結果はターミナルの表、Markdown、JSON、JUnit XML、または自己完結型の HTML レポートとして出力され、GitHub Actionでマージゲートを設定できます。

同じコアを介したインターフェース
flowchart LR
subgraph Clients
A[MCP client<br/>desktop app, IDE, agent]
B[Remote MCP client<br/>or service]
C[Terminal / CI job]
D[GitHub workflow]
end
subgraph evalsmith
S1[MCP server<br/>stdio]
S2[MCP server<br/>Streamable HTTP, stateless]
S3[CLI<br/>evalsmith run]
S4[GitHub Action<br/>uses: evalsmith-mcp@v0]
CORE[(src/core<br/>metrics, bootstrap, matchers,<br/>checks, gates, reports)]
end
A --> S1 --> CORE
B --> S2 --> CORE
C --> S3 --> CORE
D --> S4 --> CORE
S3 -. exit code + JUnit + HTML .-> C
S4 -. outputs + job summary .-> D
| インターフェース | エントリーポイント | 利用者 | 存在する理由 |
|---|---|---|---|
| stdio 経由の MCP | dist/mcp/server.js | デスクトップ MCP クライアント、IDE アシスタント、ローカルエージェント | アシスタントは会話の途中で実行結果を評価したり、設定を比較したり、トレースを監査したりでき、型付きの structuredContent が返されます。 |
| Streamable HTTP 経由の MCP | EVALSMITH_TRANSPORT=http | リモートクライアント、社内プラットフォーム、MCP Inspector | 同じツールをネットワーク経由で利用できます。ステートレスなため、保存するセッションはなく、水平スケーリングが可能です。 |
| CLI / CI | evalsmith run evalsmith.yaml | パイプラインとターミナル | --fail-under recall@5=0.8 により、メトリクスをマージゲートとして利用できます。終了コード、Markdown の概要、JUnit XML、HTML レポートが出力されます。 |
| GitHub Action | uses: diegoperezg7/evalsmith-mcp@v0 | GitHub ワークフロー | 同じゲートをステップとして利用でき、出力、ジョブの概要が得られ、インストールも不要です。 |
4 つすべてが src/core の同じ関数を呼び出します。MCP ツールは薄いアダプターです。Zod で入力を解析し、コアを呼び出して、出力スキーマに照らして検証された structuredContent を返します。
MCP の仕様
flowchart TB
subgraph Tools
T1[evaluate_retrieval]
T2[compare_configs]
T3[check_tool_calls]
T4[detect_prompt_regression]
T5[generate_report]
T6[run_suite]
end
subgraph Resources
R1["evalsmith://examples/{name}<br/>12 synthetic datasets + suite"]
end
subgraph Prompts
P1[compare_rag_configs]
P2[audit_agent_trace]
P3[review_prompt_change]
end
T1 -- structuredContent --> T5
T2 -- structuredContent --> T5
T3 -- structuredContent --> T5
T4 -- structuredContent --> T5
classDef tool fill:#ffedd5,stroke:#c2410c,color:#431407
classDef res fill:#e0f2fe,stroke:#0369a1,color:#082f49
classDef prom fill:#ede9fe,stroke:#6d28d9,color:#2e1065
class T1,T2,T3,T4,T5,T6 tool
class R1 res
class P1,P2,P3 prom
ツール
各ツールは入力と出力の Zod スキーマを宣言し、structuredContent と JSON テキストブロックを返します。また、readOnly かつ非破壊的として注釈されています。4 つのツールは冪等で、閉世界です。detect_prompt_regression と run_suite は開世界かつ非冪等として宣言されています。注釈はツールごとに設定され、ジャッジが有効な場合、これらのツールは外部モデルを呼び出し、その回答は変動する可能性があります。ジャッジを無効にした場合(デフォルト)は、ほかのツールと同様に動作します。
| ツール | 入力 | 出力 |
|---|---|---|
evaluate_retrieval | qrels、run、任意の k リスト | すべての k における平均再現率/適合率/nDCG/ヒット率、MRR、クエリごとの値、スキップされたクエリと不足しているクエリ |
compare_configs | qrels、2~3 件の {name, run}、主指標 metric、bootstrap {samples, seed, confidence} | 区間付きの順位、勝者、次点、差の対応あり区間、significant |
check_tool_calls | ログに記録された形式の trace(evalsmith、Anthropic Messages、OpenAI Chat または Responses)、expected、order: strict | lax | passed、スコア、期待される各呼び出しの一致位置と理由、予期しない呼び出し |
detect_prompt_regression | golden、baseline、candidate、任意の judge {enabled} | 判定、合格率、リグレッション、改善、ケースごとの失敗、有効時のジャッジ投票 |
generate_report | 上記の結果のいずれか、gates、format: markdown | json | junit | passed、レンダリングされたレポート |
run_suite | evalsmith.yaml への任意の config パス、gates、judge、format | passed、レンダリングされたレポート、およびスイートのファイルから読み込まれた各セクションの結果 |
run_suite は evalsmith run と同じスイートを実行するため、クライアントは会話に貼り付けずに、ファイル内のデータを評価できます。確認時にはシンボリックリンクをたどり、ワークスペースルート(デフォルトではサーバーの起動ディレクトリである EVALSMITH_ROOT)内のみを読み込みます。config が指定されていない場合は、同梱のサンプルスイートを実行します。
不正な入力(不明な指標、重複する設定名、関連文書のない qrels)は、モデルが対処できるメッセージを伴う InvalidParams ツールエラーとして返されます。ジャッジのエンドポイントが停止している場合、または HTTP エラーを返す場合は、InternalError になります。
リソース
evalsmith://examples/{name} は examples/datasets にある合成データセットを一覧表示して提供するため、クライアントは独自のデータを接続する前に、すべてのツールを試すことができます。
| 名前 | 内容 |
|---|---|
rag-corpus、rag-queries、rag-qrels | 架空の請求アプリのヘルプセンター記事20件、質問12件、評価済みの判定 |
rag-run-bm25、rag-run-hybrid、rag-run-hybrid-rerank | 3つの検索設定による上位10件のランキング |
agent-trace、agent-expected | 重複請求を返金するサポートエージェントと、実行すべき呼び出し |
prompts-golden、prompts-baseline、prompts-candidate、prompts-candidate-regressed | ゴールデンケース6件と、3組の出力 |
suite | サンプルの evalsmith.yaml |
プロンプト
| プロンプト | 引数 | モデルに求める内容 |
|---|---|---|
compare_rag_configs | metric | 設定を比較し、差を区間とともに報告して、最も弱いクエリを示します |
audit_agent_trace | order | トレースを確認し、失敗した各ステップに対する最小限の修正を提案します |
review_prompt_change | candidate | リグレッションを検出し、Markdown レポートを作成して、リリースするかどうかを判断します |
MCP クライアントとの会話
sequenceDiagram
autonumber
actor User
participant Host as MCP client (LLM host)
participant ES as evalsmith (stdio)
participant Core as src/core
User->>Host: "Is the reranker worth it on our help-center set?"
Host->>ES: initialize, tools/list, resources/list
ES-->>Host: 6 tools + JSON Schemas, 13 resources
Host->>ES: resources/read evalsmith://examples/rag-qrels (+ 3 runs)
ES-->>Host: qrels and runs as JSON
Host->>ES: tools/call compare_configs {metric: "ndcg@5", configs: [...]}
ES->>Core: compareConfigs(qrels, configs, "ndcg@5", {seed: 42})
Core-->>ES: ranking, intervals, paired delta
ES-->>Host: structuredContent {winner: "hybrid+rerank", significant: true, ...}
Host->>ES: tools/call generate_report {format: "markdown", comparison}
ES-->>Host: Markdown report
Host-->>User: "Yes: +0.153 nDCG@5 over hybrid, 95% CI [0.069, 0.251]."
メトリクス
クエリ $q$ の関連集合 $R_q$(グレードが $> 0$ のドキュメント)とランキング $D_q$($D_q^{k}$ は先頭の $k$ 件のドキュメント)に対して:
\mathrm{Recall@}k = \frac{|R_q \cap D_q^{k}|}{|R_q|}
\qquad
\mathrm{Precision@}k = \frac{|R_q \cap D_q^{k}|}{k}
\qquad
\mathrm{HitRate@}k = \mathbb{1}\left[\,R_q \cap D_q^{k} \neq \varnothing\,\right]
\mathrm{RR}_q = \frac{1}{\text{rank of the first relevant document}}
\qquad
\mathrm{MRR} = \frac{1}{|Q|}\sum_{q \in Q} \mathrm{RR}_q
\mathrm{DCG@}k = \sum_{i=1}^{k} \frac{\mathrm{rel}_i}{\log_2(i+1)}
\qquad
\mathrm{nDCG@}k = \frac{\mathrm{DCG@}k}{\mathrm{IDCG@}k}
$\mathrm{rel}_i$ はランク $i$ のドキュメントの段階的な判定(trec_eval と同様の線形ゲイン)で、IDCG は判定を降順に並べ替えた場合の DCG です。報告値は、判定済みクエリの平均です。
規約はすべてテストで網羅されています。
- 判定がすべて0のクエリはスキップされ、
skippedQueriesに列挙されます。 - 判定済みクエリが実行結果にない場合、スコアは0となり、
missingFromRunに列挙されます。 - Precision はランキングの長さではなく、$k$ で割ります。
- ランキング内で重複するドキュメント ID は最初の位置だけを残します。
trec_evalと同様に、関連ドキュメントを繰り返してスコアが1を超えることはありません。 - カットオフは1から始まります。
recall@0は拒否されます。
計算例(tests/core/retrieval.test.ts):判定 a=2, b=1, c=0、ランキング d, a, e, b, c。
DCG@5 $= 2/\log_2 3 + 1/\log_2 5 = 1.69254$、IDCG@5 $= 2/\log_2 2 + 1/\log_2 3 = 2.63093$ なので、nDCG@5 $= 0.64332$、recall@3 $= 0.5$、precision@5 $= 0.4$、RR $= 0.5$ です。
ブートストラップ。 compare_configs は、シード付き PRNG(mulberry32)を使って、クエリを復元抽出し、すべての設定で同じインデックスを使用して(ペア方式)、samples 回再サンプリングします。区間は、再サンプリングした平均値のパーセンタイルです。勝者と次点の差の区間がゼロを含まない場合、優位性は significant と判定されます。同じシードを使うと、どのマシンでも同じ区間が得られます。
ツール呼び出しマッチャー
{
"tool": "create_refund",
"args": {
"invoice_id": { "type": "exact", "value": "INV-2041" },
"reason": { "type": "any" },
"metadata": { "type": "subset", "value": { "ticket": "T-5532" } },
"to": { "type": "regex", "pattern": "@acme-robotics\\.example$" }
}
}
strict は、トレースが期待される呼び出しと順序まで完全に一致することを要求します。期待されるシーケンスを超える呼び出しがあるとチェックは失敗し、JUnit では失敗したテストケースとして表示されます。lax は順序を無視し、最大二部マッチング(増加路)によって期待される呼び出しとトレースの呼び出しを対応付けるため、緩いマッチャーが、より厳しいマッチャーだけが受け入れる唯一の呼び出しを奪うことはありません。余分な呼び出しは報告されますが、失敗にはなりません。exact を含むすべてのマッチャーは、引数がない場合に失敗します。
プロンプトのチェック
exact(デフォルトではトリミング)、regex、contains(デフォルトでは大文字と小文字を区別しません)、json_schema(出力を解析し、Ajv で検証します)、length(文字数のmin/max)。ベースラインでは成功し、候補では失敗するケースがリグレッションです。出力がない場合は失敗として扱われます。
オプションの判定機能は、両方の出力を OpenAI 互換の /chat/completions エンドポイント(Ollama を含む)に温度 0 で送信します。位置バイアスを避けるため、各ケースはベースラインを回答 A として、次に回答 B として、2 回判定されます。一方が勝者となるのは、どちらの順序でも結果が一致した場合のみです。一致しない場合は引き分けとして扱われます。ケースごとにリクエストが 2 回必要です。判定結果の横に投票内容が報告されます。
クイックスタート
npx -y evalsmith-mcp # MCP server on stdio
npm install -g evalsmith-mcp # or install the `evalsmith` CLI and `evalsmith-mcp` server
docker build -t evalsmith-mcp . && docker run --rm -i evalsmith-mcp # or run the server in a container
同梱の例とテストをソースから実行するには:
git clone https://github.com/diegoperezg7/evalsmith-mcp.git
cd evalsmith-mcp
npm ci # also builds dist/ through the prepare script
npx playwright install chromium # the HTML report tests open it in a real browser
npm test # metrics, traces, MCP in-memory + HTTP, CLI exit codes, HTML report, action
node dist/cli/index.js run examples/evalsmith.yaml
MCP クライアントに接続する(stdio)
ターミナルから:
claude mcp add evalsmith -- npx -y evalsmith-mcp # Claude Code
codex mcp add evalsmith -- npx -y evalsmith-mcp # Codex CLI
code --add-mcp '{"name":"evalsmith","command":"npx","args":["-y","evalsmith-mcp"]}' # VS Code
その他のデスクトップ MCP クライアントでは、次のような mcpServers ブロックを読み込みます(examples/mcp-client-config.json)。
{
"mcpServers": {
"evalsmith": {
"command": "npx",
"args": ["-y", "evalsmith-mcp"],
"env": { "LOG_LEVEL": "warn" }
}
}
}
クライアントを再起動し、compare_rag_configs プロンプトを試すか、evalsmith://examples/agent-trace を読み込んで確認するよう指示してください。
ストリーム可能な HTTP
EVALSMITH_TRANSPORT=http EVALSMITH_HTTP_PORT=3333 node dist/mcp/server.js
curl -s localhost:3333/healthz # {"status":"ok","version":"0.1.0"}
npx @modelcontextprotocol/inspector # connect to http://127.0.0.1:3333/mcp
| 変数 | デフォルト値 | 用途 |
|---|---|---|
EVALSMITH_TRANSPORT | stdio | stdio または http |
EVALSMITH_HTTP_HOST / EVALSMITH_HTTP_PORT | 127.0.0.1 / 3333 | HTTP バインドアドレス |
EVALSMITH_JUDGE_BASE_URL | http://localhost:11434/v1 | オプションの判定機能用 OpenAI 互換エンドポイント |
EVALSMITH_JUDGE_MODEL | llama3.1:8b | 判定モデル |
EVALSMITH_JUDGE_API_KEY | unset | ホスト型エンドポイントの場合のみ |
EVALSMITH_ROOT | current directory | run_suite がスイートとデータを読み込めるディレクトリ |
LOG_LEVEL | info | pino のログレベル。ログは常に stderr に出力されます |
CLI と CI
evalsmith run <config> [--fail-under metric=value ...] [--format table|json|markdown|html]
[--report file.{md,json,xml,html}] [--report-format markdown|json|junit|html]
evalsmith doctor [config] [--judge]
ゲートでは、recall@k、precision@k、ndcg@k、hit_rate@k、mrr、tool_calls(check_tool_calls のスコア)、prompt_pass_rate を指定できます。YAML ファイル内のゲートも適用されます。同じ名前のコマンドラインゲートがある場合は、そちらが優先されます。プロンプトのリグレッション、またはツール呼び出しチェックの失敗があると、ゲートを指定していなくても実行は失敗します。
| 終了コード | 意味 |
|---|---|
0 | すべてのゲートに合格し、リグレッションもありません |
1 | ゲートの値がしきい値を下回る、候補でリグレッションが発生する、またはツール呼び出しが一致しない |
2 | 使用方法のエラー、無効な設定、不明なメトリクス、読み取り不能なデータセット、ジャッジのエンドポイント停止 |
実際の出力
バンドルされたデータセット(examples/evalsmith.yaml)での node dist/cli/index.js run examples/evalsmith.yaml の実行結果:
evalsmith · ledgerly-support-assistant
Retrieval (12 queries, MRR 0.8403)
┌────┬────────┬───────────┬────────┬──────────┐
│ k │ recall │ precision │ nDCG │ hit rate │
├────┼────────┼───────────┼────────┼──────────┤
│ 1 │ 0.4583 │ 0.7500 │ 0.6667 │ 0.7500 │
│ 3 │ 0.7500 │ 0.4167 │ 0.7442 │ 0.9167 │
│ 5 │ 0.9167 │ 0.3000 │ 0.8059 │ 1.0000 │
│ 10 │ 1.0000 │ 0.1667 │ 0.8285 │ 1.0000 │
└────┴────────┴───────────┴────────┴──────────┘
Comparison on ndcg@5 (paired bootstrap, 2000 samples, seed 42)
┌───┬───────────────┬────────┬──────────────────┐
│ # │ config │ ndcg@5 │ 95% CI │
├───┼───────────────┼────────┼──────────────────┤
│ 1 │ hybrid+rerank │ 0.9588 │ [0.8950, 1.0000] │
│ 2 │ hybrid │ 0.8059 │ [0.6875, 0.9141] │
│ 3 │ bm25 │ 0.5596 │ [0.3782, 0.7354] │
└───┴───────────────┴────────┴──────────────────┘
hybrid+rerank wins on ndcg@5 (0.9588), +0.1528 over hybrid; 95% interval of the gap [0.0692, 0.2506] excludes zero.
Agent tool calls (strict)
┌──────────────────┬─────────┬────────┬───────┐
│ expected │ matched │ status │ notes │
├──────────────────┼─────────┼────────┼───────┤
│ search_customers │ #1 │ pass │ │
│ get_invoice │ #2 │ pass │ │
│ create_refund │ #3 │ pass │ │
│ send_email │ #4 │ pass │ │
└──────────────────┴─────────┴────────┴───────┘
All 4 expected call(s) matched (strict order).
Prompt regression
┌───────────────────────┬──────────┬───────────┬────────────────────┐
│ case │ baseline │ candidate │ candidate failures │
├───────────────────────┼──────────┼───────────┼────────────────────┤
│ classify-intent │ pass │ pass │ │
│ extract-invoice-id │ pass │ pass │ │
│ refund-policy-summary │ fail │ pass │ │
│ due-date-format │ pass │ pass │ │
│ refuse-card-number │ pass │ pass │ │
│ refund-payload │ pass │ pass │ │
└───────────────────────┴──────────┴───────────┴────────────────────┘
No regressions across 6 case(s). Pass rate 83.3% -> 100.0%.
Gates
┌────────────┬────────┬────────┬────────┐
│ metric │ min │ actual │ status │
├────────────┼────────┼────────┼────────┤
│ recall@5 │ 0.8000 │ 0.9167 │ pass │
│ ndcg@5 │ 0.7500 │ 0.8059 │ pass │
│ tool_calls │ 1.0000 │ 1.0000 │ pass │
└────────────┴────────┴────────┴────────┘
PASS
基準を引き上げると、同じ実行でビルドが失敗します:
$ node dist/cli/index.js run examples/evalsmith.yaml --fail-under recall@5=0.95 --fail-under mrr=0.9 --report report.xml
...
Gates
┌────────────┬────────┬────────┬────────┐
│ metric │ min │ actual │ status │
├────────────┼────────┼────────┼────────┤
│ recall@5 │ 0.9500 │ 0.9167 │ FAIL │
│ ndcg@5 │ 0.7500 │ 0.8059 │ pass │
│ tool_calls │ 1.0000 │ 1.0000 │ pass │
│ mrr │ 0.9000 │ 0.8403 │ FAIL │
└────────────┴────────┴────────┴────────┘
FAIL · 2 gate(s) below threshold
Report written to report.xml
$ echo $?
1
HTML レポート
--report report.html(または標準出力への --format html)を指定すると、オフラインで開ける、システムのライトモードまたはダークモードに対応した単一の HTML ファイルに実行全体が出力されます。
- 判定と、値、しきい値、ステータスを示すゲートごとのカード
- k ごとの検索メトリクスを、クエリに対するブートストラップ区間付きの棒グラフで表示し、ゲートのしきい値も表示
- 区間、勝者、次点との差を含む設定の比較
- 期待されるツール呼び出しと実際のツール呼び出し。一致したペアにはリンクが付き、不一致は明示されます
- ゴールデンケースごとのベースラインと候補の比較。失敗したチェックはワンクリックで確認できます

ダークモードと、開いた状態のプロンプトリグレッション


データセットのテキスト(ケース ID、ツール名、失敗メッセージ)は、実行不可能な <script type="application/json"> ブロックに JSON として埋め込まれ、textContent のみを使って描画されます。Content-Security-Policy によりネットワークアクセスは許可されず、ページ自身のスクリプトのみがハッシュで許可されます。テストでは、マークアップが大量に含まれるレポートを Chromium で開き、そこから何も実行されないことを確認します。npm run docs:screenshots を実行すると、上記の画像が再生成されます。
GitHub Action
- uses: actions/checkout@v5
- uses: diegoperezg7/evalsmith-mcp@v0
id: evals
with:
config: evals/evalsmith.yaml
fail-under: |
recall@5=0.8
ndcg@10=0.7
tool_calls=1
html-report: evalsmith-report.html
ゲートがしきい値を下回った場合、プロンプト候補の性能が低下した場合、またはツール呼び出しが一致しない場合、このステップは失敗し、判定結果を含む Markdown レポートをジョブサマリーに書き込みます。インストール手順もシェルも不要で、バンドルされた node24 スクリプトから CLI と同じコアを実行します。examples/github-workflow.yml は、HTML レポートをアーティファクトとして保持し、JUnit XML をチェック実行として公開する、完全なワークフローです。
| 入力 | デフォルト | 説明 |
|---|---|---|
config | evalsmith.yaml | スイートファイルです。ファイル内のデータセットパスは、このファイルからの相対パスです |
fail-under | 1 行につき 1 つの metric=value を指定します。スイートファイルのゲートに追加され、同名のゲートを上書きします | |
report-file | レポートファイルです:.md、.json、.xml(JUnit)、または .html | |
report-format | 拡張子から取得 | markdown、json、junit、または html |
html-report | 自己完結型 HTML レポートのパス | |
upload-summary | true | Markdown レポートをジョブサマリーに追加します |
| 出力 | 説明 |
|---|---|
verdict | pass または fail |
failed-gates | しきい値を下回ったゲート |
metrics | JSON 形式の検索メトリクス。例:fromJSON(steps.evals.outputs.metrics)['recall@5'] |
mrr | 検索実行の MRR |
tool-calls | ツール呼び出しのスコア(一致数/期待数) |
prompt-pass-rate | 正解データセットにおける候補の合格率 |
prompt-regressions | ベースラインでは合格し、候補では不合格となるケース |
winner | 比較で勝った構成 |
report-file | report-file のパス。指定されていない場合は空です |
html-report | HTML レポートのパス。指定されていない場合は空です |
スイートに存在しないセクションの出力は空になります。ログに出力されるデータセットのテキストは ::stop-commands:: で囲まれるため、ケース ID やツール名がワークフローコマンドを実行することはありません。CLI と同様に、判定処理はステップ環境から EVALSMITH_JUDGE_* を読み込みます。
このアクションを使わなくても、どの CI からでも CLI で同じ処理を実行できます。
npx evalsmith run evals/evalsmith.yaml --fail-under recall@5=0.8 --format markdown --report evalsmith-report.xml >> "$GITHUB_STEP_SUMMARY"
スイートファイル
name: ledgerly-support-assistant
retrieval:
qrels: datasets/rag/qrels.json # { queryId: { docId: grade } }
run: datasets/rag/runs/hybrid.json # { queryId: [docId, ...] }
k: [1, 3, 5, 10]
compare:
metric: ndcg@5
configs:
- { name: bm25, run: datasets/rag/runs/bm25.json }
- { name: hybrid, run: datasets/rag/runs/hybrid.json }
- { name: hybrid+rerank, run: datasets/rag/runs/hybrid-rerank.json }
bootstrap: { samples: 2000, seed: 42, confidence: 0.95 }
agent:
trace: datasets/agent/trace.json
expected: datasets/agent/expected.json
order: strict
prompts:
golden: datasets/prompts/golden.json
baseline: datasets/prompts/baseline.json
candidate: datasets/prompts/candidate.json
judge: { enabled: false }
gates:
recall@5: 0.8
ndcg@5: 0.75
tool_calls: 1.0
すべてのセクションは省略可能です。パスは YAML ファイルからの相対パスです。
ragcompass との組み合わせ
ragcompass はコーパスのプロファイルを作成し、RAG パイプラインの設定(パーサー、チャンク分割、top-k、ハイブリッド検索、再ランキング)を推奨します。evalsmith は、その構成が期待どおりに機能するかを確認します。
flowchart LR
A[Documents] --> B[ragcompass analyze<br/>recommended configs]
B --> C[Index 2-3 candidate configs]
C --> D[Run the eval queries<br/>save rankings]
D --> E[evalsmith compare_configs<br/>winner + intervals]
E --> F[evalsmith run in CI<br/>--fail-under gates]
設計上の判断
- まず決定論的に。 メトリクス、マッチャー、チェックは、手計算によるテストを備えた純粋関数です。判定を得るためにモデルは不要なので、実行ごとに結果が変わることはなく、有料の API キーも必要ありません。
- Judge はデフォルトで無効です。 有効にすると、OpenAI 互換のエンドポイント(ローカルの Ollama も利用可能)を経由し、その投票は判定を変更せず、判定と並べて表示されます。
- 平均値だけでなく、区間も。 12 件のクエリでは、0.03 の差が決定的に見えてしまうことがあります。固定シードを使った対応ありブートストラップにより、不確実性を可視化し、再現可能にします。
- ステートレス HTTP を適切に実装。 ステートレスな
StreamableHTTPServerTransportはリクエスト間で再利用できないため、POST ごとに専用のサーバーとトランスポートを作成します。登録処理は軽量で、実際の HTTP 経由で連続して 2 回呼び出すテストにより、これを検証します。 - stdout はプロトコル専用です。 pino は stderr に書き込み、ESLint は
src/でのconsoleの使用を禁止しているため、余計なバイトによって stdio トランスポートが壊れることはありません。CLI は結果の出力にのみ stdout を使用します。 - 1 つのスキーマを 3 つの用途に。
src/core/schemas.tsの Zod スキーマは、MCP 入力の検証、クライアントが参照する JSON Schema の生成、コアの型定義に使用されます。
プロジェクト構成
src/
core/ metrics, bootstrap, tool-call matchers, prompt checks, judge, gates, reports (incl. HTML), suite runner
mcp/ server (stdio + HTTP), tools/, resources/, prompts/
cli/ evalsmith run | doctor, table/json/markdown/html output
action/ GitHub Action entry point, bundled into dist/action
shared/ config (Zod), pino logger on stderr, MCP errors
tests/
core/ hand-computed metrics, bootstrap, matchers, checks, reports, HTML in Chromium
mcp/ InMemoryTransport client and real Streamable HTTP client
cli/ exit codes 0 / 1 / 2, JUnit file, doctor
examples/
datasets/ synthetic RAG corpus + qrels + 3 runs, agent trace, golden prompts
evalsmith.yaml, github-workflow.yml, mcp-client-config.json
npm run check # typecheck + eslint + prettier + vitest
npm run inspect # MCP Inspector against the built stdio server
リリースはバージョンタグから作成されます。 release.yml は、provenance 付きで npm、MCP Registry、GitHub Releases に公開し、アクションはリリースから Marketplace に公開されます。アクションのバンドルや v0 タグを含む手順については、docs/RELEASING.md を参照してください。変更内容は CHANGELOG.md に記載されています。
ライセンス
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。