← 一覧へ

AIエージェントに渡す仕様書の書き方──巨大な依頼を壊さず小さく渡す

この記事の読み方
この記事は「AIエージェントを工程に入れる」シリーズの第1回です。 第0回では、Claude Code / Codex 時代の開発フローを Plan、Work、Review、Com…

この記事は「AIエージェントを工程に入れる」シリーズの第1回です。 第0回では、Claude Code / Codex 時代の開発フローを Plan、Work、Review、Compound に分けました。 今回はその入口である Plan、つまり AIエージェントに渡す仕様書の書き方を扱います。

Claude Code や Codex に仕事を頼むとき、最初に迷うのはプロンプトです。

「どう書けばうまく動くのか」

ただ、実務でしばらく使うと、問題はプロンプト文そのものではないと分かってきます。

大事なのは、仕様の渡し方です。

同じ「検索機能を追加して」でも、渡し方によって結果はまるで変わります。何も考えずに頼むと、agent は足りない前提を推測で埋めます。検索対象、UI、API、状態管理、テスト方針、既存設計との合わせ方。人間が決めるべきところまで、agent が勝手に決めます。

うまくいくこともあります。

でも、それは運がよかっただけです。推測が外れたとき、速く間違えます。

AIエージェントに渡す仕様書は、立派なRFCである必要はありません。むしろ最初から巨大な仕様書を投げると、文脈が重くなり、agent は重要なところを落とします。

必要なのは、agent が迷わないだけの情報を、作業可能な大きさで渡すことです。

この記事では、仕様書を次の8つに分けて考えます。

1. 目的
2. 非目的
3. 背景
4. 変更範囲
5. 入力文脈
6. 受け入れ条件
7. テスト条件
8. 停止条件

この8つがあると、AIエージェントはかなり扱いやすくなります。

仕様書は「命令」ではなく「作業境界」

まず、仕様書を命令文だと思わない方がいいです。

悪い例:

商品一覧に検索機能を追加してください。

これは短くて分かりやすいように見えます。でも、agent にとっては空白だらけです。

人間のチームメンバーなら、途中で聞き返すかもしれません。

agent も聞き返すことはあります。でも、多くの場合は「それっぽい答え」を作りに行きます。ここが危ない。

だから仕様書は、agent に命令する文章ではなく、作業境界を作る文章だと考えます。

やることを決める。
やらないことを決める。
見てよいものを決める。
触ってよい場所を決める。
テストの条件を決める。
不明点が出たら止まる場所を決める。

これが仕様書です。

仕様駆動で考える

仕様書を書く目的は、きれいな文章を作ることではありません。

実装前に、作るものの輪郭を固定することです。

コードを書く前に、まず次を決めます。

この順番で考えると、prompt の書き方も変わります。

悪い依頼です。

商品検索をいい感じに直して。

良い依頼です。

商品一覧で、商品名の部分一致検索を追加する。

対象ユーザー:
- 管理画面で商品を探す運用担当者

入力:
- 検索語 `q`

出力:
- 商品名に `q` を含む商品一覧

維持する挙動:
- category filter
- status filter
- pagination

今回はやらない:
- SKU検索
- 検索履歴
- サジェスト

確認:
- keyword-only
- keyword + category
- keyword + status
- empty result

ここまで書くと、agent は実装前にかなり迷いにくくなります。

仕様駆動というと大げさに聞こえますが、実務ではこのくらいで十分です。

「何を作るか」より先に、「どう判断するか」を書く。

これが効きます。

まず read-only Plan から始める

最初に実装させない。

これは、かなり効きます。

最初は read-only mode で計画させる方が安定します。巨大な仕様をいきなり投げるより、まず agent にリポジトリを読ませ、どこを触るべきか、何が危ないかを出させる。

たとえば最初の依頼は、こうです。

まだ実装しないでください。

商品一覧に検索機能を追加したいです。
まず既存コードを読んで、実装計画だけ出してください。

