AI に仕様書を書かせて、AI に要件を決めさせない
「Hora Kit の設計」シリーズの 5 本目。Hora Kit では仕様書を /hora-spec という skill、つまり AI が書きます。それなのに「AI が要件を決めた」という状態にはなりません。この矛盾をどう解いているのかを、7 つのステージと節ごとの承認という仕組みに沿って書きます。
1. はじめに
この記事は、弊社(Open Reach Tech)が OSS にした AI 開発フレームワーク『Hora Kit』の設計を解説するシリーズの 5 本目です。メイン記事はこちらです。
本当の意味での自動開発を実現するためのAI開発フレームワーク『Hora Kit』をOSSにしました
用語の確認。 Hora Kit で打つコマンドは
/horaの 1 つだけです。/horaが状況に応じて/hora-spec(仕様書を書く)、/hora-setup(実装リポジトリを作る)、/hora-plan(版を確定し、機能一覧と契約を書く)、/hora-build(1 機能を 18 の関所に通す)、/hora-accept(検収する)を順に呼びます。/hora-hotfixだけは/horaが呼ばず、人が直接打ちます。docs はこのうち/hora-specを「決める側」、残りを「作る側」と呼んでいて、この記事でもその呼び方を使います。
Hora Kit では、仕様書を /hora-spec という skill が書きます。つまり AI が書きます。それなのに「AI が要件を決めた」という状態にはなりません。
この 2 つは矛盾しているように聞こえると思います。この記事では、その矛盾をどう解いているのかを、仕様書が出来上がるまでの流れに沿って書きます。
2. なぜ人に書かせないのか
最初に、そもそもなぜ AI に書かせるのか、という話をします。
docs の第 2 部は、「specs/ を人間だけの領域にしておくと、あらゆるプロジェクトの第一歩が『誰も 2 度はやらない一歩』になる」という一文で始まります。空の仕様書と書式の説明書を渡されるのは、要するに作文課題です。しかも Hora Kit の書式は厳格で、機能ごとのユースケースと受入基準、各操作の種類、2 種類ある「対象外」、決して変わらない id が要ります。渡された人は書きやすいところだけ書き、残りは /hora-plan が 1 問ずつ、いつまでも尋ねることになります。
すでに動いている製品だと、事情はさらに悪くなります。20 機能を持つ製品を記憶からこの書式で説明させれば、人は覚えているものだけを話します。そして語られなかった部分の沈黙は、「そこには何も無い」と全く同じに読めてしまいます。
だから /hora-spec が書きます。その代わり、この側にある仕組みはすべて「AI が要件を決めた」にならないために置かれています。
3. 置き場所が、意図の宣言になる
始める前に仕様書を書いておく必要はありません。手元にあるものを 3 つのディレクトリに置きます。
| ここに入れると | /hora-spec がこう理解する |
|---|---|
specs/1.0.0/request/ | これがこのバージョンで作ってほしいことだ。アイデア、要望、やることの一覧 |
specs/1.0.0/annex/ | これは仕様を説明するだけのものだ。モックアップ、図、古い設計書、スプレッドシート |
specs/1.0.0/sources/ | これは仕様そのものの一部だ。現行の要件一覧、API リファレンス |
request/ と annex/ に入れたものは、それ自体が仕様書の文面になることはありません。提案か質問としてあなたに戻ってきて、承認したものだけが書かれます。sources/ だけは扱いが違って、ここに置いて仕様書の Sources の節に宣言された文書は、仕様書そのものと同じに読まれ、/hora-plan がその中身からタスクを作ります。
迷ったら annex/ に入れてください。それで失われるものはありません。内容が本当に必要なら、対話を通って仕様書に入ります。
4. ステージ 0、そして 7 つのステージ

