NTTドコモR&Dの技術ブログです。

【Spec Kit】Web開発初心者がAI駆動でアプリ作ってみた

目次

今回のテーマ

こんにちは!NTTドコモ R&D戦略部の青栁です。
業務ではLLM(大規模言語モデル)の研究開発をしており、今年2本目の記事投稿になります。
(下記の1本目の記事もぜひご覧ください!) nttdocomo-developers.jp

宣伝はさておき本題に入ると、最近会社の業務でWebアプリを作る必要が出てきました。 しかし、私自身はスマホアプリの開発経験はあるものの、Web開発の経験はほとんどありませんでした。 そのためどうしようか悩んでいたところ、GitHubが公開した「Spec Kit」というAI開発ツールがあることを知りました。

AIと対話しながら仕様書を固め、そこから開発を進めていく「仕様駆動開発(Spec-Driven Development)」を支援するものらしいのですが、これを使ってWeb初心者がアプリを作ることは可能なのでしょうか?

今回はテスト用アプリとして、「自分が行った飲食店を記録して閲覧できるWebアプリ」を作ることができるか調査してみました。


Spec Kitを使った開発

Spec Kitの使い方

まず、Spec Kitの使い方ですが、以下のGitHubレポジトリのREADMEに記載があります。 github.com

まずは、以下のコマンドでSpec Kitをインストールします。

uvx --from git+https://github.com/github/spec-kit.git specify init <PROJECT_NAME>

そして、/speckit.〇〇〇というコマンドが多数定義されているので、それらを使って開発を行っていきます。

仕様と技術計画の作成(/speckit.specify, /speckit.plan)

まずは以下の2つのコマンドで「仕様」と「技術計画」を入力する必要があります。

  • /speckit.specify: 仕様の作成

    Use the /speckit.specify command to describe what you want to build. Focus on the what and why, not the tech stack.
    (技術的なスタックは抜きにして、「何をどんな目的で」行うためのアプリなのかを明確にする)

  • /speckit.plan: 技術計画の作成

    Use the /speckit.plan command to provide your tech stack and architecture choices.
    /speckit.specify で決めた仕様を実現するために、「どういう技術(スタック、アーキテクチャ)で作るか」を明確にする)

とはいえ、Web開発初心者の私にとって、いきなり「仕様」や「技術計画」をまとめるのは困難です。 そこで、まずはGeminiに入力内容の壁打ち相手になってもらうことにしました。

Spec Kitの /speckit.specify/speckit.plan に入力する内容を整理してもらうため、具体的には以下のようなプロンプトをGeminiに入力しました。

Geminiに最初に入力したプロンプト

行った飲食店を記録するWebページを作りたい。
Webについて詳しくないので、要件を固めるための壁打ちをさせて。
最終的に以下の2つをまとめて欲しい。
・仕様
何を構築し、なぜ構築するのか
・技術的側面
スタック、アーキテクチャ、制約条件等

現在考えている要件は以下の通りであるが、疑問点があれば確認して。
<店の登録>
・最大100件まで登録できる
・行った店で撮った写真をアップロード(最大5枚まで)
・テキストで感想を入力
・総合評価、味、コスパ、ユニークさを星5段階で評価する
・タグも複数個登録可能
・住所も登録(市町村単位まで)

<店の表示>
(全体表示)
・サムネイルで店名と総合評価(例:★★★★☆)、市町村(例:東京都千代田区)
・店名やキーワード、タグ、市町村で検索が可能
・1ページに20件表示。全部で5ページまで存在。(<前へ 1 2 … 5 次へ> のようなよくあるUIでページ移動)
(個別表示)
・全体表示で店をクリックすると、個別ページが表示され、上記で登録した要素が表示される

これに対するGeminiの回答が以下になります。 アプリの利用者や機能面など、抜けている点を確認する質問が来たので、回答します。

Geminiの回答

こんにちは。飲食店の記録Webページ作成、面白そうですね!要件を固めるための壁打ち、承知しました。

いくつか確認させてください。これらが明確になると、どのような技術で作るのが最適かが見えてきます。