確認してほしいこと:
- 商品一覧画面のコンポーネント
- 商品データの取得方法
- 既存のフィルタ、ソート、ページネーション
- 状態管理の場所
- 関連テスト
- 既存のUIパターン

出力してほしいこと:
- 変更候補ファイル
- 実装方針
- リスク
- 必要なテスト
- 不明点

この段階では、ファイルを変更しないでください。

ここでやっているのは、仕様書を書く前の仕様作りです。

人間がすべてを知っているなら、そのまま詳細な仕様を書けます。でも既存リポジトリでは、人間も忘れていることがあります。既存のコンポーネント、テストの置き場所、古い設計判断、似た実装。

agent に先に読ませると、それらが出てきます。

そして、出てきた計画を人間が見ます。

「APIは変えない」
「SKU検索は今回は不要」
「カテゴリフィルタとの組み合わせだけ見る」
「URL query 反映は次回にする」

こうやって、作業を絞ります。

8項目で仕様を書く

ここから、実際に agent に渡す仕様書の形にします。

1. 目的

目的は、短く書きます。

悪い例:

検索をいい感じにする。

良い例:

管理画面の商品一覧で、商品名の部分一致検索ができるようにする。

目的は、抽象度を上げすぎない方がいいです。

「検索体験を改善する」だと広い。UI、速度、検索精度、保存、履歴、サジェストまで含みそうです。

今回やりたいことが「商品名の部分一致」なら、そこまで書きます。

2. 非目的

非目的は、仕様書の中でかなり重要です。

AIエージェントは、余計なことをしがちです。親切に見えますが、実務では困ります。

今回やらないこと:
- SKU検索
- サーバー側検索APIの追加
- ページネーション仕様の変更
- URL query への検索条件保存
- デザインシステムの変更

これだけで、変更範囲がかなり締まります。

特に既存リポジトリでは、非目的がないと agent は「ついでに直す」を始めます。

ついでに型を整理する。
ついでにコンポーネントを分割する。
ついでに古いテストを書き換える。
ついでにUI文言を変える。

人間が見れば悪意ではないと分かります。でもPRではノイズです。

非目的は、agent に「今回はここで止まれ」と伝えるためにあります。

3. 背景

背景は、なぜこの変更をするのかです。

ただし、長く書きすぎない。

背景:
商品数が増え、カテゴリフィルタだけでは目的の商品を探しにくくなっている。
まずは管理画面内で商品名検索だけを追加し、API変更なしで改善できるか確認したい。

背景があると、agent は判断しやすくなります。

たとえば「API変更なしで改善できるか確認したい」と書いてあれば、サーバー側検索を勝手に足しにくくなります。

背景は、仕様の理由です。理由があると、agent の推測が狭まります。

4. 変更範囲

変更範囲では、触ってよい場所と、触らない場所を書きます。

触ってよい場所:
- src/features/products/
- src/components/SearchInput.tsx
- 関連する ProductList のテスト

触らない場所:
- API route
- DB schema
- migration
- デザインシステム本体
- unrelated lint / format

ここで「unrelated lint / format」を入れておくと、差分が読みやすくなります。

agent は、気を利かせてフォーマットを直すことがあります。それ自体は悪くない。でも、実装差分と混ざると review が面倒になります。

AIエージェント時代のPRでは、差分を小さく保つことがより重要になります。生成速度が上がるほど、review の負担が増えるからです。

5. 入力文脈

agent は、文脈がないと探します。

探してくれるのは便利ですが、毎回ゼロから探すと時間も文脈も使います。しかも、見るべき資料を外すことがあります。

だから、最初から入口を渡します。

まず読むもの:
- AGENTS.md
- src/features/products/ProductList.tsx
- src/features/products/filterProducts.ts
- src/features/products/ProductList.test.tsx
- docs/ui-patterns.md の search input 節

プロジェクトごとに INDEX.md を持ち、関連ドキュメントやチャンネルを注釈付きで並べると、agent はかなり迷いにくくなります。裸のURLリストではなく、「何が入っていて、いつ読むべきか」を短く添える。

これは実務でかなり使えます。

たとえば、こういう INDEX.md を置く。

