コーディングエージェントに一段落ぶんの意図を伝えると、数分で数百行のコードが返ってくる。そんな時代になった。
では、そのコードは頼んだとおりに動くのだろうか。書くのは簡単になったが、「意図どおりか」を確かめる作業は今も難しい。
これまで仕様書は、手間ばかりかかるものと見られがちだった。書いた端からコードとずれていく文書だったからだ。
エージェントが実装を書くようになると、事情が変わる。機械が実装を担うなら、「何を作りたいのか」を記した文書がいちばん大事な成果物になる。
OpenSpecは、その文書を実用的にしようとする試みだ。仕様駆動開発のための、軽くて設定しやすいフレームワークである。変更が何をするべきかを記録し、今の挙動との違いをはっきり示す。
人間とエージェントが同じ資料を見られるようにもする。古くからある問いが、新しい場面でまた顔を出す。
どこまでなら構造が助けになるのか。どこからは足かせになるのか。目新しさが薄れたあとも、この習慣は続くのだろうか。
この記事のポイント
- エージェントがコードを書く時代、仕様は意図を残せる唯一の記録であり、人間がエージェントの速さで確認できる唯一のものでもある。
- Gitで管理するテキストの仕様なら、コードと同じレビュー、差分、履歴の道具をそのまま使える。
- 「現在の正しい状態」と「提案された変更」を分けると、コードができる前に意図を承認できる。
なぜ仕様がまた大事になったのか
チャットで進める開発では、意図はプロンプトの中にしかない。セッションが終われば、そのプロンプトも消える。
誰もレビューせず、版も管理せず、あとから監査することもない。エージェントが読み違えたとき、手がかりは生成されたコードだけだ。
ところがコードを1行ずつ読むやり方では、エージェントの速さに追いつけない。
仕様は、この状況を逆転させる。残り、版を管理でき、レビューと監査ができ、人間がじっくり読める短さに収まる。
目的は、見栄えのいい文書を作ることではない。失敗を未然に防ぐことだ。あいまいなプロンプトを渡すと、エージェントはもっともらしいが間違った選択に流れやすい。
「キャッシュを追加して」と頼んだとしよう。エージェントは、違う層にキャッシュを置くかもしれない。
無効化の方法に危うい手を選ぶかもしれない。ほかの部品が頼りにしている挙動を変えてしまうかもしれない。
ひとつひとつの選択は、単体で見ればもっともらしい。仕様があれば、コードが生まれる前に選択肢を絞れる。勘違いは、直すのが安いうちに見つかる。
次の表は、意図を運ぶ2つの方法を比べたものだ。
| 観点 | 会話のプロンプト | 版管理された仕様 |
|---|---|---|
| 寿命 | セッションとともに終わる | リポジトリとともに残る |
| レビュー | ほとんどされない | プルリクエストで確認される |
| 監査 | あとから再現しにくい | 版管理に全履歴が残る |
| 範囲の管理 | 際限がない | 書かれた要件で区切られる |
| 共有される資料 | 1人と1つのエージェントにしか見えない | チーム全員とすべてのエージェントに見える |
仕様には、本番で動くエージェントのために標準的な土台をそろえる、という大きな流れも関わっている。
コーディングエージェント向けにGitと結びついた永続的な記憶を持たせる手法も、同じ要請から生まれた。ただし、2つの道具の役割は違う。
- 記憶のツールは、エージェントがコードベースについて学んだことを残す。
- 仕様のフレームワークは、エージェントが何を頼まれ、それはなぜだったのかを残す。
両方がそろうと、エージェントはセッションをまたいでも、構造のある長続きする文脈のもとで確実に働ける。