🙋‍♂️ 確認したいこと
  1. 利用者は誰ですか?
    • あなた個人だけが使う(記録・閲覧する)想定ですか?
    • それとも、友人や不特定の他の人にも見せたり、登録してもらったりしますか?
    • (これによって、ログイン機能などが必要かどうかが変わってきます)
  2. 編集・削除機能は必要ですか?
    • 一度登録したお店の情報(感想、写真、評価など)を、後から修正したり、お店の登録自体を削除したりする機能は必要ですか?
  3. なぜ「Webページ」で作りたいですか?
    • (例えば「プログラミングの学習を兼ねて」「PCでもスマホでも見たい」「デザインを自由に作りたい」など、目的によって最適な作り方が変わるためです)
  4. 検索の「キーワード」とは?
    • 「キーワードで検索」とありますが、これは具体的にどの項目(「店名」や「感想」のテキストなど)を検索対象にしたいですか?
  5. 技術的な希望や制約はありますか?
    • 特に使ってみたいプログラミング言語や技術(例: Python, JavaScript, React, WordPressなど)はありますか?

まずは、特に 1〜3 について教えていただけると、グッと具体的な仕様に近づけると思います。
もちろん、他の点についても「こうしたい」というイメージがあれば、ぜひお聞かせください!

上記に対する筆者の回答

  • 友人や不特定の他の人にも見せるが、登録は自分だけが可能
  • 編集・削除機能は必要
  • PCでもスマホでも見たいのでWebで作る
  • 店名、タグ、市町村、感想等のテキストで検索する
  • バックエンドはPython, フロントエンドはNext.js(TypeScript)を使いたい

そして、Geminiによる最終的なまとめが以下になります。 「仕様」と「技術的側面」について詳細にまとめてくれました。

Geminiによる最終的なまとめ

いただいた情報に基づき、「仕様」と「技術的側面」の2点にまとめます。


1. 仕様(何を構築し、なぜ構築するのか)
プロジェクト概要

何を構築するか:
あなた(管理者)だけが登録・編集できる、個人用の「飲食店訪問記録 Webアプリケーション」を構築します。
登録されたデータは、友人や不特定多数の人が閲覧できる公開ギャラリー(ポートフォリオ)として機能します。

なぜ構築するか:

  • 自身が訪問した飲食店の記録(写真、感想、評価など)を一元管理し、PCやスマートフォンからいつでも閲覧できるようにするため。
機能一覧
👤 管理者機能(あなた専用)
  • 認証:
    • 管理者(あなた)だけがデータの登録・編集・削除を行えるよう、ログイン機能が必要です。
  • データ登録 (Create):
    • 新しい飲食店の情報を登録します。
    • 登録件数の上限は 100件 です。
  • データ編集 (Update):
    • 一度登録したお店の情報を後から修正します。
  • データ削除 (Delete):
    • 登録したお店の情報を削除します。