# Project Index

## Product UI
- `src/features/products/`
  商品一覧、カテゴリフィルタ、検索、編集導線。
  商品一覧を触るときは最初に読む。

## UI rules
- `docs/ui-patterns.md`
  入力欄、空状態、エラー表示のルール。
  新しいフォーム要素を追加するときに読む。

## Tests
- `src/features/products/ProductList.test.tsx`
  商品一覧の表示、フィルタ、ソートのテスト。
  ProductList を変更したら確認する。

こうしておくと、仕様書が短くなります。

仕様書に全説明を書くのではなく、読むべき入口を渡す。これは agent にとっても人間にとっても楽です。

ここで GPS、Walrus Memory、Minimi のような memory layer が自然に入ってきます。目的は「何でも記憶する」ことではありません。仕様を書く前に、repo rules、past lessons、過去の判断を Plan に戻すことです。

6. 受け入れ条件

受け入れ条件は、「何ができたら完了か」です。

受け入れ条件:
- 商品名の部分一致で一覧を絞り込める
- 検索文字列が空なら全件表示される
- 既存のカテゴリフィルタと同時に使える
- 検索欄の見た目は既存の input pattern に合わせる
- API と DB schema は変更しない

受け入れ条件がないと、agent は自分で完了を決めます。

「動きました」で終わるかもしれません。でも、カテゴリフィルタとの組み合わせは見ていないかもしれない。空文字の挙動も見ていないかもしれない。

受け入れ条件は、agent の完了宣言を受け取るための基準です。

7. テスト条件

テスト条件は、受け入れ条件より具体的です。

追加または確認するテスト:
- 空文字の場合、全商品が表示される
- 商品名の部分一致で絞り込める
- 大文字小文字の扱いが仕様通りである
- カテゴリフィルタと検索条件を同時に使える
- 既存のソート順が壊れない

実行するコマンド:
- npm test -- ProductList

ここで大事なのは、「テストして」では弱いということです。

どのケースを見るのか。
どのコマンドを走らせるのか。
失敗したらどうするのか。

ここまで書きます。

テストが失敗した場合は、すぐ修正せず、
まず失敗原因を説明してください。
その後、最小の修正案を出してください。

これを入れると、agent がログを読まずに場当たり的な修正を繰り返すのを防ぎやすくなります。

8. 停止条件

停止条件は、もっと使われるべきです。

agent は進み続けます。だから、止まる条件を書きます。

次の場合は実装を止めて確認してください:
- API変更が必要に見える
- DB schema変更が必要に見える
- 既存テストが今回の変更と無関係に落ちている
- 変更対象が5ファイルを超えそう
- 仕様にないUI変更が必要に見える

これがあると、agent が勝手に大きな判断をしにくくなります。

停止条件は、人間の判断を残す場所です。

AIエージェントを使うと、人間の仕事は減るというより、判断の位置が変わります。全部を手で書くのではなく、どこで止めるかを設計する。ここが大事です。

実際に渡す仕様書テンプレート

ここまでをまとめると、こうなります。

# 仕様:商品一覧に商品名検索を追加する

## 目的

管理画面の商品一覧で、商品名の部分一致検索ができるようにする。

## 非目的

今回は以下をしない。

- SKU検索
- サーバー側検索APIの追加
- DB schema / migration の変更
- URL query への検索条件保存
- デザインシステム本体の変更
- unrelated lint / format

## 背景

商品数が増え、カテゴリフィルタだけでは目的の商品を探しにくくなっている。
まずはAPI変更なしで、商品名検索だけを追加する。

## 変更範囲

触ってよい場所:

- `src/features/products/`
- 関連する ProductList のテスト

触らない場所:

- API route
- DB schema
- migration
- デザインシステム本体

## 入力文脈

まず以下を読む。

- `AGENTS.md`
- `src/features/products/ProductList.tsx`
- `src/features/products/filterProducts.ts`
- `src/features/products/ProductList.test.tsx`
- `docs/ui-patterns.md` の search input 節

## 受け入れ条件

