仕様駆動開発と開発の手触り

はじめに

ここ数年、AIに支援されてプログラムを開発していくことは当たり前になりました。確かに当たり前にはなりましたが、ChatGPTに代表されるAIチャットアプリ、CursorのようなAIエージェント機能が組み込まれた統合エディタ、ターミナルで動作されるコマンドラインAIエージェント、様々なツールがあり、使い方も人それぞれ。成果や感じている有効性も人によってバラバラ。そんな状態が良いわけではないけれど、様々なツールにトライして自分たちで良い方向性を探ってもらいたい気持ちもある。AIを活用したプログラム開発について私の思いは宙ぶらりんなまま終わった2025年でした。

自分が具体的にコードを書くという作業から離れてしまっていたこともあり、開発者たちへの私からの提案もフンワリしたものになっていました。このままではダメだとの思いが強くなり、一念発起(というほど大げさなものではありませんが)年末年始の時間を使って小さなプロジェクトを手掛けてみることにしました。

何を作ったかというと自慢するようなことは何もなく、AI APIを利用してお手製チャットアプリを作ってみよう。コンテクスト内学習を行うためのヒントプロンプト群を管理できるような。そんなツールを作ってみようくらいのところからスタートしました。

作ったもの自体は役に立つものにはならなそうですが、もっと重要な(実は当たり前な)気づきをもたらしてくれました。そのあたりはまた別の記事に書こうと思います。

↓の画像はそのWEBアプリの画面を切り取ったものです。

なぜ仕様駆動開発を試みようとしたか

なぜ「仕様駆動開発」という手法を試してみたかったのかと言うと。。。

開発メンバーから、AI エージェントと対話しながら行っていく開発は「思ったところと関係ないところを変更されてしまって困った」「間違ったプログラムが生成され修正を繰り返すループから抜け出ることができない」などの声を聞くことが時々あり、それは何か人間側のアプローチが違っていた場合ではないかなぁと漠然と考えていたことがまずありました。

AI支援による開発記事などを読むなかで「仕様駆動開発:Spec-Driven Development」という言葉を2025年に入った頃から目にするようになりました。従来のソフトウェア開発は、まず「仕様」を作り、それに基づいて「プログラム」や「設定」を作るのが基本的なワークフローでした。

仕様が曖昧であれば、それに基づく物作りも危ういものになり、仕様が間違っていれば、それに基づいて作られたものが正解なわけがない。あたりまえのことです。しかし時間的、コスト的な制約や、ときには開発者の気力、体力の制約によって、良くない仕様、仕様になってない仕様、更新されない仕様が作られ、それに基づいた良くないプログラムが作られていく。そのようなことも当たり前になっていたのも事実でした。

どうやら「仕様駆動開発」は、その面倒な仕様をAIと一緒に生成、維持しながらプログラムを開発していくという手法、アプローチのようでした。もしかすると今までの開発体験と似たような感覚で、より良い結果をもたらしてくれる手法かもしれないと考えるようになりました。

最初の一歩

まずは最初の一歩として開発プロジェクトのリポジトリを作りREADMEファイルに何を作りたいのかを書くことにしました。内容は次のようなものでした。

## 要件

– Webアプリケーション

– 認証は行わないがクライアントデバイスを識別し、クライアントデバイスごとに履歴が保存される

– AI ApiとしてGoogle Geminiを利用する

– ユーザーインターフェイスは2つのタブで構成される

– タブ1は「ヒント」、タブ2は「チャット」と呼ぶ

– 「ヒント」タブ、「チャット」タブどちらもチャット形式のユーザーインターフェイスである

– どちらのプロンプトにも1つの画像を添付することができる

– 「チャット」タブで行われる一つのQueryに対して、サーバーでAPIに与えるメッセージは以下の内容を接続したものとする

    – 「ヒント」タブで与えられたQuery + Response

    – チャットタブのQuery + Response履歴

    – チャットタブの新しいQuery

– 「ヒント」タブで行われたQuery + Responseは名前をつけて保存することができる。また名前から再現することができる

– 「ヒント」タブに**今表示されている** Query + Responseが「チャット」タブでのQuery時に利用される。

– 「ヒント」タブはクリアして初期化することができる

– 「チャット」タブの Query + Response も名前をつけて保存することができる。

– 「チャット」タブはクリアして初期化することができる

– モバイル・デスクトップ両方で使いやすいレスポンシブレイアウトにする

– 「チャット」で一つのQueryをリクエストしたときに、実際にAPIにどのようなメッセージを与えているのかをモニターすることができる

繰り返しますが内容については触れないでください🙊。この内容を書くところから始めて↑のようなUIを持つWEBアプリとして(いくつかの仕様を追加しつつ)それなりに使えるようになるまで約1.5日。最近のAI支援開発であれば割と当たり前の時間だと思いますが、私の手元には仕様書仕様通りに動くプログラム、そして仕様とプログラムの状態が常に一致しているgitの履歴が残りました。

今回はOpen AIのGPT 5.2 Codexと対話しながら開発を行いましたが、ソースコードと一緒に作成していった仕様書類は以下のようなものです。小規模開発向けの仕様駆動開発としてChat GPTに勧められた手順をそのまま採用しました。必要十分で良かったと思いました。

  • SPEC.md – 「何を作るか」を確定させるためのトップレベルの仕様。常にここに戻って仕様を修正、詳細化しました。
  • PLAN.md – 「どういう順で作るか」の実行計画
  • DESIGN.md – 「どう作るか」を共有する設計メモ。APIやDBの仕様を作成、更新していきました。
  • TASKS.md – 「今やる作業」の実体リスト。ここに次の作業をチケット化しました
  • TESTING.md – 「どう壊れないことを保証するか」。TASK.mdの作業を確認する手順です

