どうもこんにちは。
今回は、ライブラリを開発したときに「仕様駆動開発」を実践してみたのですが、その結果や感想、考えについて述べたいと思います。
コーディングエージェントが普及してきたが...
AIに実装させるのが怖い層がまだまだいる
現状、Claude CodeやCodexといったコーディングエージェントツールなどが普及し始めていますが、実際にはまだ「AIに実装させるのは怖いから、コードは全部自分で書く」という方がいらっしゃると思っています。
正直、この感覚は正しいと思います。実際に雑な指示を出せば、AIはそれっぽいんだけど意図からズレた実装をしてしまいます。
怖いと思う原因は?
AIに実装させるのが怖いと思う原因は、果たして「AIがコードを書くこと」なのでしょうか?
いや、よくよく考えてみると、それ自体が原因なのではなく、「AIの認識と人間の認識に乖離がある状態でAIがコードを書くこと」が原因なのではないでしょうか?
多くの方が、AIを「めちゃくちゃ優秀な新人くん」として扱っているお話をよく耳にしますが、その通りだと私も考えます。どれだけ優秀な新人でも、いきなり「この機能よしなに作って」とだけ言われても無理ですよね?
それと同じで、AIにも新人くんに同じ段取りを施します。
何のコミュニケーションが不足しているのか
「コミュニケーション不足」と言っても、雑談が足りないという意味ではありません。
不足しているのは、実装前の仕様コミュニケーションです。
具体的には、最低でも以下を言語化して共有する必要があります。
- 何を作るのか(要件・受け入れ条件)
- どう作るのか(設計方針・制約・既存資産の再利用方針)
- どの順で作るのか(タスク分解・依存関係)
- 何をもって完了とするのか(テスト・レビュー基準)
ここを曖昧にしたまま実装に入ると、人間でもAIでも高確率でズレます。
怖い原因を取り除く
その段取りをワークフローとして実行可能にしたのがcc-sddです。
しかし、このライブラリを理解するには、仕様駆動開発について理解をしておく必要があります。
仕様駆動開発とは
仕様駆動開発(Spec-Driven Development)は、実装前に以下を明文化して人間とAIの認識を揃えてから開発を進める方法です。
- 要件定義(何を達成するか)
- 設計(どう作るか)
- タスク分解(どう実装を進めるか)
- 実装(合意済み仕様に従って進める)
これらを明文化することによって、人間の意図がAIに伝わりやすくなり、AIが「明記されていない部分を推測してよしなに実装を進める」ということを減らすことができます。
cc-sdd は何をしてくれるのか
cc-sddは、上記フローを「毎回手作業で要件定義書・設計書を作る」から「AIと対話しながら要件定義書・設計書を作る」に変えてくれるライブラリです。
一番の強みは、「要件定義・設計書を作成するフェーズで、実装前にレビュー可能な状態を作ることができ、AIと人間の認識を合わせることができる」ということです。
つまり、AIを「よしなに実装をしてくれる天才」ではなく、「合意済みの仕様をもとに実装をしてくれる天才」として扱えるようになります。
実際の進め方
cc-sdd を入れたら、基本は次の流れです。
-
spec-initで対象機能を起票 -
spec-requirementsで要件を要件定義書に明文化 -
spec-designで設計を設計書に明文化 -
spec-tasksでタスク管理書に実装タスクを明文化 -
spec-implで実装
上記で生成されるファイルは.kiroディレクトリに保存されます。
また、上記の各ステップは、AIだけで行なっているものではありません。AIと人間が共同で行うものです。つまり、生成される要件定義書・設計書・タスク管理書はAIと人間が共同で作成した成果物です。
これを行うことにより、以下が実現できます。
- 人間がAIと一緒に要件と設計を固めることができる
- AIが要件定義書・設計書・タスク管理書をもとに実装するため、よしなに実装することを防ぐ
- 設計漏れによる実装手戻りを防ぐことができる
これが「怖さ」を下げることにつながります。
実際にどう仕様駆動したか
実際に行った進め方を紹介します。モデルケースはmonkey_mcpのdynamic_modeの実装です。
(実際の各ファイルはボリューミーです。ここでは要点をまとめたもののみを示します。)
1. 要件定義で「何を作るか」を固定
まず、AIに対して、「tools/list の返却を軽量化したい。」ように要求と伝えます。すると、要件定義が始まります。ここからはAIが人間に対して確認を行ったりしながら要件定義書(requirements.md)を作成してくれます。
そして、対話の結果、requirements.md では、次を明文化しました。
-
tool_listing_mode = :dynamicのときtools/listはtool_search/call_proxyの2件のみ返す -
:full(デフォルト)では従来どおり全ツールを返す(後方互換) -
tool_search.queryが空なら-32602を返す -
call_proxyは登録済みツールのみ実行可能
ここで「何が正解か」を先に確定したので、実装時の解釈ブレを減らせました。
ポイントは「○○のとき、○○の動作をする」というように、Whenをうまく使って要件を定義していることです。(ライブラリの仕様でこちらが意識しなくてもWhenをうまく使ってくれます。)
2. 設計で「どう作るか」を固定
要件定義がOKであれば、次に設計書を作成します。要件定義書をもとに、設計書(design.md)を作成してくれます。人間は生成された設計書をレビューし、AIと対話しながら詳細な仕様を固めていきます。
-
Configuration: mode や search 関連の設定値を管理 -
McpController:tools/list/tool_search/call_proxyの入口 -
ToolSearcher: 検索ロジックを分離(将来差し替え可能な形) -
Registry: 既存の登録済みツール管理を再利用
加えて、シーケンス図で tool_search -> call_proxy の呼び出し順を明示しました。
私はここで、AIにリバースプロンプトを実行し、「何か実装において不明点はあるか?」と投げています。これにより、AIが設計書をセルフレビューし、設計漏れが減りやすくなります。
3. タスク化で「どの順で作るか」を固定
設計が完了したら、AIがタスク分解を行います。実装において、もっとも関わってくるものがタスク定義書(tasks.md)です。設計書のレビューでほっとせず、AIが実装するタスクが本当に間違っていないかを確認しておきましょう。
- Configuration 拡張とバリデーション
- 予約語保護(
tool_search/call_proxy) -
ToolSearcher新規実装 -
McpControllerに dynamic 分岐追加 - 統合テストと後方互換性テスト
- README 反映
ポイントは、AIがどこまで実装したら良いのか、レビュー時に「何が未完了か」を人間側がすぐ把握できるようにしておくことです。
4. 実装開始
タスクの定義が完了したら実装が開始されます。この時点で要件・設計・タスクの定義が濃いものとなっているため、皆さんの「AIに実装させるのが怖い」という気持ちは薄れているのではないでしょうか。
また、spec.json では、現在ステータスが次のように管理されています。
- requirements: done
- design: done
- tasks: done
- implementation: pending
現在のステータスが定義されていることで、「何がどこまで進んでいるのか」を把握しやすく、AIとの議論においても認識のずれが少ない状態で議論することが可能です。
以上の一連の流れが、私の言う「AI活用で一番重要なのはコミュニケーション設計」という話の具体例です。
まずは小さく始める
最初から全案件で導入する必要はありません。
-
1機能・1チケットだけ
cc-sddで回してみる - 要件/設計/タスクのレビュー体験を確認する
- 人間実装とAI実装の時間・質の比較
- 実装手戻りの回数やレビュー時間を比較
手応えが出たら、テンプレートとルールを整備して展開してみるのがいいのではないでしょうか。
まとめ
AI実装が怖いのは自然です。そりゃそうっす。でも、その怖さの正体は「AIが危険」ではなく「実装前のコミュニケーション不足のまま開発を始めること」です。
cc-sddは、AIを暴走させないための枠組みです。
- 最初に対話しながら要件を決める
- 設計で対話しながら実装方針を固定する
- タスクで責務を分解する
- その上でAIに実装させる
この順番を守るだけで、AIは「何をしでかすかわからない新人」ではなく、開発速度と品質を同時に押し上げる戦力になります。
「AIに実装させるのは怖い」と感じているなら、まずは仕様駆動で使うことだと思います。
また、上流工程の方々にとっては、「仕様駆動で開発をするなんて当たりまえじゃん」と思われるかもしれません。
ただし、みなさんが行っている要件定義や設計の業務を、AIとの対話によって行うことができるようになると効率と速度、正確性が格段に向上すると思っています。
そして、人間だけで行っている要件定義や設計を、AIと対話しながら行う要件定義や設計へシームレスに移行するツールこそがcc-sddであると考えます。
以上