テストが全部通っても移行は失敗する。SWE Refactor Benchが暴いたAI開発の盲点
長年使ってきたCのライブラリをRustへ移したい。AIエージェントに任せたところ、ビルドは成功し、用意したテストも全部緑になりました。ここまで見れば、移行は成功したように思えます。
ところが中身を開くと、Rust側は元のC実装を呼び出す薄いラッパーにすぎない。あるいは、ファイルの拡張子だけ変え、実質的には同じ仕組みを残している。動作確認は通っても、古い技術を外すという仕事は終わっていません。
2026年8月に公開されたSWE Refactor Benchは、この見落としを真正面から測ったベンチマークです。20件の全リポジトリ移行に8つの先端モデルを挑ませ、合計520回を評価しました。すべての段階を通過したのは28回、わずか5.4%でした。20件中13件は、どのモデルも最後まで通せませんでした。
驚くべき点は、AIがコードを書けなかったことだけではありません。「移行を本当に終えたか」と「元の挙動を保ったか」が別々に失敗していたことです。テスト合格をゴールにした瞬間、評価そのものが仕事の半分を見失う。この論文が突きつけるのは、モデル性能より先に受け入れ条件を設計せよ、という実務的な警告です。
バグ修正のテストを、そのまま移行へ持ち込めない
一般的なバグ修正では、最初に失敗するテストがあります。修正後にそのテストが通れば、少なくとも狙った不具合へ働きかけた証拠になります。赤から緑への変化には意味があります。
全リポジトリ移行は事情が違います。移行前のシステムは、すでに動いています。元のリポジトリへ既存テストをかければ、当然ほとんどが通ります。そのため、エージェントが何も変えずに提出しても、挙動だけを測るテストでは満点を取れてしまいます。
論文はこの盲点をBlindnessと呼びます。これはエージェントが意地悪く抜け道を探したという話に限りません。評価側が「元と同じように動くか」しか見ていないため、「古いstackが消えたか」を観測できない構造的な問題です。
テストケースを1,000件から10万件へ増やしても、この穴は埋まりません。元の実装は、そのすべてを最初から通るからです。挙動保存と移行完了は、別の証拠で確かめる必要があります。
20件の仕事は、関数の書き換えではなくシステム移行
SWE Refactor Benchが扱うのは、小さな関数の置換ではありません。SQLite、zlib、libsodium、GraphHopperなど、実在するopen-source基盤を含む20件の全リポジトリ移行です。
内訳は、言語書き換え7件、framework移行7件、platform移植3件、build toolchain移行3件です。例として、CからRust、JavaScriptからTypeScript、VueからReact、POSIXからwasm32-wasi、AutotoolsからCMake、MavenからGradleといった仕事が含まれます。
対象sourceは合計867,062行。1タスクに与えられる時間は6時間から30時間です。エージェントはnetworkなしのcontainerで、元リポジトリと移行先のtoolchain、指示を受け取り、自律的に読み、計画し、書き換え、buildし、debugし、検証します。
ここで求められるのは、コードを新しい言語で書けることだけではありません。外部API、終了status、install後のfile構成、export symbol、HTTP responseなど、下流利用者が観測する振る舞いを保ったまま、古いstackをbuild経路から外す必要があります。
つまり成功条件は二つです。
- 移行先のstackで成果物がbuildされ、旧stackがsourceとbuild closureから消えている。
- 移行後の観測可能な挙動が、元システムと一致している。
どちらか片方では足りません。「Rustで動いたが挙動が変わった」も、「挙動は同じだが実はCを呼んでいる」も、移行としては失敗です。
三段階評価で、完了、既知挙動、未知差分を分ける
この二つの成功条件を測るため、SWE Refactor Benchは評価を三段階に分けています。
第一段階はMigration Auditです。旧sourceが残っていないか、旧compilerがbuildへ入っていないか、新しいstackが主実装になっているかなど、リポジトリごとの狭い基準を確認します。一項目でも落ちれば、その提出はここで失格です。
第二段階はBehavioural Testsです。元システムから記録した130,118件の固定チェックを実行します。平均では1タスク6,000件を超えます。移行後の成果物をdrop-in replacementとして扱うため、一つでも失敗すれば次へ進めません。
第三段階はAgentic Verificationです。固定テストを書いた人が思いつかなかった差を探すため、6体のcoding agentが元と移行後の二つのtreeを比較します。各agentには1時間が与えられます。受理される反例は説明文ではなく、元では通り、移行後だけ失敗し、3回再現できる実行テストです。
この三段階は、同じ失敗を重複して数えているのではありません。第一段階は「仕事をしたか」、第二段階は「知っている挙動を壊していないか」、第三段階は「まだ知らない差を見つけられるか」を見ています。

