Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Why You Should Not Commit Your Specs

2026年09月19日に「Dev.to」が公開したITニュース「Why You Should Not Commit Your Specs」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

AIがコードを作る際の指示書(スペック)は、コード完成後にコードベースへ保存せず、削除すべき。自然言語の指示書は曖昧でコードと重複しやすく、すぐに古くなり管理が大変だ。意図はコードや簡潔なドキュメントで示すと良い。

出典: Why You Should Not Commit Your Specs | Dev.to公開日:

ITニュース解説

近年、ソフトウェア開発の現場では、新しい技術や開発手法が次々と登場している。その中でも注目を集めているのが、Spec Driven Development (SDD) という手法である。この手法は、コードを書き始める前に「スペック」と呼ばれる詳細な仕様書を作成し、それを大規模言語モデル(LLM)に入力してコードを自動生成させるというものだ。ここで言う「スペック」とは、APIの仕様書であるOpenAPIやシステムの全体像を説明するREADMEファイルとは異なり、LLMが実装すべき変更内容を具体的に記述したMarkdown形式のファイルを指す。開発者とLLMが協力して作成することが多い。

SDDが普及するにつれて、一つの重要な疑問が浮上する。コードが実装された後、この「スペック」ファイルはどのように扱われるべきかという問いだ。SDDフレームワークの多くは、このスペックのライフサイクルに関して、主に3つのアプローチを取っている。一つ目は、スペックを削除するか、コミットせずに残さないパターン。二つ目は、コードベースにコミットするが、その後は更新されずに時間が経つと古くなってしまうパターン。そして三つ目は、コミットされたスペックをコードと常に同期させ、システムの状態を最新に保つパターンである。中には、高レベルな仕様書だけを更新し、詳細なものは破棄またはアーカイブするといったハイブリッドなアプローチを採用するフレームワークもある。

しかし、筆者はそもそも、これらの「スペック」をコードベースにコミットすること自体に疑問を呈している。実装されたコードの横にスペックを保持することには、いくつかの問題点があるというのが筆者の主張だ。

まず、自然言語の持つ「曖昧さ」が挙げられる。例えば、「隔週」という言葉は「週に2回」とも「2週間に1回」とも解釈できる。コードが存在する前はこのような曖昧さが避けられない場合もあるが、一度コードが書かれれば、それはプログラミング言語という厳密なルールに従った、非常に正確な「機能の記述」となる。人間も機械も理解できるプログラミング言語は、自然言語よりもはるかに明確だ。曖昧な自然言語で書かれたスペックを、精密なプログラミング言語で書かれたコードの隣に置くことは、混乱を招くだけである。

次に、「意図」の表現について。スペックは変更の背景にある意図をコードよりもよく捉えるという意見もあるが、意図を伝えるための他の手段はすでに多数存在している。たとえば、Gitのコミットメッセージやプルリクエストの説明、コードの理解を助けるためのコメント、機能の振る舞いを保証する単体テストや結合テスト、さらには重要な設計上の決定を記録するアーキテクチャ決定記録(ADR)などがある。これらの既存の仕組みを活用すれば、スペックをコミットせずとも意図を十分に伝えられる。

また、「情報の重複」も大きな問題である。コードが実装されれば、スペックのほとんどの内容はコードを見れば自明になる。同じ情報がコードベース内に二重に存在することは、保守の負担を増やすだけでなく、どちらが正しい情報源なのかという「真実の競合」を引き起こす。コードとスペックの内容が食い違った場合、どちらを信じるべきか判断に迷うことになる。

さらに、SDDフレームワークが生成するスペックの「情報過多」も無視できない。実際にいくつかのSDDフレームワークを試したところ、一つの機能追加のために数百から数千行ものMarkdownファイルが生成された事例もある。これほどの膨大な量のファイルを毎回すべて読み込むことは現実的ではなく、プルリクエストのレビュー時にも、レビューアがその内容をスキップしてしまうか、あるいはその確認に多大な時間を要することになる。スペックの主な目的は、LLMと開発者の間で共通の理解を形成することであり、コードが生成され、その出力が開発者によって検証された時点で、その価値の大部分は失われると考えられる。

そして、「陳腐化(Rot)」の問題がある。コミットされたスペックは、コードの変更に伴いすぐに古くなってしまう。古くなったスペックがコードベースに残っていると、LLMがその古い情報を参照してしまい、現在のコードとの違いに混乱をきたす可能性がある。LLMは正確性を重視するため、スペックが古いのか、コードが間違っているのかを判断しようとして、無駄な処理コスト(トークン)を消費することにもつながる。この問題を回避するために「リビングスペック」と呼ばれる常に更新される高レベルなスペックを推奨するフレームワークもあるが、その更新自体にも時間と労力がかかる。

「再生成の幻想」という考え方も筆者は疑問視している。これは、スペックが真のソースであり、コードは必要に応じてAIが生成する使い捨ての出力であるという考えだ。もしシステム全体のコードを削除しても、スペックから簡単に再生成できるという発想だが、なぜわざわざコードを再生成する必要があるのか、筆者には明確な理由が見当たらない。言語やフレームワークを切り替える場合でも、既存のコードとテストを基盤とする方がはるかに現実的で効率的である。

これらの理由から、筆者はSDDにおける「スペック」をコードベースにコミットすることには反対である。代わりに筆者が推奨するのは、以下の方法だ。コードを開発中にスペックを利用するのは問題ないが、プルリクエストを作成する前には削除する。そうすることで、スペックはGitの履歴には残るものの、コードベースに永続的に残ることはない。変更の意図は、コード自体から明確にすることを目指すべきだ。それが難しい場合は、「何を」するのかではなく、「なぜ」そうするのかを説明する、簡潔で情報密度の高いMarkdownファイルを追加すると良い。また、リポジトリは外部のコンテキストなしで完結するようにし、新しい開発者が他の開発者の助けなしにプロジェクトに取り組めるようにするべきだ。すべての情報を一つのREADME.mdに詰め込むのではなく、テスト方法やデプロイ手順など、特定のトピックに関する情報は個別のMarkdownファイルに分割することも有効な手段である。

関連コンテンツ

関連IT用語

関連ITニュース