AIコーディングエージェントが明確な仕様を必要とする理由
本記事は、「AIエージェントは賢いので詳細な仕様は不要」という考えに反論し、最小限の仕様はコストを後工程に先送りし、完全な仕様はコストを前倒しすることを示す。著者は、AIが仕様問題を消すのではなく、むしろ顕在化させると主張する。エージェントを使って仕様の作成と検証を行い、ビヘイビア駆動開発(BDD)を採用することで、総コストを下げつつ制御可能にできる。マルチエージェントパイプラインでは特に、強い型付けインターフェースと実行可能な検証器が必要である。
本記事は元々Markus Eiseleのニュースレター『The Main Thread』に掲載され、著者の許可を得て転載されています。
現在、開発者コミュニティで次のようなメンタルモデルが広まっています。「エージェントは賢いので、物事を自分で理解できる。したがって、事前の詳細な仕様化は不要な官僚的オーバーヘッドだ。目標をゆるく記述し、エージェントに探索させ、修正しながら進めればよい。速く、柔軟に、モダンに。」
これは間違っています。エージェントの能力が不足しているからではなく、会計処理が間違っているからです。あなたはコストを排除しているのではなく、先送りし、断片化し、見えにくくしているのです。
実際の台帳を見てみましょう。
二つの極、二つの隠れたコスト
一方の極は最小限の仕様です。意図をゆるく記述し、エージェントが自由に解釈し、即座に作業を開始します。人間の労力の初期コストはほぼゼロです。しかし、すぐには見えない下流で累積するコストがあります。修正ループがあり、それぞれがトークンコストと人間の再関与時間を伴います。レビューサイクルでは、人間がすべての出力のオラクルとなり、エージェントが生成したものが本来意図されたものかどうかを判断します。そうでなければ再作業が発生します。
もう一方の極は完全な正式仕様です。TDD、BDD、Gherkinシナリオ、受け入れ基準をコード実行前に確定します。初期の人間の労力は現実的で目に見えます。しかし、下流の検証コストは根本的に異なります。テスト自体がオラクルだからです。合格か不合格か。人間はすべての出力を個別に評価する必要はなく、仕様が自動的、反復的に、疲労なく評価します。
実際にトレードオフしているのは、いつどの通貨で支払うかです。最小限の仕様はトークンコストを前倒しし、人間の判断を後回しにします。完全な仕様は人間の労力を前倒しし、後回しにするものはほとんどありません。自動検証は実行回数に応じてスケールしません。
仕様の完全性に対して総コストをプロットすると、両方のアプローチはU字型の曲線を描きます。その曲線の最小点、つまり最適点は、構造化された受け入れ基準やBDDシナリオのあたりにあります。ゼロ仕様でも40ページの正式要件ドキュメントでもありません。
落とし穴は、完全な台帳をプロットしたときに初めて見えます。最小限の仕様は、下流の再作業がチャートに入るまでは安く見えます。マルチエージェント作業では、ハンドオフ間でドリフトが蓄積するため、最小点はさらに右に移動します。
古くからの問題は常に仕様だった
ソフトウェアエンジニアリングにおける真の課題は常に仕様でした。
タイピングでも構文でもなく、抽象的なアーキテクチャでもありません。難しいのは、何が存在すべきか、何が決して起こってはならないか、どのトレードオフが重要か、システムが何を忘れてよいか、そして世界がチケットよりも複雑なときに「完了」とは何かを合意することでした。
エージェントはその問題を取り除きません。むしろ可視化します。
何十年もの間、我々は仕様問題を会議、バックログ、コードレビュー、QAサイクル、インシデントレトロスペクティブ、シニアエンジニアの個人的なメンタルモデルの中に隠してきました。ソフトウェアエンジニアリングの多くは「コードを書く」ことではなく、不完全に指定されたアイデアを十分な摩擦にかけ、欠けている部分を強制的に明らかにすることでした。
エージェントはコード生成の摩擦を減らします。それは素晴らしいことです。しかし同時に、欠けている部分が後で表面化することを意味します。なぜなら、誰かが実装の意味を本当に決める前に、システムはもっともらしい実装を生成できるからです。
旧世界では、曖昧な要件は人間の遅さにぶつかりました。エージェントの世界では、曖昧な要件は機械の速さにぶつかります。
実装が安くなると、ボトルネックは消えません。仕様と検証に移ります。
しかし、仕様を書くことは問題の半分に過ぎない
このトレードオフのほぼすべての枠組みが見落としていることがあります。仕様はエージェントに渡す前に検証される必要があるということです。
これは明白に聞こえますが、実際には体系的に無視されています。
仕様を書くとき、たとえ注意深く書いても、エージェントが実行するまで見えない形で失敗する可能性があります。内部で矛盾している可能性があります。二つの要件が互いに矛盾し、どちらも単独では明らかに間違っていない場合です。不完全である可能性があります。ハッピーパスは網羅しているが、サードパーティAPIが429を返したときの動作については何も書かれていない場合です。技術的に正しいがテスト不可能である可能性があります。仕様が機械的に検証できない振る舞いを記述している場合です。そして最も厄介なのは、あなたが書いた通りだが、あなたの意図とは異なる場合です。
エージェントが欠陥のある仕様を忠実に実行すると、デバッグが困難なものが生成されます。与えられたすべてのチェックに合格しています。問題は実装ではなく、上流の仕様自体にあります。そして修正ループはより高価になります。コードだけでなく、推論も巻き戻す必要があるからです。
したがって、仕様検証は「仕様を書く」と「エージェントを実行する」の間にある独立したコストカテゴリです。それは次のことを問います。この仕様は内部で一貫しているか?エージェントを有用に制約するのに十分完全か、しかし有効な解決策を過度に制約しないか?それは実際に我々が構築しようとしているものを記述しているか?
その検証作業は人間の時間か、エージェントの時間か、理想的にはその両方ですが、ゼロではありません。それを正直に台帳に追加した瞬間、状況は変わります。
エージェントが仕様を書く方法
この二極の枠組みが系統的に無視する第三の戦略があります。エージェントを使って仕様を作成・検証し、その後実装エージェントを使って実行するというものです。
これにより、仕様側のコスト構造が変わります。受け入れ基準やBDDシナリオを作成するための重い人間の労力の代わりに、仕様ドラフトエージェントが粗い意図から最初のバージョンを生成します。仕様検証エージェント(別の役割とシステムプロンプトを持ち、検索アクセスやドメイン知識を持つ可能性がある)が、そのドラフトの一貫性、完全性、テスト可能性をストレステストします。テスト作成エージェントが生き残った主張を実行可能なチェックに変換します。あなたは結果をレビューします。これはゼロから書くよりも速いです。
重要なのは、エージェントが単に「要件を書く」べきではないということです。それでは磨かれた霧が生まれます。
有用な仕様作成エージェントは、速記者というよりは懐疑的なプロダクトエンジニアのように振る舞うべきです。前提を明示すべきです。目標と非目標を分離すべきです。例と反例を生成すべきです。どの要件が機械的にテスト可能で、どれが依然として人間の判断に依存するかを示すべきです。怠惰な実装が見逃しそうな障害モードを特定すべきです。有効な解決策にわたって不変でなければならないものを問うべきです。
最良のプロンプトは「仕様を書いて」ではありません。むしろこれに近いものです:
別のエージェントがこれを安全に実装できる最小の仕様を起草してください。前提、非目標、受け入れ基準、エッジケース、観察可能な結果、未解決の質問を含めてください。次に、どの部分が自動テストになり、どの部分が人間のレビューを必要とするかをマークしてください。
その後、出力に対して別のエージェントを実行します:
この仕様を攻撃してください。矛盾、曖昧な用語、隠された依存関係、テスト不可能な主張、欠落した障害モード、そして実装が書かれた基準を満たしながらも意図に違反する可能性のある箇所を見つけてください。
最適点はエージェントが書いた散文ではありません。人間が承認し、エージェントが起草し、敵対的にレビューされた仕様であり、可能な限り多くのオラクルを実行可能にしたものです。
エージェントは仕様の必要性を排除しません。彼らは、仕様が実装を導くのに十分完全でありながら、まだ人間によってレビューされる、曲線の有用な部分へ移動するコストを下げることができます。
これは仕様検証を消し去るわけではありません。誰がどのコストで行うかを変えるのです。実装エージェントを実行する前に仕様を検証しなければならないという構造的要件は変わりません。変わるのは、エージェントがその作業の一部を担うようになることです。
BDDがこの問題を部分的に解決する方法
ビヘイビア駆動開発(BDD)がうまく行われた場合、仕様作成と仕様検証を同じ成果物に統合します。Gherkinシナリオは、意図の記述であると同時に実行可能なテストです。スケルトン実装に対してすぐに仕様を実行し、記述が一貫した振る舞いを生み出すかどうかを観察できます。仕様を実行可能にするという行為は、散文の受け入れ基準にはない一種の検証を強制します。シナリオを実行する前に、ある種のあいまいさを解決しなければなりません。
これが、総コスト曲線の最小点が単に再作業の減少を反映しているのではない理由です。それは、検証がメディアに組み込まれているという構造的優位性を反映しています。
BDDは、判断を繰り返しの人間レビューから実行可能なオラクルに移すときにその価値を発揮します。だからこそ、その最適点はテストするのに十分安定した振る舞いの周辺に現れます。
問題は、誰かが依然としてシナリオをうまく書かなければならないことです。Gherkinは下手に書かれる可能性があります。ビジネス言語の仕様は、BDDフレームワークがキャッチできない方法で曖昧になる可能性があります。なぜなら、曖昧さは構文ではなく、セマンティクスに存在するからです。形式は役立ちますが、規律の代わりにはなりません。
マルチエージェントパイプラインがすべてを壊す
単一のエージェントを適切に境界付けられたタスクで実行している場合、不十分な仕様は回復可能です。フィードバックループは密で、修正は局所的で、コストは制限されています。
マルチエージェントパイプラインはまったく異なるクラスの問題です。
エージェントAの出力がエージェントBの入力になるとき、Aからの解釈のずれはBの実行に増幅されます。BはAが少しコースを外れたことを知りません。Bは間違った基盤の上で懸命に自信を持って作業します。出力が人間の目に触れる頃には、エラーは複数層の一見一貫した作業を通じて増幅され、隠されています。
これにより、損益分岐点は決定的に仕様の方へシフトします。マルチエージェントシステムでは、仕様は単一実行のガイダンスではなく、エージェント間の調整契約です。その契約が不正確であればあるほど、各エージェントの解釈の自由度がばらつきを生み、それが蓄積されます。エージェント間には、緩やかな会話的なハンドオフではなく、強い型付けのインターフェースが必要です。
マルチエージェント作業では、x軸はもはや「どれだけ指定したか」だけではありません。「ハンドオフ契約はどれだけ強いか」です。最小点は、型付き契約と実行可能なバリデータへと移動します。
その契約の検証はそれに応じて重要になります。エージェントを調整する仕様に欠陥がある場合、一つのエージェントが間違ったことをするだけでなく、すべてのエージェントが並行して、それぞれ異なる間違ったことをします。
方法論から何が残るか
では、これはソフトウェアチームの調整について学んだすべてを時代遅れにするのでしょうか?
いいえ。ただし、どの部分が構造的に重要であったかは変わります。
儀式としてのアジャイルは問題があります。ステータスを空気中に読み上げるスタンドアップ、架空の精度を生み出す見積もりの儀式、管理職に不確実性が飼いならされたと安心させるためのチケットセレモニー – エージェントはこれらを必要としません。正直なところ、人間も必要としませんでした。
フィードバックの哲学としてのアジャイルは生き残ります。短いサイクルは生き残ります。抽象的な進捗よりも動くソフトウェアが生き残ります。顧客とのコラボレーションは生き残ります。現実が語るときに計画が曲がるべきだという主張は生き残ります。むしろ、エージェントはこれをより重要にします。なぜなら、エージェントは説得力のある間違ったものを非常に速く生成できるからです。フィードバックループはより密に、緩くではなくなる必要があります。
XP(エクストリームプログラミング)はさらにうまく生き残ります。テストファースト思考は生き残ります。なぜなら、実装が安くなると、実行可能なオラクルがより価値を持つからです。ペアプログラミングは人間とエージェントのペアリングに変異しますが、根本的なアイデアは変わりません。設計判断をコード生産に近づけ続けることです。継続的インテグレーションは生き残ります。なぜなら、すべてのエージェントの変更には迅速で公平なゲートが必要だからです。リファクタリングは生き残ります。なぜなら、エージェントは局所的には正しいが構造的には平凡なコードを生成できるからです。小さなリリースは生き残ります。なぜなら、大きな不可視のデルタは人間とエージェントの両方にとって迷子になる場所だからです。
おそらく消えるのは、大規模なグループ調整のための劇としての方法論でしょう。
[コスト抑制のため原文は一部省略]