🌍 閲覧者機能(全員に公開)
  • 一覧表示 (トップページ):
    • 登録されたお店を一覧で表示します。
    • 各お店の情報として「サムネイル(写真1枚目)」「店名」「総合評価 (例: ★★★★☆)」「市町村」を表示します。
    • 1ページあたり 20件 表示します。
  • ページネーション:
    • 全100件のデータを20件ずつ、最大5ページ に分けて表示します。(例: <前へ 1 2 3 4 5 次へ>
  • 検索機能:
    • 「店名」「タグ」「市町村」「感想テキスト」を対象としたキーワード検索機能を提供します。
  • 詳細表示:
    • 一覧ページで特定のお店をクリックすると、そのお店の登録データ(下記「データ項目」参照)をすべて表示する個別ページに移動します。
データ項目(お店ごとに登録する情報)
  1. 店名 (テキスト)
  2. 写真 (画像ファイル、最大5枚までアップロード可能)
  3. 感想 (テキスト、複数行入力可)
  4. 評価 (星5段階評価)
    • 総合
    • コスパ
    • 面白さ
  5. タグ (複数登録可能、例: #ラーメン, #ランチ, #個室あり)
  6. 住所 (市町村単位まで、例: 東京都千代田区)

2. 技術的側面(スタック、アーキテクチャ、制約条件)

「指定スタック」「迅速な立ち上げ」を満たすための、現実的かつモダンな構成案です。

推奨技術スタック
  • フロントエンド: Next.js (TypeScript) (指定通り)
    • UIコンポーネント: Tailwind CSSChakra UI などを利用すると、レスポンシブデザイン(PC/スマホ対応)を効率的に実装できます。
  • バックエンド: Python + FastAPI
    • 指定のPythonを使用します。フレームワークとして、モダンで高速、ドキュメントも豊富な FastAPI が Next.js とのAPI連携に最適です。
  • データベース (DB): Supabase (PostgreSQL)
    • セットアップが容易で、リレーショナルデータベース (PostgreSQL) を即座に利用できます。
  • 画像ストレージ: Supabase Storage
    • アップロードされた写真(最大 100件 * 5枚 = 500枚)を保存するために、DBと同じSupabaseのストレージ機能を使うのが最もシンプルです。
アーキテクチャ(構成案)

「ヘッドレス (Headless)」 または 「Jamstack」 と呼ばれる、フロントエンドとバックエンドを完全に分離する構成を推奨します。

  1. フロントエンド (Next.js):
    • UI(見た目)とユーザー操作を担当します。
    • データの表示・検索時は、バックエンドAPIにリクエストを送信します。
  2. バックエンド (Python FastAPI):
    • 「API (Application Programming Interface)」として動作します。
    • フロントエンドからのリクエスト(例: 「お店一覧をください」「このお店を登録して」)に応じて、データベースを操作(読み書き)し、結果をJSON形式で返します。
  3. データベース & ストレージ (Supabase):
    • お店のテキスト情報(店名、感想、評価など)は SupabaseのDB (PostgreSQL) に保存します。
    • アップロードされた写真は Supabase Storage に保存します。
認証(「自分だけ」登録・編集する方法)

バックエンドAPIを悪用されないよう、登録・編集・削除の操作には認証が必要です。

  • 学習目的ならJWT (JSON Web Token) 認証の実装がおすすめです。
    1. Next.jsで管理者用ログインページを作成します。
    2. FastAPIでID/パスワードを検証し、成功したら「トークン」を発行します。
    3. Next.jsは、以降の登録・編集リクエスト時にその「トークン」を一緒に送信します。
    4. FastAPIは「トークン」が正しいか検証してから処理を実行します。
  • 手軽さ重視なら: Supabaseに組み込まれている Supabase Auth を利用するのも手です。
制約条件と考慮事項
  • データ上限 (100件):
    • プログラム側で登録件数をカウントし、100件に達したらそれ以上登録できないように制御する必要があります(DBの機能というより、アプリケーションのロジックで実装します)。
  • ページネーション (5ページ):
    • 100件固定なので、フロントエンド (Next.js) で 1 2 3 4 5 のボタンを静的に配置しても良いでしょう。
    • 学習目的なら、バックエンドAPIに「何ページ目のデータを要求するか」(例: /api/restaurants?page=2) を伝え、DBから該当の20件だけを取得する(LIMITOFFSET)実装がより実践的です。

Geminiとの壁打ちで、仕様と技術的側面が明確化されました。 それぞれ、GitHub Copilotのチャット欄で、下記の画像のように/speckit.specify/speckit.plan の引数にそのままコピペして貼り付けます。

今回、生成AIのモデルは「Claude Sonnet 4.5」を使用しました。 上記のコマンドを入力すると、基本的にはAIが作業を進めていきつつ、所々人間側にレビューを求めてくるので、チャットで修正依頼をしたり、ファイル書き込みの承認ボタンを押したりします。

/speckit.specifyではspec.mdというファイルが生成され、以下のようなユーザーストーリーが整理されます。

spec.md(抜粋)

User Scenarios & Testing
User Story 1 - 訪問記録の閲覧 (Priority: P1)

訪問者(友人や一般の人)が、管理者が訪問した飲食店の記録を一覧で閲覧し、興味のある店舗の詳細情報を確認できる。

Why this priority: このシステムの主要な価値提供は「記録の共有・公開」であり、閲覧機能がなければアプリケーションの存在意義がありません。最も基本的で重要な機能です。

Independent Test: 管理者が事前に登録した店舗データ(少なくとも1件)をブラウザで閲覧し、一覧ページと詳細ページが正しく表示されることを確認できます。登録・編集機能がなくても、サンプルデータで独立してテスト可能です。

Acceptance Scenarios:

  1. Given システムに10件の飲食店が登録されている、When 訪問者がトップページにアクセスする、Then 10件すべての店舗が一覧表示され、各店舗のサムネイル、店名、総合評価(星表示)、市町村が表示される
  2. Given 一覧ページに複数の店舗が表示されている、When 訪問者が特定の店舗をクリックする、Then その店舗の詳細ページに遷移し、店名、全写真、感想、4種類の評価、タグ、住所、食べログURLが表示される
  3. Given システムに25件の飲食店が登録されている、When 訪問者がトップページにアクセスする、Then 最初の20件が表示され、ページネーション(1, 2)が表示される
  4. Given 訪問者が2ページ目を表示している、When 訪問者がページネーションの「1」をクリックする、Then 1ページ目(最初の20件)が表示される

また、/speckit.plan ではplan.mdというファイルが生成され、以下のような技術スタックをはじめ、ページ読み込み時間などの非機能要件も整理されます。

plan.md(抜粋)

Technical Context

Language/Version: - Frontend: TypeScript (Next.js 14+) - Backend: Python 3.11+

Primary Dependencies: - Frontend: Next.js, React, Tailwind CSS または Chakra UI - Backend: FastAPI, Pydantic, python-jose[cryptography] (JWT), python-multipart (画像アップロード) - Database Client: supabase-py

Storage: - Database: Supabase (PostgreSQL) - Image Storage: Supabase Storage

Testing: - Frontend: Jest, React Testing Library - Backend: pytest, pytest-asyncio

Project Type: Web application (frontend + backend分離)

Performance Goals: - 一覧ページ読み込み: 3秒以内(最大100件、ページあたり20件) - 検索結果表示: 2秒以内 - 画像アップロード: 5MB以下の画像、1枚あたり10秒以内

Constraints: - 店舗登録上限: 100件 - 画像枚数上限: 1店舗あたり5枚、全体500枚 - 画像ファイルサイズ: 1ファイルあたり5MB以下

Scale/Scope: - 想定ユーザー数: 管理者1名、閲覧者数十名程度 - データ件数: 最大100店舗、最大500画像 - 画面数: 約6画面(一覧、詳細、検索結果、登録フォーム、編集フォーム、ログイン)

タスク分割・実装(/speckit.tasks, /speckit.implement)

この後は、/speckit.tasksで具体的な作業タスクに分割し、/speckit.implementで実装を行います。

/speckit.tasksでは、下記のような100タスクに分割されました。

/speckit.implementでは、基本的には人間がコードを書くことはなく、全てAI任せです。 ここに関しては、Webプログラミングの知識がない自分にとって、非常に助かりました。 人間はデータベースやデプロイの設定と実行テストを行い、必要に応じて問題点を指摘していきます。ちなみに、コマンド別ではここが最も時間を要しました。
- /speckit.specify/speckit.plan/speckit.tasks: 各10分程度
- /speckit.implement: 約6時間

完成したサイトの画面

最終的に以下のようなサイトを完成させることができました。

サイト画面


AI駆動開発における課題

Spec Kitにより、Web開発初心者の私でもそれらしいアプリを形にすることができました。
しかし、「コマンド一発で完璧なアプリが完成したか」というと、答えは No です。

実際に納得のいくクオリティにするまでには、上記のように 約6時間 の試行錯誤(主に /speckit.implementでの修正)が必要でした。
開発プロセスを通して感じた、AI駆動開発における壁や課題についてまとめます。

1. 「動くコード」と「実用的なコード」の差

AIは「仕様書に書かれた機能」を実装するのは得意ですが、仕様書に明記されていない「当たり前」の品質を担保するのが苦手な場合がありました。

特に以下の点は、AI任せにしていると見落とされがちなポイントでした。

  • モバイル対応の欠如: 「PCとスマホで見たい」と要件に入れたものの、初期実装ではレスポンシブ対応が不十分で、スマホで見るとレイアウトが崩れてしまった
  • パフォーマンスへの配慮(N+1問題): DBへのアクセス処理において、都度クエリを発行するような、いわゆる「N+1問題」が発生。機能としては動くが、データ量が増えると極端に重くなる実装
  • キャッシュ戦略: 画像や静的データのキャッシュ設定が考慮されておらず、毎回フルロードが発生

これらは熟練のエンジニアなら無意識に実装するレベルのことかもしれませんが、AIには明示的に指示しない限り、最短ルート(とりあえず動く実装)を選ばれる傾向があります。

2. ツール選定とコスト管理

今回、AIが提案した技術スタック(Next.js + FastAPI + Supabase等)について、Web開発に詳しいチームメンバーにレビューを依頼したところ、「モダンな構成を活用できており、選択として違和感はない」という評価をもらいました。一般的なWeb開発に関しては、AIは確かに筋の良いアーキテクチャを提案する能力を持っているようです。

しかし、もし相談できる有識者が周りにいなかったらどうでしょうか?全くの初心者が、AIの提案に対して商用レベルでの採用可否を判断し、自信を持って開発スタートのGoを出すことは非常に困難だと感じました。

また、AIの知識は学習データに基づいていると考えられるため、ツールの最新機能や料金体系、規約変更などが完全には反映されていないリスクがあります。 今回のようなプロトタイプ開発なら許容できますが、実際のビジネスで運用する場合、ツール選定やコスト管理の最終判断は、AI任せにせず人間が最新情報を調査・検証する必要があります。「AIが提案したから」ではなく、「人間が裏取りをして承認したから」というプロセスが不可欠だと痛感しました。

3. ドキュメントとコードの乖離

開発上で非常に大変だったのが ドキュメントの更新忘れ です。

開発が進むにつれて、「やっぱりこの機能を変えたい」「バグがあったのでロジックを変える」といった修正が発生します。AIに指示すればコードは修正してくれますが、ドキュメントの修正は忘れられがちです。

その結果、コードは最新だがドキュメントは古いという状況が多く発生しました。
この場合、AIはドキュメント側を正として認識するため、次の修正指示を出した時に古い仕様に基づいた修正を行いエラーが発生するという負のループに陥りました。 コードだけでなく、ドキュメント類も常に同期させるよう、人間側が管理・指示する必要があります。

4. セキュリティ面

最後に、最も気をつけたいのはセキュリティ面です。 今回AIが実装したコードについて、AI自身にセキュリティチェックをさせたところ、以下のような脆弱性が多数指摘されました。

また、開発中のやり取りの中で、APIキーなどの機密情報を平文のままコードに書き込み、GitHubにプッシュしようとする場面 もありました。 .env ファイルに切り出すよう指示すれば修正してくれましたが、何も言わなければそのまま公開されていました。

セキュリティに関しても、AIを過信せず、人間が最終的な責任を持つ必要があると痛感しました。


まとめ:Web初心者はSpec Kitでアプリを作れるか?

結論として、「作れるが、完全な自動化はまだ厳しい」 というのが私の感想です。

Spec Kitの強みとして、何もない状態から仕様と設計を固め、土台となるコードを一気に生成するスピードは圧倒的です。Web初心者の私でも、環境構築からデプロイまで辿り着けました。 一方、人間の役割として、生成されたものの良し悪しを判断し、セキュリティやコスト、非機能要件といった細かい部分を補正する監督者としての役割が求められると感じました。

ただ、これまで「何から手を付けていいか分からない」と立ち止まっていた初心者にとって、Spec Kitが強力な相棒になることは間違いありません。これからWeb開発を始める方は、ぜひ一度AI駆動開発を体験してみてはいかがでしょうか。