図2:会話型プロンプトと仕様書ベースのワークフロー比較
「軽い」と「設定できる」は実際に何を指すのか
OpenSpecの中心にある主張は、こうだ。
仕様のフレームワークは、儀式めいた手続きを増やさず、チームのほうに合わせて形を変えるべきだ。この主張が頼りにする「軽い」と「設定できる」という2つの言葉には、それぞれ具体的な約束があり、具体的な危うさもある。
この節のポイント
- 軽いとは、仕様をGitにテキストで置き、言葉数を絞り、特定の製品に縛られないこと。
- 設定できる自由には、統一感を失う代償がある。選択肢の多さより、良い初期設定のほうが大切だ。
- 構造と柔軟さの釣り合いは、チームが何を作っているかで変わる。
「軽い」の中身
「軽い」には、3つの具体的な約束がある。
- コードのそばにあるテキスト。 仕様はリポジトリの中にあり、別のツールには置かない。
- 少ない語彙。 先に学ぶ必要のある重い書式ではなく、ひと握りの概念だけで動く。
- 縛られないこと。 特定のエディター、モデルの提供元、ホスト型サービスに依存しない。
仕様がGitのテキストなら、コードと同じプルリクエストの流れに乗る。
差分も取れる。変更は履歴にも残る。衝突の解消のしかたも、コードと変わらない。
仕様の変更は、別の場所で管理する別の文書ではなく、コミット履歴の一部になる。要件を変えることが、記録に残り、レビューできる出来事になるわけだ。
設定できることの代償
柔軟さがあれば、チームは自分たちの領域に合わせて、テンプレート、ディレクトリの構成、作業の段階を調整できる。
ただし、設定できる項目が増えるたび、統一感が崩れる場所も増える。 チームごとに使い方が違うと、同じコードベースの中でも仕様の見た目がそろわなくなる。
すると、エージェントもレビュアーも、共通の構造という恩恵を失う。
難しいのは、良い初期設定を選ぶことだ。フレームワークは、利用者の代わりにほとんどの判断を済ませておき、本当に役立つ選択肢だけを残すのがよい。そうしないと、判断を支えるどころか、先送りするだけになる。
構造が少なすぎる場合と多すぎる場合の釣り合いは、チームによって違う。
| 失敗の型 | 現れ方 | 結果 |
|---|---|---|
| 簡素すぎる | チームが独自の決まりを作る | 仕様がばらばらになり、エージェントへの入力も不ぞろいになる |
| 決めすぎる | どんな変更にも重いテンプレートと段階が要る | 技術者が負担と感じ、迂回するようになる |
| ほどよい | 強い初期設定と、意味のある少数の選択肢 | 小さな変更を遅らせずに、仕様の統一感を保てる |
どんな組織にもぴったり合う設定は存在しない。決済基盤を作るチームなら、社内ツールを試作するチームより、多めの構造を受け入れるかもしれない。
フレームワークの役目は、どちらのチームも、相手のやり方を押しつけられずに使えるようにすることだ。
提案から実装まで:変更のライフサイクル
エンジニアリングの仕事の多くは、ゼロから作ることではなく、既存のシステムを変えることだ。だから、使える仕様フレームワークは、変わらない完成形を書くだけでなく、変更そのものを扱えなければならない。
この節のポイント
- 変更は、全面的な書き直しではなく、現在の仕様との差分として書く。
- 「現在の正しい状態」と「提案された差分」を分けると、コードができる前に承認できる。
- 仕様が役立つかどうかは、変更の種類しだいだ。
4つの段階
OpenSpecのライフサイクルは、4つの段階で進む。
- 差分を提案する。 変更を、現在の仕様との違いとして書く。全面的な書き直しにはしない。
- 影響をはっきりさせる。 提案の中で、どの既存の挙動が変わり、どれが変わらず、何がそれに依存しているのかを示す。
- 実装タスクを導き出す。 承認された差分から、人間やエージェントが取り組む具体的なタスクを作る。
- 変更を本体に戻す。 承認されて実装が終わったら、差分を本体の仕様に統合する。それが新しい「現在の正しい状態」になる。
「現在の正しい状態」と「提案された差分」を分けておくと、エージェントを使う場面では、次の3つの点で特に効く。
- レビュアーが、区切られた成果物を見られる。 コードができる前に、変更の明確な説明を承認できる。
- 勘違いが早く表に出る。 差分の中の誤った前提なら、コメント1つで直せる。同じ前提がマージ済みのコードに入り込むと、やり直しの1サイクルが必要になる。
- エージェントが、要件をこっそり書き換えられない。 仕様が、レビューを受けた別の成果物であれば、エージェントは自分が作ったものに合わせて要件を調整できない。
この習慣が報われるのはいつか
この習慣には、負担もある。1行の修正や誤字なら、差分を書く手間のほうが大きいかもしれない。仕様を書く価値のある変更と、その場で直したほうが早い変更とを、チームではっきり分けておく必要がある。
レビューの関門にも、似た緊張がある。承認の段階は、明確な判断を迫るので、結果を良くすることがある。
一方で、レビュアーが仕様をよく読まずに承認するなら、形だけの儀式に落ちてしまう。関門が役立つのは、そこに立つ人が中身と向き合うときだけだ。
中心の問いは、差分を書くことが結果を良くするのか、それとも実装を遅らせるだけなのか、である。答えはおそらく、変更の種類で変わる。
実務者の報告では、あいまいさが大きい場面ほど効果が大きいという。上の議論とは合う話だが、厳密に測られたわけではない。
| 変更の種類 | 仕様の価値の見込み | 理由 |
|---|---|---|
| 複数のシステムやチームにまたがる | 高い | 影響の分析で、システム間の破綻を見つけられる |
| 受け入れ基準があいまい | 高い | 基準を書くことで、あいまいさが表に出る |
| 公開されている挙動やAPIを変える | 高い | 利用する側に、明確な記録が要る |
| 影響が限られ、よく分かっている修正 | 低い | 手間が効果を上回りそうだ |
| 試作段階の実験 | 低い〜中程度 | 要件がすぐ変わるのが前提になる |
人間とエージェントをつなぐ窓口としての仕様
良い仕様は、3つの仕事を同時にこなす。ひとつめは、あいまいな意図を区切られたタスクに変えて、エージェントの選択肢を絞ること。ふたつめは、「完了」をエージェントが確かめられる形で定めること。
みっつめは、生成された行を全部読まなくても、人間がレビューできる記録を残すことだ。ここには、読み手が2種類いるという難しさがある。
機械が動けるほど正確でありながら、プロダクトオーナーが承認できるほど読みやすくなければならない。
この節のポイント
- 仕様は、あいまいな目標ではなく、検証できる基準を書くと効く。
- エージェントは、出力を確かめて絞り込む制約の中のほうが、よく働く。
- 監査できる仕様があれば、失敗したとき、何が悪かったのかを推測に頼らず調べられる。
基盤の側でも、エンジニアは似た問題に直面している。
エージェントが確実に使えるように、データの層やAPIを設計する場面だ。そこでは、意味の明確さと、はっきり定義された取り決めが、エージェントの成否を左右する。要件も同じである。