520回のうち、三段階すべてを通ったのは28回
実験では8つの先端モデルを26のmodel-effort構成で動かし、各構成が20タスクへ1回ずつ挑戦しました。合計は520実行です。
Migration Auditを通ったのは340件、65.4%でした。移行そのものは、多くの実行で始められています。しかし固定チェックをすべて通し、かつ移行も完了して第三段階へ進めたのは88件です。最後に6体の検証agentをすべて振り切ったのは28件、全体の5.4%でした。
失敗は対照的な二群に分かれます。
- 30件は固定チェックをすべて通したのに、移行を完了していませんでした。
- 252件は移行を完了したものの、元の挙動を壊していました。
この数字は、完了確認と回帰確認を一つのscoreへ混ぜる危険をよく表しています。片方だけを見れば、もう片方の失敗へ高得点を与えてしまいます。
最良構成はclaude-opus-5のxhigh effortで、scoreは47.0 / 100、20件中5件が受理されました。次点のgpt-5.6-solは最良構成で28.5でした。model名の順位より重要なのは、最良でも半分に届かなかったことです。
99%まで行けても、最後の1%が製品を止める
移行を完了した340実行だけを見ると、58%は固定チェックの99%まで到達しました。一見すると、かなり仕上がっています。しかし100%を通したのは26%でした。
99.9%から100%へ届く最後の一歩だけで、35件が脱落しています。libraryが1,000回に1回だけ間違うとしても、その1回に当たる下流利用者には100%の障害です。移行は平均点ではなく、互換性の境界で壊れます。
さらに、固定チェックを100%通して第三段階へ進んだ88件のうち、60件では検証agentが反例を見つけました。例えば、HTTP headerの区切り方、timestampで小数点の代わりにcommaを受け付ける挙動、SQLiteが特定mode変更時に補助fileを削除する挙動など、元実装の細かな癖が差として表れました。
固定テストは、作者が先に思いついたことを測れます。agentic verifierは、提出物を見た後から弱点を探します。この順番の違いが、見つかる不具合の種類を変えています。
言語移行が難しく、build変更は比較的進みやすい
移行の種類によっても差が出ました。build toolchain移行はMigration Audit通過率80.8%、平均score 31.4でした。一方、言語書き換えはAudit通過率54.9%、平均score 5.6です。
build toolchain変更は、成果物の外形と元sourceの大部分を保ちながら、生成経路を置き換えます。それでもpackage、symbol、install treeまで合わせる必要はありますが、言語そのものを変えるより守る対象が見えやすい傾向があります。
言語書き換えでは、ownership、memory管理、例外、型変換、標準libraryの細かな挙動まで再設計しなければなりません。CをRustへ逐語的に移し、unsafeなpointer管理までそのまま再現すれば、外からの挙動は合っていても、移行で得たかった安全性は手に入りません。
ここでも、挙動だけを測る評価では足りません。何を消し、何へ置き換え、どの設計上の利益を得る仕事なのか。移行目的を構造的な受け入れ条件へ落とす必要があります。
実務では三つの証拠を別々に要求する
ここからは論文の結果を踏まえたAICompanyの提案です。自社のcoding agentへ大きな移行を任せるなら、ひとつの総合scoreではなく、三種類の証拠を別々に残すと扱いやすくなります。
一つ目は構造証拠です。旧dependency、旧compiler、互換shim、埋め込み済みbinaryが、sourceとbuild closureから消えたことを確認します。単純な文字列検索だけでなく、実際に何がcompileされ、何がlinkされたかまで追います。
二つ目は回帰証拠です。既存テストを通すだけでなく、元システムから入力と出力を採取し、移行後へ同じ入力を与えるdifferential testを作ります。exit code、file、symbol、HTTP response、文字encodingなど、利用者が観測する面を分けます。
三つ目は反証証拠です。実装したagentとは別のagent、または別担当が、移行後だけ壊れる入力を探します。報告書だけではなく、再実行できるtest caseを受け入れ条件にします。

