HN 日本語サマリー

← 一覧へ戻る
AI・機械学習

エージェントはテスト/検証技術をどの程度うまく利用できるか?

How well do agents use test/verification techniques? (danluu.com)

156 pointsby vinhnx61 コメント

要約

コーディングエージェントが効果的なテスト技術を使用することで品質基準を満たすことが容易になったにもかかわらず、ソフトウェアの品質が悪化している現状を踏まえ、エージェントがテスト手法をどれだけ効果的に利用できるかを検証した記事です。RustでZstd実装の評価を再利用し、「テスト駆動開発(TDD)」、「Lean 4」、「QuickCheck」、「プロパティベーステスト」などの指示を与えた場合の効果を比較しています。結果として、デフォルト(追加指示なし)が平均を上回り、多くの指示が期待通りに機能しないことが示唆されています。

全文翻訳

エージェントはテスト/検証テクニックをどの程度効果的に使用できるか?

以前、コーディングエージェントが効果的なテストテクニックを使用することで、特定の品質基準を満たすことがこれまで以上に容易になった一方で、ソフトウェアの品質は悪化しているように見えると指摘しました。これは、開発者が使用しているデフォルトの設定がうまく機能していない可能性を示唆しています。ここでは、エージェントに特定のテクニックやライブラリを使用するように指示するだけで、実装の正確性が向上するかどうかをテストし、テストの専門知識がない人が特定のテクニックを適用したり特定のライブラリを使用したりするように指示した場合のエージェントの有効性を検証します。

エージェントプログラミング言語の効果を比較したこの議論で再利用したZstdの実装評価を使用し、代わりに、エージェントにZstdを「テスト駆動開発を使用せよ」「Lean 4を使用せよ」「QuickCheckを使用せよ」「プロパティベーステストを使用せよ」などの異なる追加指示を与えた場合の、異なるテストテクニックとテストライブラリの効果を比較します。IMAP RFCなど、他のいくつかの評価も実施しましたが、ここでは簡単に触れます。

すべての実装はRustで行われました。テストされた26のプロンプト条件は、ACL2、Alloy、"Audit and fuzz risky areas"、"Audit first"、Creusot、Default(追加指示なし)、Differential testing、Fuzzing、Hegel、Insta、Judgement(エージェントに最良のテクニックを使用するように指示)、Kani、Lean 4、"Make no mistakes"、Metamorphic testing、Mutation testing、Property-based testing、Proptest、QuickCheck、rstest、Rust組み込みテストフレームワーク、SMTソルバー(Z3、cvc5、Yicesすべて利用可能)、Spin、TDD、TLA+、Verusでした。さらに、4つのスキルもテストされました。Hegel(公式Hegelスキルを使用)、ECC Rustテストスキル(ECCは25万スター、3.8万フォークを持つスキルのコレクション)、Trail of Bitsプロパティテストスキル、そして私が書いたテストスキル(私はスキルではなくプロンプトを使うルーディットで、良いスキルの書き方には全くセンスがありません)です。私のスキル以外は、Codexに質問して関連スキルを見つけた際に、上位に来たスキルが選ばれました。

予測

条件がどのように機能するかについて、いくつかの推測を事前に登録しました。

  • TDDは期待を下回るだろう(信頼度55%)
    • 実際、TDDが期待を下回ると考えたため、TDDを追加しました。
    • エージェントがTDDをどのように実行するか不明なため、この信頼度は低いです。おそらくエージェントはTDDを実行せず、期待を下回らない何かを実行するかもしれません(あるいは、TDDの期待を下回るという私の考えが間違っているかもしれません)。
  • 形式手法は期待を上回らないだろう(信頼度52%)
    • 形式手法は効果的で有用(今やこれまで以上に)ですが、優れたテスト方法も同様に効果的で有用であり、単純な問題では、同レベルの能力で使用された場合、形式手法が期待を上回ることはないだろうと考えています。
    • 上記と同様ですが、さらに、エージェントが何を指示されてもどのように実行するか不明なため、信頼度は低いです。形式手法はエージェントコーディングのための効果的なテストテクニックよりも誇張されているため、ラボが合成データでRL環境を訓練し、効果的なテストテクニックのためにエージェントを訓練することなく、形式手法に非常に効果的なエージェントを訓練した可能性は完全にあり得ます(これは容易にできるはずですが、効果的なテストテクニックがあまりトレンドでないため、行われていないでしょう)。
  • "Make no mistakes" は指示なしよりも期待を上回らないだろう(信頼度95%)
    • これはジョークであり、多くの人が試したことです。もしそれが機能するなら、人々はとっくに気づいているはずですよね?
  • ECCテストスキル(25万スター、3.8万フォーク)は期待を上回らないだろう(信頼度65%)
    • やや大きく、有用と思われる情報がありません。エージェントにTDDの使用を指示します。それがエージェントにTDDを使わせる程度には、これを悪化させるだろうと予想しています(そして、それはTDD条件よりも指示的ですが、おそらく成功しにくいでしょう。しかし、それ以外の情報は有用ではなく、いくらかのコストがかかります)。
    • 私のスキルの予測はすべて信頼度が低いです。なぜなら、私はスキルをあまり使わず、それらを真に評価する方法を知らないからです。私はこれを、「プロンプトとしてテキストを渡し、LLMのコンテキストウィンドウにこのものが浮遊しているとしたら、どれほど効果的だろうか?」と考えています。
  • Hegelのスキルは期待を上回らないだろう(信頼度65%)
    • 非常に大きい(SKILL.mdとリンクされたRustリファレンスで20kトークン超)であり、エージェントの指示というよりチュートリアルのように読めます。
  • Trail of Bitsテストスキルは期待を上回らないだろう(信頼度55%)
    • 有用と思われる情報が含まれていますが、かなり大きいです。
全体的な結果

以下は、テストされた条件(Codex、GPT-5.6 Sol、mediumおよびxhighの努力レベル)の結果を示す、非常に乱雑なグラフです。データを見る際、私はほとんどの人よりもはるかに密で乱雑なグラフを好みます(例えば、この最初のグラフ)。ほとんどの人はこのようなグラフを読みにくいほど乱雑だと感じるため、情報を一連のグラフに分割し、それぞれがより少ない情報を示すようにしますが、ここではそうしません。以下の理由から、この非常に乱雑なグラフを提示します。このグラフでは、x軸にコスト、y軸に(非表示の)テストを100%パスした実行の割合を示しています。各条件と努力レベルで平均80回の実行(マウスオーバーするとブートストラップ共分散、50%の不確実性が表示され、似たものを同じ色にする試みがあります。例えば、形式手法は青系、プロパティベーステストは緑系などです):

[画像: 乱雑なグラフ。x軸はコスト、y軸はテストを100%パスした実行の割合。様々なテスト手法やスキルがプロットされている。]

一つわかることは、何も劇的に期待を上回るものはないということです。しかし、Default(追加指示なし)は平均を大きく上回る結果を出しました。xhighを見ると、平均して、ファジングとPBT関連の条件は形式手法よりもわずかに良好でしたが、mediumでは状況はより混在していました。Codexが試すように推奨したテスト関連スキルは期待を下回りましたが、私たちの迅速なカスタムスキルはまずまずの結果でした(大きな違いは、私たちのスキルがデフォルトの動作からより生産的な動作へと誘導するように設計されているのに対し、他のスキルはチュートリアルのようなものです)。TDDは予測通り、うまくいきませんでした(あるスキルもエージェントがTDDを使用したことを示唆しており、そのスキルもエージェントが指示に従おうとしたケースでは成績が悪かったです)。

実際のエージェントの動作を見ると、一般的にエージェントはこれらのツールやテクニックをあまりうまく使用できないことがすぐにわかります。ここで指摘したように、私が話した誰もが指摘しているように、エージェントはテストが非常に苦手で、合理的に「デフォルトで」テストする方法を理解していないようです。例えば、Gary Bernhardtのコメントを見てみましょう。

AIエージェントのテストへのアプローチ、ほぼ以下の通りです。

  1. 15年前にモックに反対した人が考えた病的なケースを、実際にモックを使ったことがないまま採用する。過剰なモックのナイーブな夢。

  2. それらの病的なケースをテスト戦略のバックボーンにする。

