- エージェンティック・コーディングでは「仕様書でコードを置き換えられる」という主張に対し、仕様が十分に精密になると結局はコードと同じ形に収束せざるを得ないという根本的な限界を指摘
- OpenAIのSymphonyプロジェクトを見ると、そのSPEC.mdは仕様ではなく、実質的にはMarkdown形式の疑似コードである
- 実際にSymphonyの仕様をもとにHaskell実装を試みた結果、多数のバグやエージェントの無限待機など、信頼性の問題が発生
- 仕様作業は本来コーディングよりも深い思考を要求するが、現在の業界における速度最適化の風潮の中では、AIが生成した低品質な仕様が量産される構造になっている
- 「garbage in, garbage out」の原則はコーディングエージェントにもそのまま当てはまり、明確さと詳細さを欠いた文書からは信頼できるコード生成は不可能
エージェンティック・コーディングにおける二つの誤解
- エージェンティック・コーディング擁護派が拠り所にする二つの核心的な誤解がある
- 誤解1: 仕様書は対応するコードより単純である — エンジニアを仕様書を書く管理者へと変え、エージェントのチームに作業を委任できるというアウトソーシング的な見方
- 誤解2: 仕様作業はコーディング作業より必ず思慮深い — 仕様書を挟めば品質が向上し、よりよいエンジニアリング実践が促進されるという主張
仕様のふりをしたコード: Symphony事例の分析
- OpenAIのSymphonyプロジェクトは、仕様書(SPEC.md)から生成されたエージェント・オーケストレーターとして紹介されているが、実際のSPEC.mdの内容は仕様というよりMarkdown形式の疑似コードに近い
- SPEC.mdに含まれる内容の種類:
- データベーススキーマの散文的ダンプ —
session_id、thread_id、codex_input_tokens などのフィールド列挙
- コードの散文化 — 並行性制御の
available_slots = max(max_concurrent_agents - running_count, 0) のような式、再試行バックオフの式(delay = min(10000 * 2^(attempt-1), agent.max_retry_backoff_ms))など
- モデルのコード生成を助けるために明示的に追加された "Config Fields Summary (Cheat Sheet)" のような重複セクション
start_service() 関数のように、実質的にはコードそのものである「Reference Algorithms」セクション
- 仕様書がコードの代替物だと主張しながら、その文書自体がコードのように読めるのは欺瞞的である
- 仕様書を十分に精密にしようとすれば、必然的にコードの形へ変形させるか、高度に構造化された形式的な英語で書かなければならない
Dijkstraの「狭いインターフェース」論
- Dijkstraの文章を引用し、インターフェースの選択は単なる労働分配ではなく、インターフェースをまたぐ協業とコミュニケーションのコストが追加されると述べる
- ギリシャ数学は言語的・視覚的活動にとどまって停滞し、イスラム代数学は修辞的スタイルへ回帰して衰退し、西欧が中世スコラ学の「空虚な言語的精密さの試み」から脱し、Vieta、Descartes、Leibniz、Booleらの形式的記号体系によって発展したという歴史的事例を示す
- エージェンティック・コーダーは、エンジニアリング労働が要求する**「狭いインターフェース」(= コード)** を避けることはできず、その労働を見かけ上は違っても同じ精密さを要求する形に変換できるだけである
不安定性: 仕様ベースのコード生成における信頼性の問題
- Symphony READMEが推奨する通りにClaude CodeへHaskellでの実装を依頼した結果、動作しなかった
- 多数のバグが発生し、プロンプトによる修正が必要だった(コミット履歴で確認可能)
- エラーメッセージなしに「動作」する場合でも、
codex エージェントが簡単なLinearチケット(「空のgitリポジトリを作成」)に対して何の進展もなく無限待機した
- Dijkstraの言い方を借りれば、Symphonyの「空虚な言語的精密さの試み」は、それでもなお信頼できる実装生成に失敗していることが確認された
- この問題はSymphonyに限られない — YAML仕様のように極めて詳細で広く使われ、適合性テストスイートまで備えた仕様であっても、大半のYAML実装は仕様に完全準拠できていない
- Symphonyの仕様は、すでに含まれているElixir実装の6分の1の規模に達しており、さらに拡張すれば、Borgesの「正確さについての科学」——帝国と同じ大きさの地図を作って結局無用になったという寓話——のような状況に至る
- 「より主流の言語で生成すれば結果はよくなる」という反論については、エージェントがHaskellコード生成に苦戦するのであれば、それは学習データを越えた一般化能力の不足を示唆している
スロップ(Slop): AI生成仕様の品質問題
- 仕様作業は本来、コーディングより難しいはずであり、コーディングを始める前にプロジェクトを熟慮的・批判的な視点から見つめさせることが目的である
- しかし、技術企業で労働を縮小・過小評価しようとする業界の流れの中で、「仕様作業はコーディングより簡単だ」という前提から出発すれば、失敗は避けられない
- 納品速度の最適化を追求しながら、仕様作成が要求する難しく不快な作業をこなすことは不可能である
- Symphony SPEC.mdのSection 10.5(
linear_graphql extension contract)は典型的なスロップの例であり、「仕様らしく見える」文の寄せ集めという一貫性・目的・全体像の理解を欠いたエージェント生成物の形を取っている
query は空でない文字列でなければならない、正確に一つのGraphQL操作を含まなければならない、など個別の規則は列挙されるが、全体的な文脈が欠けている
- このような仕様書は、人間が書いたとしても必然的にスロップにならざるを得ない — 一貫性や明確さではなく、納品時間に最適化しているからである
- コードスニペットが構文ハイライトなしで
text として注釈されている点もAI生成文書の兆候であり、モデルが依頼の趣旨ではなく文字通りの指示に従った結果だと推測される
結論
- 仕様は本来、時間を節約するための仕組みとして設計されたものではない
- 納品時間の最適化が目的なら、中間の仕様書を挟むよりもコードを直接書く方が有利である
- 「garbage in, garbage out」 の原則はそのまま適用される — 明確さと詳細さに欠ける文書を入力すれば、コーディングエージェントがその不足分を信頼性高く埋めてくれるような世界は存在しない
- コーディングエージェントは心を読む存在ではなく、たとえそうだとしても、思考そのものが混乱していればどうにもならない
6件のコメント
モデル主導開発のときとまったく同じことのようですね。
仕様ベース開発であるSDDは、もともとあったものではないでしょうか。
Python や JavaScript ベースのソリューションは、詳細な仕様書だけでも十分満足のいく実装が可能なようですね。こちらは C/C++ ベースのゲーム・医療分野なのですが、FULL AI AGENT への委任どころか、詳細な仕様書だけで自動化するのもかなり冒険だと感じるこの頃です。
Hacker Newsのコメント
曖昧なドキュメントを与えてもコーディングエージェントは詳細を補えない、という話には同意しない
LLM は本質的に 言語の補間/外挿マシン であり、不足した詳細を埋めるのが非常に得意だ
短く簡潔な説明だけで動くコードを作り出す例は多い
ただし、こうした詳細補完が常に正しいわけではなく、信頼性を確保するには重要な部分を明示的に制約する必要がある
現在はコードを書く文化はあるが、超精密な仕様を書く文化は NASA のような場所を除けばほとんど存在しない
コードが短くありふれているほど上手くいくが、複雑な説明では簡単に破綻する
結局「詳細補完が間違うことがある」と認めるのは、信頼できる生成が難しいという意味だ
たとえば Synquid のようなプログラム合成言語がある
数学的に正確な仕様がプログラム生成においてどんな限界を持つかを示している
specification gap と呼ばれる問題、つまりプログラムが仕様を忠実に実装していると証明することが核心的な課題だ
自然言語は曖昧すぎて、プログラムを定義するには不適切だ
LLM がもっともらしい詳細を埋めるからといって、このギャップが解消されるわけではない
数学的仕様言語は精密だが学習曲線が急で、単に Markdown でプロンプトを書くよりはるかに難しく、労働集約的だ
モデルが自分の関心を記憶していたり、自前の知識で隙間を埋めたりして、完成したアプリやゲーム、ホワイトペーパーを生み出す
あるときは「まさに自分が欲しかったもの」であり、またあるときは「自分が言おうとしていたまさにその感じ」になる
意味、文脈、ニュアンスを扱う能力については、人間以上に見える部分さえある
AI はますます 賢く有能 になっている
つまり、まったく新しい詳細を創造しているというより、学習データから引き出しているのに近い
「十分に詳細な仕様はすなわちコードだ」という言葉には共感する
これは Brooks の No Silver Bullet の議論と同じだ
だが大半の人は、そこまでの詳細さを望んでいない
「AI に ToDo アプリを作って」と言うとき、実際には「自分が想像したものより良いアプリを作って」と言っているに等しい
だがこのアプローチは、別種のソフトウェアにはあまりうまく拡張できない
結局その差別化要素を仕様として表現する必要がある
だが データベース、ファイルシステム、並列計算 のように正確性と性能が重要な領域では、仕様より実装のほうがはるかに難しい
こうした分野で AI が形式検証を通るコードを作るのは大きな挑戦だ
収益化したり競争したりするには、具体的な要件が必要になる
vibe coding を情報理論の観点で見ると、小さなプロンプト空間から有用なプログラム空間を復元する デコーダ が存在する、という仮定になる
このとき圧縮率こそが vibe coding の利得だ
「IRC チャネルベースのチームコミュニケーションアプリ」のようなプロンプトは、Slack を知らなければ復号できない
したがって、何が欠けているか を認識することが重要だ
効果的に AI コーディングを行うには、プロンプトを短い単位に分け、既存のドキュメントや試したコードなども一緒に与える必要がある
Algorithmic Information Theory によれば、文字列の情報量は最も圧縮された自己完結的表現の長さに等しい
ただし「自己完結的」という条件は、モデルの 重みがコードブックの役割 を果たすときにしか成り立たない
人間は LLM よりはるかに多くの 共有文脈 を前提にしているため、デコーダの限界を過大評価しがちだ
だが強い制約と明確な重点を持つシステムなら、vibe coding の圧縮率を爆発的に高められる気がする
自然言語は、プログラミング言語よりアクセスしにくい人々に 新しいインターフェース を提供する
LLM が代わりに考えてくれるわけではないが、アイデアを動くシステムに変える 新しい経路 を開いてくれる
そのうち人々は、モデル性能とトークン効率のために LLMSpeak のような技術英語の方言を作るようになる気がする
曖昧さを減らし、トークンを節約し、複雑な概念を単語ひとつに圧縮するようなものだ
文法的にも Oxford comma のような規則が生まれ、明確性を高めるだろう
そこまで細かく仕様化するなら、わざわざプロンプトを書く理由がない
結局、人間の言語で再定義する必要があるので、トークン節約効果は限定的だ
Lojban wiki, Lojban話者の動画 を参照
人工方言の試みは Esperanto のように失敗する可能性が高い
こうした言語は、むしろ LLM 同士で使うときに有用かもしれない
すでにプログラミング言語がその役割を果たしている
仕様(spec)とは、その条件を満たすすべてのプログラムを含む 封筒(envelope) のようなものだ
この封筒を作ることは、単一のプログラムを書くことより難しい
LLM が毎回違うコードを生成するように、仕様は良い実装も悪い実装も許容する
実際には、ひとつの実装が採用されると、それが次のバージョンの事実上の仕様になる
既存コードのある環境(brownfield) では仕様がきれいではないため、LLM はうまく対応しにくい
仕様の 1 行が他の行とどう相互作用するかまで考えなければならないという 組み合わせ爆発 がある
しかしコンパイラの立場から見れば、コードもまた仕様にすぎない
結局「コードのほうが仕様より簡単だ」というのは相対的な話だ
「ユーザー資格情報を保存する」という仕様は、bcrypt から平文 cookie まで含みうる
人間には「それはやってはいけない」という直感があるが、エージェントは明示しなければ分からない
したがってセキュリティを確保するには、してはいけないこと まで仕様化しなければならない
性能やセキュリティが重要なら、その属性を明記すべきだ
たとえば「このプログラムは O(n) でなければならない」といった文は、実装よりはるかに簡単だ
人によって spec の意味を違う使い方をしているように見える
私にとって spec は「何をするか(what)」を定義するもので、plan は「どうやるか(how)」、build packet は「詳細なステップ」を意味する
たいていの場合、重要なのは「何を」だ
データが A から B へ、C を経由して D に保持され、E で F の形式で表現されることを仕様として書くのは、Rust コードとして実装するよりずっと簡単だ
「エージェント型エンジニアリング」をやってみると、仕様書がコードより長くなること がよくある
自然言語は不完全だが、コードは正確だ
仕様の目的は、何度も反復開発しても機能を維持することにある
テストやコメントよりも ウォーターフォール型の設計文書 のほうが効果的だった
このやり方で、完全な vibe coding プロジェクトのリファクタリングや言語変更もスムーズに進められた
今はまるで 70〜80 年代の開発フローに戻ったような感じだ
「TCP インターフェースを実装せよ」のような文は、実際のコードよりずっと短い
結局、明確なスキーマ にマッピングできるなら、自然言語も十分に圧縮的でありうる
Spec → LLM の方向は非効率で無駄が多い
むしろ LLM → Spec のほうが現実的だ
仕様がコンパイル可能な形で存在するなら、LLM はそのフィードバックを受けてより良いコードを生成できる
「検証済み英語(validated English)」を作ろうという試みは、むしろ複雑さを増す
結局重要なのは、実際に動くコードだ
コードには、仕様よりはるかに多くのものが含まれている
ほとんどのプロジェクトでは 90% が フレームワークやインフラのコード で、ビジネスロジックは 10% にすぎない
仕様は言語やフレームワークの細部を扱わないので、ずっと簡潔だ
そうすると仕様とほぼ同じレベルのコードになる
ドメイン専門家でも読めるし、テストもしやすい
だが実際のコードはかなり大きく変わる
仕様を 管理ツール として見る視点と、エンジニアリングツール として見る視点の衝突が認知的不協和を生んでいる
マネージャーは仕様を委任チケットとして見るが、開発者は思考を磨く 思考の道具 として使う
一部の開発者は便宜上マネージャーの考え方で始めるが、すぐに気づくことになる
ハイプや投資家向けミーティングでしばらくは持たせられても、最終的にユーザーが欲しがるのは 実際の製品 だ
この次はウォーターフォールとアジャイルも再発明するんでしょうね。
C組み込み開発者として、Feature/Subfeatureについてほぼすべての流れをchartで確認できるように仕様を作成したうえで
仕様を長く検討して最終確定したあと、
仕様と完全に1対1で対応するコードを生成して使っています。
仕様でレビューすると、コードレビューより可読性が圧倒的に高いので。