この分離にはもう一つ利点があります。失敗したときに、modelの能力不足なのか、仕様不足なのか、回帰suite不足なのかを切り分けやすくなります。三つを一つの点数へ溶かすと、どこを直すべきか分からなくなります。
小さく試すなら、移行前後の契約を一枚にする
いきなり30時間の全リポジトリ移行へ進む必要はありません。まず一つのpackageやservice境界を選び、移行前後の契約を一枚にまとめるところから始められます。
最低限、次を明記します。
- 消えるべきもの:旧dependency、旧runtime、旧build command、互換layer。
- 残るべきもの:public API、data format、error、performance上限、install artifact。
- 比較方法:元と移行後へ同じ入力を与え、差を記録する手順。
- 反例の条件:元で成功し、移行後で失敗し、繰り返し再現できること。
次に、実装agentへ見せる検証と、最後まで隠す検証を分けます。すべてのtestを隠す必要はありません。日常のdebugに必要なtestは見せたうえで、移行完了を判定する構造条件と、提出後に生成する差分testを独立させます。
最後に、99%を進捗として記録しつつ、公開可否は100%で判定します。途中の改善を見えなくする必要はありません。ただし、完成の閾値を平均scoreへ変えないことが大切です。
公開資材は充実しているが、全結果の再現は重い
SWE Refactor Benchの公式repositoryはApache-2.0で公開されています。調査時点のcommit 1270471ccb5e6f254627784658d4e29acb90b953 には、20タスク、container環境、Migration Audit、Behavioural Tests、Agentic Verificationの資材が含まれていました。
一方で、論文の全実験を再現する負担は大きいままです。520回の長時間実行に加え、第三段階では提出ごとに6体の検証agentを各1時間動かします。AICompanyでは公開構成と検証資材の存在を確認しましたが、520回を再実行していません。
また、各model-effort-taskは原則1実行です。確率的なagentの成否が別のrunでどれだけ揺れるかは、直接測っていません。20タスクも実在の基盤を幅広く含む一方、すべての企業repositoryや移行形態を代表するものではありません。
Migration AuditにはLLM judgeが使われます。人手監査では、確認された誤りは点を厳しくする方向でしたが、自動判定が真値そのものになるわけではありません。
第三段階も検証agentの強さへ依存します。論文の分析では、強い2体を外すと受理数は28件から46件へ増えます。反例が見つからないことは、挙動同値の数学的証明ではありません。現実的に強い反証探索であり、形式検証の代わりではないと読むべきです。
AIへ大きな仕事を頼むほど、採点表を深くする
SWE Refactor Benchが示したのは、AIエージェントが全リポジトリ移行にまだ苦戦しているという事実です。ただ、それ以上に重要なのは、評価が浅ければ失敗を成功として数えてしまうことです。
何も移行せずテストだけ通す。移行はしたが挙動を壊す。既知テストは完璧でも、提出後に作られた反例で落ちる。520回の実験では、この三つが別々に起きました。
AIへ任せる仕事が大きくなるほど、最後の「動いた」を細かく分解しなければなりません。変更が本当に完了したか。既知の契約を保ったか。未知の差を探しに行ったか。この三つを独立して確認して初めて、緑のtest結果を安心へ変えられます。
モデルを替える前に、採点表を深くする。大規模なagent開発で最初に効く改善は、案外そこかもしれません。
参考資料
- SWE Refactor Bench 論文
- SWE Refactor Bench HTML全文
- SWE Refactor Bench 公式homepage
- SWE Refactor Bench 公式repository
- 確認したrepository commit