図6:OpenSpec仕様書の構造要素と人間・エージェント間の理解統一メカニズム
大事なのは形式より明確さ
最大の危険は、根拠のない安心感だ。きれいに整った仕様でも、間違った前提を含むことはある。
「性能を改善する」という要件は、エージェントにも人間にも役立たない。形式ばって見えるだけだ。構造は助けになるが、実際の働きをするのは明確さである。
検証できる場面と、はっきりした要件の書き方は、書かれたことと意図したこととの隔たりを縮める。ただし、なくしてしまうことはできない。その差がいちばんよく現れるのが、受け入れ基準だ。
| あいまいな要件 | 検証できる要件 |
|---|---|
| 「もっと速くする」 | 「検索クエリの95パーセンタイル応答時間を100ミリ秒未満にする」 |
| 「エラーをうまく処理する」 | 「上流がタイムアウトしたら、retry-afterヘッダー付きのHTTP 503を返す。部分的な結果は決して返さない」 |
| 「より多くのユーザーに対応する」 | 「同時5,000セッションを維持し、エラー率を0.1%より上げない」 |
| 「セキュリティを向上させる」 | 「有効なトークンのないリクエストは拒否し、拒否のたびに送信元IPと時刻を記録する」 |
良い仕様は、制約とトレードオフも、はっきり書く。書かれていなければ、エージェントは間違った目標に向かって最適化するかもしれない。誰も書き留めなかった一貫性の保証を捨てて、遅延の目標を満たすことがある。
テストの入力だけを特別扱いして、テストを通すこともある。何を変えてはいけないかを書くことは、何を変えるべきかを書くことと同じくらい大切な場合が多い。
ハーネスがエージェントの働きを高める
本番向けのエージェントに関する最近の取り組みからは、より大きな教訓が見えてくる。
エージェントは、自由に推論させるより、出力を制約し、確認し、ふるいにかける「ハーネス」の中に置いたほうが、よい成果を出しやすい。1
仕様は、計画と実装の段階のためのハーネスにあたる。エージェントには、定められた目標、確認できる「完了」の定義、判断を記録する場所が与えられる。
どれもが、もっともらしいが間違った出力の入り込む余地を狭める。
チームが期待する効果は、はっきりしている。やり直しの回数が減り、レビューが分かりやすくなり、実装中のあいまいさも減る。
ところが、仕様駆動開発でその効果が出るという証拠は、今のところ大半が体験談にとどまる。きちんと評価するなら、仕様がある場合とない場合でエージェントの出力を、多数のタスクにわたって比べる必要がある。
モデルの能力とプロンプトの質も、そろえなければならない。この種の研究は、まだ大規模には行われていない。
それまでは、改善したという主張は、もっともらしい仮説として受け取ったほうがよく、確立した結果とは言えない。
仕様を監査できるようにする
ハーネスの考え方からは、フレームワーク自体も監査できるべきだ、という結論も出てくる。エージェントの出力がおかしくなったとき、チームは次の3つを再構成できなければならない。
- エージェントが受け取った仕様。 要件が間違っていたのか、読み違えたのか。
- エージェントが決めたこと。 仕様が何も語っていない部分で、どんな選択をしたのか。
- そう決めた理由。 記録された理由があったのか、それとも隙間を推測で埋めたのか。
この記録がなければ、エージェントの失敗を調べる作業は、当て推量になる。記録があれば、失敗は次の仕様を良くする教訓になる。
導入の現実、残された問い、これから
設計が良いだけでは、フレームワークは成功しない。目新しさが薄れたあとも、チームが使い続けてこそ成功と言える。仕様駆動開発には、実際の現場で表に出てくる、いくつかの現実的な障害がある。
- 同期。 速く動くコードに仕様を合わせ続けるのは難しい。古くなった仕様が1つあるたび、ほかの仕様への信頼も削られる。
- 古くなった文書。 本体に戻されず、廃止もされない仕様がたまっていく。人もエージェントも、それに惑わされかねない。
- 最初にかかる手間。 エージェントのおかげで、コードを書くのがほぼ無料のように感じられる。そのため、技術者は、遅くなりそうに見える手順に抵抗する。
- 価値の証明。 チームが取り入れるのは、レビューが速くなり、バグが減り、引き継ぎが明確になる道具だ。作業手順が整うだけでは、支持はなかなか得られない。
この節のポイント
- 仕様が定着するのは、コードとの同期が保たれ、実際に役立つと示せたときだけだ。
- 規模の拡大と、チームやツールをまたぐ標準化は、まだ決着していない。
- 今問われているのは、仕様がどんな形になるのか、そしてチームが一貫して使うのか、ということだ。
ちょっと立ち止まって
エージェントや同僚が、動きはするけれど意図とは違うものを作った。そんな最近の場面を思い出してみてほしい。すれ違いは、どこから始まっていただろうか。
コードの中だっただろうか。それとも、その前に交わされた言葉の中だっただろうか。仕事を始める前に、「完了」とは何かを書き留めていたら、その一文で問題に気づけていただろうか。

図4:提案から実装までの変更ライフサイクル(OpenSpec準拠)

図9:OpenSpec導入のロードマップ(4段階フェーズ別展開計画)
脚注
-
GoogleのMantis脆弱性スキャンのハーネスは、報告されている一例だ。より優れたモデルを使ったことだけでなく、エージェントの仕事を構造化したことで、厳しいセキュリティの現場で誤検知を減らした。https://research.google/blog/mantis-a-novel-approach-to-vulnerability-discovery/ ↩