はじめに:開発の中心が「コード」から「仕様」へ回帰しつつある
近年、ChatGPT / Claude / Gemini / Cursor などの生成AIの進化によって、
ソフトウェア開発のあり方は大きく変わりつつあります。
特に注目すべき変化は、
「自然言語で書いた仕様を、AIが理解し、コード・テスト・レビューまで補助する」
という開発スタイルが、実務レベルでも現実的になってきた点です。
これまで開発の中心は常に「コード」でした。
仕様書は後追いになりがちで、やがて陳腐化し、
「正しい仕様はコードを読むしかない」という状況に陥ることも少なくありません。
こうした背景の中で、あらためて注目されているのが
Documentation-Driven Development(ドキュメント駆動開発:DDD) です。
ただし、本記事で扱うDDDは、
厳密なドメイン設計を行うための設計手法そのものではありません。
生成AI時代においてDDDを、
AIに正しく仕事をさせるための、思考と仕様の置き場所
として捉え直し、
ドキュメント → コードの流れをどこまで現実的に自動化できるのか
という観点から整理していきます。
ドキュメント駆動開発(DDD)とは?
DDDとは、
ドキュメント(仕様)を開発の起点に置き、その仕様に基づいて実装・テストを進める考え方
です。
従来の課題
DDD自体は昔から知られていましたが、現場では次のような課題がありました。
- 仕様書を最初に書くコストが高い
- 変更が入るたびにドキュメント更新が必要
- 結果としてドキュメントが放置される
- コードと仕様が乖離する
理想論として語られつつも、
「人間が完璧なドキュメントを書く前提」
がネックとなり、運用が難しい手法だったと言えます。
AIによる転換点:DDDを支える前提条件が変わった
生成AIの登場によって、この状況が大きく変わり始めています。
- 雑な自然文でもAIが構造化してくれる
- 抜け漏れや矛盾を指摘してくれる
- 仕様からコード・テストまで連続的につなげられる
DDDそのものが進化したというよりも、
DDDを成立させるための前提条件が変わった
と捉える方が自然です。
結果としてDDDは、
「重い設計手法」から「軽く始められる実務フレーム」へと
変化しつつあります。
なぜ今、DDD × AI が強力なのか
1. 自然言語を構造化するのがAIは得意
AIは、箇条書きレベルの要件からでも、
- API仕様
- データ構造
- 制約条件
- 異常系
といった要素を補完・整理してくれることがあります。
人間が「なんとなく」書いた仕様を、
AIが「曖昧さの許されない構造」に落とし込んでくれる点は非常に強力です。
2. 仕様に沿ったコードを“叩き台”として生成できる
Cursor や ChatGPT などを活用することで、
- モデル定義
- APIエンドポイント
- バリデーション
- 例外処理
- テストの雛形
といった初期実装が一気に生成されるケースがあります。
すべてを任せるのではなく、
「書き始めるための土台を作ってもらう」
という使い方が現実的です。
3. 仕様とコードの差分レビューをAIが補助できる
AIに次のように依頼するだけで、
このコードは仕様に沿っていますか?
差異があれば指摘してください。
- レスポンス項目の不足
- ステータスコードの不一致
- バリデーション漏れ
などを指摘してくれることがあります。
人間レビューの代替ではなく、
網羅性を補完する存在
として有効です。
AI活用DDDの全体ワークフロー
この流れが示しているのは、
- 人間:何を作るか・なぜ作るかを決める
- AI:作業を高速に具体化する
という役割分担です。
Step 1:自然文で仕様を書く
最初から完璧な仕様を書く必要はありません。
目的:ユーザー情報管理API
機能:登録・取得・削除
項目:id, name, age, created_at
制約:ageは整数
認証:なし
このレベルで十分です。
AIが不足点を質問し、仕様を育ててくれます。
Step 2:AIに仕様として整形してもらう
AIに以下のように依頼します。
この要件をAPI仕様として整理してください。
曖昧な点は質問し、OpenAPI風に構造化してください。
結果として、次のような仕様が生成される場合があります。
paths:
/users/{id}:
get:
summary: ユーザー情報取得
parameters:
- in: path
name: id
required: true
Step 3:Cursorでコード生成
cursor edit ./api/user.py --prompt "
この仕様に基づいてFastAPIで実装してください
"
@router.get("/users/{id}", response_model=User)
def get_user(id: int):
if id not in fake_db:
raise HTTPException(status_code=404, detail="Not found")
return fake_db[id]
“書き始めるまでの時間”が大幅に短縮されます。
Step 4:AIによるテストコード生成
def test_get_user_not_found(client):
response = client.get("/users/999")
assert response.status_code == 404
テストの網羅性向上や、
テスト作成の心理的ハードル低下に寄与します。
Step 5:AIレビューで整合性チェック
AIは以下のような点を指摘することがあります。
- バリデーション不足
- レスポンス項目漏れ
- 異常系の未実装
人間レビューと組み合わせることで、
品質が安定しやすくなります。
追加サンプル:CRUD生成例
@router.post("/users", response_model=User)
def create_user(payload: User):
new_id = max(fake_db.keys()) + 1
user = User(id=new_id, **payload.dict())
fake_db[new_id] = user
return user
メリット(可能性ベース)
- 手戻りが減る可能性が高い
- 仕様とコードの乖離が起きにくい
- 属人化を抑えやすい
- テストが揃いやすい
- 非エンジニアと会話しやすい
注意点
- AIは誤解することがある
- 曖昧な仕様は曖昧な実装につながる
- セキュリティ情報の入力には注意
- 最終判断は必ず人間が行う
まとめ:DDDは「AIへの指示書」として復活しつつある
DDDは、正解の設計を導くための銀の弾丸ではありません。
しかし生成AI時代においては、
「何を作るか」「なぜそうするか」を言語として固定するための
非常に相性の良いフレーム
になりつつあります。
コードを書くこと自体のコストが下がった今、
設計とは「コードを書く前に、何を言葉で決めるか」を整理する行為です。
その意味で、
ドキュメント → コードの流れを意識的に設計することは、
これからの開発における現実的な選択肢の一つ
だと言えるでしょう。