- 商品名の部分一致で一覧を絞り込める
- 検索文字列が空なら全件表示される
- 既存のカテゴリフィルタと同時に使える
- 検索欄の見た目は既存の input pattern に合わせる
- API と DB schema は変更しない

## テスト条件

追加または確認するテスト:

- 空文字の場合、全商品が表示される
- 商品名の部分一致で絞り込める
- カテゴリフィルタと検索条件を同時に使える
- 既存のソート順が壊れない

実行するコマンド:

- `npm test -- ProductList`

テストが失敗した場合は、すぐ修正せず、
まず失敗原因を説明する。
その後、最小の修正案を出す。

## 停止条件

次の場合は実装を止めて確認する。

- API変更が必要に見える
- DB schema変更が必要に見える
- 既存テストが今回の変更と無関係に落ちている
- 変更対象が5ファイルを超えそう
- 仕様にないUI変更が必要に見える

このくらいで十分です。

ポイントは、詳細すぎないことです。

すべての実装手順を人間が書く必要はありません。そこまで書くなら、自分で実装した方が早い場合もあります。

仕様書に書くべきなのは、agent が勝手に決めると困ることです。

仕様書を一発で完成させようとしない

仕様書は、最初から完成させなくていいです。

むしろ、agent に作らせて、人間が削る方がよいことがあります。

最初にこう頼みます。

まだ実装しないでください。

以下の目的に対して、実装用の仕様書ドラフトを作ってください。

目的:
管理画面の商品一覧に、商品名の部分一致検索を追加する。

ドラフトに含めるもの:
- 非目的
- 変更範囲
- 入力文脈
- 受け入れ条件
- テスト条件
- 停止条件

不明点は、勝手に決めずに質問として列挙してください。

agent がドラフトを出します。

人間は、それを見て削ります。

「これは今回はやらない」
「このテストは不要」
「API変更は禁止」
「このファイルは触らない」
「この不明点は今回は固定」

仕様書を書く仕事も、agent と分担できます。

ただし、最終判断は人間が持つべきです。特に、非目的、停止条件、受け入れ条件は人間が見る。

ここを agent に丸投げすると、agent が自分に都合のよい仕様を作ります。

仕様が長くなったら分割する

仕様書が長くなりすぎたら、タスクが大きすぎる可能性があります。

たとえば、次の依頼は大きいです。

商品一覧に検索、フィルタ保存、CSVエクスポート、URL query 反映、
サーバー側検索、権限別表示を追加してください。

これは一つの依頼に見えますが、実際は複数の変更です。

一気に渡すと、agent は大量の判断を抱えます。文脈も重くなり、差分も大きくなり、review がつらくなります。

こう分けます。

Step 1: クライアント側の商品名検索だけ追加する
Step 2: カテゴリフィルタとの組み合わせを整理する
Step 3: URL query への反映を追加する
Step 4: 必要ならサーバー側検索に移す
Step 5: CSVエクスポートは別PRにする

agent に最初から全部やらせるのではなく、PR にできる単位に分けます。

AIエージェントは大きな仕事もできます。でも、チーム開発では、作れるかどうかより review できるかどうかが重要です。

小さく渡すのは、agent のためだけではありません。人間の review のためでもあります。

仕様書と AGENTS.md を分ける

仕様書と AGENTS.md を混ぜない方がいいです。

仕様書は、今回のタスクのためのものです。

AGENTS.md は、リポジトリ全体で繰り返し使うルールです。

たとえば、これは仕様書に書く内容です。

今回は商品名検索だけを追加し、SKU検索はしない。

これは AGENTS.md に書く内容です。

UI変更では、既存のデザインシステム本体を変更しない。
必要に見える場合も、まず提案に留める。

毎回使うルールは AGENTS.md
今回だけの条件は仕様書。

この分け方をしないと、AGENTS.md がすぐ太ります。

CLAUDE.md が長くなりすぎると、それ自体が負荷になります。毎回すべてを読み込むと、そのセッションに不要な情報まで文脈を圧迫します。だから、長くなったら guide や skill に分け、必要なときだけ読む形にする。