特定のテストテクニックやテストライブラリの使用をエージェントに依頼しても、このアプローチは期待ほど大きくは変わりません。各条件で何が起こったかを詳細に見ますが、大まかには、テストテクニックに関して、エージェントは通常、通常書くテストを、異なるタイプのテストテクニックのフレームワーク内に書くか、テクニックを表面上は使用するが、そのテクニックから価値を引き出すことは実際には行わない傾向があります。ほとんどの場合、テクニックが指定されると、彼らはGaryが説明したようなことを、そのテクニックに関して行います(例えば、形式手法の場合、ほとんど無関係なプロパティを証明し、プロパティベーステストの場合、エージェントは完全にランダムな入力に大きく依存し、無効/拒否ケースを多用するか、些細なプロパティを見つけて低価値のランダムケースを実行します)。IMAP RFC(各条件で40回の実行を試行)や他のランダムなRFC(数回の個別の実行を試行)でも、結果は実質的に変わりませんでした。一般的に、問題の種類に関わらず、Zstdのようなビット操作問題、IMAPのようなプロトコル[1]、あるいはそれ以外のものであっても、エージェントは形式手法やテストライブラリやテクニックを効果的に使用しませんでした。

xhighでは、エージェントは一般的に書いたテストをパスさせることができましたが、テストの質が悪かったです(例えば、4つのビットストリームを使用する機能のテストに4つの同一のビットストリームを提出し、ビットストリームを転置した場合に発生する可能性のあるバグを見逃すなど)。以前のZstd評価で言語に関して指摘したように、ナイーブなループで低レベルの努力で実行すると、結果が悪化します(エージェントはこれをもっと行い、低い正確性で停滞します)。

AIラボがエージェントがうまくテストする方法を学習するためのRL環境を作成していない理由に興味があります。なぜなら、ソフトウェアが合理的に機能しないことは、コーディングエージェントの採用にとって重要であり、RLに適したものであるように思われるからです。以前見たように、エージェントは有界実行時間最適化問題に非常に熟達しています。これは、RL環境を大量に作成してトレーニングするのにまさに適した種類の問題だからです。これは、試してみると見かけよりも難しいことの一つかもしれませんが、効果的なテストとテストテクニックのためのRL環境を作成することは、問題の同じクラスにあるように思われます。おそらく、制限要因は、効果的なテストテクニックに関する知識がそれほど広まっていないため、誰もそれを試そうと考えず、人々がエージェントに非効率的なテスト(例えば、標準的な単体テストを行うことによって)をさせていることかもしれません[2]、あるいはこの問題が何らかの理由で実行時間最適化よりもパッケージ化するのがはるかに難しいのかもしれません。エージェントがテストや検証なしで一般的に正しいコードを書けるほど優秀になるまで、これは無意味な点になるかもしれませんが、少なくとも公開されているエージェントの初期から現在(2026年9月)までの状態では、エージェントがテストの専門家から指導を受けることなくテストする方法をある程度知っていれば、エージェントコーディングの効果を大幅に向上させることができたでしょう。

以下では、各条件でエージェントがどのように動作したかを、正確性の低い順に見ていきますが、順序から強い結論を導き出すことには注意が必要です。

ここでの多くの失敗は、プログラミング言語がトークン使用量と正確性に与える影響を見たときに観察された失敗と類似しているように見えます。なぜなら、失敗はしばしば特異的だからです。例えば、プログラミング言語に関して、エージェントはJavaではそうではないのに、Clojureではバイト変換のセマンティクスを誤解する率がかなり高いことがわかりました。エージェントは(そしておそらくある程度は)unchecked-byteではなくbyteで変換することでJavaのバイト変換セマンティクスを取得できることを知っているはずですが、それでもです。

人々が一部の言語がエージェントにとって他の言語よりも優れている理由について、あらゆる種類の曖昧な高レベルの説明を持っていますが、エージェントが実際に行っていることや失敗モードを見ると、人々が好きな言語がエージェントコーディングに適している理由について聞いた説明のどれも、実際には真実ではありません(Rustのメモリ安全性に関するコメントを除く、これは多言語pandoc評価で、エージェントが書いたC、C++、Rust間のメモリ安全性問題を比較して検証されました)。代わりに、不明な理由で発生する特異的な失敗の束が見られます[3]。言語に関しては、言語の人気とパフォーマンス(低コストと高正確性の両方)の間に中程度の相関が見られるため、より人気のある言語にはより多くのトレーニングデータ(人間のコードだけでなく、合成データも含む)があったことが理由であると推測するのは合理的です。ここでは、明確なパターンはありません。ただし、エージェントは、ライブラリやテクニックの名前だけを与えられた場合、テストまたは検証テクニックを効果的に使用できないことがほとんどです(後で何がうまくいくかについて議論します)。各条件で何が起こったかについて読みたくない場合は、最後の項目にスキップするにはここをクリックしてください。

Verus

Verusは、SMTソルバーと様々な種類の推論を使用して、コードが仕様に一致することを証明します。

Verusはコードが仕様に一致することを証明できますが、エージェントはそうしませんでした。代わりに、Zstdに関連する様々な抽象的なプロパティについて証明を行いました。私自身はVerusのようなツールを使ったことがないため、専門家や初心者ユーザーが通常何をするかについては話せませんが、チュートリアルを読む限り、エージェントが実際のコードの検証にVerusを使おうとせず、抽象的な推論にのみ使用したことは少し奇妙だと感じます。これは、実際のコードのプロパティを証明しやすくするように設計されているように思えます。

さらに、証明されたプロパティを見ると、一般的に証明されたプロパティの数は少なく、証明されたプロパティは面白くありませんでした。例えば、エージェントは「有効なカーソル/インデックス/距離が与えられた場合、結果の操作は範囲内に留まる」といったことを証明しましたが、これは証明すること自体は悪くありませんが、バグの原因にはなりませんでした。また、エージェントはしばしば、実質的に A => A である空虚な証明を書きました。この形式の実際のVerus証明は次のとおりです。

  requires
      0 < a <= window,
      0 < b <= window,
      0 < c <= window,
  ensures
      0 < c <= window,
      0 < a <= window,
      0 < b <= window,

エージェントが実際に何かを証明した場合、一般的に比較的単純なことを証明し、バグが発生しやすい部分に関するプロパティの証明を避けました(例えば、エージェントはエンコードとデコードでビットストリームの順序を反転させることに失敗することが多く、テストがこれを検出できなかったのは、テストが回文だったためです。おそらく、ここで反転の証明のようなものがエージェントに別の方法で「考えさせる」かもしれません)。

VerusとVerusのドキュメントだけを与えられた場合、エージェントはVerusから価値を得ていないようです。

