CodexやClaude CodeのようなAIエージェントに、既存資料の修正や複数ファイルにまたがる実装を任せるとき、長いMarkdownプロンプトだけでは不十分なことがあります。
背景、目的、改善方針、変更対象、許可事項、完成条件が同じ文章の中に並ぶと、AIが「参考として伝えた方針」と「実際に変更すべき内容」を混同しやすくなるためです。
そこで使えるのが、次の三層構造です。
三層構造の概要
YAMLフロントマター
文書の種類、version、対象、状態などの管理情報を記録します。
Markdown -本文
背景、目的、理由、判断経緯など、人間が理解するための文脈を説明します。
JSON -仕様
合意済みの変更対象、実装内容、完成条件など、AIが実行する具体的な仕様を固定します。
YAMLで管理し、Markdownで説明し、JSONで仕様を固定する
という使い分けです。
JSONを使えばAIが突然賢くなるわけではありません。効果は、「改善の方向性」「実際の変更命令」「変更してよい範囲」「完成条件」を別々のフィールドへ分け、AIが独自に解釈できる余白を減らせることです。
Markdownだけでは混ざりやすい情報
たとえば、既存のスライドを改善するために、次のような指示を一度にまとめて出したとします。
- 全体として、初見の人にも分かりやすくしたい
- 2枚目の説明を整理したい
- 5枚目では役割を色で分けたい
- 必要であれば、説明を補うスライドを追加してよい
人間は、「既存構成を基本的に維持しながら、指定された部分を改善する」と読むでしょう。しかしAIは、「初見の人にも分かりやすくする」という目的や、「スライドを追加してよい」という許可を広く解釈し、全体構成やストーリーまで再設計することがあります。これは、プロンプトが短すぎるから起こるとは限りません。むしろ説明を丁寧に追加した結果、文章の中で異なる種類の情報が混ざっていることが原因になる場合があります。一つのMarkdown本文には、次のような性質の違う情報が同居しがちです。
- 達成したい目的
- 改善の方向性
- 実際の変更命令
- 追加を許可する範囲
- 維持すべき既存内容
- 完成と判断する条件
人間には文脈で区別できても、AIにとってはすべて「実装判断に使える文章」です。そこで、会話で決めた内容を、そのまま長い文章として渡すのではなく、いったん仕様へ変換します。
YAML、Markdown、JSONの役割
YAMLフロントマター
この文書は何かYAMLフロントマターには、文書そのものの管理情報を置きます。
---
document_type: implementation_spec
schema_version: "1.0"
title: 既存スライドの改善仕様
repository: example/example-repository
target_branch: main
status: approved
authoritative_spec: embedded_json
---
ここで管理するのは、たとえば次の情報です。
- 文書の種類
- schemaのversion
- 対象リポジトリ
- 対象ブランチ
- 承認状態
どの部分を仕様の正本とするか本文を読まなくても、ファイルの用途と状態を確認できます。
Markdown
なぜそうするのかMarkdown本文には、背景、目的、判断理由を書きます。
# 目的
初見の利用者が、個別ツールの機能だけでなく、
各ツールが業務フローのどこを担うか理解できるようにする。
# 設計意図
既存の構成は原則として維持する。
本文は背景と判断基準を説明し、具体的な変更対象はJSONで定義する。
背景や理由までJSONの文字列へ押し込むと、人間がレビューしづらくなります。長い説明、比較、補足はMarkdownに任せた方が自然です。
JSON
具体的に何を実装するのかJSONには、合意済みの実装仕様を置きます。
{
"task": "revise_existing_slide_deck",
"objective": "専門部品と前後工程の接続を理解できる構成にする",
"edit_policy": {
"default": "keep",
"only_modify_explicit_targets": true
},
"requested_changes": [
{
"target": "slide_2",
"instruction": "利用史よりも設計原則を主役にする"
},
{
"target": "slide_5",
"instruction": "人、AI、CLIの役割を色で分離する"
},
{
"target": "slide_6",
"instruction": "説明順に番号を付ける"
}
],
"acceptance_criteria": [
"指定された箇所以外の内容が維持されている",
"各変更が既存のデザインシステムに沿っている",
"変更後のスライドに文字切れや重なりがない"
]
}
ここでは、「分かりやすくする」という目的と、「実際にどこを変更するか」が別のフィールドに分かれています。さらに、
{
"edit_policy": {
"default": "keep",
"only_modify_explicit_targets": true
}
}
と明記すれば、目的を達成するためにAIが編集範囲を独自に拡張する余地を減らせます。
そのまま使えるテンプレート
以下の形にしておくと、人間が読める仕様書として扱いながら、AIには変更対象と完成条件を明確に渡せます。
---
document_type: implementation_spec
schema_version: "1.0"
title: 既存成果物の変更仕様
repository: owner/repository
target_branch: main
status: approved
authoritative_spec: embedded_json
---
# 目的
この変更で達成したい状態を書く。
# 背景と設計意図
なぜ変更するのか、どのような判断をしたのかを書く。
以下のJSONを実装仕様の正本とする。
Markdown本文とJSONが競合する場合は、JSONを優先する。
## 実装仕様
```json
{
"task": "modify_existing_artifact",
"objective": "達成したい状態",
"edit_policy": {
"default": "keep",
"only_modify_explicit_targets": true
},
"requested_changes": [
{
"target": "対象を一意に特定できる名前",
"instruction": "実施する変更"
}
],
"allowed_extensions": [],
"acceptance_criteria": [
"完成と判断する条件",
"維持すべき条件",
"検証すべき条件"
]
}
```
# 実装時の扱い
JSONの `requested_changes` に記載された項目を実装対象とする。
Markdown本文は背景と判断基準として参照するが、本文だけを根拠として編集対象を拡大しない。
# 検証
実装後は `acceptance_criteria` ごとに、合格、不合格、未確認を報告する。
実際の運用フロー
この形式は、最初からすべてをJSONで考えるためのものではありません。
おすすめする流れは次のとおりです。
AIに自然言語で相談する
↓
Markdownで背景と選択肢を整理する
↓
人間が採用・不採用を決める
↓
合意済みの内容だけをJSONへ固定する
↓
Codexなどへ実装を依頼する
↓
acceptance_criteriaに沿って検証する
重要なのは、自由に考える段階と、仕様を固定する段階を分けることです。
相談中には、採用されなかった案や仮説も出てきます。会話全体をそのまま渡すと、それらが実装候補として再び混入することがあります。
そこで、人間が判断した後に、合意した内容だけを仕様へ変換する工程を置きます。
なぜJSONだけにしないのか
JSONは、項目の境界や必須情報を固定するのには向いています。しかし、すべての情報をJSONへ入れるのがよいわけではありません。
たとえば、次の内容はMarkdownの方が扱いやすいでしょう。
- 背景となる問題
- 複数案を比較した理由
- 読者や利用者の想定
- 長い参考資料
- 例外や微妙なニュアンス
- 人間によるレビューコメント
アイディアを考える初期段階までJSONへ押し込むと、思考が窮屈になり、人間にとっても修正しづらい文書になります。
したがって、JSONは思考の形式ではなく、合意後の仕様を固定する形式として使います。
形式によってAIの結果は変わる
同じ内容であっても、プレーンテキスト、Markdown、JSON、YAMLなどの入力形式によって、モデルの出力が変わることは複数の研究で報告されています。
ただし、どのモデル、どの作業でもJSONが常に最良という意味ではありません。モデルや課題によって結果は異なります。
今回の三層構造の主な目的も、JSONにすることでモデルの能力を直接高めることではありません。
三層構造にする狙い
- 性質の異なる情報を分離する
- 合意済みの変更だけを固定する
- 編集範囲を明示する
- 完成条件を検証可能にする
つまり、プロンプト形式の性能競争というより、AIエージェントへ作業を渡すための要件管理として使います。
この方法が向いている作業
すべてのAI利用で、この形式を作る必要はありません。誤字修正や一行の変更なら、普通の自然言語で十分です。一方、次のような作業では効果が大きくなります。
- 既存成果物を部分的に変更する
- 変更してはいけない範囲がある
- 複数の合意事項がある
- 別のAIセッションへ引き継ぐ
- 実装後の検証が必要
- 過剰実装や勝手な再構成を防ぎたい
- 人間とAIの判断過程を記録したい
- Gitでversion管理したい
特にCodexやClaude Codeのように、複数ファイルを読み、判断し、実際に変更するエージェントでは、単なる依頼文よりも、変更範囲と受入条件を持った仕様の方が扱いやすくなります。
同じ要件を二重に書かない
この構成で注意したいのは、MarkdownとJSONへ同じ要件を重複して書かないことです。
少しずつ異なる指示が両方に書かれていると、どちらを優先すべきか分からなくなります。
役割は明確に分けます。
- YAMLは「この文書は何か」
- Markdownは「なぜそうするのか」
- JSONは「具体的に何を実装するのか」
そして、正本を明記します。
authoritative_spec: embedded_json
Markdown本文にも、
JSONと本文が競合する場合は、JSONを優先する
と書いておきます。
プロンプトから、version管理できる仕様へ
この方法の利点は、AIへの指示を、その場限りのチャットではなく、version管理可能な成果物にできることです。
仕様として保存すれば、次の情報を後から確認できます。
- なぜこの変更をしたのか
- どこまで変更を許可したのか
- どの案を採用したのか
- 何をもって完成としたのか
- 後から追加された要件は何か
また、JSON部分を抽出すれば、将来的にはJSON Schemaによる検査、タスクの自動生成、受入条件のチェックにも利用できます。
これはプロンプトエンジニアリングというより、AIエージェント向けの要件管理に近い考え方です。
まとめ
AIへ複雑な作業を任せるとき、必要なのは詳細なプロンプトを書くことだけではありません。
会話の中で決まった内容を、
- 管理情報
- 背景と理由
- 合意済み仕様
- 完成条件
へ分け、次の工程へ渡せる成果物にする必要があります。
そのための実用的な構成が、
YAMLで管理し、Markdownで説明し、JSONで仕様を固定する
という三層構造です。
AIをチャットの相手ではなく作業者として使うほど、「何を頼むか」だけでなく、「合意した内容をどの形式で固定するか」が重要になります。
この記事を第一回として、これからAIを実務に実装するという連載をしようと思います。