コード生成エージェントにテストを書かせれば、品質は簡単に上がる。そう期待したくなるが、実際にはそう単純ではないらしい。Dan Luu のこの記事は、その直感をかなり意地悪に検証している。エージェントに「TDDを使え」「QuickCheckを使え」「property-based testingを使え」と指示したとき、どれだけ実際の正しさに効くのかを、かなり大きな条件数で比べた。結果は、派手な万能策は見えず、むしろエージェントはテスト手法の使い方自体が下手だ、という話になっている。
元記事は、以前に行った Zstd 実装の評価を土台にしている。Zstd は圧縮関連の実装課題で、そこに coding agent を使わせ、テストや検証のやり方を変えたときに正答率がどう動くかを見た。実装言語は Rust にそろえ、エージェントには同じ課題をさまざまな追加指示つきで解かせている。たとえば「Use test-driven development」「Use Lean 4」「Use QuickCheck」「Use property-based testing」といった具合だ。
試した条件はかなり多い。ACL2、Alloy、Creusot、Differential testing、Fuzzing、Kani、Lean 4、Mutation testing、Proptest、QuickCheck、rstest、Rust built-in test framework、SMT solvers、Spin、TDD、TLA+、Verus など、合計26条件に加え、いくつかの skill も比較している。skill とは、エージェントに与える追加の手引きのようなものだ。Hegel の公式 skill、ECC Rust test skill、Trail of Bits の property test skill、そして筆者が自作した skill も試されている。
評価の仕方はシンプルで、各条件について80回ずつ実行し、隠しテストを100%通過した割合を見る。使ったモデルは codex with GPT-5.6 Sol で、medium と xhigh の effort を比較している。結果を並べたグラフはかなり雑然としているが、そこから読み取れるのは、どの条件も圧倒的には勝たないということだ。Default、つまり追加指示なしでも平均以上の成績を出している。xhigh では fuzzing と property-based testing 系が formal methods よりやや良く見えるが、medium ではかなり混ざる。TDD は筆者の予想どおり振るわなかった。skill も、筆者の自作を除くと全体としては伸び切らない。
筆者が特に強調するのは、エージェントがテスト技法を「名前だけ」使ってしまうことだ。たとえば formal methods を指示すると、重要な性質を証明するのではなく、どうでもいい性質を証明して終わる。property-based testing では、乱数入力を投げるだけで、無効ケースばかり踏んだり、ほぼ意味のない自明な性質を何度も確かめたりする。IMAP RFC や別の RFC でも似た結果が出ていて、題材が変わっても傾向は変わらなかったという。
面白いのは、xhigh だとテスト自体は通ることが多いのに、そのテストが弱いことだ。たとえば4つの bitstream を扱う機能で、4つとも同じものを入れてしまい、順序の入れ替わりで起きるバグを見逃す。つまり「テストを書いた」という事実と、「役に立つテストを書いた」という事実は、かなり別物だとこの記事は示している。
まず驚くのは、追加指示を増やしても底上げがあまり起きないことだ。ふつうは「TDDを使え」「property-based testingを使え」と言えば、少なくとも無策よりはましになる気がする。だがこの記事では、エージェントは表層だけをなぞり、実質的な改善につながらない。ここで見えているのは、ツールの不足というより、問題の切り分け能力の不足だと思う。何を検証すべきか、どこで壊れやすいか、何が高価値な失敗か。そこを見抜けないままテスト技法の名前だけを与えても、動きはあまり変わらない。
この点は、今のAI支援開発の使われ方ともつながる。現場では「AIにテストを書かせる」「AIにレビューさせる」といった導入が進んでいるが、実際には生成物の量だけ増えて、検証の質は上がっていないケースがありうる。記事の結果は、その懸念にかなり近い。私は、エージェント活用の本当の難所はコード生成そのものより、検証の設計にあると思う。しかも検証は、生成よりもずっと地味で、上手さが見えにくい。だからこそ、雑な運用をすると成果が過大に見えやすいのではないか。
この記事でもうひとつ刺さるのは、formal methods が特別に強いわけでもない、という点だ。世間では formal methods のほうが高尚で、AIにも効きそうな印象がある。だが実際の結果は、少なくともこの条件では、fuzzing や property-based testing が少し良い場面もあり、formal methods が万能に勝つわけではない。これは地味だが重要で、技法のブランド力と実際の効果が一致しないことを示している。
私には、この結果は「手法の選定」より「使い方の設計」のほうがずっと重要だと読めた。TDD でも QuickCheck でも、道具名を渡すだけでは足りない。どういう失敗パターンを狙うのか、どの入力空間を切り出すのか、何を不変条件として見るのかまで含めて指示しないと、エージェントは平凡なことを平凡にやるだけだ。逆に言えば、人間がうまく設計すれば効く余地はある。記事の筆者が自作 skill である程度ましな結果を出しているのも、その可能性を示しているように見える。
筆者は、AI labs がどうして testing の上達を狙った RL 環境をあまり作っていないのか不思議だ、とも書いている。これはかなり本質的な疑問だと思う。コード生成モデルは、正しそうなコードを出す訓練より、間違いを見つける訓練のほうが、実務では効きやすいはずだからだ。とくにソフトウェアは、見た目がもっともらしいだけでは意味がない。壊れる入力を見つける力、検証の粒度を調整する力、失敗を再現する力が必要になる。
ただ、ここで気をつけたいのは、RL 化が簡単だと決めつけないことだと思う。筆者は「同じクラスの問題」に見えると述べるが、実際には、runtime optimization のように答えが機械的に採点しやすい課題と、テスト設計の良し悪しを評価する課題では、評価器の作り方がかなり違うはずだ。だからこそ未成熟なのだろうし、まだ広く使われていないのかもしれない。とはいえ、今の公開エージェントを見る限り、検証能力の底上げはかなり効く改善点に見える。ここを飛ばしたまま「AI コーディングは十分強い」と言うのは、少し楽観的すぎるのではないか。
この記事の一番厄介なところは、エージェントが「動くコード」を作れるようになっても、検証が弱いと品質は安定しない、と突きつけてくるところだ。隠しテストを通ることと、現実のバグを防ぐことは同じではない。むしろ、簡単なテストを大量に通してしまうほど、問題が見えにくくなることさえある。これは開発者にとってかなり嫌な話だが、今のAI支援開発にはその危険がある。
私の見方では、今後しばらく重要になるのは「どのモデルが強いか」より「どのワークフローが弱いテストを量産しないか」だと思う。AI にコードを書かせるなら、レビュー、プロパティ設計、境界値の洗い出し、失敗ケースの再現まで含めて一連の作業にしないと、成果はすぐ頭打ちになる。この記事は、エージェントの限界を悲観しているだけではない。むしろ、まだ改善余地がかなり大きい領域を具体的に示している。その意味で、AI コーディングの次のボトルネックは「もっと賢く書くこと」ではなく、「もっとましに壊すこと」なのだと思う。