ステージ 0 は、渡されたものを読むところです。request/ を最初に、次に sources/ と annex/、そして specs/1.0.0/ の残りを読みます。新規プロジェクトなら一文で通過しますし、既存プロジェクトならリポジトリと文書を読んで、仕様とコードの食い違いを 1 件 1 行で記録します。
そこから 7 つのステージが順に走ります。
| # | ステージ | skill | 書くもの |
|---|---|---|---|
| 1 | ユースケースとアクター | /hora-spec-usecases | アクター、用語、各機能のユースケースと受入基準 |
| 2 | 地平線 | /hora-spec-horizon | 今回作るもの、今は作らないもの、永久に作らないもの。実装順 |
| 3 | 非機能要件 | /hora-spec-nonfunctional | 利用者数、最重の操作、可用性、保持期間、ミドルウェア |
| 4 | データ、API、実行 | /hora-spec-backend | リポジトリ構成、データモデル、操作一覧、ジョブ |
| 5 | 画面と対話 | /hora-spec-frontend | 各画面が呼ぶ操作、各ユースケースが通る画面 |
| 6 | セキュリティ | /hora-spec-security | 全操作の呼び出し可能者と拒否時の挙動 |
| 7 | 文書全体のレビュー | /hora-spec-review | 矛盾、到達不能なユースケース、観測できない基準 |
順序は規則です。ユースケースが先で、画面が後です。画面から始めると、画面に無い要件が消えてしまうからです。
各ステージも関所と同じ 3 状態で、通過・未通過・理由付き n/a しかありません。n/a を持てるのはステージ 5 だけで、これはフロントエンドを宣言しない版、たとえばスマホアプリ向けの API だけの版のためのものです。認証が一切ない版でも、ステージ 6 でそのことと理由を述べる必要があります。
5. 「読むこと」は「推測すること」ではない
ここが、この側で一番大事な線です。
コードを読み、示されているものを草案にし、提示し、誰かに是としてもらう 可
コードを読み、そこから含意される要件を書く 不可
specs/ を守る不変条件が禁じているのは、要件を推測することです。読むことを禁じたことは一度もありません。だからステージ 4 は既存のマイグレーション、モデル、API スキーマを深く読みますし、ステージ 6 は認可フィルタとロールチェックを読んで「今日、誰がこの操作を呼べるか」を確定させます。それは事実なので「確認」として出てきます。
一方で「誰が呼べるべきか」は、誰も決めていない決定です。それは質問として出てきます。
6. 尋ね方は 3 種類あって、混ぜてはいけない
skill が人に何かを出すとき、3 つの形があります。
確認 「こう読み取りました。合っていますか」
提案 「こうすることを勧めます。決めるのはあなたです」
質問 「これはどこにも決まっていません。何ですか」
| 確認 | 提案 | 質問 | |
|---|---|---|---|
| 内容の出所 | skill が読んだ証拠 | skill 自身の考え、または誰かの要望 | まだどこにもない |
| 「はい」と答えると | 事実として入る | 承認された決定として入る | — |
docs は、この区別が崩れる方向を名指ししています。危険なのは、提案を確認の形で出すことです。人は skill が発明したものに「はい、合っています」と答え、それが既存の事実として specs/ に入ってしまいます。
たとえば「この画面にはエラー状態がある」という文は、コードにあるなら確認で、無いなら提案です。同じ文が両方を意味してはいけないので、提案のときは必ず「この画面にエラー状態を足すことを提案します」と書かれます。
7. 承認は節ごと

| 粒度 | なぜそうしないか |
|---|---|
| 行ごと | 承認回数が負担になり、誰も 2 度は続けない。結果として仕様書が書かれないままになる |
| 節ごと | これを使っている。節は、単独で意味を持つ最小の単位 |
| 文書ごと | 1 回の「はい」で承認された仕様書は、誰も読んでいない仕様書。承認が無いより悪いのは、記録がそう言わないから |
各節は全文が提示され、あなたが承認してはじめて spec.md に書かれます。
ちなみに、提案は許されているのではなく、要求されています。製品を求める人は自分の頭の中にある製品を語るので、その抜けは内側からは見えません。依頼を分解し、流れのより良い形を出し、誰も考えていなかったケースを名指すことが、この側の価値です。禁じられているのは黙って入る提案であって、提案そのものではありません。
8. 質問は「まとめて」戻ってくる
文書を 20 個置いても、20 回聞かれるわけではありません。ステージ 0 の確認は、sources/ の全体で 1 往復、annex/ で 1 往復、request/ で 1 往復です。あとは置き場所を変えたいものについて 1 往復するだけです。
対話の負担は「質問の数」ではなく「同じことを何度も聞かれる回数」で決まると弊社は考えていて、まとめられた確認はその後者を消しています。
9. 実例について
/hora-spec が実際に書いた仕様書のサンプルは、現在整備中です。数十万行規模のアプリケーションのサンプルコードと仕様書を公開する予定で、公開したらこの節を差し替えます。
10. 2 版目からは差分になる
2 つ目の版から、spec.md は 1 つ前の版に対する差分だけを書きます。7 つのステージが決めることの大半は前の版で決着しているので、この版が触らない節を持つステージは、直前の版の答えを提示して確認を取り、引き継ぎを書き添えて通過します。
<!-- carried: 1.0.0's numbers, confirmed unchanged -->
これは推測ではなく確認です。引き継ぎは、走らなかったステージと見分けのつかない唯一の通過なので、確認の記録を残しておかないと区別がつかなくなります。ステージ 6 と 7 だけは、その版が足すものについて決して引き継ぎません。新しい操作の呼び出し可能者は、それを導入した版で必ず述べます。
11. まとめ
「AI に仕様書を書かせる」は、うまくやらないと「AI が要件を決める」になります。Hora Kit がその間に置いた線は 4 本です。読むのは自由だが推測は禁止、確認・提案・質問を混ぜない、承認は節ごとに全文を見せる、順序は規則でユースケースが先。
仕様書を AI に書かせようとして、出来上がったものが信用できずに困っている方の参考になれば幸いです。
原典はこちらです。 https://github.com/openreachtech/hora-core/blob/main/docs/quick-start.ja.mdhttps://github.com/openreachtech/hora-core/blob/main/docs/architecture.ja.md