これは AGENTS.md でも同じです。

短く、繰り返し効くものだけを置く。
細かい手順は guide に逃がす。
今回だけの条件は仕様書に置く。

この整理があると、agent の Plan が安定します。

ツールが出てくる場所

仕様書を書く段階でも、周辺ツールは自然に出てきます。

ただし、主役はツールではありません。詰まった場所にだけ出てくるべきです。

前提が毎回消えるなら memory layer

repo rules、past lessons、過去のレビュー指摘が毎回消えるなら、memory layer を考えるタイミングです。

GPS、Walrus Memory、Minimi のようなツールは、この位置に入ります。

見るべき点は、記憶量ではありません。

仕様書の前に、必要な前提を戻せるか。ここを見ます。

入力文脈が散らばるなら index

Slack、Drive、Notion、GitHub、docs が散らばっていると、agent は毎回探し回ります。

この場合、まず必要なのは高機能ツールではなく、INDEX.md です。

どこに何があり、いつ読むべきかを短く書く。

それでも足りなければ、MCP や検索ツールを足す。

順番を逆にしない方がいいです。入口が整理されていない状態でツールだけ増やすと、agent はより広い範囲を迷うようになります。

仕様が毎回似ているなら template / skill

毎週のように同じ種類の仕様を書くなら、テンプレートや skill にします。

たとえば、UI変更、API変更、migration、障害調査、ライブラリ更新。それぞれで見るべき点は違います。

一度うまくいった仕様書を、次回のテンプレートにする。

これが Compound です。

悪い仕様書、良い仕様書

最後に、悪い仕様書と良い仕様書を並べます。

悪い仕様書:

商品一覧に検索を追加してください。
いい感じにお願いします。
テストもお願いします。

これは短いですが、ほぼすべてを agent に丸投げしています。

少し良い仕様書:

商品一覧に商品名検索を追加してください。
カテゴリフィルタと一緒に使えるようにしてください。
テストも追加してください。

目的は少し見えます。でも、変更範囲、非目的、停止条件がありません。

良い仕様書:

商品一覧に商品名の部分一致検索を追加してください。

今回はクライアント側で絞り込みます。
API変更、DB schema変更、URL query 反映、SKU検索はしません。

まず以下を読んでください:
- AGENTS.md
- src/features/products/ProductList.tsx
- src/features/products/filterProducts.ts
- src/features/products/ProductList.test.tsx

触ってよい場所:
- src/features/products/
- 関連テスト

受け入れ条件:
- 商品名の部分一致で絞り込める
- 空文字なら全件表示
- カテゴリフィルタと同時に使える
- API と DB schema は変更しない

テスト:
- ProductList の関連テストを追加または更新する
- npm test -- ProductList を実行する

停止条件:
- API変更が必要に見える場合
- DB schema変更が必要に見える場合
- 変更対象が5ファイルを超えそうな場合
- 既存テストが今回と無関係に落ちる場合

これなら、agent はかなり迷いにくくなります。

そして人間も review しやすい。

仕様書は agent のためだけではありません。未来の自分、reviewer、次にこの作業を引き継ぐ人のためにもなります。

まとめ

AIエージェントに渡す仕様書は、長ければよいわけではありません。

短すぎると、agent が勝手に決めます。長すぎると、文脈が重くなり、重要なところが落ちます。

必要なのは、作業境界です。

この8つを書けば、agent はかなり扱いやすくなります。

そして、最初から完璧な仕様書を書こうとしなくていいです。

まず read-only で読ませる。
計画を出させる。
人間が削る。
小さな作業単位に分ける。
今回だけの条件は仕様書へ。
繰り返すルールは AGENTS.md や skill へ。

この流れができると、AIエージェントは「たまに当たるコード生成」ではなく、開発工程の中で扱える作業者に近づきます。

次回は、出てきた成果物をどう検品するかを扱います。

仕様を書けても、review が弱いと、生成量がそのままレビュー負債になります。次は Trace、Eval、Pre-CI Review の話です。

← 一覧へ