EvalArc:スコアが上がったとき、エージェントはどこで退行したのか

エージェント評価の 2 回の実行をチェック単位で比べ、平均スコアの上昇に隠れた回帰を見つけます。Inspect AI などに対応し、採点器も監査できます。

EvalArc は、AI エージェント(agent)の評価結果をレビューするための Python 製コマンドラインツールです。総合スコアではなく、case ごと、チェック項目ごとに 2 回の実行を比較し、事前に明記した受け入れ基準で判定したうえで、第三者が生の記録から再計算できるレポートを出力します。想定しているのは、平均スコアが上がった一方で、以前は合格していたチェックが失敗し始めたという状況です。総合スコアだけを見ていると、この種の回帰は見逃されてしまいます。

具体例

リポジトリに付属するデモは、模擬的なカスタマーサポートのチケット処理タスク(support-routing)です。新しいバージョンでは、スコアが 90% から 93.75% に上がりました。2 つのチェックが改善し、以前は合格していた 1 つのチェックが失敗に変わっています。原因はツール呼び出しの記録にありました。あるツール呼び出しは実際にはメモを書き込んでいたのにエラーを返し、エージェントが新しい冪等キーで再試行したため、同じメモが 2 回書き込まれたのです。この case のスコアは 0.9375 ですが、厳格なメモのルールでは受け入れ基準を満たさないと判定されます。EvalArc のトラジェクトリビューには、このエラー、この再試行、それに伴って生じた状態の変化が 1 つずつ表示されます。

採点はホスト側に残った最終的なチケットの状態だけに基づき、候補プログラムが自ら「成功」と主張しても考慮されません。1 つの case が解決済みとみなされるのは、すべてのチェックに合格した場合だけです。

手元の評価結果に使う

evalarc diff は、2 つの Inspect AI ログ、promptfoo の --output ファイル、または JUnit XML を読み込み、case ごとに各チェックを対応づけて比較します。ベースラインで合格していたチェックが失敗した、合格率が下がった、スキップされた、消えた、のいずれかに該当すると、コマンドは終了コード 1 で終わり、2 つの入力のコピーを添えたオフラインのレポートを出力します。リポジトリに記録された Inspect の例では、accuracy が 0.625 から 0.8125 に上がる一方で、3 つのチェックが合格しなくなっています。GitHub Action も用意されており、PR 上で直接マージを止められます。

- uses: noteflowai/evalarc@v0.16.0 # または完全なコミット SHA
  with:
    baseline: evals/baseline.json
    current: results/current.json

リポジトリには、実際のモデル構成の変更記録も公開されています。Qwen/Qwen3-8B(BF16)と Qwen/Qwen3.8-27B-FP8 を比較したもので、公開されているカスタマーサポートの計画立案 case 8 件について、構成ごと・case ごとに 3 回ずつ生成し、48 件の生の回答をすべて保存して、pytest ネイティブのチェックで採点しています(記録に使ったハードウェアは NVIDIA L40S)。完全な計画の一致数は 15/24 から 19/24 に増えましたが、5 つのチェックが退行し、5 つが不安定になったため、アップグレードのゲートは不合格と判定されました。README では、これら 10 件のブロッキングチェックが 2 種類の形式上の問題を共有していることも説明しています。already-closed の回答で actions フィールドが抜けていたことと、resolved-bug で JSON が Markdown のコードブロックに包まれていたことが 2 回あったことです。つまり、失敗の原因が 10 個独立してあるわけではありません。作者は、これが小規模な開発用の例にすぎず、モデルのランキングではないことも明記しています。2 つのモデルはアーキテクチャ、パラメータ数、量子化方式がいずれも異なり、データ汚染の除去も行っていません。

採点器そのものを監査する

EvalArc のもう半分の役割は、採点器が既知の欠陥を検出できるかどうかを検証することです。参照実装と、意図的に欠陥を埋め込んだ複数のバージョンを用意し、それぞれの欠陥が想定した評価軸で検出されるかを確認します。組み込みのタスクパックは 3 つです。

タスク内容宣言された欠陥1 つの case だけで検出
durable-kvコーディングの成果物:レスポンス、トランザクション、再起動後の永続化83
support-routing模擬チケットツール:ルーティング、メモ、クローズ、無関係な状態72
robot-evidence-review出典付きの記録:座標、クロック、欠落した観測61

保存済みの監査では、宣言された欠陥 21/21 件をすべて検出しました。そのうち 6 件は 1 つの case だけで検出されており、その case を削除すると見逃すことになります。コーディングタスクはシードごとに 15 case で、6 つの重み付き評価軸(基本動作 25%、検証 15%、トランザクション 20%、CAS 15%、永続化 15%、クラッシュリカバリ 10%)に分かれています。「真偽値と数値を等しいとみなす」という欠陥は 0.925 の部分点を得ますが、完全解決にはなりません。部分スコアと受け入れ判定は別々に計算されるからです。期待値は候補のコンテナの外で計算され、採点器は候補プログラムが報告する reward を決して採用しません。

試し方

オンラインデモ(noteflowai.github.io/evalarc)は保存済みの Docker 実行を再生するもので、インストールもアカウントもモデルのキーも不要です。ローカルへのインストール(Python 3.11 以降):

python3 -m venv .venv
. .venv/bin/activate
python -m pip install evalarc==0.16.0
evalarc --version

オフラインでの再検証には Docker、Node、GPU、モデル API のいずれも不要で、手順は docs/first-review.md にあります。整合性を検証するコマンドは終了コード 0 で、比較コマンドは回帰があるため終了コード 1 で終わります。参照実装と 8 つのコーディング欠陥を実際に実行するには Docker が必要です。

docker pull python:3.12-slim
evalarc audit --seeds 17 41 97 --output runs/audit

終了コード 0 は参照実装が合格し、すべての欠陥が想定した評価軸で検出されたこと、1 は監査または候補が失敗したこと、2 は入力が無効か環境に障害があることを示します。自分のコーディングエージェントを評価するには、まず evalarc init workspace/durable-kv でワークスペースを生成し、TASK.md をエージェントに渡します。変更が終わったら evalarc evaluate を実行します。

制約と注意点

  • ステータスは Research preview で、現在のバージョンは 0.16.0(2026-09-28)、MIT ライセンスです。ローカルのワークフローは Linux のみに対応し、Python のコア部分にはサードパーティのランタイム依存がありません。
  • 検出結果が成り立つのは、宣言された欠陥、選んだ case、記録された実行条件の範囲内だけです。未知の欠陥に対するカバー率も、reward hacking への耐性も示すものではありません。乱数シードを変えただけでは、独立した held-out 評価にはなりません。
  • EvalArc 自体は LLM を呼び出さず、モデルの認証情報も設定しません。トラジェクトリのインポートは限られたエクスポート形式だけを受け付け、任意のクラウドのエクスポートには対応していません。README には、AgentCore のオンライン評価は実施していないと明記されています。
  • --backend local --trust-local は現在のユーザーの権限で候補プログラムを実行します。信頼できない候補を隔離するには Docker を使ってください。
  • 公開されている小規模な GPU 実験は、ほとんどが否定的または結論の出ない結果です。たとえば公開 SWE タスク 3 件での 36 回の試行では、ネイティブの受け入れ判定を得たものは 1 回もなく、そのうち 5 回は上流のインフラ側のフラグにより「結論なし」として記録されました。作者はこれらを開発用の実験として残しているだけで、何らかの効果を主張してはいません。

リンク