はじめに
こんにちは!サイオステクノロジーの吉永です。
この記事は「SIOS社員が今年一年で学んだこと」のアドベントカレンダー4日目の記事です。今年は生成AI活用事業やWEBアプリケーション開発に携わる中で、AIコーディングアシスタントとの協業について多くのことを学びました。今回は試行錯誤を重ねる中で、今年になって流行りだした「仕様駆動開発(SDD)」と実現するためのツールについて書こうと思います。
先日、OSC福岡2025で「もうAIに振り回されない!OpenSpecで実現する予測可能なAI開発」というテーマで登壇する機会もいただき、この一年の学びを整理することができました。本記事では、その内容をより詳しくお伝えしたいと思います。
さて、AIコーディングアシスタント(Claude Code、GitHub Copilot、Cursorなど)を使っていると、こんな経験はありませんか?
「ユーザー認証機能を追加して」と頼んだら、1000行のコードが生成された
「いや、JWTじゃなくてセッション認証で…」と訂正したら、また1000行のコードが生成された
「そもそもReactじゃなくてNext.jsで…」と再度訂正したら、さらに1000行のコード生成…
この無限ループ地獄、実は「Vibeコーディング」と呼ばれる現象なんです。
Vibeコーディングとは何か
「Vibeコーディング」という言葉は、OpenAIの共同創業者であるAndrej Karpathyが2025年2月に初めて提唱した概念です。LLM(大規模言語モデル)の性能が飛躍的に向上したことで可能になった、全く新しい開発スタイルを指します。
Vibeコーディングの特徴
Vibeコーディングは、従来のソフトウェア開発の常識を覆すような特徴を持っています。まず、コードの存在を忘れて感覚的に開発するという点が挙げられます。開発者はコードの詳細を理解することなく、AIに自然言語で指示を出すだけで機能が実装されていきます。
エラーメッセージが表示されても、その意味を理解しようとはせず、コメントなしでそのままコピペしてAIに投げます。AIが何らかの修正を提案してくれることを期待するわけです。
さらに驚くべきことに、コードが開発者の理解を超えて成長していきます。気づいたら数千行のコードベースになっていて、その全貌を誰も把握していないという状況が生まれます。音声入力でAIに指示を出すことも一般的で、散歩しながらコーディングすることも可能です。
バグに遭遇した場合は、修正できなければ回避策で対処するか、ランダムな変更を加えてバグが消えるまで試すというアプローチが取られます。これは従来のデバッグとは全く異なる手法です。
一見すると非常に効率的で革新的に見えますが、実はこのアプローチには深刻な問題が潜んでいます。
根本的な4つの問題
Vibeコーディングの背後には、以下の4つの根本的な問題が存在します。
- 曖昧な要求仕様
最も大きな問題は、「何を作るか」が明確でないことです。開発者が曖昧な指示をすると、AIは自身の学習データに基づいて推測で補完します。例えば「ユーザー認証を追加して」と言った場合、AIはJWT認証、セッション認証、OAuth、Basic認証など、様々な選択肢の中から独自に判断して実装を進めます。
結果として、開発者が意図していた認証方式とは全く異なる実装が生成されることになります。これを修正するために再度プロンプトを投げると、また別の実装が生成される…という無限ループに陥るのです。
- コンテキストの欠如
プロジェクトには必ず技術スタック、コーディング規約、アーキテクチャパターンといったプロジェクト固有のコンテキストが存在します。しかし、これらの情報がAIに伝わっていないと、既存のコードベースに適合しないコードが生成されてしまいます。
例えば、プロジェクトがNext.js 15のApp Routerを使っているのに、AIがPages Routerで実装してしまう。データベースアクセスにPrismaを使っているのに、生SQLで書かれてしまう。このような不整合が頻発します。
- 非決定的な出力
LLMの性質上、同じプロンプトでも毎回違う結果が返ってきます。これは再現性の欠如を意味します。昨日うまくいった方法が今日は通用しない。同僚が成功した方法を自分が試しても同じ結果にならない。このような状況では、チーム開発が非常に困難になります。
- 知識の散逸
AIとの対話の中で重要な決定事項が決まっていきます。「このAPIはRESTfulに設計する」「認証トークンはHTTP-onlyクッキーに保存する」「エラーハンドリングは専用のミドルウェアで行う」など、プロジェクトの重要な方針が決まっていくわけです。
しかし、これらの決定事項はチャット履歴に埋もれてしまい、後から見返すことができません。新しいセッションを始めたり、別の開発者が作業を引き継いだりすると、同じ議論を最初からやり直すことになります。
これらの問題を解決するため、コミュニティでは様々なアプローチが試みられてきました。
Vibeコーディングの問題を解決するため、最初に登場したのがCLAUDE.mdというアプローチです。
CLAUDE.mdの登場
CLAUDE.mdは、プロジェクトのルートディレクトリに配置するAIへの指示書です。Anthropic社のClaude Codeに特化しており、プロジェクトのガイドライン、ベストプラクティス、制約事項などを記述します。
従来のアプローチ:CLAUDE.md/AGENTS.md
これにより、先ほど述べた「コンテキストの欠如」という問題を解決しようとしました。AIがプロジェクトの技術スタック、コーディング規約、アーキテクチャパターンを理解できるようになるわけです。
# プロジェクト概要
ECサイトのバックエンド開発
## 技術スタック
- Node.js + TypeScript
- Express.js、PostgreSQL、Jest
## コーディング規約
- 関数は単一責任の原則に従う
- エラーハンドリングは必須
- テストファーストで実装
## 実装時の注意
1. TypeScriptの型定義を含める
2. APIはRESTfulに設計
3. 認証はJWT Bearer tokenを使用CLAUDE.mdは2025年6月頃から段階的に進化してきました。
CLAUDE.mdの進化
第1段階(2025年6月頃)では、単なるチートシートとして使われていました。プロジェクトの基本情報を提供し、よく使うコマンドをリスト化する程度の内容でした。この段階では、開発者がマニュアルを見る手間を省く程度の効果しかありませんでした。
第2段階(2025年7月〜9月)になると、AIの制約を定義するツールへと進化しました。詳細なスタイルガイドを記述し、ワークフローを自動化する指示を含めるようになりました。さらに、過去の失敗から学習するため、「やってはいけないこと」のリストも追加されました。
モノレポ(複数のプロジェクトを1つのリポジトリで管理する構成)に対応するため、階層的な設定管理も可能になりました。ルートのCLAUDE.mdで全体的なルールを定義し、各サブプロジェクトのCLAUDE.mdで個別のルールを上書きできるようになったのです。
AGENTS.mdの登場
2025年8月19日、OpenAIがAGENTS.mdをオープンフォーマットとして公開しました。これは、Anthropic社独自のCLAUDE.mdをより汎用的にしたものです。

