
はじめに
こんにちは!ぐるなびでバックエンドエンジニアをしている開発部の寺井です。
十数年PHPを主戦場にしてきましたが、最近Go言語を使ってぐるなびアグリサービスの開発に携わっています。
クリーンアーキテクチャも初めて理解しようとしており……難しい。
この記事では、GitHubが提唱する 「Spec-Driven Development(仕様駆動開発 / SDD)」 と、その実践ツール 「GitHub Spec Kit(speckit)」 を紹介します。仕様と設計原則を明文化し、それを中心に開発を進めることで、AIとの協働でも一貫したアーキテクチャを維持できるようになります。
目次
- はじめに
- 目次
- 1. 仕様駆動開発(SDD)って?(TDD/BDDと何が違うの?)
- 2. 導入:GitHub Spec Kitの導入
- 3. Agent設定との使い分け(instructions vs agents vs prompts)
- 4. 実演:GraphQLから仕様書を作り出す
- 5. 導入のポイント
- まとめ:SDDを勧めたい理由(AI時代の再現性)
- 著者紹介
GitHub Copilotで開発が変わった。でも、何かが足りない。
GitHub Copilotの Agent Mode が登場し、実装をAIに任せられる時代になりました。しかし、こんな壁にぶつかっていませんか?
ユースケースにビジネスロジックが漏れ出す
ドメインモデルに書くべき処理をユースケース層で実装されてやり直しを指示毎回同じ指示を繰り返す
「ドメイン層はインフラに依存しないで」と何度も説明、そのうちAIに対して口調が荒くなるチームで使うと出力がバラバラ
同じ機能でもエンジニアごとに構造が違う(昨日指示したのとも違うぞ!?)
原因は 「仕様が曖昧なままコードを生成している」 ことです。
仕様駆動開発(SDD)と GitHub Spec Kit
「Spec-Driven Development(仕様駆動開発 / SDD)」 は、GitHubが提唱する開発アプローチです。「仕様を最初に明確にし、それを中心に開発を進める」ことで、従来の「コードが真実」を逆転させ、「仕様が真実、コードはその表現」 という Power Inversion を実現します。
AI時代にSDDが重要な理由:
AIは曖昧な指示が苦手
構造化された仕様があれば出力精度が向上手戻りが減る
仕様を先に固めれば「これじゃない」が減るドキュメントと実装の同期
仕様を起点にすれば常に最新
GitHub Spec Kit(speckit) は、このSDDを実践するツールです:
質問→仕様→計画→タスク→実装 の段階的ワークフロー
Constitution(憲章) による一貫したアーキテクチャ管理
テンプレート によるAIの暴走防止
1. 仕様駆動開発(SDD)って?(TDD/BDDと何が違うの?)
アジャイル開発の文脈で「テスト駆動開発(TDD)」や「ビヘイビア駆動開発(BDD)」は定番になりました。
ただ、CopilotのAgent Modeで開発していると、
- テスト設計やシナリオを指示して
- テストを生成して
- 実装を生成して
……という“人間が主導するTDD/BDDの手触り”を、そのまま移植するのが難しい場面があります。
AIの活用が進むほど、
- 実装イメージをある程度持って「仕様書レベルの指示」を出して
- コーディングを任せてスピードを出す
という状況が増えがちです。
そこで出てくる課題が、冒頭で挙げた 「同じ指示の繰り返し」 と 「指示の履歴が残らない」 です。
SDDは"外側のループ"を回す
SDDは仕様(受入条件)を文章で固め、矛盾・抜けをチェックしてから計画→タスク→実装と進む仕様を中心にした外側のループです。TDDは実装フェーズの内側のループ(Red→Green→Refactor)で品質を積み上げます。
ウォーターフォールとの違い:SDDの仕様書は「AIに読ませるコンテキスト」で変更前提。[NEEDS CLARIFICATION]で不明点を残しながら段階的に明確化するアジャイルなアプローチです。
- SDDで「何を・なぜ」を合意(AIへのコンテキスト提供)
- BDDで「受入条件」を読みやすく書く(必要なら)
- TDDで「どう作るか」を安全に進める
speckitの流れ:従来開発との違い