一部手で修正したり追記したりを行いましたが、必ずAIに対して修正、追記内容を共有し、資料の矛盾を解消させたり、次の作業プランを作成させたりしました。

こんなフローになった

実際に私とAI Agentとの間で開発作業中に行われた対話をザックリと図示したものが下の図です。

対話をわかりやすく表現しようと思ったのですが、どうも堅苦しい感じになってしまいました。シーケンス図というよく使われるチャートで表現したものです。左側が「私」、右側が「AI Agent」で、左から右への矢印が私が尋ねたり指示したこと。右から左への矢印がAIからの回答や結果報告です。

loopという箱の中が「繰り返し行われた対話」で、altという箱の中が「もしこうだったら」行われた対話です。大きな繰り返しの中に小さな繰り返しや「もし」が入れ子になっていることがわかると思います。

この作業中とにかく意識したことは

  • 作りたいもの、改善したいものに関する説明を言葉で表現し文書に残すこと
    • (AIなしの場合)プログラムファーストになって文書化されていないものが多くなりがち
  • 仕様文書をできるだけAI Agentにメンテナンスさせ関連する仕様も修正させること
    • (AIなしの場合)こちらを直したけど、あちらを直していないになりがち
  • 仕様文書に基づいて行わせるプログラミング作業は、どのような作業になるのか提案を先に行わせる
    • (AIありの場合)やらせてみてダメだったで暗黒スパイラルに陥りがち
  • プログラミング作業の規模が大きそうだったらタスクを小さく分解させて文書化させて、小さな単位で実行させる
    • (AIありの場合)何が行われたのかを把握ができなくなってしまい思わぬことろの間違いを見過ごしがち

こんなようなことでした。もう少し簡略化すると

  • とにかく仕様文書を先に作る/作らせる。追加、修正、変更作業も常に仕様文書から
  • 仕様文書のメンテナンスもAI Agentに行わせる
  • AI Agentに行わせるプログラミング作業は、何を行うのか実行前に必ず計画を提案させる
  • 作業規模が大きそうだったら小さく分割して実行させる

のようになるでしょうか。

よくよく考えてみると年代は違っても「よいプログラム作成の心構え」として多くの心あるプログラマーが学んできたことでした。相手はAIですが基本は同じなのかもと思ったりしました。

AI Agentをパートナーとする作業のイメージをわかりやすく表現できないかとNano Bananaでイラストを作成してみました。

プログラムの開発作業は、大量に生み出されていく仕様文書群と、それらに基づいて生成されるこちらも大量なソースコードを相手とした戦いです。油断をするとプログラムは腐ったり虫に食われたりして簡単に壊れてしまいます。私とAI Agentは協力しあってその戦いに勝利しようとしています。勝利のためには今取り組まなければならない課題に一緒にフォーカスを当て、協力しあって課題を解決しなければいけない。。。

AI Agentをパートナーとして行う開発作業の中で何となく私の中に心構えのようなものが浮かびあがってきました

  • 勝手に仕様やプログラムを修正してAIを置いてきぼりにしない
  • 内容を一度には理解できない程の大量作業を行わせて(文句も言わずにやってくれますが) AIに置いてきぼりにされない

今回の仕様駆動開発体験で得られた一番大きな成果はこの理解だったように思います。

仕様とプログラムを同時に維持していくことの意味

今回の開発では仕様文書群とソースコードを同じgitリポジトリで管理しました。フォーカスする一つのタスクに対してブランチを作成し、タスクに関連する仕様文書の更新やソースコードの生成、改善作業はそのブランチ内で完結させるようにしていきました。

そうすることによって、あるタスクが始まった(前のタスクが終了した)時点では、仕様文書とソースコードの内容が一致した状態が保証されます。

これは過去のある時点に戻っても、そこでは「仕様文書とソースコードの内容が一致している」という状態が維持されていることを意味します。今まで経験したプロジェクトでこんな状態を維持できたことは一度もないです。

開発者とAI Agentが、いつの時点のものでも仕様文書とソースコードを見ることで、その時点の文脈に戻ることができる。そして正しい情報に基づいて作業を行うことができる。

仕様駆動開発は「手戻りを起こさない」ことを目的とした開発スタイルであるという記事を読んだことがありますが、私はむしろ「手戻りをそれほど恐れなくて良い」開発スタイルではないかと思っています。

開発の手触り

「今までのようなプログラミング」という仕事が終わりそうだという時代の節目がやってきています。プログラミングを長い間生業としてきた私がAI Agentと協力してプログラム作成を行う「仕様駆動開発」という手法に今回チャレンジしてみました。実際に今回の開発ではソースコードを書くことはほとんど行わなかったです。

そうでしたが、私には今までと同じような開発の手触り、手触りとしか表現できないのですが、今までのプログラミングと同じような感覚、喜びや充実感の感覚がありました。何となくですが、このような時代の先にもまだプログラミングの楽しみは残っているような希望を感じられた開発体験でありました。

終わり

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

弊社代表取締役です
18才からプログラミングを仕事にしてきました
紙の本と歩くことが好きです

目次