AI駆動開発でWEBサービスを作ってみる

はじめに
生成系AIの発展が目まぐるしい中、どんなことが出来るのか試してみたく実際に作ることにしました。
最後まで作り終える前にまたトレンドが変わっそうな気もしますが、気長にやっていきます。
ゴール
以下の工程全てAIを使い作成することとします。 細かい調整は適宜手動で行います。
- 要求定義
- 要件定義
- 基本設計
- 製造
- 単体(結合)テスト
- 総合テスト
詳細設計については個人的に実装と変わらなくない?と思ってる人間なのでやりません
利用するAIサービス
いろいろあると思うのですが自分が今使える以下を軸に作成を進めます
- ChatGPT plusプラン
- v0 プレミアムプラン
- GitHub Copilot Proプラン
作るWEBサービス
ブログのサムネイル作成に困っているのでChatGPTに投げるサムネイル生成プロンプトを作るWEBサービスを開発しようと思います。
要求定義
要求定義についてはAIがエンジニア、自分が顧客という設定で進めていきます。 プロンプトのはじめはこんな感じでやってみました。
1あなたはフロントエンドスペシャリストです。
2特に顧客とやり取りを行う上流工程が得意なエンジニアです。
3
4私は顧客となるので質問形式で会話を進めて要求定義書を作成してください。
5
6要求定義書はマークダウン形式で作成をお願いします全文を記述すると長くなるのでトグルで閉じるようにしました。 詳細が気になる人は展開してみてください。
出来上がった要求定義は以下の通りです。
1# サムネイル作成支援ツール 要求定義書
2
3## 1. 背景
4現在、ブログ運営において記事ごとにサムネイル画像を作成しているが、
5生成系AIサービスを活用しても次のような課題が発生している。
6
7- 生成される画像のクオリティが安定せず、意図したデザインにならない
8- テキストベースのプロンプトでは細かな指示が困難
9- 作成・修正に時間がかかり、作業負担が大きい
10
11このため、サムネイル作成に過剰な工数を要し、
12本来注力すべきコンテンツ制作やマーケティング活動に支障が出ている。
13
14## 2. 目的
15サムネイル作成にかかる作業時間とストレスを大幅に削減し、
16誰でも短時間で高品質なサムネイル生成用プロンプトを作成できる環境を構築する。
17
18これにより、ブログ運営全体の効率化とコンテンツ品質向上を実現する。
19
20## 3. 達成したい世界
21- 専門的なプロンプト知識がなくても、誰もが簡単にサムネイルの指示作成ができる
22- 用途・ターゲットに最適化されたサムネイルを短時間で準備できる
23- 作成作業に伴う心理的負担を軽減し、企画や制作に集中できる環境を整える
24
25## 4. 要求内容
26- **用途(サービス向け)・ターゲットユーザー・出力サイズ**を選択または入力できること
27- 作成モードとして、以下2種類を提供すること
28 - **簡易作成モード**:フォーム入力だけでプロンプトを自動生成
29 - **カスタム作成モード**:GUI上で文字・画像・アイコンなどの要素を自由に配置・編集可能
30- 文字要素に対しては、装飾やエフェクト(影、縁取り、発光、ぼかし等)を設定できること
31- アイコン・イラストには、一般的な素材に加えて**人物画像**も含めること
32- 作成結果として、ChatGPT向けに最適化されたプロンプトを生成・表示し、ワンクリックでコピーできること
33
34## 5. 想定利用者
35- ブログ運営者
36- SNSマーケティング担当者
37- 個人事業主・フリーランス
38
39## 6. 成功イメージ
40- サムネイル作成にかかる時間を現状比で50%以上削減できる
41- サムネイルのクオリティ満足度を向上できる
42- サムネイル作成に対する「面倒」「難しい」といった負担感を解消できる要件定義
要求定義のプロンプトに続ける形で要件定義の作成を行います。 始まりは以下の通りです。
1要求定義の内容を元に要件定義の作成をお願いします。
2情報に不足がある場合は適宜質問をお願いします。こちらも同様全文を記述すると長くなるのでトグルにしています。 気になる方は展開して確認してもらえればと思います。
出来上がった要件定義は以下の通りです。
1# サムネイル作成支援ツール 要件定義書
2
3## 1. システム概要
4本ツールは、ブログ記事やSNS投稿用のサムネイル画像を生成する際、
5誰でも簡単・直感的にプロンプトを作成できる支援ツールである。
6
7用途・ターゲット・サイズを入力し、必要に応じてGUIまたは簡易作成モードで要素の情報を設定し、
8最終的にChatGPT等で利用できるプロンプトを生成・コピーできる。
9
10本ツールはフロントエンドのみで動作し、データ保存はブラウザローカルで行う。
11
12---
13
14## 2. 機能要件
15
16### 2.1 共通機能
17
18| ID | 機能名 | 概要 |
19|----|---------|------|
20| F-01 | トップ画面 | 作成モード選択(簡易 or カスタム) |
21| F-02 | 入力フォーム | 用途・ターゲット・サイズの入力/選択 |
22| F-03 | 簡易作成モード | 入力フォームで用途・ターゲット・サイズに加え、以下を入力可能:<br>・文字要素:テキスト内容、エフェクト設定、位置(画面上/右/下/他要素の下 など)<br>・画像要素:画像カテゴリ選択(人物画像・アイコン等)、配置位置(同上)<br>各要素はリスト選択形式で大まかな位置指定を行い、GUIモードのような自由配置は行わない。入力内容から自動でプロンプトを生成。 |
23| F-04 | カスタム作成モード | GUIエディタで要素を配置・編集 |
24| F-05 | プロンプト出力 | 生成されたプロンプトを画面表示 |
25| F-06 | コピー機能 | 出力プロンプトをワンクリックでコピー |
26| F-07 | 設定保存 | ブラウザローカルストレージに「作成内容」を**複数保存可能**。保存名を指定して新規保存/既存保存名で上書き保存ができる。保存データは後から読み込み可能で、読み込んだデータはカスタム作成モードのGUIエディタに内容が反映される。 |
27
28---
29
30### 2.2 カスタム作成モード機能(F-04詳細)
31
32| ID | 機能名 | 概要 |
33|----|---------|------|
34| C-01 | 要素配置 | 文字・画像枠・アイコン枠・吹き出し・枠線などの「ワイヤーフレーム」をGUI上に配置。各要素に付加情報を設定可能。画像・アイコンは実際の画像を表示せず、枠として表現。 |
35| C-02 | 文字表示 | 入力したテキスト内容をGUI上に**そのまま表示**し、位置関係・サイズ感の確認を可能にする。文字にエフェクトをかけたプレビュー表示は不要。 |
36| C-03 | 文字編集 | テキスト内容、フォント種類、サイズ、色、装飾、エフェクトなどの付加情報を設定可能(※GUIにはエフェクトは反映しない) |
37| C-04 | 画像枠編集 | 画像枠(人物画像、背景画像など)を配置し、各枠に対して「どのような画像か」の付加情報を設定可能。 |
38| C-05 | レイアウト保存 | 編集したワイヤーフレーム構造および各要素の付加情報をブラウザローカルストレージに**複数保存可能**。保存名指定により新規保存/既存保存名で上書き保存が可能。保存データを読み込むと、GUIエディタに該当の要素配置・付加情報が適用され、続きから編集できる。 |
39| C-06 | 編集履歴 | undo/redo機能を提供。 |
40
41---
42
43## 3. 非機能要件
44
45- ブラウザのみで動作(サーバ不要、DB不要)
46- データ保存はブラウザローカルストレージを使用
47- レスポンシブ対応(PC/タブレット/スマホ)
48- 日本語UI
49- 軽快な操作感(1秒以内の画面応答)
50- 個人情報の外部送信なし
51- プロンプト出力はChatGPT互換形式
52
53---
54
55## 4. UI要件(概要)
56
57- トップ画面:作成モード選択UI
58- 簡易作成画面:
59 - 入力フォーム(用途/ターゲット/サイズ)
60 - 要素追加入力(テキスト内容・エフェクト・位置/画像カテゴリ・位置)
61 - プロンプト生成 → コピー
62- カスタム作成画面:
63 - ワイヤーフレームエディタ(画像枠や要素は枠のみ表示、**テキストは実内容を表示**)
64 - プロンプト生成 → コピー
65- 画面構成:ヘッダー/作成エリア/出力エリア/操作ボタン
66
67---
68
69## 5. 制約条件
70
71- 本ツール自体で画像ファイルは出力しない
72- GUI上では画像プレビューは行わない(画像枠のみ)
73- テキスト内容は実際に表示するが、装飾・エフェクトのプレビューは行わない
74- 簡易作成モードでは自由な位置調整は不可(大まかな位置のみ選択可)
75- 生成プロンプトはChatGPT等外部AIに入力して画像生成する前提
76- サーバ・データベースを用いない(完全フロントエンド)
77
78---
79
80## 6. 想定利用シナリオ
81
82### 簡易作成モード
83
841. トップ画面で「簡易作成」を選択
852. 用途/ターゲット/サイズを入力
863. 文字要素を追加(内容入力・エフェクト設定・配置位置選択)
874. 画像要素を追加(カテゴリ選択・配置位置選択)
885. 必要な要素を全て追加
896. 「プロンプト生成」ボタンを押す
907. プロンプトが出力エリアに表示される
918. 「コピー」ボタンでプロンプト取得
929. 取得したプロンプトをChatGPTに貼り付けて画像生成
93
94### カスタム作成モード
95
961. トップ画面で「カスタム作成」を選択
972. GUI上で画像枠やテキストを配置
98 - 画像枠はワイヤーフレームとして配置
99 - テキストは入力内容をそのまま配置
1003. 各要素に付加情報(どのような画像か/フォント指定など)を設定
1014. 必要に応じて保存名を付けて保存(新規保存/上書き保存)
1025. 保存データ読み込み時には既存GUIに要素配置と情報が反映
1036. 「プロンプト生成」ボタンを押す
1047. プロンプトが出力エリアに表示される
1058. 「コピー」ボタンでプロンプト取得
1069. 取得したプロンプトをChatGPTに貼り付けて画像生成
107基本設計
基本設計も同様に先ほどのプロンプトに続ける形で作成を行います。 始まりは以下の通りです。
1ありがとうございます
2これで確定でお願いします。
3
4次は基本設計に進んでいただけないでしょうか同様全文を記述すると長くなるのでトグルにしています。 気になる方は展開して確認してもらえればと思います。
出来上がった基本設計は以下の通りです。 最終的なテキストをの出力をお願いすると一度ですべて出力できないようで「続き」とお願いする必要がでました。
1# サムネイル作成支援ツール 基本設計書
2
3## 1. システム構成図
4
5ブラウザ(フロントエンドのみ)
6
7┌───────────────────────────────┐
8│ ブラウザ(フロントエンドのみ) │
9│ ┌───────────────────────┐ │
10│ │ トップ画面(モード選択) │ │
11│ ├───────────────────────┤ │
12│ │ 簡易作成モード画面 │ │
13│ │ ├─ 入力フォーム(用途/ターゲット/サイズ)│ │
14│ │ ├─ 文字・画像要素入力フォーム │ │
15│ │ └─ プロンプト出力/コピーボタン │ │
16│ ├───────────────────────┤ │
17│ │ カスタム作成モード画面 │ │
18│ │ ├─ GUIエディタ(ワイヤーフレーム) │ │
19│ │ ├─ プロンプト出力/コピーボタン │ │
20│ │ └─ 保存/読み込み機能 │ │
21└───────────────────────────────┘
22
23※ サーバなし、外部APIなし、完全フロントエンド構成
24
25---
26
27## 2. 画面・機能設計
28
29### 2.1 トップ画面
30
31| UI要素 | 内容 | 処理概要 |
32|---------------|---------------------|------------------------------|
33| ヘッダー | ツール名ロゴ | 常時表示 |
34| モード選択ボタン | 簡易作成モード選択 | 簡易作成モード画面へ遷移 |
35| モード選択ボタン | カスタム作成モード選択 | カスタム作成モード画面へ遷移 |
36
37---
38
39### 2.2 簡易作成モード画面
40
41| UI要素 | 内容 | 処理概要 |
42|----------------|-----------------------------|----------------------------------------|
43| ヘッダー | ツール名ロゴ | 常時表示 |
44| 用途入力欄 | 入力フォーム | 用途情報を入力 |
45| ターゲット入力欄 | 入力フォーム | ターゲット情報を入力 |
46| サイズ入力欄 | 入力フォーム | 出力サイズ情報を入力 |
47| 文字要素入力欄 | 入力フォーム | テキスト内容を入力 |
48| エフェクト選択 | セレクトボックス | テキストエフェクト選択 |
49| 文字位置選択 | セレクトボックス | テキスト配置位置を選択(上/右/下/他要素下) |
50| 画像カテゴリ選択 | セレクトボックス | 画像カテゴリを選択(人物/アイコン等) |
51| 画像位置選択 | セレクトボックス | 画像配置位置を選択(上/右/下/他要素下) |
52| 要素追加ボタン | ボタン | 入力内容の文字/画像要素をリストに追加 |
53| 要素リスト | 追加済み要素の一覧 | 登録済み要素の内容確認・削除機能 |
54| プロンプト生成 | ボタン | 入力内容・要素リストからプロンプトを自動生成 |
55| コピー | ボタン | 生成されたプロンプトをクリップボードにコピー |
56
57---
58
59### 2.3 カスタム作成モード画面
60
61| UI要素 | 内容 | 処理概要 |
62|----------------|-----------------------------|----------------------------------------|
63| ヘッダー | ツール名ロゴ | 常時表示 |
64| ワイヤーフレームエディタ | 配置エリア | 要素を配置(画像枠=矩形枠/文字=実テキスト) |
65| 要素追加ボタン | ボタン | エディタ上に新規要素追加 |
66| 要素削除ボタン | ボタン | 選択要素を削除 |
67| 要素移動 | UI操作(ドラッグ/矢印等) | 要素位置を移動 |
68| サイズ調整 | UI操作(リサイズハンドル等) | 要素サイズを変更 |
69| 付加情報編集 | ポップアップ | 選択要素の付加情報(属性)を編集 |
70| 保存 | ボタン | 現在の配置/情報をローカルストレージに保存(新規/上書き) |
71| 読み込み | ボタン | 保存データを読み込み、エディタに反映 |
72| プロンプト生成 | ボタン | 配置要素+付加情報からプロンプトを生成 |
73| コピー | ボタン | 生成されたプロンプトをクリップボードにコピー |
74
75---
76
77### 2.3.1 付加情報編集ポップアップ
78
79#### テキスト要素の場合
80
81| UI要素 | 内容 | 処理概要 |
82|-----------------------|-----------------------------|----------------------------------------|
83| 部分テキストリスト | contentParts[] 一覧 | 既存の部分テキスト一覧をリスト表示 |
84| 部分選択 | リスト内選択 | 編集対象の部分を選択 |
85| テキスト入力欄 | 入力欄 | 選択部分のテキストを編集 |
86| フォント名選択 | セレクトボックス | フォント名を選択 |
87| フォントサイズ入力 | 数値入力欄 | フォントサイズを入力 |
88| 色選択 | カラーピッカー | 文字色を選択 |
89| エフェクト選択 | セレクトボックス | エフェクトを選択 |
90| 部分追加ボタン | ボタン | 部分テキストを追加 |
91| 部分削除ボタン | ボタン | 部分テキストを削除 |
92| 部分並び替え | UI操作(上下ボタン) | 配列順序を変更 |
93| 保存ボタン | ボタン | 編集内容を保存し反映 |
94| キャンセルボタン | ボタン | 編集を破棄しポップアップを閉じる |
95
96#### 画像要素の場合
97
98| UI要素 | 内容 | 処理概要 |
99|-----------------------|-----------------------------|----------------------------------------|
100| 画像カテゴリ選択 | セレクトボックス | 画像カテゴリを選択 |
101| 説明入力欄 | 入力欄 | 内容説明を入力 |
102| 保存ボタン | ボタン | 編集内容を保存し反映 |
103| キャンセルボタン | ボタン | 編集を破棄しポップアップを閉じる |
104
105---
106
107## 3. 処理設計(イベント処理表)
108
109### 3.1 簡易作成モード画面
110
111| イベントID | UI要素名 | イベント内容 | 実行処理概要 |
112|-------------|----------------|------------------------|-------------------------------------------|
113| EVT-001 | 要素追加ボタン | クリック | 入力欄の内容(文字 or 画像)をバリデーション → 要素リストに追加 |
114| EVT-002 | プロンプト生成 | クリック | 入力値・要素リスト内容を元にテンプレート展開 → プロンプト文字列生成 |
115| EVT-003 | コピー | クリック | 表示中のプロンプト文字列をクリップボードにコピー |
116
117---
118
119### 3.2 カスタム作成モード画面
120
121| イベントID | UI要素名 | イベント内容 | 実行処理概要 |
122|-------------|----------------|------------------------|-------------------------------------------|
123| EVT-101 | 要素追加ボタン | クリック | エディタ上に新規要素(文字枠 or 画像枠)を追加/初期位置配置 |
124| EVT-102 | 要素削除ボタン | クリック | 選択中要素をエディタ上から削除 |
125| EVT-103 | 付加情報編集 | 編集確定 | 編集した属性内容を対象要素に反映 |
126| EVT-104 | 保存 | クリック | エディタ上の配置情報+付加情報をJSON構造にまとめ → localStorage保存(保存名指定/上書き) |
127| EVT-105 | 読み込み | クリック | localStorageから指定データ読み込み → エディタ上に配置反映 |
128| EVT-106 | プロンプト生成 | クリック | エディタ上の要素情報+付加情報からプロンプト生成ロジック実行 |
129| EVT-107 | コピー | クリック | 表示中のプロンプト文字列をクリップボードにコピー |
130
131---
132
133## 4. データ設計
134
135### 4.1 保存データフィールド定義
136
137| フィールド | データ型 | 必須 | 説明 |
138|--------------------------------------|-----------|------|-----------------------------------------|
139| name | 文字列 | ○ | 保存名 |
140| createdAt | 日時文字列 | ○ | 保存日時(ISO形式) |
141| mode | 文字列 | ○ | 作成モード("simple" or "custom") |
142| canvasSize.width | 数値 | ○ | キャンバス横幅 |
143| canvasSize.height | 数値 | ○ | キャンバス高さ |
144| elements | 配列 | ○ | 要素一覧 |
145| elements[].id | 文字列 | ○ | 要素ID(ユニークID) |
146| elements[].type | 文字列 | ○ | 要素種別("text" or "image") |
147| elements[].position.x | 数値 | ○ | X座標 |
148| elements[].position.y | 数値 | ○ | Y座標 |
149| elements[].size.width | 数値 | ○ | 幅 |
150| elements[].size.height | 数値 | ○ | 高さ |
151
152※ type="text" の場合のみ
153
154| フィールド | データ型 | 必須 | 説明 |
155|---------------------------------------|-----------|------|--------------------------------------|
156| elements[].contentParts | 配列 | ○ | テキスト部分ごとのリスト |
157| elements[].contentParts[].text | 文字列 | ○ | 部分テキスト内容 |
158| elements[].contentParts[].style.fontFamily | 文字列 | 任意 | フォント名 |
159| elements[].contentParts[].style.fontSize | 数値 | 任意 | フォントサイズ |
160| elements[].contentParts[].style.color | 文字列 | 任意 | 色(16進カラーコード) |
161| elements[].contentParts[].style.effect | 文字列 | 任意 | エフェクト種別 |
162
163※ type="image" の場合のみ
164
165| フィールド | データ型 | 必須 | 説明 |
166|--------------------------|-----------|------|---------------------------|
167| elements[].imageCategory | 文字列 | 任意 | 画像カテゴリ(person/iconなど) |
168| elements[].description | 文字列 | 任意 | 画像内容の説明文 |
169
170---
171
172## 5. 出力プロンプト設計
173
174### 5.1 出力フォーマット例(全情報入り)
175
176```text
177【用途】ブログ記事のアイキャッチ
178【ターゲット】30代女性向け
179【サイズ】1200x800
180【要素リスト】
181
1821. テキスト
183 - 内容:
184 - "見出し"
185 - フォント: Arial
186 - サイズ: 24
187 - 色: #000000
188 - エフェクト: shadow
189 - "タイトル"
190 - フォント: Times New Roman
191 - サイズ: 28
192 - 色: #ff0000
193 - エフェクト: outline
194 - 位置: x=100, y=50
195 - サイズ: width=300, height=100
196
1972. テキスト
198 - 内容:
199 - "小見出し"
200 - フォント: Verdana
201 - サイズ: 18
202 - 色: #00ff00
203 - エフェクト: glow
204 - 位置: x=200, y=180
205 - サイズ: width=250, height=80
206
2073. 画像(カテゴリ: person)
208 - 内容説明: 笑顔の女性、スーツ姿
209 - 位置: x=400, y=220
210 - サイズ: width=200, height=200
211
2124. 画像(カテゴリ: icon)
213 - 内容説明: メガホンのアイコン
214 - 位置: x=50, y=300
215 - サイズ: width=100, height=100
216実装
設計書が出来上がったのでv0を使って実装してみます。 プロンプトについては「v0で生成するコードをAtomic Designにするプロンプト」の内容を元に進めています
以下がプロンプトとなっています。 一度のやり取りだけでは機能の実装漏れとかがあったので何度かやり取りして出来上がったのが「こちら」です。
1サムネイル作成支援ツールのデザイン作成をお願いします。
2
3以下が要求定義になります。
4
5--- 要求定義をコピペ ----
6
7
8以下が要件定義となります。
9
10--- 要件定義をコピペ ----
11
12
13以下が基本設計となります。
14
15--- 基本設計をコピペ ----
16
17以下はコーディング規約となるので厳守でお願いします。
18- TailwindCSSは使用せず、すべてカスタマイズしたCSSで実装してください。
19- shadcn/ui は使用せず、すべてカスタマイズしたコンポーネントで実装してください。
20- UIはAtomic Designの概念に基づいて実装してください。
21 - atoms
22 - 最も基本的なUI要素(例:ボタン、入力フィールド、ラベル)
23 - components/atomsディレクトリに配置
24 - 基本的にサーバーコンポーネントとして実装する
25 - 基本的にステートレスコンポーネントとして実装する
26 - 単にプロップスを受け取り、UIをレンダリングする役割とする
27 - 基本的にサーバーコンポーネントとして実装する
28 - molecules
29 - 複数の原子を組み合わせた機能的なUIグループ(例:フォーム、カード)
30 - components/moleculesディレクトリに配置。
31 - 基本的にサーバーコンポーネントとして実装する
32 - 基本的にステートレスコンポーネントとして実装する
33 - 単にプロップスを受け取り、UIをレンダリングする役割とする
34 - 基本的にサーバーコンポーネントとして実装する
35 - organisms
36 - 複数の分子(場合によっては原子も)を組み合わせて、より複雑なUIセクションを形成(例:ヘッダー、フッター)
37 - components/organismsディレクトリに配置。
38 - ステート管理が不要であれば、サーバーコンポーネントとして実装する
39 - templates
40 - ページのレイアウトを定義し、実際のコンテンツを配置する前の構造を提供
41 - components/templatesディレクトリに配置
42 - pages
43 - 各種ルーティング用のページ
44- state管理とstateを更新するためのロジックはhokksを利用する
45- Next.jsに依存しない様々なプロジェクトで使えるような共通ロジックは「utils」フォルダに実装してください。
46- api疎通は「Repository Factory」パターンで実装してください。
47- apiから受け取ったデータは「zod」で型チェックを行うようにしてください。
48 zodの定義はmodelsフォルダに実装してください。
49
50### ディレクトリ構成(サンプル一部のみ)
51/components/
52 ├── atoms/
53 │ ├── button/
54 │ │ ├── index.tsx
55 │ │ ├── style.css
56 │ ├── badge/
57 │ │ ├── index.tsx
58 │ │ ├── style.css
59/pages/
60 ├── index.tsx
61 ├── style.css
62/models/
63 ├── hoge.ts
64/repositories/
65 ├── factory.ts
66 ├── hogeRepository.ts
67/utils/
68 ├── date.ts
69 ├── file.ts終わり
内容が長くなったので一旦ここで一区切りです。 感想としてはAIでここまで作れるのはすごいなぁと思いつつ小規模なサービスなので出来てるかもなという気持ちです。
次はv0から実際にリポジトリに反映してそちらでAWSへのデプロイ、テスト実装などを行おうと思います。 いくつか実装漏れの機能があるのですが、テストで検知するためにあえて放置するようにします。
ちなみにこの記事に使っているサムネイルは実際に先ほど作ったWebサイトでプロンプトを作成していChatGPTに投げて作りました。