speckitは、質問(clarify)→仕様(specify)→計画(plan)→タスク(tasks)→実装(implement) という順序で段階的に進めます。各ステップで成果物(spec.md、plan.md、tasks.md等)が生成され、意思決定の履歴が残ります。
SDDのキモ:仕様が真実、コードは表現
SDDでは、「仕様はコードの付属物ではなく、コードを生み出す中心」です。
- 従来:コードが真実(結果として仕様が古くなる)
- SDD:仕様が真実、コードは"仕様の表現"(ズレたら仕様を直して再生成)
半年後の改修でも、spec.md を更新して /speckit.plan → /speckit.implement で完了。AIが書いたコードを読み解く必要がありません。
テンプレがAIの暴走を抑える
spec.md のルール:
- ○ WHAT(何を)・WHY(なぜ)だけ
- × HOW(どう作るか)は書かない
- ? 不明点は [NEEDS CLARIFICATION] で残す
Phase -1 Gates(実装計画の事前チェック):
Simplicity Gate - プロジェクト数は3つ以内?未来の拡張性を入れていない?
Anti-Abstraction Gate - フレームワークを直接使用?独自抽象レイヤーを作っていない?
Integration-First Gate - API仕様を先に定義している?
ゲートを通らない場合は plan.md に理由を明記して例外申請します。
2. 導入:GitHub Spec Kitの導入
前提:Python 3.11+ と uv
Spec Kit自体はPython製のCLIツールですが、生成されるのはMarkdownファイルです。つまり、プロジェクトの使用言語(Go/PHP/TypeScriptなど)には一切依存しません。Python環境はSpec Kitの実行にのみ必要で、あなたのGoプロジェクトがPythonに汚染されることはありません。
また、uv を使うことで、システムのPython環境を汚さず、Spec Kitを独立した環境で実行できます。
# uv のインストール(未導入なら) curl -LsSf https://astral.sh/uv/install.sh | sh # Spec Kit CLI のインストール(uv が仮想環境を自動管理) uv tool install specify-cli --from git+https://github.com/github/spec-kit.git --python python3.13 --native-tls # 既存プロジェクトへ初期化(例) specify init --here --ai copilot --force
※既存プロジェクトに --here で入れる場合、README.md や .gitignore 等が競合・上書きされる可能性があるので、事前コミット推奨です(--force は特に注意)。
初期化すると、主に以下が入ってきます。
.github/agents/:Copilotのスラッシュコマンド(/speckit.planなど)の“台本”.github/prompts/:agentから参照する文面テンプレ.specify/:憲章(constitution.md)やテンプレ、スクリプト
constitution.md:AIが判断に迷ったときの「意思決定基準」
.specify/memory/constitution.md は、AIに対する自動コードレビュー(Lint)のようなものです。人間がコードレビューで指摘するような「その抽象化、本当に要る?」「これ、プロジェクト増やしすぎじゃない?」という視点を、AIが実装計画を作る段階で自問自答させます。
具体例:constitution.md に書くこと
# このプロジェクトの原則 ## 技術スタック - バックエンド: Go 1.xx系など使用しているバージョンを記載 - データベース: PostgreSQL - テスト: 標準 testing パッケージ ## アーキテクチャ原則 - クリーンアーキテクチャを採用 - ドメイン層は外部依存を持たない(インターフェースで依存逆転) - ユースケース層がドメイン層を呼び出す(逆は禁止) ## コーディング規約 - エラーは必ず errors.Is/As でラップするようにする - 構造体のフィールドはすべてタグ付き(`json:", `db:"`) - テストカバレッジは80%以上
これがConstitutional Gatesとして機能します。/speckit.plan で計画を作る際、AIが以下を自動チェック:
Simplicity Gate - 将来の拡張性は本当に必要?YAGNI原則の遵守
Anti-Abstraction Gate - 過剰な抽象化を避け、標準ライブラリを優先
Integration-First Gate - API仕様を実装前に定義
ゲートを通らない場合は plan.md に理由を明記して例外申請します。これにより「なぜ複雑にしたか」の意思決定が記録に残ります。
3. Agent設定との使い分け(instructions vs agents vs prompts)
ここが「SDDが再現性に効く」ポイントです。
チーム共通のベース指示 .github/copilot-instructions.md
- 用途:プロジェクト全体で常に守るべきルール
- 内容:コーディング規約、アーキテクチャ、Git操作ルール
- 適用:リポジトリ内のすべてのCopilot操作
agents(.github/agents/*.agent.md)
Copilotの“左下に出る” /speckit.plan みたいなスラッシュコマンド本体です。

handoffの仕組み:次のステップへの誘導
各agentファイルに handoff設定 を追加することで、次に実行すべきagentへの「バトンタッチ」を定義できます。
handoffを実装した場合の体験(VS Code上):
/speckit.specifyで仕様書を作成- Copilotが「仕様書が完成しました。次は実装計画を作りますか?」と クリック可能なボタン を表示
- そのボタンをクリックすると
/speckit.planが自動実行 - 計画が完成すると、また「次は
/speckit.tasksでタスクに分解しますか?」とボタンが出る
agent.mdファイルにこのようなhandoffsを作成しておくと画像のようなボタンが出てきます
handoffs:
- label: Phase 1実装開始(Domain層)
agent: speckit.implement
prompt: 作成された実装計画書に基づき、Phase 1(Domain層:モデル定義・Repositoryインターフェース)の実装を開始してください。実装完了後、テストを実行して結果を確認してください。

推奨されるhandoffの流れ:
speckit.clarify.agent.md→/speckit.specifyを提案speckit.specify.agent.md→/speckit.planを提案speckit.plan.agent.md→/speckit.tasksを提案speckit.tasks.agent.md→/speckit.implementを提案
handoff機能を実装することで、開発者は「次に何をすべきか」を迷わずに段階的なワークフローを進められます。各段階の成果物(spec.md、plan.md、tasks.md)が明確に残るため、意思決定の履歴が追跡可能になります。
※handoffの実装方法については、GitHub Spec Kitの公式ドキュメントを参照してください。
Spec Kitでは、以下のようなagentファイルが用意されています:
.github/
└── agents/
├── speckit.clarify.agent.md
├── speckit.specify.agent.md
├── speckit.plan.agent.md
├── speckit.tasks.agent.md
├── speckit.implement.agent.md
├── speckit.analyze.agent.md
└── speckit.checklist.agent.md
デフォルトだと
mdファイル名通りに出力されますが
--- name: 仕様書作成 description: 要望に基づいて詳細な仕様書を作成します。 ---
このようにわかりやすい名前に変更することも可能です

prompts(.github/prompts/*.prompt.md)
agentの中から参照される/使われることがある文面テンプレ(短いことが多い)です。
- 「ユーザーにどう聞くか」
- 「どういう形式で出力させるか」
を揃える場所で、ここを整えると“言い回し”や“出力フォーマット”がチームで揃いやすくなります。
speckit の agents / prompts と合わせると、「台本」「短いテンプレ」「(必要なら)追加ルール」を分割管理しやすくなります。
4. 実演:GraphQLから仕様書を作り出す
ここからが「SDDっぽさ」が一番伝わるところです。
たとえば、GraphQLのAPIを追加したいとします(例としてかなり簡略化)。
type Query { user(id: ID!): User } type User { id: ID! name: String! }
4-1. /speckit.clarify:まず"質問"を作る
Copilotにいきなり「実装して」と言う前に、仕様を固めるための質問を先に出します。
重要:仕様書すらも、人間がゼロから書く必要はない
SDDと聞くと「仕様書を完璧に書かなきゃ…」とプレッシャーを感じるかもしれません。しかし、/speckit.clarify では、AIと壁打ち対話をするだけで、AIが仕様の叩き台を作ってくれます。
実際の操作:
> /speckit.clarify GraphQL APIでユーザー情報を取得したい [Agent] 以下の点を明確にしましょう: - user(id) でユーザーが見つからない場合、null を返す?エラーにする? - 認可は必要?(本人のみ?管理者?) - name は表示名?本名?(更新される?履歴は必要?) - 監査ログやPIIの扱いは? [ユーザーが回答] > NotFoundはnullで返す。認可は不要。nameは表示名で、ユーザーが変更できる。 [Agent] 了解しました。では仕様書の草案を作りましょう。
こういう"埋めるべき穴"が先に見えるので、同じ指示を繰り返す回数が減ります。質問が整理できたら、次は /speckit.specify で仕様書を作成します。
仕様書もAIと対話して固まったものを spec.md に落とさせるだけ。 ゼロから人間が書く必要はありません。これが、SDDへの心理的ハードルを劇的に下げるポイントです。
※この例ではGraphQLを使っていますが、REST APIや単なるGoのStruct定義とメソッド作成でも同様です。仕様駆動開発の本質は「何を作るかを先に明確にする」ことであり、技術スタックには依存しません。
4-2. /speckit.specify で受入条件を明確化
BDDっぽく、Given/When/Thenで書くと読みやすくなります。
例(断片):
- Given:
id=123のユーザーが存在する - When:
user(id: "123")を実行する Then:
idとnameを返すGiven:
id=999のユーザーが存在しない- When:
user(id: "999")を実行する - Then:
nullを返す(またはドメインエラーを返す)
ここまでが固まると、実装が変わっても「何を満たせばOKか」が残ります。
また、迷うところは推測せずに spec.md にこう残します。
- 例:
[NEEDS CLARIFICATION: user(id) の NotFound は null?エラー?]
4-3. /speckit.plan → /speckit.tasks で実装準備
/speckit.plan で技術方針を決定し、/speckit.tasks でタスクに分解します。
plan.mdには「ドメイン層→ユースケース層→インフラ層」の変更箇所とPhase -1 Gatesのチェック結果が記録されます。tasks.mdでは [P] マーカーで並行実装可能なタスクを明示し、依存関係も管理されます。
生成される成果物の全体像:
specs/
└── 001-user-query-api/
├── spec.md # 要件定義(WHAT/WHY)
├── plan.md # 技術方針・アーキテクチャ
├── data-model.md # データ構造・スキーマ
├── contracts/ # API仕様
│ ├── graphql-schema.graphql
│ └── rest-endpoints.md
├── research.md # 技術選定の調査結果
├── quickstart.md # 主要な検証シナリオ
└── tasks.md # 実装タスクリスト
4-4. /speckit.implement で実装
最後は /speckit.implement で実装します。AIがconstitution.mdとタスクリストに従ってコードを生成し、テストも自動作成します。実装中の判断は implementation-notes.md に記録され、後から見返せます。
変更が生じたら仕様側を更新して /speckit.plan を再実行すれば、変更管理も容易です。
5. 導入のポイント
よくある誤解と真実
| 誤解 | 真実 |
|---|---|
| 仕様書を書く時間がもったいない | 最初に仕様を15分で固める方が、AIと5往復(30分〜1時間)より50%以上短縮 |
| 要件が変わるから仕様書は無駄 | spec.md更新→/speckit.plan再実行で変更箇所が明確。影響範囲の調査が不要 |
| AIは設計原則を理解できない | constitution.md + Phase -1 GatesでAIが自動チェック |
導入ステップ
- パイロット(1〜2週間) - 小規模な新機能で試す
- チーム展開(1〜2ヶ月) - constitution.md合意、仕様レビュー導入
- 複数チーム - 成功事例共有、ベストプラクティス蓄積
既存プロジェクト:新機能からSDDを適用し、徐々に範囲を広げることを推奨。
まとめ:SDDを勧めたい理由(AI時代の再現性)
- Agent Modeの“同じ指示の繰り返し”は、仕様の穴・前提の散逸が原因になりやすい
- speckitで「質問→仕様→計画→タスク」が型化されると、指示の履歴が成果物として残る
- TDD/BDDは否定せず、SDDの中に自然に取り込める
まずは小さな機能で、受入条件を1ページに書くところから始めるのがおすすめです。
