こんにちは、@yellow-seedです。
システムの中心となっているモノレポに、仕様駆動開発フレームワークのOpenSpecを導入しました。
仕様駆動開発のツールには、良さそうだけれどチームに持ち込むのは大変そう、という印象がつきまといます。フル装備で入れようとすれば実際に大変です。ただ、導入の進め方を工夫することで、その大変さの大半は避けられました。
OpenSpec 導入前夜の課題
弊社は全社的にAI活用を推進していて、開発チームでもAIコーディングエージェントを日常的に使っています。AIを積極利用することについては全社的なコンセンサスが得られた状態からスタートしています。
一方で、どう指示するか、実装前にどこまで擦り合わせるかといった進め方が丸ごと個人任せになっていました。結果として次のような状態が生まれます。
- 同じようなタスクでも、担当者によって成果物の品質が大きく揺れる
- うまくいったやり取りが個人のチャット履歴の中に埋もれ、チームの再現可能な資産にならない
- レビュアーから見ると、そのコードがAIとどんな合意のもとで書かれたのか追跡できない
揺れを収めるには、実装プロセスそのものに共通の型が必要です。個人のプロンプト力を鍛える方向で追いつく話ではありません。考えていたのはそこまでで、何を型にするのかは決まっていませんでした。
なぜOpenSpecだったのか
代替候補としては、GitHub製のSpec Kitと、AIに常時読ませる規約や設計方針をsteeringドキュメントとして自前で整備する案の2つ検討しました。
検討の末、OpenSpecを選びました。決め手は、公式ドキュメントに例示されているRapid Iteration Workflowを見つけたことです。ワークフロー定義のサンプルの1つで、本来4種類ある成果物のうち、提案を書くproposal.mdと実装チェックリストのtasks.md、この2種類だけでまわす最小構成になっています。
| OpenSpecの標準成果物 | 役割 | Rapid Iteration Workflow |
|---|---|---|
| proposal.md | なぜやるか(背景・目的・影響範囲) | 使う |
| specs/…/spec.md | 何が変わるか(ADDED、MODIFIED、REMOVEDのデルタ要件) |
使わない |
| design.md | どう作るか(技術的な判断) | 使わない |
| tasks.md | 作業手順のチェックリスト | 使う |
フル装備の仕様駆動を丸ごと背負う必要はなく、まずこの2種類から始められる。それが分かって、導入の絵が具体的に浮かびました。
ここからは、OpenSpecに対して扱いやすいと感じた点を具体的に紹介していきます。
現在の仕様と変更提案をディレクトリで分けている
ディレクトリは、現在のシステム仕様を置くopenspec/specs/と、進行中の変更提案を置くopenspec/changes/に分かれています。1つの変更はchanges/配下の1フォルダに閉じていて、なぜやるかをproposal.md、何が変わるかをspecs、作業手順をtasks.mdが受け持ちます。
変更のspecはデルタ方式です。要件にADDED、MODIFIED、REMOVEDのマーカーを付けて変わる部分だけ書くため、既存システムの仕様を最初に全部書き起こす必要がありません。すでに動いているプロジェクトへ後付けするなら、ここが導入コストを直接左右します。
構造のチェックをCLIに任せられる
openspec validateは、変更ドキュメントの構造的な問題を機械的に検出します。進行中の変更を並べるopenspec list、中身を表示するopenspec showなど、CLIコマンドも一通り揃っています。
ドキュメントが揃っているか、次に何をすべきか。この判断をAIエージェントの読解力に委ねずに済みます。チェックの結果が毎回同じである以上、メンバーごとに使うツールやモデルが違っても、プロセスの品質は同じ基準で揃います。担当者によって成果物の品質が揺れるという最初の困りごとには、この仕組みがいちばん有効でした。
完了した変更を仕様へ畳み込む仕組みがある
変更の実装が終わったらopenspec archiveを実行します。すると変更フォルダのデルタ仕様がspecs/本体へマージされ、フォルダ自体は日付プレフィックス付きでchanges/archive/へ移動します。
完了のたびに現在の仕様が更新され、過去の意思決定は日付順に残ります。作業ドキュメントが散らかり続けません。なぜそう決めたのかの記録も、個人のチャット履歴からリポジトリの側へ移ります。仕様書とコードの乖離というドキュメント駆動につきまとう問題への回答も、最初からワークフローに組み込まれています。
すべてプレーンなMarkdownで、導入も撤退も軽い
成果物は全部ただのMarkdownです。専用のビューアも独自フォーマットもなく、リポジトリにコミットしてPRで普通にdiffレビューできます。仕様とコードが同じPRの同じ画面に並ぶので、そのコードがどんな合意のもとで書かれたのかをレビュアーがその場で追えます。やめたくなってもMarkdownの山が残るだけで、撤退コストもほぼありません。
工程を強制せず、柔軟さに重きを置いている
OpenSpecには、前工程を終えないと次へ進めないという関門がありません。公式が掲げるのもfluid not rigid、built for brownfieldです。Spec Kitとの比較記事でも、厳格な工程の関門を持つ重量級のSpec Kitに対して、OpenSpecは軽量で自由に反復できる点が対比されています。
Rapid Iteration Workflowのように、ワークフロー定義そのものをスキーマとしてカスタマイズし、成果物を減らすことも増やすこともできます。対応先はClaude Code、Cursor、Copilotなど30以上のAIツールで、スラッシュコマンド経由のため特定のIDEやモデルに縛られません。チームとしてはClaude Codeを推奨としていますが、CursorやGitHub Copilotも社内では利用可能なため、この柔軟性は相性が良いと判断しました。
段階的に入れるためにやったこと
いきなりフル装備で導入すれば、またルールが増えた、と受け取られます。抵抗をどこまで削れるかを最優先にして、次の順番で進めました。
事前準備としていつものPull Requestテンプレートと対応付ける
最初に手を付けたのは、OpenSpecの成果物と、チームにすでに定着していたPull Requestテンプレートの対応の整理です。
リポジトリには以下のようなテンプレートを導入しています。
## チケット - [JIRA]() ## 概要 <!-- なぜやるのか。変更した目的を記載してください。(チケットで説明できない補足的な事項など) - やったこと: 変更した内容を記載してください。 - [ ] xxx - [ ] xxx - やらなかったこと: レビューアーが指摘する時間を減らすため、このPRであえてしなかったことがあれば、その内容と理由を記載してください。なければこの項目を削除してください。 - e.g) チケットにはxxxのタスクがあるがPRが肥大化するので、それは別PRで対応します --> ## レビューして欲しい点・気になること <!--なければこの項目を削除してください --> ## 動作確認手順 <!-- - 変更内容を確認した環境、方法を記載してください。 e.g.) - 観点: 動作確認でなにを確認したかの観点を記載してください。 - 環境: ローカル or staging - 方法: curlコマンドで確認した, Connect経由で確認した, etc. - 手順: 確認した手順を記載してください。 - 正常系 - e.g) curlコマンドで確認した場合 1. curl -X GET http://localhost:3000/api/v1/xxx 2. レスポンスが200であることを確認する 3. エビデンスを記載する - 異常系 - e.g) curlコマンドで確認した場合 1. curl -X GET http://localhost:3000/api/v1/xxx 2. レスポンスが400であることを確認する 3. エビデンスを記載する --> ## Ref <!--関連するPR、参考記事など、レビュワーがレビューするにあたっての補足情報。なければこの項目を削除してください -->
このテンプレートと OpenSpecの作成するドキュメントは、以下のような対応関係があると判断しました。
- PRテンプレートの「背景・目的」 ⇄
proposal.md(なぜやるか・外部契約) - PRテンプレートの「作業内容チェックリスト」 ⇄
tasks.md(作業手順・タスク)
この整理があると、説明の中身が変わります。新しい概念を覚えてください、ではなく、いつもPRに書いているあの欄を実装の前に書くようになるだけです、と言えます。導入時の概念説明のコストが目に見えて下がりました。
同じタイミングで、開発補助ツールのバージョンを管理するmiseも入れました。アプリケーション本体とは独立したCLIツールの置き場所と配布方法を先に決めておいたので、OpenSpec CLIの導入はmise install一発で済むようにしました。
第1段階は公式サンプルをそのまま導入することから
最初のスキーマは、Rapid Iteration Workflowの例をほぼそのまま持ち込みました。独自カスタマイズに時間をかけず、proposal.mdとtasks.mdがPRテンプレートと対応する、その体験づくりだけに集中しています。
この段階ではspecs/への仕様の蓄積をあえて止め、軽量運用に振りました。
コマンドの構成には手を入れていません。openspec initはプロファイル設定に従ってコマンドを生成し、デフォルトのcoreプロファイルで入るのはpropose、explore、apply、archiveの4つです。Claude Codeなら/opsx:proposeのようなスラッシュコマンドと、その実体となるskillが組で置かれます。初期状態が、実装前に提案を書いて合意するという一点にほぼ絞られていたので、削る作業が要りませんでした。
生成物はリポジトリにコミット済みです。メンバー側はmise installでCLIを入れるだけで、各自がopenspec initを叩いて構成がばらつく余地は最初からありません。
第2段階で specs/ を解禁し、追加のコマンドも足す
軽量運用が回り始めた1か月後、デルタ仕様をspecs/へ蓄積する選択肢を開きました。全変更に強制はしていません。外部仕様が変わる変更など、蓄積する価値があるときに使える状態にしただけです。
解禁したあとも、specs/はあまり厚くなりませんでした。これまでにアーカイブした22件の変更のうち、仕様を積んだのは2件、design.mdまで書いたのは1件です。
アーカイブを振り返って気づいたのは、その大半が既存実装のリファクタリングと、溜まったデータの整理だったことです。外部から見える振る舞いが変わる変更は、そもそもそれほど出ていません。specs/の薄さは運用の不徹底ではなく、自分たちが普段どんな変更をしているかの反映でした。全件を強制にしていたら、この偏りは毎回きちんと仕様を書く手間の側に隠れて、見えないままだったかもしれません。
チームが手応えを感じ始めた段階で、coreには入っていない検証コマンド(openspec verify)を足しました。成果物と実装の整合性の確認まで含めて、フローを厳密にした形です。現在はここにいます。厳密さは最初に課すものではなく、手応えが出てから足す、という方針がAIを伴うツールの導入とは相性がいいと感じました。
用意中のドキュメント肥大化対策
運用を続けるとchanges/配下のフォルダは増え続けます。GitHub Actionsのcron起動で、完了済みの変更を定期的に自動アーカイブする仕組みを準備中です。openspec archiveが標準機能としてあるので、定期実行に乗せるだけで済みます。
導入してみての所感
実装前にproposal.mdで合意してから書き始めるため、AIとの往復回数が減りました。書き上がったものを見てそうじゃないとやり直す、あの手戻りが起きにくくなっています。
proposal.mdとtasks.mdが固まり切った状態で実装に入ると、AIが自走できる期間が明らかに伸びました。途中で人が割り込んで軌道修正する回数が減り、チェックリストを順に消化していく様子を見守るだけの時間が長くなっています。減った往復回数が、トークン消費のコストにも表れてきてくれることを期待しています。
いちばん大きな変化は、開発プロセスの型が固まったことです。まず提案を書き、合意してから実装する。この共通言語がチームにでき、AIの使い方の個人差をプロセスの側が吸収するようになりました。
誰におすすめできるか
導入して4か月、いちばん相性が良いのは、意思決定の記録をリポジトリの中に置きたいチームです。
ADRを運用しようとすると、たいていは採番ルールとテンプレート、置き場所を自前で決めるところから始まります。OpenSpecのchanges/archive/は、そのすべてを最初から持っています。日付プレフィックスが採番になり、proposal.mdが決定理由の書式になり、アーカイブ先が置き場所になる。しかも実装の直前に書くものなので、決定を後追いで思い出しながら書き起こす手間もかかりません。ADRのために別のツールを立てるくらいなら、このCLIを使ってしまうほうが早いです。
ほかに向いているのは、既存プロジェクトへ後付けしたいチームです。デルタ仕様のおかげで、現行仕様を全部書き起こす作業が要りません。メンバーごとに使うAIツールが違うチームにも向きます。成果物がMarkdownなので、誰がどのツールから書いても同じものが残ります。
逆に、最初から工程を厳格に縛りたいなら、Spec Kitのような重量級のほうが素直です。OpenSpecは工程を強制しないので、書かずに実装してしまうのを止める仕組みは持っていません。そこはチーム側の合意で支える前提になります。
今後の展望
次は実装プロセスの外側へ広げたいと考えています。AI活用のボトルネックは、実装より前後の工程に残っています。
- リリースする際のビジネス部門への説明やQAエンジニアへのインプットでは、外部的な振る舞いのBeforeとAfterを定期的に説明します。proposal.mdはその外部契約を書く場所なので、リリース説明資料の一次ソースとして使えそうです
- テスト管理ツールのQaseを、開発者による動作デモの記録蓄積に使い始めました。proposal.mdに書かれた外部契約からQase APIへテストケースを自動生成する連携(あるいは、Qaseのテストケースからproposal.mdの一部を生成する連携)フローも、現実味を帯びてきています
- 節目ごとに人がAIの成果物へフィードバックを返したい場面があります。レビューを差し込むためのツールであるcrit.mdをフローに組み込む案は、まだ検討中です
まとめ
OpenSpec単体を新しいプロセスとして提案すると、説明のハードルが上がります。PRテンプレートのように先に定着している型と対応付けて出すのが、いちばん通しやすい入り方でした。仕様ドキュメントが溜まって大変になりそうという不安も、openspec archiveの定期実行で片が付くので、導入を止める理由にはなりません。proposal.mdがPR説明、リリース説明、テストケースといった最終成果物へ連続していくと示せると、実装者以外にも価値が伝わります。
正直なところ、ここまで抵抗なく回るとは思っていませんでした。導入前に困っていた品質の揺れは、プロセスの側でかなり吸収できています。この型を実装の外側まで伸ばせるかは、これからです。
株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。
Akerunにご興味のある方はこちらから