AGENTS.mdの最大の特徴は、複数のAIツール間で共有される共通指示として機能することです。Claude Code、GitHub Copilot、Cursor、Windsurf、Aiderなど、様々なAIコーディングアシスタントで同じ指示書を使い回せます。
また、推奨言語は英語です。これには明確な理由があります。AIモデルの学習データは英語が圧倒的に多く、技術用語も英語の方が曖昧性が少ないためです。国際的なチームで開発する場合も、英語で書かれていれば誰でも理解できます。
AGENTS.mdには、以下のような内容が含まれます:
実装ガイドラインとして、コード規約(命名規則、ファイル構成、型定義)、エラーハンドリングパターン、セキュリティチェックリスト、認証実装パターンなどを記述します。
ワークフロー指示として、新機能開発プロセス(要件確認→実装→検証→コミット)、バグ修正プロセス、コードレビュー基準などを定義します。
これにより、AIは単にコードを生成するだけでなく、プロジェクトのワークフローに沿った作業を進められるようになりました。
CLAUDE.md/AGENTS.mdの限界
しかし、CLAUDE.md/AGENTS.mdにも限界があることが分かってきました。特に、プロジェクトが成長するにつれて以下の問題が顕在化してきたのです。
- 仕様の管理が困難
プロジェクト全体の説明が1つのファイルに含まれているため、様々な問題が発生します。
まず、すべての機能の仕様が混在してしまいます。認証機能、決済機能、通知機能、管理画面…といった個別の機能の仕様が、すべて1つのファイルに書かれることになります。ファイルが肥大化し、数千行になることも珍しくありません。
次に、過去の決定事項がどこかに埋もれてしまいます。「3ヶ月前に決めた認証方式の詳細はどこに書いてあったっけ?」と探しても、膨大なファイルの中から該当箇所を見つけるのは困難です。
また、現在作業中の内容が見つけにくいという問題もあります。複数の機能を並行して開発している場合、どれが完了していて、どれが進行中で、どれが未着手なのか、ファイルを読むだけでは判断できません。
さらに深刻なのは、途中参加メンバーが全体像を把握することが困難という点です。新しく参画したエンジニアが数千行のCLAUDE.md/AGENTS.mdを読んでも、プロジェクトの歴史的経緯や現在の状態を理解するのは非常に難しいのです。
- 変更の追跡が不可能
CLAUDE.md/AGENTS.mdはGitで管理されているため、理論上は変更履歴を追跡できます。しかし実際には、どの機能がいつ追加されたかを把握するのは困難です。
ファイル全体の差分を見ても、「500行目に3行追加、800行目に5行修正」といった情報しか得られません。それが認証機能の変更なのか、決済機能の追加なのか、コーディング規約の更新なのか、差分だけでは判断できないのです。
仕様変更の履歴が残らないことも問題です。「なぜ認証方式をJWTからセッション認証に変更したのか?」という意思決定の背景が記録されていないため、同じ議論が何度も繰り返されることになります。
複数人で作業している場合、この問題はさらに深刻です。メンバーAが認証機能の仕様を更新し、同時にメンバーBが決済機能の仕様を追加すると、Gitのコンフリクトが発生します。1つのファイルに全てが集約されているため、並行作業が非常に困難なのです。
さらに、セッションが異なると情報が共有されないという問題もあります。Claude Codeで月曜日に作業した内容が、火曜日の新しいセッションでは引き継がれません。CLAUDE.mdに書かれていない暗黙的な決定事項は、毎回失われてしまうのです。
- スケーラビリティの欠如
最も深刻なのは、プロジェクトが大きくなると管理不能になることです。
小規模なプロジェクト(1〜2人、数ヶ月の開発期間)であれば、CLAUDE.md/AGENTS.mdは十分機能します。しかし、10人以上のチーム、1年以上の開発期間となると、話は別です。
特に、既存機能の変更(1→N)が困難です。新しい機能を0から作る場合(0→1)は、CLAUDE.md/AGENTS.mdに新しいセクションを追加すればよいだけです。しかし、既存の機能を変更する場合(1→N)、ファイル内の該当箇所を見つけ、整合性を保ちながら更新する必要があります。
大規模プロジェクトでは、各フォルダにCLAUDE.md/AGENTS.mdが点在することもあります。frontend/CLAUDE.md、backend/CLAUDE.md、infra/CLAUDE.mdといった具合です。これらのファイル間で矛盾が生じると、AIはどちらを優先すべきか判断できず、混乱してしまいます。
結果として、全体像の把握が困難になります。プロジェクトの現在の状態を理解するには、複数のCLAUDE.md/AGENTS.mdをすべて読み、Gitの履歴を追跡し、さらにコードベースを確認する必要があります。
これらの限界を克服するため、新しいアプローチが求められました。それが仕様駆動開発(SDD)です。
仕様駆動開発(SDD)の台頭
2025年に入って、仕様駆動開発(Spec-Driven Development、SDD)という新しいアプローチが急速に注目を集めるようになりました。
SDDの本質
SDDの本質は、一言で表すと以下のようになります:
「コードを書く前に、何を作るかをAIと合意する」
これは当たり前のように聞こえるかもしれません。しかし、Vibeコーディングの時代には、この「当たり前」が忘れ去られていたのです。
従来のソフトウェア開発では、要件定義→設計→実装という順序が基本でした。しかし、AIコーディングアシスタントの登場により、「とりあえずAIにコードを書かせてみて、動かなかったら修正する」というアプローチが一般化しました。
SDDは、AIコーディング時代においても、設計の重要性を再認識させてくれるアプローチなのです。
SDDのキーコンセプト
SDDには、4つのキーコンセプトがあります。
- 明確な仕様定義は、曖昧さを排除することを目指します。「ユーザー認証を追加して」ではなく、「Google OAuthを使った認証を追加し、セッションは24時間有効とし、ログアウト機能も提供する」といった具体的な仕様を定義します。
- 人間とAIの共通理解は、同じ認識を持つことを重視します。AIが生成するコードが、開発者の意図と完全に一致するよう、事前に仕様をすり合わせます。これにより、「期待と違う」という問題を大幅に減らせます。
- 予測可能な実装は、実装前に結果が見えることを意味します。詳細な仕様があれば、実装後のコードがどのようになるか、事前に予測できます。これにより、手戻りを最小限に抑えられます。
- 追跡可能な変更は、いつ、何が変わったかを明確にします。仕様の変更履歴を残すことで、「なぜこうなっているのか」という疑問に答えられるようになります。
従来フローとSDDフローの違い
この違いを図で表すと、非常に明確です。
従来のVibeコーディングフローは、以下のような循環構造になっています:
アイデアをプロンプトに変換し、AIがコードを生成します。生成されたコードをデバッグし、問題があれば修正します。しかし、修正してもまた別の問題が発生し、フラストレーションが溜まっていきます。結局、最初に戻って別のアプローチを試す…という無限ループに陥るのです。
一方、SDDの開発フローは、直線的で明確です:
アイデアを仕様という形で文書化します。その仕様を人間がレビューし、AIと合意します。合意が得られてから初めて実装に移ります。実装が完了したら、仕様をアーカイブして知識として蓄積します。各ステップが明確で、後戻りが最小限に抑えられているのが特徴です。
SDDがもたらす4つの価値
SDDは、開発プロセスに以下の4つの価値をもたらします。
- 予測可能性により、実装前に結果が予測できます。詳細な仕様があれば、「この機能を実装すると、データベーススキーマはこうなり、APIエンドポイントはこれだけ追加され、フロントエンドコンポーネントはこう変更される」ということが事前に分かります。これにより、予期しない副作用を防げます。
- 監査可能性により、すべての変更が追跡可能です。仕様の変更履歴を見れば、「いつ、誰が、なぜ、この変更を行ったか」が明確に分かります。コンプライアンスやセキュリティ監査においても、この追跡可能性は非常に重要です。
- 再利用性により、仕様が知識として蓄積されます。過去のプロジェクトで作成した認証機能の仕様を、新しいプロジェクトで再利用できます。同じ問題を何度も解決する必要がなくなるのです。
- チーム協業により、異なるAIツールでも同じ仕様を共有できます。メンバーAがClaude Codeを使い、メンバーBがCursorを使っていても、同じ仕様を参照していれば、一貫性のあるコードが生成されます。
現在の主要なSDDツール(2025年11月時点)
SDDを実現するツールは、2025年に次々と登場しました:
- Kiro (AWS) – https://kiro.dev
- Spec Kit (GitHub) – https://github.com/github/spec-kit
- OpenSpec (Fission AI) – https://github.com/Fission-AI/OpenSpec
- BMad Method (BMad Code) – https://github.com/bmad-code-org/BMAD-METHOD
- cc-sdd (国産OSSツール) – https://github.com/gotalab/cc-sdd
それぞれのツールには特徴がありますが、今回はOpenSpecを中心にご紹介します。
OpenSpecとは
OpenSpecは、Fission AIが開発した仕様駆動開発を実現する軽量なワークフロー管理ツールです。