結果を見ると、集計されたxhighのVerusの結果は良好です(正確性は平均よりわずかに低いですが、はるかに安価です)。mediumの結果は平均的なコストで、正しい実行の割合が最も低く、正しいテストの平均数も最も低かったです。エージェントはVerusから実際には価値を得ていなかったため、正確性に関しては主に従来のテスト(組み込みRust #[test]関数と単体テスト)を行っていました。mediumからxhighに移行する際、エージェントは従来のテストにより多くの労力を費やし、Verusの使用にはわずかな労力しか費やさなかったため、xhighの結果は良好でした。

実際のテストを見ると、エージェントがVerusを使用した2つの機能のうちの1つ(4ストリームジャンプテーブル)で、Verusエージェントは160ケース中89ケースでテストを作成しましたが、これは偶然にもDefaultエージェントと同じ数でした。しかし、Verusエージェントは悪いテストを書く可能性がはるかに高かったです。彼らはテストに不正確な結果をエンコードする可能性が高く、また、すべての4つのストリームを同一にするなど、空間をあまりカバーしない簡単なテストを作成する可能性も高かったです。この種のことは、失敗が特異的であると私が言ったことの一例です。Verusを使用しない場合にエージェントが不十分なテストを書くことを必然的に引き起こすVerusの性質はありません。また、Verusを使用する人間が不十分な単体テストを書くとは一般的に期待しません。Clojureを使用する人間がバイト変換の間違いをより多く犯すとは期待しないのと同じように、しかし、何らかの理由でこれがここで起こりました(おそらく偶然です)。

AIラボ内部の人が物事の理由についてより良い情報にアクセスできるかどうかはわかりませんが、外部のここでは、このようなことがなぜ起こったのかを判断するのは一般的に非常に困難です(言語の問題についてもっともらしい仮説を立てた場合でも、多くの言語の多くのサンプルを実行する必要があり、同じことを研究した論文は、言語の人気/エージェント有効性の相関を観察しませんでした。なぜなら、それらはそのような弱い相関について推論するには言語が少なすぎるか、問題が小さすぎて些細すぎたためです)。

Alloy

Alloyはしばしばバウンデッドモデルチェッカーと呼ばれます。Alloy 6ではいくつかの追加機能が導入されているため、これは正確ではないかもしれませんが、これは私の専門分野をはるかに超えています。私の理解では、Alloyでは通常、コードが機能することを証明するのではなく、モデルに関するプロパティを証明します。

Alloyは2番目に低い正確性スコアを獲得し、珍しくmediumとxhighの両方で一般的に成績が悪かったです。これは示されていませんが(何も追加していないように見えるため)、一般的に、結果はmaxとxhighの間で強く相関しており、mediumの結果とは大きく異なっていました。

Verusで見たように、Alloyを使用したエージェントは、正確性に関してはほとんど標準的なRust #[test]に依存し、Alloyではほとんど時間を浪費していました。ここでも、形式ツールを不適切に使用しても正確性は向上しませんでした。

Alloyの使用には、問題やリスクを見つけることに近い個別のケースがいくつかありましたが、それでもごく少数でした。あるケースでは、Alloyが反例を見つけ、それがエージェントに緩和策を実装させる原因となりました。残念ながら、反例は実際には発生できない8ビットオーバーフローに依存していました。なぜなら、実際のZstd実装は64ビットusizeを使用しており、入力が与えられた場合オーバーフローの可能性がなかったため、実際のバグを防ぐことなくコードをより複雑にしただけでした。

別のケースでは、Alloyの仕様が不正確で、関連するテストが失敗しました。テストが失敗した後、エージェントはAlloyの仕様を修正しました。仕様が正確であれば、おそらくエージェントは失敗なしで正しいコードを書いたでしょう。良い結果になった可能性のあるケースがいくつかありましたが、実際の問題が防止されたかどうかは不明です。

Alloyエージェントは、Verusエージェント(主に算術などのチェックを行っていた)よりもZstdアルゴリズムに密接に関連するものをモデル化しましたが、それでもモデル化が間違っていました。

Differential testing

差分テストは、同じ入力を複数の実装に与えて結果を比較し、問題を検出するテクニックです。原理的には、LLMで試すのは妥当なことのように思えます。なぜなら、私たちはしばしばサイコロを振るたびに異なる結果を得ており、ここで指摘したように、エージェントが実装を繰り返す(全体の一部、あるいは関数の一部にすぎない場合もある)と、最初からやり直すよりも悪い結果になることが多いからです。

しかし、これは3番目に低い結果をもたらしました。この場合、xhighでは平均をわずかに上回る結果でしたが、mediumでははるかに平均を下回りました。エージェントは2つの完全な実装を作成して比較しませんでした。160回の実行のうち、135回は差分テストと呼べるものでしたが、他の条件で見たように、これらは一般的に些細で効果がありませんでした。そして、差分テストがバグを検出できた可能性のあるケースでは、独立した方法で実装する代わりに、エージェントは同じことを2回行い、両方のバージョンに同じバグをエンコードしました。

私は時々エージェントに独立して物事を行うように指示し、別々のコンテキストで起動させますが、差分テストではこれは効果的に行われず、エージェントは一般的に同じものを2回書くだけでした。

Hegel Skill

公式HegelスキルがHegelの動作をどのように変更するかを議論するのは理にかなっていますが、正確性の逆順で、Hegel SkillはHegelよりも上に表示されます。なぜなら、結果は正確性においてHegelよりも悪かったからです。このスキルに関する議論は、以下のHegelのセクションを参照してください。

Lean 4

Lean 4は、インタラクティブな定理証明器とでも言うべきものです。

Leanについては事前に予測を登録しませんでしたが、もし形式ツールのどれがうまくいくかについて予測を登録していたら、Leanをリストに入れるでしょう。なぜなら、それは比較的ホットでトレンディであり、RL環境からの合成データのおかげでパフォーマンスが良い可能性が高いからです。

Leanエージェントはプロパティを証明しましたが、Verus条件と同様に、エージェントは主にバグが発生しやすい領域やリスク領域に触れない算術証明を行いました。

他の形式条件と同様に、Leanエージェントは標準的なRustテストに大きく依存していました。これまでの形式条件と同様に、重要でないことの証明をいくつか行っても、正確性は向上しませんでした。

QuickCheck

QuickCheckはプロパティベーステストライブラリであり、おそらく長らく最もよく知られているライブラリですが、現在はHypothesisがその王冠を保持しているかもしれません。

残念ながら、エージェントはプロパティベーステストの使用において、これまでに見た形式ツールと同様の効果しかありませんでした。QuickCheckを使用する際、エージェントはほとんど非常に単純な「スモークテスト」を作成し、あまりチェックしませんでした。また、ランダムな入力を使用しましたが、これはZstdのようなものをテストするには非常に貧弱です(なぜなら、それらは数少ない失敗/拒否コードパスのいずれかにしか到達しないためです)。

また、チェックされたプロパティは比較的少数でした。すべてのエージェントがQuickCheckを使用しましたが、160回の実行のうち63回は単一のプロパティしかチェックしませんでした。エージェントは再び主に従来のテストに依存していましたが、技術的にはQuickCheckを使用していました。何らかの理由で、エージェントはデフォルト条件や他のほとんどの条件よりも多くの従来のテストを作成しましたが、テスト修正の繰り返しは少なかったです(これにより、この条件は平均以下のコストで終了しました)。

TDD

TDDは、IMAP RFC評価と同様に、ここでも期待を下回りました。

TDDプロンプトは、エージェントの動作に大きな変化をもたらしたようです。エージェントは2倍のテストを生成し、より反復的なテストコードテストコードなどのワークフローで作業しましたが、TDDの支持者は、エージェントが実際にはTDDを使用していないと言うでしょう。エージェントが何らかの細かい反復TDDを行ったインスタンスは少数でした。

全体として、エージェントは以前よりも多くのテストを作成しました。例えば、エージェントは、実質的な(スタブではない)実装を行う前に、160ケース中67ケースで1つ以上の失敗するテストを持っていましたが、デフォルト条件では0ケースでした。

広範なテストクラスに関して、TDDはあらゆる種類のテストをより多く生成しました。小さく些細なテストが多く、統合テストやエンドツーエンドテストも多くありました。明白な高レベルの「エージェントがXをやりすぎた、あるいは少なすぎた」というようなものは、データには当てはまらないようです。特定の失敗と、それらがテストによってどのように見逃されたかを見ると、TDD条件にはこれらのいくつかが含まれていることが観察できます。例えば、Zstdは、4つのHuffmanストリームがある場合にジャンプテーブルと呼ばれるものを使用します。

TDDエージェントは、一般的なケースをカバーするテストをより多く書いたにもかかわらず、このジャンプテーブルの評価テストで失敗する可能性が高かったです。何らかの理由で、TDDエージェントは、ハードケースをカバーしないテスト(例えば、すべての4つのストリームを同一にするなど、Verusで見られたように)を書く可能性が高かったです。これは、AIラボの人々がどのような可視性を持っているのか疑問に思う別のケースです。なぜなら、TDDでエージェントをプライミングしたことが、なぜより悪いテストとより悪い実装を書くことにつながったのか、外部からは明らかではないからです。

TDDと少数のテスト条件だけを見ると、TDDのコードはしばしば多くの小さな、あまり良くないテストを持つように見えるという仮説が立てられるかもしれません。したがって、エージェントをTDDでプライミングすると、これらの種類の非効果的なテストをより多く書くようになるかもしれません。しかし、Verusでも同じパターンが見られる理由は不明です。もしVerus(または他の)の動作に共通の理由がある場合、オープンモデルで実験を再実行し、モデル内部で何が起こっているかをある程度検査することで、これがTDDに当てはまるかどうかを確認できるかもしれません。

2つのスキルも、エージェントにより反復的なアプローチで実行させました。おそらく、より頻繁に実行することでより良い結果が得られるという理論に基づいています。そして、それらのスキルは両方とも期待を下回りました。一般的に、すべての条件において、エージェントはxhighとmax(示されていませんが、maxはコストが大幅に低いにもかかわらず、xhighよりもわずかに高い正確性を持っていました)で書いたテストをパスさせることができました。より反復的に自分のテストをパスさせることは、エージェントに誤ったテストを書かせる傾向があり、誤った動作を強制しました。

Yossi Kreininは、TDDがなぜより悪いテストにつながる可能性があるかについて、次のように考えています。

参考までに、コードを書く前にテストを書くと、何が難しいかについてあまり知らないため、難しいケースをテストするのが難しくなり、ランダムテスト(tddとは関連付けられていないと思いますが)を行ったとしても、バグがある方向に分布を誘導する可能性は低くなります。コードを書いたか、少なくともそれを見ることができる場合、何が単純に正しいように見え、何が機能するかもしれないし、機能しないかもしれないかを知っています。それは、それが何をするかを理解するのが簡単ではないからです。言い換えれば、tddは複雑な機械にとって、ホワイトボックステストよりも効果が低いと思われるブラックボックステストにあなたを誘導します。これは人間にとってはそうなるはずですが、エージェントについてはあまり確信がありません。

TDDが期待を下回るだろうという私の予測は正しかったでしょうか?結果だけを見ると、答えは「はい」です。私の理由(書面で明示的に登録されていませんが、私が何を考えていたかは知っています)については、はっきりしないと思います。私の考えは、最近 様々な文脈で 議論したように、エージェントで良いパフォーマンスや正確性を達成する上で、エージェントに正しいことを実際にやらせ、単に過学習させないことが鍵となります。方法論全般について、この指示がエージェントの動作をどのように変えたかではなく、TDDは過学習を引き起こすように設定されているように見えます。

エージェントはより悪いテストを書き、時には比較的コストが高く非効果的な反復ワークフローを使用しましたが、人間がTDDを使用し、その後エージェントに実装を指示した場合に予想される失敗モードが実際の問題であったかどうかはわかりません。そして、その問題が私の直感の源でした。この推論を評価するには、おそらくさらに多くの評価と調査が必要であり、追加データの結果は私の元の推論が間違っているだろうと推測します。

Spin

Spinはモデルチェッカーです。

これで、結果が平均からそれほど離れていない範囲に入ってきました。Spinはmediumとxhighの両方で平均より中程度に成績が悪かったですが、コストは平均を下回りました。他の形式ツールで見られたように、Spinの使用は一般的に効果がありませんでした。具体的には、Spinを使用してある種の動作をモデル化しても、その動作をカバーする非表示テストのパス/フェイルとは相関がありませんでした。Spinの使用は表面的なもので、生産的ではありませんでした。

Hegel

HegelはHypothesisに基づいたプロパティベーステストライブラリです。

今や予想されるように、エージェントはHegelを効果的に使用しませんでした。使用した範囲では、表面的な使用に留まり、一般的に通常のテストに大きく依存した後で使用しました。エージェントが実際にはそのことを意味のある形で行っていないと言うのは繰り返しになるので、これらのセクションは短くし、特定の興味深い点だけを強調します。

エージェントが実際に使用したワークフローは、一般的に次のとおりでした。

  1. RFCとAPI/契約を読む
  2. Zstdを実装する
  3. 通常のテストを実行する
  4. Hegelのドキュメントを読む
  5. Hegelを使用して1〜4個の単純なプロパティベーステストを作成する
  6. 通常の組み込みRustテストを引き続き使用する

前述のように、Hegelスキルは正確性を向上させませんでした。正確性は悪化しました(ただし、ランダムである可能性も十分にありました)。より顕著だったのは、コストが大幅に増加したこと(mediumで26%、xhighで41%増加)で、これは因果関係があるようです。

スキルはエージェントにテストをより多く生成させました。追加されたテストは、主に不正な入力がパニックを引き起こさないか、およびラウンドトリップテストのチェックでした。前者は、エージェントがプロパティベーステストやファジングのすべての条件で既に過剰な量を行う傾向があったため、追加の労力は有用ではありませんでした。後者は、本質的に悪いアイデアではないように思えます(私もしばしばエージェントにラウンドトリップテストを作成するように明示的に指示し、それらは特定のプロパティをチェックするのに役立つように思えます)が、最もバグが発生しやすい領域では行われませんでした。追加の指示なしでは、エージェントは比較的些細なプロパティのラウンドトリップテストを作成する傾向があり、それらは既に正しい可能性が高かったです。

コストに関しては、コストには複数の理由があります。一つは、スキルがかなり大きいこと(スキルで34k文字、さらに45kのRust固有リファレンスをロードし、合計20kトークン超になります)です。これは実行開始時にロードされ、その後の多くの操作で再読み込みされました。これにより、mediumで平均900k、xhighで1.8Mの平均追加ドルコストが発生しました(キャッシュヒット率は非常に高かったですが、初期読み込み後99.85%でしたが、十分に再読み込みされたため、総コストのかなりの割合を占めました)。

乗数コスト(この乗数は前の数値に含まれています)は、スキルが構造化された操作セットを指定したことで、より多くの作業が発生したことです。この作業は正確性を向上させなかったため、コストが増加しましたが、それに伴う利益はありませんでした。

注意すべき点は、スキルが160ケース中157ケースでのみ使用されたことです。LLMを使用する場合に一般的に起こるように、アクションと結果はランダムです。特定のタスクに使用すべきだと考えるスキルがエージェントに利用可能であっても、AIラボの外部の人には不透明に見える要因によって、それを使用するかどうかは異なります。

ToB skill

この場合、160回の実行のうち108回だけが実際にスキルを開いて読みました。スキルはRustでproptestの使用を提案していますが、スキルは依存関係を追加するために承認が必要だと提案しており、これらはすべて単一ターンの自律実行だったため、これは行われませんでした。

これまでに見た他のプロパティテストケースと同様に、プロパティテストは初歩的で、役立つ方法では行われませんでした。

Rstest

Rstestはフィクスチャベースのテストライブラリです。

エージェントは実質的にrstestを使用しませんでした。技術的には使用しましたが、ほとんど標準的な単体テストをrstest内に記述し、rstestを意図した通りに使用しなかったため、rstestの目的を損ないました。これは、これまでに見たテクニックのいくつかに高レベルで当てはまるかもしれませんが、エージェントは少なくとも他のテクニックの一部を表面上は使用していました(Hegelで低価値のプロパティテストをいくつか書くなど)。しかし、ここではエージェントはRstestをRstestたらしめるもの(プロパティベーステストライブラリのアナロジーは、それらでプロパティベースではない単体テストを書くだけの場合)を使用しませんでした。

Rust test

これは、エージェントがDefault条件で使用し、他の条件でも非常に重用した標準のRust組み込みテストフレームワークを指します。

エージェントに組み込みテストフレームワークの使用を明示的に指示した結果、テスト数は増加しましたが(mediumで2倍、xhighで25%増)、正確性の向上にはつながりませんでした。エージェントが間違えた場合、それは重要な動作をテストしなかったり、不正確なテスト動作を実装したりしたことが原因であることが多かったです。テストを追加しても、リスクの高い動作のカバレッジが実質的に増加したり、不正確な動作をエンコードしたテストの割合が減少したりすることはありませんでした。

Yossi Kreininは次のように付け加えています。

固定の入出力形式のテストは、機械と人間の両方でこれを助長すると思います。入力を生成する場合、出力を正または負として分類するコードが必要になります。このコード自体にバグがあるかもしれませんが、少なくとも何が正しいかを考え、実行して出力が正しい答えであると仮定するよりも簡単に判断できるようになります。固定出力では、コードの出力をエンコードして、それが理にかなっていると確信してしまう可能性が非常に高いです。

Creusot

CreusotはVerusと同じ分野に位置します。

他の形式条件で見られたように、Creusotは効果的に使用されませんでした。

Mutation testing

ミューテーションテストは、テストの有効性を判断するためにコードを変更し、その後、良いカバレッジを得るためにテストを追加することを含みます。ミューテーションテストは標準的なプログラミング用語ですが、エージェントは一般的に実際にミューテーションテストを行わず、代わりに通常のテストを行い、実際にはミューテーションテストではない方法で少量の変更を行いました。これは、TDD指示が動作を変更したが、エージェントにTDDを実行させなかったのと似ています。

ミューテーションテストが行われたケースはいくつかありましたが、ごく少量で、まれでした。

Judgement

この条件では、エージェントに判断に基づいて適切にテスト方法を適応的に使用するように指示しました。これまでの結果から、予想通り、エージェントはほとんど標準的なRust単体テストを使用しました。一部のエージェントは限定的なファジングを行いました。エージェントは他のテストや形式ライブラリにアクセスできましたが、それらを使用しませんでした。

Fuzzing

ファジングは、テスト入力を何らかの方法でランダム化することを含みます。

エージェントは、ランダムなバイトを入力として送信することに大きく依存していましたが、そのほとんどは同じコードパス(無効な入力)に到達する結果となりました。エージェントは、有効な入力のランダムなバリエーションを送信しようとしましたが、それもほとんどの場合、入力拒否パスを繰り返し実行するだけでした。

エージェントがランダムな構造化入力を生成したまれな機会(160ケース中10回)では、半分の確率で実際のバグが見つかりました。その中には、些細ではないケースもありました。160ケース中5ケースでファジングを少し効果的に使用したのは、必ずしも良いとは言えませんが、これまでに見たテクニックの効果的な使用法の中では最も良い部類でした。これはまた、エージェントがこれをより良く訓練できること、そして訓練を変更せずにこれをより良くするように指示できることを示唆しています。ある意味では、彼らはこれを行う方法を知っていますが、実際にそれをプッシュされない限り、実際には行いません。

Insta

Instaはスナップショットテスト(ゴールデンテストとも呼ばれる)のためのライブラリで、結果を「スナップショット」または「ゴールデンファイル」と呼ばれる正しい結果と比較します。一般的に、スナップショットは通常、シリアライズされたデータの一種です。例えば、データ構造のJSONオブジェクトや、CLI出力のログなどです。

予想されるように、スナップショットテストはほとんど使用されず、エージェントは主に従来のテストに依存していました。エージェントはInstaを使用しましたが、多くの場合、Insta内で通常の単体テストを記述するだけでした。

SMT

エージェントには、SMTソルバーの使用が指示され、Z3、cvc5、Yicesがインストールされていました。

エージェントは主にSMTソルバーを、FSE状態範囲、ヘッダー算術などの計算を行うためのスクラッチパッドとして使用しました。エージェントが何かをモデル化した場合でも、一般的な間違いを避けるために、通常は正しいものをモデル化しませんでした。

例えば、byte1 + (byte2 << 8) + 0x7F00であるべき計算がありました。多くのアージェントは代わりにbyte1 + (byte2 << 8) | 0x7F00を実装しました。エージェントはSMTソルバーを使用してこの計算に関連するプロパティを証明しましたが、それでも間違ったコードを書き、SMTの使用はDefault(指示なし)よりも良くないように見えました。

TLA+

TLA+は動作をモデル化するための言語とツールです。

平均を上回る結果のセットに入ってきました(ただし、Defaultよりは劣ります)。しかし、前述のように、実際の順序をあまり真剣に受け取るべきではありません。これは必ずしも重要ではありませんが、TLA+はmediumで平均をわずかに上回り、xhighでさらに平均を上回るスコアを獲得しました。

160/160のエージェントが何らかのTLA+モデルを作成しました。一般的にはZstdの状態機械モデルです。特定のカバレッジのために、30がHuffman/FSE/エントロピー(バグが多い領域)をモデル化しました。他の形式ケースと同様に、TLA+モデリングはフローの比較的後半(多くの標準テストと実装の後)で行われました。エージェントは時々TLA+モデルのエラーを見つけて修正しましたが、TLA+の問題が実際のRustコードの変更につながったインスタンスは見つかりませんでした。

本格的なTLA+モデリングが行われていたにもかかわらず、正確性が向上したとしても、観察が困難な小さな方法でした。一般的に、より洗練されたTLA+モデリングを行った実行は、正確性が高くありませんでした。

Metamorphic testing

メタモルフィックテストでは、関連する入力が出力に期待される関係を持つことを確認します。例えば、ソート関数では、等しくない入力の順序を変更しても出力の順序が変わらないこと、加算では、入力に値を加えるとオーバーフロー moduloで値が加算されることを確認できます。

他の条件で見たように、メタモルフィックテストは正確性に関してあまり有用には使用されませんでした。実際に合理的なプロパティがいくつかチェックされました(例:フレーム境界にスキップ可能なフレームを挿入しても出力は変わらない、合法的なブロック再分割を行っても出力は変わらないなど)。しかし、これらはエージェントが比較的頻繁に間違える領域にヒットしなかったため、これらのプロパティをチェックしても役立ちませんでした。一般的に、エージェントは古いジョークのファンであるように見えました。

警官が街灯の下で何かを探している酔っ払いを見つけ、何を失ったか尋ねる。彼は鍵を失ったと言い、二人で一緒に街灯の下を探す。数分後、警官はここで本当に失くしたのか尋ねると、酔っ払いは「いいえ、公園で失くしました」と答える。警官はなぜここで探しているのか尋ねると、酔っ払いは「ここが明るいからだ」と答える。

奇妙なことに、メタモルフィックテストはmediumよりもxhighで少なく使用されました。

ECC

ECC Rustテストスキルはまずまずの結果でしたが、主にスキルの大部分が無視されたためです。エージェントは一般的にスキルを開いて読みました(160/160が読みました)、これによりテストがより多く生成されたようです。この条件では、エージェントはより多くのテストを生成しただけでなく、エージェントがスキルを読んだ時期(早いか遅いか、あるいは読まなかったか)を見ると、露出ベースの勾配でテストが追加された数に違いが見られます。

ECCはデフォルトとほぼ同じスコアを獲得しましたが、エージェントがスキルにさらされたときのパフォーマンスに基づくと、これはランダムだと推測します。エージェントがスキルを早く見たほど、その動作はより影響を受け、正確性の結果は悪化しました。

ECCは生のスコアに関してはまずまずでしたが、スキルを読まなかった7人のエージェントが異常に良い結果を出し、100%の正確性を達成し、その後、ECCに遅れて目を向け、わずかに影響を受けた9人のエージェントも良い結果を出し、100%の正確性を達成しました。これは、mediumがxhighと同じスコアを獲得したという異常なECCの結果も説明しています(これらの実行のうち、エージェントがスキルをほとんど見なかったのは、mediumで発生しました)。スキルがいつ呼び出されるかどうかにバイアスがある可能性はありますが、全体的なパターンは、ECCが効果的ではないことを示唆しています。ただし、ECCが幸運のお守りとして結果を改善すると考える場合は別ですが、それはスキルが実際には使用されていない場合にのみ発生し、それは低努力レベルでより可能性が高いです。

もちろん、エージェントは見ていないスキルに影響されるべきではありません。スキルが実際にエージェントに影響を与えたケースを見ると、ECCは平均を下回るスコア(Rust組み込みフレームワークとCreusotの間)であり、Rust組み込みフレームワークと同様の失敗モードで、多くの小さく意味のないテストがありました。スキルはエージェントに赤・緑のTDDを使用するように指示します。エージェントの動作は、TDD実践者がTDDと呼ぶものではないかもしれませんが、エージェントは機能実装の前に小さなテストを作成し、結果として多くのテストが生成されます。前述のように、これはエージェントが開発するための効果的な方法ではないため、結果は指示なしおよびスキルなしよりも悪いです。

ちなみに、Cavemanモードを試したときに指摘したように、かなりのばらつきがあり、人々はしばしば少数の小さな実行によってスキルが有用であると思い込まされます。この場合、スキルを160回実行しましたが、これはかなり大きな数であり、合理的な人間が行うよりも多いです。それにもかかわらず、表面上、スコアだけを見ると、ECCはまずまずに見えます。

LLMを使用する際のノイズを平均化するために、はるかに多くの実行が必要になります。ここでやったように、結果を検査し、人間の脳を少し使うことができますが、公開LLMベンチマークについて人々が話すとき、スキルであれ他のものであれ、これはほとんど行われていないのを見ます。それどころか、トップラインの数字を渡すのを見ることがほとんどです。たとえそれが無意味な場合でも、退屈な統計的理由のためであったり、さらに悪いことに、ベンチマークが致命的に欠陥がある場合、それはSenior SWE-Benchの場合でした。

Default

Defaultは、エージェントにテストまたは検証の指示を与えませんでした。

これまでの結果から、Defaultが平均を上回るスコアを獲得したことは驚くことではありません。エージェントは、特定のライブラリを使用したり、特定のテストテクニックを使用するように指示された場合、一般的に有用でないことを行っていました。エージェントに無用な作業をさせる指示を与えない方が、無用な作業をさせる指示を与えるよりも良い結果になるというのは理にかなっています。

Audit

Auditは、実装後にコードを監査するようにエージェントに指示しました。160/160のエージェントが実際にこれを行い、151のエージェントが問題を検出したと主張し、その結果として変更を加えました。エージェントは一般的に合理的な監査対象を選択しましたが、通常は独立した監査を新しいコンテキストで行わず(これは私がしばしばエージェントに依頼することです)、しばしば既に犯したのと同じ間違いを監査でも犯しました。

42が独立したエージェントを使用しましたが、これらの実行は実際には成績が悪かったです(これは因果関係ではなく、エージェントがより悪い、またはより困難な状況にあったため独立した監査を開始したと判断した可能性があります)。Auditはxhighで最高の正確性を達成しましたが、mediumでは平均以下の正確性であり、この監査はすべて、特にxhighでコストを大幅に増加させました。平均すると、AuditはDefaultと同程度であり、xhighでは本当に良いがmediumでは悪いのかどうかは定かではありません。それはもっともらしいですが、十分な証拠があるとは思いません。

Em Chuは次のようにコメントしています。

ここでの結果は私の経験と一致しています。コードの監査は、現在私のトークンのほとんどを消費する場所です。なぜなら、私はそれが非常に有用だと感じているからです。ただし、私は常に2つの指示を与えています。

  • サブエージェントを起動しないでください。コード/差分を自分で読み、理解してください。
  • コードを実行しないでください。

なぜなら、私はLLMがどちらかのことを許可すると著しく愚かになると感じるからです(もちろん、測定はしていませんが)。コンテキストウィンドウを超えるような大きな変更を一切行わない場合でも、実際にはコードを読み込んだり推論したりしません。

また、通常は「敵対的になれ」「すべての可能な機能の組み合わせを考慮せよ」「入力空間全体を考慮せよ」のようなくだらないものを含めますが、それがどれほど役立つかはあまり確信がありません。

それは興味深い試みになるでしょうが、最近の投稿で指摘したように、投稿の詳細を減らすように努めているため、それは別の投稿のトピックになるかもしれません。

Audit and fuzz risky areas

Zstdの場合、この指示に従うと、エージェントはFSE(FSE)、Huffman(Huffman coding)、ビットリーダー、および状態に重点を置きました。これらは一般的に、エージェントがしばしば問題を見逃す領域であり、エージェントはこれらの領域がリスクが高いと正しく考えていました。ファジングの対象となった領域は、プレーンなFuzzing条件よりも良い選択でした。

mediumの努力レベルでは、エージェントは指示をほとんど無視し、実行しませんでしたが、xhighでは指示に従いました。この条件は成績が悪かったわけではありませんが、指示なしよりも良くはありませんでした。

実際のエージェントの動作を見ると、一つの問題は、エージェントが単に多くのランダムな入力を生成することが多く、それらは一般的に無効であり、興味深い条件をテストしなかったことです。

人間テスターがランダム化されたテストを生成する場合、一般的にランダム化を「興味深い」入力を生成するようにターゲットしますが、エージェントはそれを怠りました。エージェントはまた、出力を効果的にチェックせず、多くの場合、クラッシュのみをチェックしました。ファジングはしばしばクラッシュのみをチェックし、プロパティをチェックしないことと関連付けられているため、これはそれほど驚くべきことではありませんが、おそらく人間がZstd実装をテストする場合に望むものではないでしょう。

Make no mistakes

これは技術的にはDefaultよりも高いスコアを獲得しましたが、動作は実質的に異ならないように見え、スコアは非常に近いです。これはランダムな変動によるものだと推測します。私が結果を見たすべてのレベルで、それらはDefaultのランダムな描画と区別がつきませんでした。

Kani

KaniはRustのモデルチェッカーライブラリです。

「実際にコードに形式手法を適用する」という点では、KaniはZstdコードで実際に使用されたため、最も良いカバレッジを持っていました。しかし、それは時々しか起こらず、ほとんどの使用は表面的なものでした。

実際にKaniの使用が些細ではないバグを捉え、Rustコードの変更につながったケースが1つありました。160回中1回は素晴らしいとは言えませんが、エージェントが時々Kaniを合理的に使用するのに偶然出会うことができることを示しています(これは、RL環境で使用された場合、モデルがKaniをより効果的に使用する方法を学習できるだろうと推測します)。

Kaniは他の条件よりも顕著に高いコストがかかりました。これは、Kaniの出力を繰り返し読み込むことが高価であったため、高い入力トークンコストにつながったようです。

ACL2

ACL2は定理証明器です。ここの結果について注意すべき点の一つは、多くのケースでACL2がOOM(192 GiB制限)になったことです。OOMの結果はカウントされなかったため、結果は不明瞭な方法で偏っています。

ACL2はDefaultよりも高いスコアを獲得しましたが、これが因果関係があり、重要であるなら驚きです。他のほとんどの形式手法で見られたように、ACL2は主に正確性に大きな影響を与えないことを証明するために使用されたため、これが正確性を向上させる理由は不明です。

多くの異なる条件では、他の条件が著しくパフォーマンスを低下させない限り、Defaultまたはそれに相当する"Make no mistakes"がトップに来るとは予想しません。

Proptest

Proptestはプロパティベーステストライブラリです。

他のランダムテストと同様に、ほとんどのテストはあまり興味深くなく、ランダムネスへの過度の依存が低いカバレッジにつながりました。

プロパティベーステストの一般的に貧弱な使用にもかかわらず、proptestの縮小機能(テスト失敗を引き起こすより単純な入力を発見すること)は時折いくらかの価値を提供しました。これは、他のほとんどのケースで見たほとんど価値がない、または全くないよりも優れています。

Property-based testing

他のテクニックベースのアプローチと同様に、エージェントはすべてのオプションがインストールされたコンテナを持っていました。すべてのエージェントがproptestを選択したため、これは実質的に2番目のproptest条件になりました。

proptest条件と同様に、テストはほとんど良くありませんでしたが、時折バグを見つけ、縮小機能はいくつかの勝利を生み出したようです。

この2番目の「偶発的な」proptestアームも、proptestと同様に平均を大きく上回るスコアを獲得したことは、わずかに興味深いです。

Skill

ここでは、Skillは私がテストするための単純なスキルをテストするために書いたスキルを指します(大規模/複雑なスキルとは対照的に、私が関連テストスキルを検索したときに発見したものです)。

おそらくスキルを使うべきですが、私は実際にはそれを使わず、代わりにプロンプトを維持し、何が起こったかを見て、さらにプロンプトを続けることをしています。その結果、私はスキルについて良いスキルを作るものが何であるかについての直感を持っていません。しかし、Max Bittkerは、テストに関する私の頭の中の情報の一部をエンコードしようとするテストスキルで結果を見るのは興味深いだろうと提案しました。その結果を見て、彼は「だから言ったじゃないか」という反応をしました。

私はこれについて事前に登録された予測を書きませんでしたが、私の頭の中の予測は、これがうまく機能しないだろうということでした。2015年に人間への伝達を試みたことから、書面でテスト方法を明確に説明するのは得意ではないと思います。私は人々と一緒に座って、彼らに何をするかを見せました。これは一般的に彼らを生涯変え、平均をはるかに超えるバグ発見者に変えましたが、人に見せて伝えることと、それを書いて伝えることは異なる(そしてより簡単な)スキルです。

この場合、スキルは次のとおりでした。

  • 実装前に微妙なバグが発生しやすい領域について考える。それぞれの領域について、考えられる間違いと妥当な代替解釈を述べ、結果が異なるチェックを作成する(境界の両側で非対称/境界例を優先する)。
  • 実装後、高リスク領域については、本番コードのコンテキストなしで独立して結果を再導出し、比較する(新しいコンテキスト、ヘルパー関数を再利用しない)。
  • 可能な場合は、プロパティベーステストまたはランダム入力を利用して空間を探索する。ノーパニックまたはクラッシュしないランダム化には労力を最小限にする。
  • ランダム化する場合、興味深い状態とコードパスを探索する入力に傾ける(単に同じエラーパスにすべて入るような入力を無造eseにランダム化するだけではない)。これには構造化されたランダム入力が必要になる場合がある。
  • 詳細について不確かな場合は、独立した推論を使用して何が正しいかを確認する(新しいコンテキスト、ヘルパー関数を再利用しない)。

これは最も高いスコアを獲得しましたが、意図した通りには機能しませんでした。実際には、新しいコンテキストのことはほとんど行われなかったため、そこに含まれていたのは無意味でした。それが効果的なもので、エージェントにもっと頻繁に行わせるために洗練する必要があるのか、それとも削除すべきものなのかはわかりません(技術的には最適な頻度で発生している可能性もありますが、私はそれを強く疑っています)。

「Audit and fuzz risky」で指摘したように、エージェントはリスクの高い領域を特定する方法を知っているように見えましたが、これはエージェントが正しいことをしたことを必ずしも意味しませんでした。例えば、エージェントはZstdのエンコードとデコードのビットストリーム反転をリスクが高いと特定しましたが、エージェントはこれらを実行するテストでより良くはなりませんでした。特定の例を見ると、medium実行#35では、エージェントがこれをリスクが高いと特定し、独立した導出と監査を行いましたが、それでも失敗しました。関連するテストがありましたが、入力は回文だったため、順序を反転させても同じ結果になり、この部分が逆になっている実装の失敗を許容しました。

もう一つの問題は、ファジング/プロパティベーステストのすべてが「手動」で行われたことです。エージェントがproptestの使用に慣れており、proptestが頼りになる有用な仕組みを持っていることを考えると、このスキルは、エージェントにproptestを使用するように指示することで、簡単に改善できるでしょう。エージェントへの指示は、標準的な失敗モードである無用な「ランダムすぎる」テストの生成を最小限に抑えることを意図していましたが、方向性としては機能し、より多くのエージェントがいくらか意味のあるテストを生成しましたが、テストは依然として人間が書くであろうものよりも劣っていました(アクティブな人間のガイダンスを持つエージェントも同様です)。これを反復せずに、一般的なガイダンスが何であるかはわかりません(Zstdの構造を数分間見て、Zstd固有のガイダンスを与えることとは対照的に、これは私が他の問題でうまく機能したことの一つです)。

スキルの最初のドラフトとして、これはひどいものではないと思いますが、まだ使用する準備はできていないと思います。もし、RFCライクな問題、ビット操作集約的な問題などに過学習していないことを確認するために、さらに多くの例で試された改善されたバージョンを見ることができればと思いますが、私は通常スキルを作成せず、一度も反復したことがないため、これは私や他の人間が実際にエージェントを操作する場合に何をするかを捉えられていません。

私はプロンプトを作成し、結果を見て(必ずしもコードではなく、エージェントが何をしたと言っているか、そしてエージェントの要約、そして一部の実際の実験結果)、それに基づいて再度プロンプトを作成することに慣れているため、情報を事前にロードすることには慣れていません。これは、情報に反応することとはかなり異なる問題です。以前のファジング作業から、エージェントが陥りやすい失敗モードを見てきました。このスキルはそれらの失敗モードを防ぐことを意図していましたが、時々チェックする方が、完全に事前にロードするよりも簡単です。そして、事前にロードされた指示は、標準的な失敗モードを止めるには十分ではありませんでしたが、いくらか緩和しました。

前述のように、データをきれいで見やすい方法で分割しようとしませんでした。それは、エージェントが実際に行ったことを見ると、ほとんどがかなり非効果的だったように思われ、"Verusを悪く使っているエージェント"が"QuickCheckを悪く使っているエージェント"よりもどれだけうまくやっているかを見るのは、それほど興味深いとは思えません。私が少し興味深いと思うことの一つは、リスクが高い、または微妙なバグが発生しやすい領域を特定するように求められたとき、エージェントはそれを実行できたことです。

しかし、一般的に、提案されたライブラリやテクニックに関わらず、エージェントはそのテクニックを使用できませんでした。以前議論したように、単にエージェントに「テストしろ」と頼んだり、繰り返しテストをもっとするように頼んだりしても、テストは不十分になります。テストテクニック(そのうちいくつかは個人的に非常に効果的だとわかっています)を使用するように依頼しても、テストは不十分になります。私が書いた迅速で簡単なスキルは、物事を少し改善できるかもしれませんが、実際に役立つには、私が費やした2分よりも多くの時間が必要でしょう。Yossi Kreininは、ソフトウェアテストの状態はひどいので、エージェントが(いわば)トレーニングにフォールバックした場合、貧弱な結果を期待すべきだというコメントをしました。これは私たちが目にしたものです。

何らかの理由で、エージェントはproptestの使用においていくらか優れているように見えましたが、テストのレベルは、proptestのマニュアルを読み、テスト方法のガイダンスを受けた合理的な人間が期待するものよりもはるかに低かったです。より多くのガイダンスを受けたエージェントが、他のライブラリよりもproptestでより効果的かどうか興味がありますが、それは別の投稿のトピックです。なぜなら、私は投稿を30分で終わらせるように努めており、ここでは9000語を超えており、30分でタイプするのに合理的な量を超えています。

スキル作成に関する素朴な考え

スキルについて十分な知識がないため、良いスキルをどのように書くかは言えませんが、この投稿で見たすべてのスキル(私が数分で書いたものを除く)と、これらの他の2つの実験からのスキルは、人間向けのチュートリアルの指示のように書かれているように見えます。つまり、スキルの目標は、何かを行う方法を説明することのようです。私のようなスキルを1つしか書いたことのない人間の素朴な考えは、すでにトピックに関するある程度の知識を持っているモデル(ここでは他の実験でもそうでした)と連携する場合、これは最適ではないだろうということです。モデルはすでに何らかのデフォルトの動作分布を持っているため、行動を可能にする指示を書くのではなく、その動作を変更する声明を与える方が自然なことだと感じます。

明白な問題の一つは、ハーネス、モデル、および努力レベルごとに異なるデフォルトの動作が得られることですが、プロンプトやスキルに大量のテキストを投入しても、実際にはこれを変更しません。それは、エージェントをデフォルトから遠ざけるための長い方法にすぎず、意図しないプッシュを行う可能性のある多くのテキストが含まれています。ここで見たように、テキストの多くは無視されます(そして、何がいつ無視されるかは、ハーネス、モデル、および努力レベルに依存します)。例えば、ECCスキルでは、読まれた場合でも、ほとんどの指示は無視され、TDD指示は影響力がありましたが(結果を悪化させました)、TDDを実行するという指示は、明確に記載されていたにもかかわらず、実際には従われませんでした。

効果的なプロンプトのタイプは、モデルリリースや努力レベルの間で十分に変化するため、「コードをうまくテストする」といった一般的なことについて、これらのスキルが多くのモデルや努力レベルでどのように機能するのかは不明です。GPT-5.5からGPT-5.6への移行だけでも、GPT-5.5でかなり確実に機能していた多くのことが機能しなくなったり、信頼性が大幅に低下したりしたため、私の作業方法は大幅に変化しました(全体的な能力レベルは高いにもかかわらず)。GPT-5.6をGPT-5.5のようにプロンプトしないのと同じように、同じスキルを使いたくないと思います。

AIラボの誰か以外で、各モデルと努力レベルに対して何が効果的かを確認するためにスキルを評価し、モデルと努力レベルで差別化されたスキルのポートフォリオを作成する手間をかける人がいるかどうかはわかりません。また、AIラボが競合他社のハーネスやモデルに最適化されたスキルを持っているとは期待できません。そのため、一般的な「テスト」スキルについてはわかりません(前述のように、テストしたスキルと同様の失敗モードを持つと思われるテストスキルをいくつか見ました)。しかし、私がよく使う特定のハーネス/モデル/努力レベルで機能するいくつかのスキルを持つことはできるでしょう。

テストについて考えてみると、特定のモデルが特定の努力レベルで陥る特定の落とし穴があり、それらから抜け出させたいのですが、テスト対象のもの、望む品質レベル、および品質の次元に依存しない、エージェントに一般的に実行させたい汎用的なテストワークフローはありません。そのため、エージェントが一般的に実行すべきテスト手順のセットを概説する汎用テストスキルは望まないと思います。これは私が実行する多くのタスクに当てはまります。タスク固有の方法で実行したいのであり、汎用的な方法ではありません。私に質問をして、正しい指示をエージェントに発行するようなスキルの種類を想像できますが、モデルが急速に改善していることを考えると、個人的な使用のために何かを作成する場合、それが有用になるまでそのようなスキルを調整するのに時間を費やすのは意味がないと思います。もし私がエージェント製品に取り組んでおり、より多くの人にそれを使用してもらいたいのであれば、それは別の話かもしれませんが、私が試したスキルはここでテストしたスキルと同じ失敗モードを持っていたため、あまり効果的ではないスキルを作るのはかなり簡単に見えます。

スキルは、エージェントにワークフローの実行方法やAPI/インターフェースとの対話方法を教えるようなものには、一般的に役立つ可能性があると思います。例えば、Sawyer Hoodのウェブブラウザを操作するエージェントを支援するスキルなどです。私はそのスキルを試したことはありませんが、それを推奨しているわけではありません。しかし、それを読むと、エージェントにウェブブラウザを操作させようとするときに、非常にうまく機能し、多くの手間を省くことができるように思えます。しかし、実際のスキル(およびスクリプト)を読むと、ここで試したテストスキルとは非常に異なるスタイルを持っています。

マックス・ビットカー、ヨッシ・クレイン、エム・チュー、デニス・スネル、@panoramic.blue、ジェイミー・ブランドンにコメント/修正/議論に感謝します。

P.S. 過去数回の投稿に、半端な(ほとんど修正/監査/クリーニングされていない)結果をできるだけ早く書き上げる実験を行っているという注記を付けています。なぜなら、エージェントは実験を非常に迅速に実行できるため、そうでなければ何も書き上げないからです。実際、この実験はプログラミング言語のトークンコスト/正確性実験を実行した直後に実行しましたが、正規表現エンジンの作成とインタープリタおよびネイティブコードコンパイラの作成、Codexの正規表現クエリでネイティブコードコンパイラを使用するripgrepのフォーク版を実行する実験、その他いくつか書き上げる時間がなかったものについて書き上げたかったため、これを書く時間がありませんでした。これらの各書き上げを30分で行うことを目標としていましたが、実行した実験と書き上げたものの間にはまだかなりの遅れがあります。

数年間、私はこのような実験を実行し、興味深い結果を数人の友人に話して、そのままにしていました。もしこれらのより迅速な(そして質が低い)実験と書き上げについて意見があれば、どう思うか教えてください(X Bsky Mastodon)!

付録:いくつかの応答

David R. MacIver は次のように述べています:

残念ながら、@danluu さんは正しいです。Hegelスキルは現在、あまり良くありません。

多くのエージェントスキルの一般的な問題は、エージェントがエージェントスキルを書くのが下手で、私たち(私たち自身も含む)もスキルを書くためにエージェントを使用していることだと思います。

共通の友人が、MacIverが(後に?)ベンチマークを設定し、Hegelスキルの欠陥を確認し、スキルを改善するか、Hegelのコメント/ドキュメントを調整してスキルが不要になるように取り組んでいると述べました。もしこの投稿から得られる唯一のことがHegelのスキルの改善であれば、それはすでに素晴らしいことだと思います。以前議論したように、測定とベンチマークは過小評価されていると思います。なぜなら、単に測定値を公開するだけで、人々が知らなかった問題点を示し、いくつかの変更を動機付けることができるからです。この投稿も、変化を引き起こした投稿の1つです。これは、そのような投稿の1つであることは素晴らしいことです。

付録:エージェントの愚かさ

分析のために単純なルックアップをエージェントに依頼した後、それは2時間20分実行されたPerlプロセスを実行し、私がそれを終了させました(私は本当にこのようなものを自動的に検出する何かが必要ですが、それはかなり一般的です)。

A subagentはPerlを使用して比較的小さいファイル(44kB、1364行)に対して正規表現検索を行いましたが、式はPCREで退化的であり、組み合わせ的に大量の作業を行いました。私はここで数分で構築しようとしたFRE正規表現エンジンを使用してこれを再実行しようとしましたが、0.7秒でマッチングが完了しました(Rust正規表現は0.6秒でした)。

エージェントが何かをしているときに何が起こるかわかりませんが、少なくともこの状況は防ぐことができました。第一に、エージェントはこのような組み合わせ爆発を引き起こす可能性のある正規表現エンジンを呼び出すことを避けるべきでした。このために、より安全な正規表現エンジン(例えば、デフォルト設定のripgrep)を使用しない明確な理由はないようです。第二に、エージェントは発行しようとしている正規表現を発行できたはずです。実際の発行された正規表現は、無用なほど大きなキャプチャを返し、成功した場合に意図したとおりに機能しません。第三に、サブエージェント(またはハーネス)は、サブエージェントが終了した後でも、このようなもの(この場合は、これを起動したサブエージェントが30秒後に停止しましたが、検索はサブエージェントによって使用される結果を返すことを意図しているため、サブエージェントが終了した場合には価値がないにもかかわらず、このプロセスを無期限に実行し続けました)を自動的に終了させることができたはずです。

私は実際にエージェントが残したものをクリーンアップするプロセスを持っています(エージェント自体がメモリをリークしたり、一時的なビルド成果物がスペースを消費したりするなど)が、暴走したPerlプロセスを探していませんでした。これも追加すべきものですが、この問題に遭遇した人は私だけではないはずです。私のくだらないツールのソースコードを公開することもできますが、主要なハーネスがこの問題を修正すれば、それは時代遅れになるはずです。したがって、AIラボがこの種のことをすぐに修正するだろうと考えると、私のツールをオープンソース化する理由はないはずです。

付録:実験の詳細

迅速に書くために、これを省略します(すみません!)。条件間の分布は、言語が正確性とトークンコストに与える影響を見たときの分布と根本的に異なりません。この投稿を30分で書き上げたいと思っていましたが、10k語近くになっており、これは間違いなく30分以上の執筆量です(30分で10k語は毎分300語以上です)。

一つ指摘しておきたいのは、このプログラミング言語に関する投稿と同様に、非常に興味深く説得力のある結果に見えるものがいくつかありました(少なくともトップレベルのグラフを見て、何か目立つものがあるかどうかを見た場合)。しかし、それらを詳しく見ると、実験を設定するためにエージェントに短いプロンプトを与えたことによる実験エラーが原因でした。それらのエラーを修正すると、より退屈な否定的な結果が得られました。ただし、Codexが提案したスキルが有用に見えた部分は、逆効果になったという点を除きます。


  1. 全体として、IMAPの結果はあまり興味深いものではありませんでした。ビジネスロジックの問題として、より興味深いかもしれないと思いましたが、言語を見たときに見たpandoc評価ほど巨大で高コストではありませんでした。それには、一部のあまり効果的でない言語で実行あたり1kドル以上のAPIコストがかかり、Rustでは30%のテスト合格率を得るだけでも700ドル/実行かかりました(この評価は、完璧なスコアを達成した実行の割合という、はるかに難しい指標を使用しています)。IMAP評価では、完璧なスコアを達成したのは1回の実行だけでした(mediumでの"Make no mistakes")。一般的に、5.6 Solにとって一発で処理するには少し複雑すぎるロジックがいくつかありました。一つの見方としては、"Make no mistakes"がmediumで2.5%のスコアを獲得し、他のすべての条件で0%だったということです。最後に、"Make no mistakes"が機能した証拠です!

実際の結果を見ると、以前と同様に、すべての方法はあまり効果的ではありませんでした。適合性が高いと思われるものでさえそうです。例えば、TLA+はIMAPの状態と並行性に自然に適合するため、うまくいくと思うかもしれません。原理的には、プロトコルの多くの高レベル部分をモデル化するのに適しているはずです。しかし、Zstdの結果で見たように、エージェントはほとんどの実装をRustで行うことを「決定」し、その後、初期プロンプトで指示されたツールを取り出しました(80人のエージェントのうち5人がコーディング前にTLA+を使用しましたが、80人中75人がその逆を行いました)。何らかの理由で、エージェントはほとんどの場合、TLA+を使用して小さなメールボックスの変更をモデル化することを選択しました。複数のオブザーバー、イベントキュー、UIDVALIDITY、メールボックスエポックなどをモデル化するためにTLA+を使用したエージェントはいませんでした。これらの領域でエージェントは実装で多くの間違いを犯しました。代わりに、エージェントはCONDSTOREやQRESYNCのようなものをモデル化しましたが、Default条件は99.6%以上のテスト合格率を持っており、TLA+エージェントはこれらのことをモデル化していたにもかかわらず、合格率が低かったです。

私が試したすべての評価に共通する一つのことは、それらがRFCであるということです。これは非常に非現実的ですが、それらが非現実的である方法は、仕様がほとんどのプログラマーがエージェントに実装を依頼するときにエージェントに与える仕様よりも、はるかに明確で、詳細で、曖昧さがないことです。ここで見た失敗モードは、ほとんどの現実世界の問題では同じか、それ以上であると予想されます。

(戻る)
2. 面白いことに、ChatGPTに事実確認を依頼したところ、この段落は間違っていると指摘されました。なぜなら、人々がテストを書くためにRL環境を使用したことを訓練したという論文があるからだと述べ、単体テストを書くように訓練されたエージェントが悪いテストを書いた3つの論文をリンクしました。これはまさに、LLMが今日行うような悪いテストにつながる可能性のあるものです。効果的なテストテクニックをより理解している人間がエージェントを指導する必要があるのです。人々が正確性を重視する複数の独立したサブフィールドでは、人々は一般的に、単体テストを書くこととは反対の、いくつかの関連テクニックのセットに独立して収束しています。もちろん、エージェントをこの、人々が正確性を真剣に考えるときにやることとは反対のことをするように訓練することは、良い正確性につながる可能性は低いです。

RL環境とランダムテストに関連するいくつかの研究があります。この論文などですが、モデルが特定のガイダンスなしに{PBT、ファジング、ランダムテストなど}のいずれかで非効果的であることから、これは大手のAIラボのモデルのトレーニングに真剣には組み込まれていないようです。

(戻る)
3. 人々の言語の優位性に関する表明された理由は、モデルがはるかに良くなった後に真実になるかもしれませんが、そうなる理由はほとんどありません。推測するなら、ポーカーのようなものになるでしょう。人々は、シミュレーションがコンピューターが多くの状況で人間を打ち負かすことができるほど強力になったとき、無効にされた最も効果的なものについての考えをたくさん持っていました。人々が最適なソルバープレイと一致すると言う「レンジアドバンテージ」のような「現代的な」概念でさえ、ソルバーデータからは実際に出てきません、詳しく見ると。それらは単に心地よいカクテルパーティーのコンセプトであり、理解しやすく、説得力があるように聞こえます。

人間が人間にポーカーを教える場合、これらの概念を使用することはまだ理にかなっているでしょう。なぜなら、カジュアルプレイの場合、人間はソルバーラインを研究して最適なものに近いものを理解するほど、一般的に研究したくないからです。しかし、コーディングエージェントが何が得意で何が苦手かについて話す場合、実験を実行して何が機能するかを確認できるのに、カクテルパーティーのアイデアを無意味に振り回す理由はありません。そして、これまでに実行された実験は、これらの抽象的な理由Xが良いまたは悪いという説明のほとんどを裏付けていません。

(戻る)