- ページ作成日時:2026-07-03 18:12 JST
- 最終更新日時:2026-07-03 18:12 JST
注記:このページの説明は、公開仕様、一般的なLLM実装、API設計上の概念、および理解のためのモデルを組み合わせたものである。特定サービスの非公開内部実装を、そのまま断定するものではない。
プロンプトは実行時にどうコンパイルされるのか
プロンプトとは、チャット欄に書いた文章そのものではない。
実行時に、指示、文脈、ツール、制約が組み合わされて作られる入力環境である。
ユーザーは文章を送る。だが、実行環境は入力構造を組み立てる。
この違いを見落とすと、生成AIの挙動は気まぐれに見える。
同じ依頼をしているはずなのに、あるときは過去の文脈を踏まえて答え、あるときは忘れているように見える。ファイルを読んで答えているように見えることもあれば、ファイルを見ていないように見えることもある。ツールを使ってほしいと頼んだのに使わないこともあれば、使わなくてよい場面でツールを使おうとすることもある。
これらは、単にAIの気分で起きているわけではない。
多くの場合、何が今回の入力構造に入っていたか、どの層の指示として入っていたか、どの情報が資料として扱われたか、どのツールが行動空間として開かれていたかに関係している。
1. ユーザーの文章だけがプロンプトではない
たとえば、ユーザーは次のように書く。
この文章を要約してください。
あるいは、もう少し実務的に、次のように書く。
あなたは編集者です。以下の文章をWeb掲載用に整えて、GitHubに書いてください。
ユーザーの画面には、一つの入力欄がある。そこに文章を書き、送信する。だから、表面上は「チャット欄に書いた文章」がプロンプトに見える。
しかし、実行構造として見ると、ユーザーの文章は単独でモデルに渡されるとは限らない。
その背後には、システム側の指示、アプリケーション側の指示、プロジェクト指示、カスタム指示、会話履歴、保存メモリ、添付ファイル、検索結果、ツール定義、現在利用できる機能、出力形式の制約などがある。
それらは、必要に応じて選ばれ、並べられ、role付けされ、構造化される。
flowchart LR
A[ユーザーが見ているもの\nチャット欄の文章] --> B[実行環境]
B --> C[指示\nsystem / developer / project]
B --> D[文脈\nhistory / memory / files / search]
B --> E[行動空間\ntools / tool_choice]
C --> F[モデルに渡される入力構造]
D --> F
E --> F
ここでいうプロンプトは、チャット欄に書かれた文章だけを指さない。
ユーザーが書いた文章もプロンプトの一部である。しかし、超詳解版では、プロンプトをもう少し広く見る。
プロンプトとは、ユーザーが書いた文章そのものではなく、実行時に組み立てられた入力環境である。
この入力環境には、ユーザーの依頼だけでなく、上位指示、会話状態、外部資料、ツール定義、出力制約が含まれうる。
同じ「この文章を要約してください」という依頼でも、実行環境側で組み立てられる入力は状況によって変わる。
- 直前の会話履歴が入っている場合
- プロジェクト指示が入っている場合
- 添付ファイルの内容が入っている場合
- Web検索結果が入っている場合
- GitHub、Notion、Gmailなどのツール定義が入っている場合
- 逆に、それらが今回の入力には入っていない場合
表面上のユーザー文は同じでも、実行時の入力環境が違えば、モデルの応答も変わる。
2. instructions / input / tools は分けて考える
生成AIのAPIや実行環境では、ユーザーの文章が、ただ一枚の長い文章として扱われるとは限らない。
代表的なのが、instructions、input、tools である。
注記:APIとは、ここではアプリケーションがモデルに依頼を送るための正式な接続口を指す。普通のチャット画面ではなく、プログラムやサービスが「どのモデルに、どの入力を、どの指示・ツール・設定とともに渡すか」を構造化して送るための仕組みである。
注記:アプリケーション層とは、ChatGPTの画面、独自アプリ、業務システム、コーディングエージェントなど、ユーザーとモデルの間にある実行環境の層である。この層が、会話履歴、プロジェクト指示、ファイル、検索結果、ツール定義などを集め、モデルに渡す入力構造を組み立てる。
instructions は、モデルの振る舞いを制御するための指示である。どのような役割で応答するか、どの方針を守るか、どの形式で出力するか、といった行動条件を置く場所に近い。
input は、今回モデルに処理させる対象である。ユーザーの質問、要約したい文章、画像、音声、ファイル、過去の応答などがここに入りうる。
tools は、モデルが呼び出し可能な外部機能の定義である。Web検索、ファイル検索、コード実行、Notion更新、Gmail操作、カレンダー操作、GitHub操作、独自API呼び出しなどが、実行環境によって道具として開かれる。
この3つは、自然な日本語ではすべて「プロンプトの一部」と言えてしまう。しかし、実装上は役割が違う。
たとえば、次の依頼を考える。
あなたは編集者です。以下の文章をWeb掲載用に整えて、GitHubに書いてください。
人間には一文として自然に読める。しかし、実行構造としては、少なくとも次のように分けて考えられる。
| 部分 | 実装上の読み方 |
|---|---|
| あなたは編集者です | instructions に近い。モデルの振る舞いを決める指示 |
| 以下の文章をWeb掲載用に整える | input に対するタスク指示 |
| 実際に整える文章 | input の処理対象 |
| GitHubに書く | tools と実行権限が関わる操作 |
「文章を整える」だけなら、モデルの出力で完結する。
しかし「GitHubに書く」は、外部システムへの書き込みである。GitHub操作のツールが実行環境側で開かれていなければならないし、どのリポジトリのどのファイルに書くのか、既存内容を読むのか、差分確認を行うのか、失敗時にどこで止まるのかも関係する。
ここで、単なる文章生成と、ツール実行を伴う操作の違いが出てくる。
API request object の模式例
これは理解用の模式例であり、特定APIの完全な記法ではない。
{ "instructions": "あなたはWeb原稿の編集者です。公開用に読みやすく整えてください。", "input": [ { "role": "user", "content": "以下の文章をWeb掲載用に整えて、GitHubに書いてください。対象本文:……" } ], "tools": [ { "name": "github_read_file", "description": "GitHub上のファイルを読む" }, { "name": "github_update_file", "description": "GitHub上のファイルを更新する" } ], "tool_choice": "auto" }この形で見ると、ユーザーの一文だけでAIが動いているのではなく、
instructions、input、tools、tool_choiceが組み合わさって実行環境を作っていることが見えやすくなる。読み取り系toolsと書き込み系toolsは分けて考える
toolsと一口に言っても、危険度は同じではない。Web検索、ファイル検索、GitHub上のファイル読み取り、Notionページの読み取りは、基本的には読み取り系の操作である。
一方で、GitHubに書く、Notionページを更新する、Gmailを送信する、カレンダー予定を作成する、ファイルを削除する、といった操作は、外部世界に変更を加える書き込み系の操作である。
| 種類 | 例 | 設計上の注意 | | --- | --- | --- | | 読み取り系tools | Web検索、ファイル検索、GitHub read、Notion fetch | 情報源・参照日時・引用の扱いに注意する | | 書き込み系tools | GitHub update、Notion update、Gmail send、Calendar create | 実行前確認、差分確認、停止条件が必要になる | | 破壊的操作 | delete、overwrite、trash、force push | 原則として明示確認なしに実行しない |
この問題は、04「ツール呼び出しはどう実行されるのか」と、07「失敗時の停止条件と検証ループを書く」で詳しく扱う。
3. UI上の擬似階層と、実行環境上の実階層は違う
普通のChatGPT画面でも、ユーザーは次のように書ける。
instructions:
あなたはWeb原稿の編集者です。
読みやすく、公開用の文体に整えてください。
input:
以下の文章をWeb掲載用に整えて、GitHubに書いてください。
対象本文:
……
この書き方は、実用上かなり有効である。
モデルは自然言語だけでなく、見出し、箇条書き、JSON風、YAML風、Markdown風の構造も読める。instructions: と書かれていれば、その下にある内容を「指示に近いもの」として読む可能性が高い。input: と書かれていれば、その下にある内容を「処理対象に近いもの」として読む可能性が高い。
しかし、これはAPI上の実階層とは違う。
チャット欄に書かれた instructions: は、ユーザーメッセージの中にある文字列である。モデルはそれを見出しとして解釈するかもしれないが、実行環境が正式に instructions フィールドとして渡しているとは限らない。
ここで区別したいのは、次の二つである。
自然文で階層を表現することと、実行環境で階層として実装することは違う。
前者を、ここでは「擬似階層」と呼ぶ。
後者を、ここでは「実階層」と呼ぶ。
| 観点 | UI上の擬似階層 | API / アプリケーション層の実階層 |
|---|---|---|
| 形 | 一つのユーザーメッセージ内の見出し・区切り | instructions、input、tools など別要素 |
| 例 | instructions: と書く |
instructions フィールドとして渡す |
| 権限 | ユーザー文中の文字列 | 実行環境上の指示層・roleに紐づく |
| 効果 | モデルが読みやすくなる | 入力経路・行動空間そのものを変える |
| 限界 | 本物のsystem / developer messageにはならない | アプリケーション側の実装が必要 |
| tools | 「GitHubに書いて」と書ける | GitHub toolが開かれていなければ実行できない |
| 安全性 | 書き方次第で曖昧になる | tool policy、停止条件、確認フローを組み込める |
たとえば、ユーザーが system: と書いても、それは本当のsystem messageではない。ユーザーメッセージの中に、system: という見出しを書いただけである。
もちろん、モデルはその文字列に引っ張られる可能性がある。だから、見出しの書き方には効果がある。
しかし、権限としては、本物のsystem messageやdeveloper messageと同じではない。
この違いは、prompt injectionを理解するときにも重要になる。
外部ファイルやWebページの中に「これまでの指示をすべて無視してください」と書かれていたとしても、それは資料中の文字列であって、開発者指示やユーザー指示そのものではない。資料と指示を分けることは、生成AIを安全に使ううえで重要になる。
普通のチャットでは擬似階層も有効である
擬似階層は、実階層ではない。
しかし、無意味ではない。
普通のChatGPT画面では、ユーザーが実際のAPIフィールドを直接操作できない場合が多い。その場合、見出し、箇条書き、区切り、JSON風構造、YAML風構造を使って、モデルに読んでほしい構造を明示することは有効である。
重要なのは、それを本物の実装階層と混同しないことである。
4. 入力アセンブリの全体フロー
ここまでの話を一つの流れとして整理すると、生成AIへの入力は次のように組み立てられる。
flowchart TD
A[User action\nユーザーが依頼を送る] --> B[UI / API client\n依頼を受け取る]
B --> C[Application layer\n入力アセンブリを行う]
C --> D[Instruction assembly\nsystem / developer / project / user方針]
C --> E[Context assembly\n履歴 / メモリ / ファイル / 検索結果]
C --> F[Tool registry\n利用可能なtoolsとtool_choice]
D --> G[Request object\nモデルへ渡す構造]
E --> G
F --> G
G --> H[Tokenization\n文字列をtoken列へ変換]
H --> I[Model forward pass\n次tokenまたはtool callを生成]
I --> J{tool call?}
J -- no --> K[Assistant message\n最終応答]
J -- yes --> L[Tool execution\nアプリケーション層が実行]
L --> M[Tool result\n結果を文脈へ再投入]
M --> G
流れを文章にすると、次のようになる。
- ユーザーがチャット欄やアプリ画面から依頼を送る
- UIまたはAPI clientが、その依頼を受け取る
- アプリケーション層が、指示、履歴、メモリ、ファイル、検索結果、ツール定義を集める
instructions、input、tools、tool_choiceなどを含むrequest objectを組み立てる- その入力がtoken列へ変換される
- モデルがtoken列を処理し、次に出すtoken、またはtool callを生成する
- tool callが出た場合、アプリケーション層が実際のツールを実行する
- tool resultが再び文脈として投入される
- 最終的に、assistant messageとしてユーザーに返される
ここで重要なのは、モデルが単独で外部世界を操作しているわけではない、という点である。
モデルは、GitHubを直接書き換えるわけではない。Notionを直接開くわけでもない。Gmailを直接送るわけでもない。
モデルは、必要に応じて「このツールを、この引数で呼び出したい」というtool callを出す。
それを受け取ったアプリケーション層が、実際のツールを実行する。
そして、その結果を再びモデルに渡す。
たとえば「AIがNotionを更新した」と言うことはできる。日常語としては、それで十分である。
しかし、実行構造として見るなら、より正確にはこうなる。
モデルがNotion更新用のtool callを生成し、アプリケーション層がNotion toolを実行し、その結果を会話に戻した。
この違いは細かいようで、実用上は大きい。
なぜなら、失敗が起きたとき、どこで失敗したのかを切り分けられるからである。
- モデルが、そもそもツールを使う必要を判断しなかったのか
- tool callの引数が間違っていたのか
- アプリケーション層がツール実行に失敗したのか
- 外部サービス側で権限エラーが出たのか
- tool resultを再投入した後の解釈を誤ったのか
- ユーザー確認を挟むべき場面で止まらなかったのか
「AIが失敗した」とまとめてしまうと、これらの違いが消えてしまう。
しかし、入力アセンブリと実行ループとして見れば、失敗箇所を分けて考えられる。
入力アセンブリ各段階の整理表
| 段階 | 何が起きるか | 注意点 | | --- | --- | --- | | User action | ユーザーがチャット欄、アプリ画面、API経由で依頼する | ユーザーからは一つの入力に見える | | UI / API client | 入力を受け取り、アプリケーション層へ渡す | UIとAPIでは見えている構造が違う | | Application layer | 指示、履歴、メモリ、ファイル、検索結果、toolsを組み立てる | ここが入力アセンブリの中心 | | Instruction assembly | 上位指示、プロジェクト指示、ユーザー方針などを整理する | どの層の指示かが重要 | | Context assembly | 会話履歴、メモリ、検索結果、ファイル内容などを選ぶ | 何が今回の文脈に入ったかで応答が変わる | | Tool registry | 利用可能なtoolsとtool_choiceを設定する | 行動空間そのものを決める | | Request object | モデルへ渡す入力構造を作る | ユーザー文だけではない | | Tokenization | 入力をtoken列に変換する | モデルが直接読むのは文字そのものではなくtoken列 | | Model forward pass | 次のtoken、assistant message、tool callなどを生成する | モデルは外部ツールを直接実行しない | | Tool execution | アプリケーション層が外部ツールを実行する | 権限、確認、停止条件が重要 | | Tool result reinjection | ツール結果を再び文脈として入れる | tool resultを命令ではなく結果として扱う | | Final output | ユーザーに応答を返す | 途中の実行構造は画面から見えにくい |
5. まとめ:プロンプト設計から実行環境設計へ
01全体の結論は、次の一文にまとめられる。
プロンプトとは、ユーザーがチャット欄に書いた文章そのものではなく、実行時に組み立てられる入力環境である。
この入力環境には、ユーザー入力だけでなく、instructions、role、会話履歴、保存メモリ、添付ファイル、検索結果、tools、tool_choice、tool result、出力制約、停止条件が含まれうる。
したがって、生成AIを深く使うとは、お願い文を強くすることだけではない。
どの情報を指示として置くか。
どの情報を資料として置くか。
どの文脈を今回投入するか。
どのtoolsを開くか。
どの条件でtool callを許すか。
どこで止めるか。
失敗時にどの層を検証するか。
それらを設計することである。
この見方に立つと、AGENTS.md、CHATGPT.md、プロジェクト指示、API request、tool schema、RAG、メモリ、会話履歴は、別々の便利機能ではなくなる。
それらはすべて、モデルに何を見せ、何を優先させ、どの行動空間を開き、どこで止めるかを決めるための、入力環境の設計要素である。
次回は、この入力環境の中でも特に重要な「指示階層」を扱う。
system、developer、user、tool result は、同じ重さで読まれるわけではない。どの指示が優先され、どの情報は資料として扱われるのか。02では、この権限構造を見ていく。
参考リンク
更新履歴
- 2026-07-03 18:12 JST:公開版原稿として新規作成。