OpenSpecが解決する問題
OpenSpecは、先ほど述べたCLAUDE.md/AGENTS.mdの限界を、直接的に解決することを目指して設計されています。
既存プロジェクト向けに最適化されているのが、OpenSpecの最大の特徴です。新規プロジェクトを0から立ち上げる場合ではなく、すでに動いているプロジェクトに後から導入できるよう設計されています。既存のコードベースに影響を与えることなく、段階的に導入できます。
複数のAIツールに対応しているのも重要なポイントです。Claude Code、Cursor、GitHub Copilot、Aiderなど、様々なAIコーディングアシスタントで使えます。チームメンバーがそれぞれ異なるツールを使っていても、同じ仕様を共有できるのです。
軽量な構造により、学習コストが低いことも魅力です。複雑な設定ファイルやビルドツールは不要で、基本的にはMarkdownファイルを編集するだけです。既存のドキュメント作成スキルがあれば、すぐに使い始められます。
変更管理の明確化は、OpenSpecの核心的な機能です。Gitのpull requestのように、仕様の差分を明確に管理できます。「何が追加され、何が変更され、何が削除されたか」が一目で分かります。
OpenSpecワークフロー
OpenSpecは、以下の4つのステップで動作します。
- Proposal(提案)では、変更内容を提案します。「二要素認証を追加したい」「検索機能にフィルタを追加したい」といった変更を、構造化された形で提案します。この段階では、まだコードは生成されません。
- Review(レビュー)では、提案された仕様を確認・調整します。人間が仕様を読み、不明点があればAIと対話しながら詳細化していきます。この段階で、実装の方向性が固まります。
- Apply(適用)では、合意された仕様に基づいて実装を実行します。AIが仕様を読み取り、それに従ってコードを生成します。仕様が明確なので、AIの出力も予測可能です。
- Archive(アーカイブ)では、完了した変更を知識として蓄積します。提案時に作成した変更差分を、マスター仕様に統合します。これにより、プロジェクトの仕様が常に最新の状態に保たれます。
OpenSpecの核となる概念:2つのフォルダ
OpenSpecの構造は、驚くほどシンプルです。基本的に、2つのフォルダで構成されています。
AGENTS.md
openspec/
├── specs/ # 現在の仕様
│ └── auth/
│ └── spec.md # 認証機能の仕様
│
└── changes/ # 提案中の変更
└── add-profile-filters/
| ├── proposal.md # 変更内容
| ├── tasks.md # タスクリスト
| ├── design.md # 技術仕様
| └── specs/
| └── auth/
| └── spec.md # 仕様の差分
└── add-frontend-ui/openspec/specs/フォルダには、現在の仕様を管理します。これは、プロジェクトの「現在の状態」を表します。認証機能、決済機能、検索機能など、各機能の仕様が独立したファイルとして管理されます。
openspec/changesフォルダには、提案中の変更を管理します。これは、プロジェクトの「未来の状態」を表します。各変更提案は独立したディレクトリとして管理され、その中に提案内容、タスクリスト、技術仕様、仕様の差分などが含まれます。
この構造により、CLAUDE.md/AGENTS.mdの「すべてが1つのファイルに混在する」という問題が解決されます。また、複数の変更を並行して進めることも容易になります。
変更差分の概念
OpenSpecの最も強力な機能の1つが、Gitのpull requestと同様の変更差分管理です。
# プロフィール仕様の変更差分
## ADDED Requirements
### 要件: ロールフィルター
システムはユーザーロールによるフィルタリングを提供しなければならない
## MODIFIED Requirements
### 要件: 検索レスポンス(更新版)
検索結果にはフィルター適用状態を含めなければならない
## REMOVED Requirements
### 要件: 全件表示
(廃止:パフォーマンスの問題により)この差分形式により、レビュー時に何が変わるのかが一目で分かります。
ADDEDセクションには、新しく追加される要件が記載されます。この例では、「ロールフィルター」という新機能が追加されることが分かります。
MODIFIEDセクションには、既存の要件の変更が記載されます。「検索レスポンス」という既存の要件が更新され、フィルター適用状態を含むようになることが分かります。
REMOVEDセクションには、廃止される要件が記載されます。「全件表示」機能がパフォーマンスの問題により廃止されることが分かります。
この差分形式は、Gitのdiffやプルリクエストに慣れているエンジニアにとって、非常に理解しやすいものです。コードレビューと同じように、仕様もレビューできるのです。
OpenSpecの実際の使い方
実際のシナリオを使って、OpenSpecの使い方を詳しく見ていきましょう。
シナリオ:二要素認証(2FA)を追加
既存の認証システムに2FA(二要素認証)を追加する場合を考えます。現在はメールアドレスとパスワードによる認証のみですが、セキュリティ向上のため、SMSまたは認証アプリによる2FAを追加したいとします。
Step 1: 変更提案の作成
まず、変更提案を作成します。コマンドラインから直接実行することも、AIアシスタントに自然言語で依頼することもできます。
# コマンドライン、またはAIアシスタントに依頼
/openspec:proposal 二要素認証を追加または、より自然な言葉で:
開発者: 「プロフィール検索にロールとチームでのフィルター機能を
追加するOpenSpec変更提案を作成して」
AI: 「OpenSpec変更提案を作成します...」
*openspec/changes/add-profile-filters/を生成*このコマンドを実行すると、AIが自動的に以下のファイル構造を生成します:
openspec/changes/add-2fa/
├── proposal.md # 変更の意図と背景
├── tasks.md # 実装タスクリスト
├── design.md # 技術仕様
└── specs/auth/
└── spec.md # 2FAの仕様(差分)proposal.mdには、なぜこの変更が必要なのか、どのような価値を提供するのかといった背景情報が記載されます。「セキュリティ向上のため、2FAを導入する。これにより、不正アクセスのリスクを大幅に低減できる」といった内容です。
tasks.mdには、実装に必要なタスクが列挙されます。「データベーススキーマに2FA用のテーブルを追加」「SMS送信機能を実装」「認証アプリとの連携機能を実装」「フロントエンドに2FA設定画面を追加」といった具体的なタスクです。
design.mdには、技術的な設計が記載されます。「2FAのコードは6桁の数字とし、有効期限は5分間」「SMS送信にはTwilio APIを使用」「認証アプリとの連携にはTOTPプロトコルを使用」といった技術的な決定事項です。
specs/auth/spec.mdには、認証機能の仕様の差分が記載されます。これが最も重要なファイルで、既存の認証仕様に対する変更点が明確に示されます。
Step 2: 仕様のレビューと調整
生成された仕様を確認し、必要に応じて調整していきます。この段階では、AIと対話しながら仕様を詳細化していきます。
開発者: 「ロールとチームフィルターの受け入れ条件を追加して」
AI: 「仕様差分を更新します…」
specs/profile/spec.mdとtasks.mdを編集
例えば、「2FAのバックアップコードはどうするか?」「2FAの設定は任意か必須か?」「既存ユーザーへの移行はどうするか?」といった疑問点を、この段階でAIと議論します。
AIが提案する仕様に納得できない場合は、何度でも修正を依頼できます。「バックアップコードは10個生成し、1回使用したら無効にする」「既存ユーザーは次回ログイン時に2FA設定を促すが、強制はしない」といった具体的な要件を追加していきます。
この段階では、まだコードは一切生成されていません。仕様を固めることに集中します。コードを書く前に設計を固めるという、ソフトウェア開発の基本原則に立ち返っているわけです。
Step 3: 実装
仕様に合意したら、いよいよ実装フェーズに移ります。
# コマンドライン、またはAIアシスタントに依頼
/openspec:apply add-profile-filtersまたは、自然言語で:
開発者: 「仕様が良さそうです。実装しましょう」
AI: 「タスクを順番に実装します...」
Task 1.1 ✓ データベーススキーマ更新
Task 1.2 ✓ APIエンドポイント追加
Task 2.1 ✓ フロントエンドコンポーネント作成AIは、tasks.mdに記載されたタスクを順番に実行していきます。各タスクが完了するたびに、進捗が表示されます。
仕様が明確なので、AIの出力も予測可能です。「データベーススキーマ更新」タスクでは、予想通りuser_2faテーブルが追加されます。「APIエンドポイント追加」タスクでは、POST /api/auth/2fa/enable、POST /api/auth/2fa/verifyといったエンドポイントが実装されます。
もし問題が発生した場合でも、どのタスクで問題が起きたかが明確なので、デバッグが容易です。タスクは小さな単位に分割されているため、問題の切り分けがしやすいのです。
Step 4: アーカイブと知識の蓄積
実装が完了し、テストも通ったら、変更をアーカイブします。
# コマンドライン、またはAIアシスタントに依頼
/openspec:archive add-profile-filtersまたは、自然言語で:
このコマンドを実行すると、以下のことが起こります:
開発者: 「変更をアーカイブして」
AI: 「変更をアーカイブします...」
*openspec archive add-profile-filters --yes*
✓ 仕様が更新されましたopenspec/changes/add-2fa/specs/auth/spec.md(差分)が、openspec/specs/auth/spec.md(マスター仕様)に統合されますopenspec/changes/add-2fa/ディレクトリが削除されます- Git履歴に、この変更が記録されます
結果として、openspec/specs/フォルダには常に最新の仕様が保たれ、openspec/changes/`フォルダには進行中の変更のみが残るという、クリーンな状態が維持されます。
CLAUDE.mdのみの場合との比較
ここで、従来のCLAUDE.mdのみを使った場合と、OpenSpecを使った場合を比較してみましょう。
CLAUDE.mdのみの場合の作業フロー:
- CLAUDE.mdをエディタで開く
- どこに2FAの仕様を書くべきか迷う(認証セクション?セキュリティセクション?新しいセクション?)
- 適当な場所に仕様を追記する
- AIにプロンプト:「2FAを追加して」
- AIが大量のコードを生成する(1000行以上になることも)
- 生成されたコードをレビューしようとするが、何が変更されたのか分からない
- 既存の認証ロジックへの影響範囲が不明
- 他の開発者がCLAUDE.mdを更新していて、Gitコンフリクトが発生
- コンフリクトを解決するが、自分の変更と他の人の変更が混ざって分かりにくい
結果:
- × 仕様がCLAUDE.md内で埋もれる(後から見つけるのが困難)
- × 変更履歴が残らない(なぜこの仕様になったかが不明)
- × チーム間での共有が困難(誰が何を変更したか分からない)
OpenSpecを使用した場合の作業フロー:
/openspec:proposal 二要素認証を追加とコマンド実行- 構造化されたファイル群が自動生成される
- proposal.md、tasks.md、design.md、spec差分を順番にレビュー
- 不明点があればAIと対話しながら詳細化
- 仕様に合意したら
/openspec:applyで実装開始 - タスクごとに進捗を確認できる
- 各タスクの成果物をその場でレビュー
- 問題があれば該当タスクだけを修正
- 完了後に
/openspec:archiveで知識として蓄積 - 他の開発者は別の変更提案で並行作業可能(コンフリクトなし)
結果:
- ✓ 変更内容が明確(dedicated directoryで管理)
- ✓ 影響範囲が把握できる(差分形式で表示)
- ✓ チーム全体で知識を共有(アーカイブで蓄積)
- ✓ 並行作業が可能(changes/以下で分離)
既存のAGENTS.md/CLAUDE.mdは不要?
ここで疑問が生じます。「OpenSpecがあれば、AGENTS.md/CLAUDE.mdは不要なのか?」
答えは「いいえ、併用が推奨されています」です。
AGENTS.md/CLAUDE.mdとOpenSpecは役割が異なります。
AGENTS.md/CLAUDE.mdは、全体的な指示を記述します。プロジェクトのコーディング規約(「変数名はcamelCaseで書く」「ファイル名はkebab-caseで書く」など)、プロジェクト全体のアーキテクチャ(「MVCパターンを採用」「依存性注入を使う」など)、共通のワークフロー(「コミット前に必ずlintとtestを実行」など)といった、プロジェクト横断的なルールを定義します。
OpenSpecは、個別機能の仕様を管理します。認証機能の詳細な仕様、決済機能のAPI設計、検索機能のアルゴリズムなど、機能ごとの具体的な仕様を管理します。
両者は補完関係にあります。AGENTS.md/CLAUDE.mdが「プロジェクトの憲法」だとすれば、OpenSpecは「個別の法律」のようなものです。
OpenSpecは、AGENTS.md/CLAUDE.mdと統合するための特別なブロックを提供しています:
<!-- OPENSPEC:START -->
# OpenSpec 操作手順
この手順は、本プロジェクトで活動するAIアシスタント向けです。
以下のリクエスト時には常に `@/openspec/AGENTS.md` を開いてください:
- 計画や提案に関する言及がある場合(proposal、spec、change、plan などの単語を含む)
- 新機能の導入、互換性のない変更、アーキテクチャ変更、大規模なパフォーマンス/セキュリティ作業に関するもの
- 曖昧な内容で、コーディング前に正式な仕様書が必要な場合
`@/openspec/AGENTS.md` で以下の内容を学習してください:
- 変更提案の作成と適用方法
- 仕様書のフォーマットと規約
- プロジェクト構造とガイドライン
この管理ブロックを維持し、「openspec update」で手順を更新できるようにしてください。
<!-- OPENSPEC:END -->このブロックをAGENTS.mdに追加することで、AIアシスタントがOpenSpecの使い方を自動的に学習します。ユーザーが「新機能を追加したい」と言えば、AIは自動的にOpenSpecの変更提案を作成するようになります。上記のブロックはOpenSpec init実行時に自動的にCLAUDE.mdに追加されます。
他ツールとの比較
ここで、主要なSDDツールを比較してみましょう。OpenSpec以外にも、優れたSDDツールがいくつか存在します。
Kiro(AWS)
Kiroは、AWSが開発したSDDツールです。大規模プロジェクト向けに設計されており、プロジェクトの方向性と個別機能の仕様を明確に分離する2層構造が特徴です。
.kiro/
├── steering/ # プロジェクト方向性(変更頻度:低)
│ ├── product.md # プロダクトのビジョン、目標、ターゲットユーザー、主要機能
│ ├── tech.md # 技術スタック、アーキテクチャ方針
│ └── structure.md # ディレクトリ構造、命名規則
└── specs/ # 機能仕様(変更頻度:高)
└── add-2fa/
├── requirements.md # 機能要件
├── design.md # 技術設計
└── tasks.md # 実装タスクプロジェクト構造:
steering/フォルダには、プロジェクト全体の方向性を定義します。これは変更頻度が低い情報です。
product.mdには、プロダクトのビジョン、目標、ターゲットユーザー、主要機能といった、プロジェクトの根幹を成す情報が記載されます。例えば、「このアプリケーションは、中小企業の経理担当者をターゲットとした経費精算システムです。主要機能は、経費の申請・承認・精算です」といった内容です。
tech.mdには、技術スタック、アーキテクチャ方針、使用するライブラリなどが記載されます。「Next.js 15 + NestJS + PostgreSQLを使用」「マイクロサービスアーキテクチャを採用」「認証にはAuth0を使用」といった技術的な決定事項です。
structure.mdには、ディレクトリ構造、命名規則、モジュール間の依存関係などが記載されます。「フロントエンドは/frontend、バックエンドは/backendに配置」「コンポーネント名はPascalCaseで書く」といった構造的なルールです。
一方、specs/フォルダには、個別機能の詳細仕様を定義します。これは変更頻度が高い情報です。
各機能ごとにディレクトリを作成し、その中にrequirements.md(機能要件)、design.md(技術設計)、tasks.md(実装タスク)を配置します。
Kiroの2層構造の利点:
この2層構造により、プロジェクトの憲法(steering/)と個別の法律(specs/)が明確に分離されます。
steering/を変更するのは慎重に行うべきです。なぜなら、すべての機能に影響するからです。一方、specs/は頻繁に変更されます。新機能を追加するたび、既存機能を修正するたびに更新されます。
この分離により、チーム間の役割分担も明確になります。プロダクトマネージャーやアーキテクトはsteering/を管理し、個別の開発者はspecs/を管理する、といった分業が可能です。
大規模プロジェクト(数十人のチーム、数年にわたる開発)では、この構造が非常に有効です。
Spec Kit(GitHub)
Spec Kitは、GitHubが開発したSDDツールです。新規プロジェクトを0から立ち上げる際に最適化されており、プロジェクトの立ち上げから運用まで、すべてのフェーズをカバーする重厚なドキュメント構成が特徴です。
プロジェクト構造:
specs/001-todo-app-git-oauth/
├── spec.md # 機能仕様書
├── checklists/
│ └── requirements.md # 品質チェックリスト
├── plan.md # 実装計画(技術選定)
├── research.md # Phase 0: 技術調査
├── data-model.md # Phase 1: データモデル
├── contract/
│ └── openapi.yaml # Phase 1: API制約
├── tasks.md # Phase 2: 実装タスク
└── quickstart.md # 開発者ガイドSpec Kitの特徴は、4つのフェーズに分かれた開発プロセスです。
Phase 0: 仕様作成
Phase 0: 仕様作成では、何を作るかを定義します。
spec.mdには、機能の概要、ユーザーストーリー、受け入れ基準などが記載されます。「エンジニアとして、Google OAuthでログインできるようにしたい。ログインに成功したら、ダッシュボードにリダイレクトされる」といった内容です。
research.mdには、技術調査の結果が記載されます。「認証ライブラリとしてNextAuth.jsとAuth0を比較した結果、NextAuth.jsを採用する。理由は、Next.jsとの統合が容易であり、無料枠が充実しているため」といった調査レポートです。
Phase 1: 設計
Phase 1: 設計では、どう作るかを設計します。
plan.mdには、実装計画が記載されます。技術選定の詳細な理由、アーキテクチャ図、開発スケジュール、リスク管理などが含まれます。
data-model.mdには、データモデルが記載されます。「Userテーブルには、id (UUID)、email (string)、name (string)、createdAt (timestamp)を含む」といった具体的なスキーマ定義です。
contract/openapi.yamlには、APIの仕様がOpenAPI形式で定義されます。これにより、型安全性が確保され、APIドキュメントも自動生成できます。
Phase 2: 実装
Phase 2: 実装では、具体的な実装ステップを実行します。
tasks.mdには、実装タスクが列挙されます。「プロジェクト初期化」「データベース設定」「認証エンドポイント実装」「ログインUI作成」といった具体的なタスクです。
Phase 3: レビュー
Phase 3: レビューでは、実装内容の動作確認を行います。
quickstart.mdには、開発者ガイドが記載されます。環境構築手順、開発サーバー起動方法、テスト実行方法、デプロイ手順などが含まれます。新メンバーが参画したとき、このquickstart.mdを読めばすぐに開発を始められるようになっています。
さらに、checklists/requirements.mdには、品質チェックリストが含まれます。機能要件、非機能要件、テストカバレッジ、ドキュメント、コード品質など、各項目について確認すべき事項がリスト化されています。
Spec Kitの強み:
Spec Kitは、新規プロジェクトを0から立ち上げる際の完全なガイドとして機能します。何をどの順番で行えばよいか、何を確認すべきかが明確なので、経験の浅いチームでも品質の高いプロジェクトを立ち上げられます。
また、OpenAPI連携により型安全性を確保できるのも大きな利点です。APIの仕様が変更されたら、自動的に型定義も更新され、フロントエンドとバックエンドの不整合を防げます。
GitHub Copilotとの統合も考慮されており、GitHub上のプロジェクトで特に威力を発揮します。
3ツールの比較表
3つのツールを表で比較すると、以下のようになります:
| 特徴 | OpenSpec | Spec Kit | Kiro |
|---|---|---|---|
| 対象 | 既存PJ (1→N) | 新規PJ (0→1) | 全プロジェクト |
| 構造 | 2フォルダ (specs + changes) | 4フェーズファイル | 2層構造 (steering + specs) |
| 主要ファイル | proposal.md tasks.md spec 差分 | spec.md + research.md plan.md + data-model.md tasks.md quickstart.md | product.md tech.md structure.md requirements.md design.md tasks.md |
| 変更管理 | 差分 + アーカイブ | Git履歴 | Git履歴 |
| 価格 | 無料(AIツール利用料のみ) | 無料(AIツール利用料のみ) | 有料(毎月 無料枠あり) |
どれを選ぶべきか
それぞれのツールには明確な使い分けがあります。
OpenSpecは、既存プロジェクトに導入したい場合に最適です。すでに動いているプロジェクトに後から導入でき、学習コストが低く、複数の変更を並行して進めやすいのが特徴です。
「今のプロジェクトにSDDを導入したいが、大きな変更は避けたい」「チームメンバーが異なるAIツールを使っている」「複数の機能を同時並行で開発している」といった状況では、OpenSpecが適しています。
Spec Kitは、新規プロジェクトを立ち上げる場合に最適です。0から丁寧にガイドしてくれ、ドキュメントが重厚で、品質チェックリストも完備されているのが特徴です。
「新しいプロジェクトをこれから始める」「チームメンバーに経験の浅い人が多い」「品質を重視したい」「GitHub Copilotを使っている」といった状況では、Spec Kitが適しています。
Kiroは、大規模で長期的なプロジェクトでしっかりした構造が必要な場合に最適です。steeringとspecsの2層構造が強力で、プロジェクトの方向性と個別機能を明確に分離できるのが特徴です。
「数十人規模のチームで開発している」「数年にわたるプロジェクト」「プロダクトマネージャーと開発者の役割分担を明確にしたい」「予算がある(有料ツールを導入できる)」といった状況では、Kiroが適しています。
AIコーディングの進化
AIコーディングは、ここ数年で劇的に進化してきました。
- 第1世代: コード補完の時代(2021年頃〜)では、GitHub Copilot、TabNineなどのツールが登場しました。これらは、コードの一部を書くと、次の行を予測して補完してくれるというものでした。開発者の生産性は向上しましたが、あくまで「補完」に過ぎず、開発者が設計し、コードを書くという基本は変わりませんでした。
- 第2世代: 対話型コード生成の時代(2023年頃〜)では、ChatGPT、Claude、Cursorなどが登場しました。自然言語で「ユーザー認証機能を作って」と指示すると、完全なコードが生成されるようになりました。これは革命的でしたが、同時にVibeコーディングという問題も生み出しました。
- 第3世代: 仕様駆動開発の時代(2025年〜)では、OpenSpec、Kiro、Spec Kitなどが登場しました。コードを書く前に仕様を定義し、AIと合意するというアプローチです。これにより、予測可能で、監査可能で、再利用可能な開発が実現されました。
開発者の役割の変化
仕様駆動開発の登場により、開発者の役割も変化しています。
第2世代のAIコーディングでは、開発者は「AIのサポートでコードを書く」という役割でした。AIが生成したコードをレビューし、修正し、統合するという作業が中心でした。
第3世代のAIコーディングでは、開発者は「仕様を設計し、AIを操縦する」という役割に変化しています。コードを書く作業の多くはAIに任せ、開発者は「何を作るべきか」を明確に定義することに集中します。
ただし、以下の点は変わりません:
- コードを読む能力、理解する能力は依然として重要です。AIが生成したコードが正しいかどうかを判断するには、コードを読み解く力が必要です。
- コードを書く作業はAIに任せていくのが今後のトレンドです。単純なCRUD操作、ボイラープレートコード、テストコードなどは、AIに任せることで効率化できます。
- そして、「何を作るべきか」を明確に定義する能力がより重要になっていきます。曖昧な指示ではなく、具体的で明確な仕様を書ける能力が、これからのエンジニアに求められるのです。
チーム開発の改善
SDDは、チーム開発にも大きな改善をもたらします。
- 知識の蓄積と共有が可能になります。仕様が文書として残るので、「なぜこの設計になっているのか」「どういう経緯でこの技術を選定したのか」が後から分かります。新しいメンバーが参画しても、仕様を読めば素早くキャッチアップできます。
- 品質の向上も期待できます。予測可能な出力により、「期待と違う」というギャップが減ります。レビュー可能な変更により、仕様レベルでのレビューが可能になります。追跡可能な履歴により、問題が発生したときに、どの変更が原因かを特定しやすくなります。
まとめ
この一年の学びを、3つのポイントにまとめます。
- 仕様は新しいソースコード
AIとの協業において、明確な仕様が最も重要です。コードそのものよりも、「何を作るか」を定義する仕様の方が価値を持つ時代になりました。仕様さえあれば、AIがコードを生成してくれます。逆に、仕様がなければ、AIは迷走します。
- AIとの協業には構造が必要
Vibeコーディングから脱却し、予測可能な開発へ移行する必要があります。感覚的にコードを書くのではなく、構造化されたプロセスでAIと協業することで、品質と生産性の両立が可能になります。
- AIに振り回される開発から、AIを使いこなす開発へ
仕様駆動開発(SDD)により、より良いソフトウェアを効率的に構築できます。AIは強力なツールですが、それを使いこなすのは人間です。明確な仕様を定義し、AIを適切に操縦することで、真の生産性向上が実現されます。
さいごに
今回は試行錯誤を重ねる中で、今年になって流行りだした「仕様駆動開発(SDD)」と実現するためのツールについて書きました。今年は業務内外で学んだ生成AIツールやAzureリソースに関することなど幅広い内容のブログを投稿できたと思います。これからも業務関係なく学んだ内容を投稿していこうと思います。

