GENAI-RON🧠生成AI論🥦

生成AIのしくみ 超詳解 01

プロンプトは実行時にどうコンパイルされるのか

チャット欄の文章だけではなく、指示・文脈・ツール・制約が実行時に組み立てる入力環境としてpromptを読む。

  • ページ作成日時: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や実行環境では、ユーザーの文章が、ただ一枚の長い文章として扱われるとは限らない。

代表的なのが、instructionsinputtools である。

注記: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が動いているのではなく、instructionsinputtoolstool_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 / アプリケーション層の実階層
一つのユーザーメッセージ内の見出し・区切り instructionsinputtools など別要素
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

流れを文章にすると、次のようになる。

  1. ユーザーがチャット欄やアプリ画面から依頼を送る
  2. UIまたはAPI clientが、その依頼を受け取る
  3. アプリケーション層が、指示、履歴、メモリ、ファイル、検索結果、ツール定義を集める
  4. instructionsinputtoolstool_choice などを含むrequest objectを組み立てる
  5. その入力がtoken列へ変換される
  6. モデルがtoken列を処理し、次に出すtoken、またはtool callを生成する
  7. tool callが出た場合、アプリケーション層が実際のツールを実行する
  8. tool resultが再び文脈として投入される
  9. 最終的に、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全体の結論は、次の一文にまとめられる。

プロンプトとは、ユーザーがチャット欄に書いた文章そのものではなく、実行時に組み立てられる入力環境である。

この入力環境には、ユーザー入力だけでなく、instructionsrole、会話履歴、保存メモリ、添付ファイル、検索結果、toolstool_choice、tool result、出力制約、停止条件が含まれうる。

したがって、生成AIを深く使うとは、お願い文を強くすることだけではない。

どの情報を指示として置くか。

どの情報を資料として置くか。

どの文脈を今回投入するか。

どのtoolsを開くか。

どの条件でtool callを許すか。

どこで止めるか。

失敗時にどの層を検証するか。

それらを設計することである。

この見方に立つと、AGENTS.mdCHATGPT.md、プロジェクト指示、API request、tool schema、RAG、メモリ、会話履歴は、別々の便利機能ではなくなる。

それらはすべて、モデルに何を見せ、何を優先させ、どの行動空間を開き、どこで止めるかを決めるための、入力環境の設計要素である。

次回は、この入力環境の中でも特に重要な「指示階層」を扱う。

system、developer、user、tool result は、同じ重さで読まれるわけではない。どの指示が優先され、どの情報は資料として扱われるのか。02では、この権限構造を見ていく。

参考リンク

更新履歴

  • 2026-07-03 18:12 JST:公開版原稿として新規作成。