はじめに
従来のワークフローからの転換
AIツールの登場により、ソフトウェア開発の伝統的なプロセスが根本から変わりつつあります。GitHubCopilotやChatGPTなどのAIアシスタントが開発現場に浸透するにつれ、従来の「要件→設計→コード」という流れから「要件→コード→設計」という新しいワークフローへのシフトが効果的であることが実証されています。
なぜコードファーストアプローチが効果的なのか
1. 早期フィードバックサイクルの確立
コードファーストアプローチでは、要件定義後すぐに実装に移行することで、問題点を早期に発見できます。実際に動作するコードを通じて要件の曖昧さや矛盾を特定し、修正することができます。
要件を明確にするための「つくる」なのです
これは、アジャイル原則における「包括的なドキュメントよりも動くソフトウェア」です。
AIどうこうの話じゃなく、早くにユーザからのフィードバックもらえるのは絶対的に良いことなんです。それがエンプラ開発であろうとな。
2. AIツールの得意分野を活かした作業分担
AIツールは、パターン認識とコード生成に優れている一方、抽象的な要件から正確な設計文書を作成することには限界があります。コードファーストアプローチでは、AIの得意分野を最大限に活用できます:
- ChatGPT: 要件の明確化と初期コード生成
- GitHub Copilot: インクリメンタルなコード改善と品質向上
- 両ツール: 実装済みコードを基にした設計文書の生成
3. 設計とコードの一貫性確保
実装済みコードから設計文書を生成することで、設計と実装の乖離を防止できます。これは特に、時間経過とともに変更される要件に対応する際に重要です。
従来のアプローチとの比較
従来のアプローチとコードファーストアプローチを比較すると、以下のようなメリットがあります
評価項目 | 従来(設計→コード) | コードファーストアプローチ |
---|---|---|
開発速度 | 設計に時間がかかり、実装開始が遅れる | 早期に実装を開始でき、開発サイクルが短縮 |
要件理解 | 設計段階で誤解が発生する可能性 | 早期の実装で要件の曖昧さを解消 |
設計品質 | 抽象的で実装との乖離が生じやすい | 実装済みコードを基にするため正確 |
ドキュメント整合性 | 更新されにくく、時間経過で乖離 | コード変更と同時に更新可能 |
AIツール活用度 | 低(設計段階でのAI活用が限定的) | 高(AI得意分野を最大限活用) |
実践的なコードファーストワークフロー
ステップ1: 要件定義の高度化
ChatGPTを活用して要件を明確化し、エッジケースや潜在的な課題を洗い出します。
User: ユーザーが商品を検索して購入できるECサイトの検索機能について要件を整理したい
ChatGPT: 以下の点を考慮しましょう:
- 検索条件(キーワード、カテゴリ、価格範囲など)
- ソート機能(人気順、価格順など)
- 検索結果のページネーション
- 検索結果がない場合の代替提案
- モバイル対応の検討
...
ステップ2: プロトタイプコードの生成
明確化された要件をもとに、ChatGPTでベースとなるコードを生成します。
// ChatGPTが生成した検索機能の初期コード
function searchProducts(keyword, filters = {}) {
const { category, minPrice, maxPrice, sortBy } = filters;
// データベースからの検索ロジック
let results = database.products.filter(product => {
// キーワード検索
if (keyword && !product.name.toLowerCase().includes(keyword.toLowerCase())) {
return false;
}
// カテゴリフィルター
if (category && product.category !== category) {
return false;
}
// 価格範囲フィルター
if (minPrice && product.price < minPrice) {
return false;
}
if (maxPrice && product.price > maxPrice) {
return false;
}
return true;
});
// ソート処理
if (sortBy === 'price_asc') {
results.sort((a, b) => a.price - b.price);
} else if (sortBy === 'price_desc') {
results.sort((a, b) => b.price - a.price);
} else if (sortBy === 'popularity') {
results.sort((a, b) => b.viewCount - a.viewCount);
}
return results;
}
ステップ3: GitHub Copilotと共にコード品質向上
Copilotを活用して、初期コードの品質向上、テスト作成、リファクタリングを行います。
// Copilotによる改善提案を取り入れたコード
function searchProducts(keyword, filters = {}) {
const { category, minPrice, maxPrice, sortBy, page = 1, perPage = 20 } = filters;
// データベースからの検索ロジック(パフォーマンス最適化)
let query = database.products.createQuery();
if (keyword) {
query = query.where('nameIndex', 'contains', keyword.toLowerCase());
}
if (category) {
query = query.where('category', '==', category);
}
if (minPrice !== undefined) {
query = query.where('price', '>=', minPrice);
}
if (maxPrice !== undefined) {
query = query.where('price', '<=', maxPrice);
}
// ソート処理
const sortOptions = {
'price_asc': { field: 'price', direction: 'asc' },
'price_desc': { field: 'price', direction: 'desc' },
'popularity': { field: 'viewCount', direction: 'desc' },
'newest': { field: 'createdAt', direction: 'desc' }
};
const sortOption = sortOptions[sortBy] || sortOptions.popularity;
query = query.orderBy(sortOption.field, sortOption.direction);
// ページネーション
const offset = (page - 1) * perPage;
query = query.limit(perPage).offset(offset);
// 総件数取得(別クエリ)
const totalCount = await database.products.count(query.getWhereConditions());
// 結果取得
const results = await query.execute();
return {
items: results,
pagination: {
page,
perPage,
totalCount,
totalPages: Math.ceil(totalCount / perPage)
}
};
}
ステップ4: 設計文書の生成
完成したコードをインプットとして、設計文書をMermaid記法で生成します。
次に処理フローを追加します。
LLMの特性から見た優位性の詳細
人間とAIの特性は異なります。特にLLMの特性と限界変数を鑑みたタスクの分割や順序は、for人間とは異なるものになります。
1. トークン化とシンボル処理効率
LLMはコードという形式的な言語をトークン化して処理する際に高い効率を示します。コードには明確な構造(宣言、制御構造、関数呼び出しなど)があり、LLMはこれらのパターンを学習データから認識しやすくなっています。
# トークン化の例
function searchProducts(keyword, filters) {
↓
[function] [searchProducts] [(] [keyword] [,] [filters] [)] [{]
2. 中間表現としてのコードの優位性
コードは形式的で曖昧性の少ない中間表現として機能します。
- 検証可能性: コンパイルや実行によって即座に検証可能
- 具体性: 抽象的な概念が具体的な実装として表現される
- 完全性: 実装に必要なすべての詳細が含まれる
AI生成出力の品質評価も圧倒的に行いやすいです
3. 逆方向設計プロセスの効率性
コードから設計文書を生成する「逆方向設計」は、従来の「順方向設計」よりも効率的です:
- 実装の全詳細が既知であるため、抽象化が容易
- エッジケースや例外処理が既に考慮されている
- 実際に動作する処理フローに基づいた正確な図表生成が可能
実践的なヒント
初期段階でのAIプロンプト例
「ユーザー登録機能を実装したいです。以下の要件があります:
- メールアドレスとパスワードでの登録
- SNSアカウント連携による登録
- 登録時のメール認証
- ユーザープロフィール情報の登録
これらの要件を満たすRESTful APIのエンドポイント設計と、
主要なコンポーネントの実装コードを生成してください。言語はNodeJS、フレームワークはExpressを使用します。」
コードからの設計ドキュメント生成プロンプト例
「以下は商品検索機能の実装コードです:
[実装コードを貼り付け]
このコードに基づいて、以下のドキュメントを生成してください:
1. クラス図(Mermaid記法)
2. シーケンス図(Mermaid記法)
3. 主要コンポーネントの責務説明
4. APIエンドポイントの仕様」
まとめ
コードファーストアプローチは、AIの特性を活かした効率的な開発手法として注目されています。実装からのフィードバックループを早期に確立し、AIの得意分野を最大限に活用することで、高品質な成果物を短期間で作成できるようになります。
ちょっと誤解されそうなので強調しておくと "要件定義" は以前大事 です。
むしろ要件定義の重要性と比重が高まっている。言葉からコードが生み出せるようになったのだから。
"要件定義" のなかにAIコーディングのプロト実装が追加でインクルードされるイメージです。
何はともあれ。AIさん、友達からよろしくお願いします。