エージェント評価 — ベンチとハーネスの作法
エージェントのスコアは「モデルの点」ではなく「モデル+ハーネス+環境+採点規則の点」です。SWE-benchの1件がどんな部品でできているか、手数が伸びると一手の差がなぜ桁で効くか、リポジトリやネットワークから答えが漏れる四つの経路、そして部分点を安全に設計する条件までを1から扱います。
SWE-bench: Can Language Models Resolve Real-World GitHub Issues?
一次資料 — この記事の根拠
この解説の公開 2026-08-27
SWE-bench: Can Language Models Resolve Real-World GitHub Issues?arXiv:2310.06770論文ページ·PDFSWE-agent: Agent-Computer Interfaces Enable Automated Software EngineeringarXiv:2405.15793論文ページ·PDF
「SWE-bench で50%」は何を言っているのか
発表資料に「SWE-bench Verified 50%」と書いてあったとします。素直に読めば「実際のGitHubのバグの半分を直せる」です。ところがこの数字は、モデル単体の性能ではありません。モデル・足回り(ハーネス)・作業環境・採点規則の四点セットで初めて決まる数字で、そのうち三つは棒グラフには出てきません。
比喩は採用試験です。四択の筆記で満点を取る人と、リポジトリを渡されて「このバグ直しておいて」で結果を出す人は、別の能力を測られています。後者で効くのは、テストの回し方を知っているか、直したついでに別の機能を壊さないか、詰まったときに引き返せるか。エージェント評価が測ろうとしているのはこの後者で、だから測り方そのものが設計対象になります。
ベンチマークを読むときの三つの問い — 何を測ったか、どう採点したか、問題が漏れていないか — は、エージェントでもそのまま必要です。その上に、これから見る三つが積み増しになります。
一問一答と違う三つのこと
1. 環境がある。 四択問題の入力は文字列ですが、エージェントの入力はリポジトリであり、シェルであり、ファイルシステムです。しかも入力が大きいだけでなく、エージェントは入力を書き換えられます。極端な話、落ちているテストを削除して「全部通りました」と報告できてしまう。採点する側は、環境の初期状態と最終状態の両方を管理しなければなりません。
2. 手数がある。 一発の生成なら成否は1回の勝負ですが、エージェントは何十手も打ちます。一手あたりの成功率を 、必要な手数を とすると、完走できる確率はこうなります。
は 手目で破綻しない確率、 は最後まで行くのに必要な手数、 は完走する確率です。要するに、一手ごとの生存率を全部掛け算したものが完走率という、当たり前の式です。
当たり前でなくなるのは数を入れたときです。一手99%で50手なら 、95%なら 。一手あたり4ポイントの差が、完走率では8倍近い差になります。逆側から見ると、完走率という一つの数字だけを眺めていても、どの一手が足りていないのかは永遠に分かりません。
3. 副作用がある。 四択の採点は答え合わせで終わりますが、エージェントは外に書き込みます。ファイルを消し、コマンドを叩き、APIを呼ぶ。評価環境が本番の認証情報を持っていた、という事故は採点以前の問題として起きます。エージェントの評価環境は、壊れてよい使い捨ての箱として作るのが前提です。
SWE-benchの1件を開ける
SWE-bench(Jimenez et al., 2023)は、実在のGitHub issueと、それを閉じた実際の修正コミットから機械的に作られたベンチマークです。12個のPythonリポジトリから集めた2,294件のタスクからなり、1件はこんな部品でできています。
{
"repo": "django/django",
"base_commit": "…", // 修正が入る直前の状態。ここから作業を始める
"problem_statement": "…", // issue本文。モデルに渡してよいのは原則ここだけ
"patch": "…", // 人間が実際に書いた修正(正解・モデルには見せない)
"test_patch": "…", // その修正と一緒に入ったテスト
"FAIL_TO_PASS": ["…"], // 修正前は落ち、修正後に通るべきテスト
"PASS_TO_PASS": ["…"] // 修正の前後どちらでも通り続けるべきテスト
}
設計の勘所は、正解を「人間のパッチとの一致」で測っていないことです。同じバグの直し方は何通りもあるので、文字列で比べれば正しい修正も不正解になります。代わりに置かれたのが実行による検証で、FAIL_TO_PASS が「直っていること」を、PASS_TO_PASS が「壊していないこと」を担当します。この二本立てが、動くけれど別の機能を巻き添えにするパッチを弾きます。
派生セットの名前も押さえておきます。Lite(300件)は評価を回しやすいものを選び直したサブセット、Verified(500件)は人手で1件ずつ確認し、issue本文だけでは仕様が定まらない問題や、テストが厳しすぎて正しい修正でも落ちる問題を除いたものです。数字を比べるときは、まずどのセットの数字かを確認します。母集団が違えば、同じ「50%」は別の量です。
resolved の定義は、論理積である
SWE-benchの主指標 resolved(解決率)は、1件ごとに0か1です。
と はさきほどの FAIL_TO_PASS と PASS_TO_PASS、 は「そのすべてについて成り立つ」、 はテスト が通ったかどうかです。要するに、直すべきテストが全部通り、かつ壊してはいけないテストが1つも落ちなかったときだけ1点、それ以外は0点。
この二値性は評価としては誠実です。八割方直った修正は、利用者から見れば直っていません。ただし開発の計器としては粗すぎて、「惜しかった」と「そもそも環境構築で終わった」が同じ0点になります。ここが部分点の設計動機で、後で扱います。
コメント
コメントにはログインが必要です