コンテキストエンジニアリング

2026年8月16日

🐧 要するにどういう話か

ChatGPTが出てすぐのころは、望みの回答を得るにはプロンプト(入力)の工夫が重要だという認識により「プロンプトエンジニアリング」などといわれはじめたが、その成果が都度モデル側に取り込まれていくにつれ、モデルの自律性とそれが動作する環境のほうが問題になりはじめ、今度はコンテキスト(文脈)管理のほうが重要だと認識されはじめた。一般ユーザーにも「AIだからよしなにやってくれるんでしょ」という感じで何でも突っ込んではうまくいかないことがうっすら認識されつつある。それこそエンジニアリングが必要だ、というのがコンテキストエンジニアリングの話である。

1. はじめに

この文書は、Prompt Engineering Guide などを参考にして作成した。

2. コンテキストエンジニアリングとは

定義

AIモデル(特に大規模言語モデル:LLM)が望ましい回答を生成するようにプロンプト(指示)を設計・最適化する技術をプロンプトエンジニアリングという。コンテキストエンジニアリングはその上位概念である。

  • プロンプトとは、自分が書く指示である。
  • コンテキストとは、モデルがその場で見ているすべてである。指示、知識、ツールの定義、対話履歴、ツールの結果を含む。

LLM が1回の推論で一度に見て参照できるテキストの範囲(最大トークン数)をコンテキストウィンドウという。これはモデルの「ワーキングメモリ」に相当し、有限である。コンテキストウィンドウのサイズを(最大)コンテキスト長という。

コンテキストエンジニアリングは、LLM の推論時に渡すトークン集合の整備と管理を通じて、望ましい結果が得られる確率を最大化する技術の総称である。対象はプロンプトだけでなく、コンテキストウィンドウに入る全体である。

比喩

Andrej Karpathy 氏は、LLM を CPU、コンテキストウィンドウを RAM、コンテキストエンジニアリングを OS(オペレーティングシステム)にたとえた。OS が CPU の RAM に何を載せて何を追い出すかを決めるように、コンテキストエンジニアリングはその限られたコンテキストウィンドウに何を入れるかを決める。

なぜ必要か

コンテキストウィンドウの容量には限界があるし、容量に余裕があっても何でも詰め込めばよいというわけではない。理由は次の通りである。

  • コンテキストの劣化(context rot):コンテキストウィンドウ内のトークン数が増えるほど、モデルが関連情報を見つけ出す能力が低下する。
    • Transformer のアテンション機構は n トークンに対し n² の対関係を生むが、LLM がコンテキストを処理するための注意の量、いわば「アテンション予算」は有限である。トークンが増えるほどこの有限な予算を消費し、注意が薄まり、正しい情報の取り出しが難しくなる。
  • コンテキスト汚染(context pollution):トークンが増えるほど、悪影響のある相互作用の確率が高まる。LangChain は失敗モードを次の 4 つに整理した。
    • Poisoning(毒):コンテキストに誤った情報が混入し、モデルが誤った方向へ導かれる。
    • Distraction(そらし):無関係な内容が混在し、モデルの関心が分散する。
    • Confusion(混乱):曖昧な情報が混ざり、モデルの動作が不安定になる。
    • Clash(衝突):相互に矛盾する指示が混在し、動作が予期できないものになる。

つまり、「情報が多いほどよい」というわけではない。必要最小限の高シグナルなトークンのみを入れることが重要である。

対象の幅

コンテキストエンジニアリングが扱うのは、コンテキストウィンドウに入るすべてのものである。

  • システムプロンプト
  • ツール
  • 少数例(few-shot)
  • RAG(検索拡張生成)
  • 構造化された入力・出力
  • メモリ

LangChain は、コンテキストを次の 3 つのタイプに整理した。

  • Instructions(指示):プロンプト、メモリ、少数例、ツールの説明など。
  • Knowledge(知識):事実、データ、取得した文書など。
  • Tools(ツール):モデルが呼べるツールとその定義、ツールの結果など。

誰に使えるか

コンテキストエンジニアリングは、次の 3 つの立場のいずれでも使える。

  1. ビルダー:システムプロンプト、ツール、メモリ、圧縮など、基盤側を設計する人。
  2. コーディングエージェントの利用者:Claude Code、Cursor、Windsurf などで、ルール、自動圧縮、メモリ、サブエージェントなどの機能を使う人。
  3. 利用者:LLM へメッセージを送る人。そのメッセージ自体がコンテキストエンジニアリングである。

Prompt Engineering Guide では「盲目的な指示(blind prompting)」と「プロンプトエンジニアリング」を区別している。「盲目的な指示」は文脈を考えずに短いタスクの記述を送ることで、プロンプトエンジニアリングは文脈と構造を考えた指示である。コンテキストエンジニアリングは、さらに全体系にまで視野を広げたものである。

基本原則

コンテキストエンジニアリングの基本原則は 1 文で言える:「望ましい結果が得られる確率を最大化する、最小の高シグナルなトークン集合を見つけよ」。これは 5 章以降の全技術が狙う目標である。

3. AI エージェントの基礎

コンテキストエンジニアリングが最も重要となるのは、AI エージェントの構築においてである。この章では、AIエージェントの基礎を整理する。

3 層の心のモデル

エージェントは、次の 3 層で理解できる。

  • モデル:LLM 本体
  • エージェント:モデル + ツール + ループからなるシステム
  • 基盤:ループを実行し、ツールを呼び出し、状態を管理するコード

エージェントとは何か

エージェントは、LLM がループの中で自律的にツールを使ってタスクを遂行するシステムである。通常の LLM 呼び出しとの違いは、モデルが「次に何をすべきか」を繰り返し決め、ツールを使う点にある。

フロー型と自律ループ型

エージェント的なシステムには、次の 2 つの形がある。

  • フロー型(workflow):開発者が流れを事前に定義し、各ステップのコンテキストも事前に設計できる。次の手の判断はコード側が持つ。
  • 自律ループ型(agent):モデルが次の手を自分で決める。どのツールを使うか、その順も事前には分からない。そのため実行時コンテキスト管理(必要時取得、圧縮、ノート取り、サブエージェント)が本質的になる。次の手の判断はモデル側が持つ。

近年は自律ループ型が主流になりつつある。それゆえ、構築側でも利用側でもコンテキストエンジニアリングの重要性が増している。

3 つの部品

エージェントには、次の 3 つの基本的な部品がある。

  • プランニング:LLM がタスクをステップに分解し、推論する。過去の動作を振り返り、調整する。
  • ツール使用:コードインタプリタ、Web 検索、計算機などの外部ツールを呼ぶ。いつ、どう使うかの選択が重要である。
  • メモリ:
    • 短期(ワーキング)メモリ:直近のコンテキストのバッファとして機能する。多くのタスクでこれで足りる。
    • 長期メモリ:ベクトルストアなどの外部ストアで実装する。過去の情報を検索し、再利用できる。

ファンクション呼び出しとエージェントループ

ファンクション呼び出し(ツール呼び出し)は、LLM がツールを使う仕組みである。流れは次の通りである。

  1. コンテキストの組み立て:システムプロンプト、ツールの定義、ユーザのメッセージ、過去の履歴をまとめてモデルに渡す。
  2. ツールの判断:モデルがツールを呼ぶべきか、どのパラメータを使うかを決める。
  3. ツールの実行:基盤側のコードがツールを実行する。
  4. 観察:ツールの結果が観察(observation)として返る。
  5. 応答:モデルは観察を受け取り、次の応答を生成する。必要であれば 2 に戻る。

エージェントループを図で示す。

flowchart TD A["ユーザのメッセージ"] --> B["コンテキストの組み立て
システムプロンプト + ツール + 履歴"] B --> C{"ツールを呼ぶべきか"} C -- "呼ぶ" --> D["ツールを実行"] D --> E["観察をコンテキストに追加"] E --> C C -- "呼ばない" --> F["ユーザへの応答"]

ここで重要なのは、観察がコンテキストに積み上がることである。モデルは次回に応答を返すとき、過去のすべての観察を含んだコンテキストに基づいて判断する。つまりエージェントが働けば働くほどコンテキストは膨らみ、その管理が重要になる。これがコンテキストエンジニアリングの動機である。

4. コンテキストウィンドウに入るもの

この章では、コンテキストウィンドウに入るものと、その扱い方を整理する。

システムプロンプト

システムプロンプトはコンテキストの土台である。次の点に注意する。

  • 適切な高さ(right altitude):高レベルな目標と低レベルな詳細を両方書かない。適切な粒度を選ぶ。システムプロンプトはエージェントの「憲法」であり、原則を書く。すべての規則を列挙しない。
  • セクション分割:役割、規則、ツール使用、出力形式などのセクションに内容を分ける。
  • 最小限の十分な情報:すべてを詰め込まず、必要なものだけを入れる。

Prompt Engineering Guide の deep-research エージェントのシステムプロンプトは、「エージェントの定義」「一般的な指示」「ツールの説明」「エラー処理」の構造を持っている。セクション分割の良い例である。

ツール

ツールはトークンを消費しやすいコンテキストである。

  • 最小限のセット:必要なツール以外を与えない。ツールが多すぎると、モデルの選択が不安定になる。
  • 明確な説明:説明欄が最も重要である。何を実行して、いつ使うかを書く。
  • 重複の回避:似た機能のツールを複数持たせると、どれを使うかの判断が揺れる。
  • 毎ターン消費される:ツールの定義は毎回の LLM 呼び出しでコンテキストの一部になる。トークンを消費し、コストとレイテンシに影響する。

少数例(few-shot)

少数例は有効だが、注意して選ぶ。

  • 多様で典型的な例:代表的な例を少数選ぶ。
  • エッジケースの列挙を避ける:エッジケースを列挙すると、コンテキストが膨らみ、アテンションが薄まる。

その他の要素

ウィンドウに入るその他の要素は次の通りである。

  • ユーザ入力:ユーザ入力を他のテキストと区切り(デリミタ)で分ける。混同を減らす。
  • 構造化出力(structured output):出力形式(JSON スキーマなど)を指定する。一貫性が高まる。
  • 動的コンテキスト:現在の日付など、実行時に変わる情報を渡す。LLM の知識は過去に止まるため、現在日を渡すことが重要である。
  • 階層構造:コンテキストはシステム / タスク / ツール / メモリの層に分かれる。各層は役割と寿命が異なる。

5. コンテキストエンジニアリングの 4 つの戦略

LangChain は、コンテキストエンジニアリングの技術を次の 4 つの戦略に整理した。書き出す、選ぶ、圧縮する、分離するである。

書き出す(Write)

情報を外に書き出し、取得可能にする。

  • スクラッチパッド:エージェントが中間結果をファイルに書き込む。長いタスクで状態を残すのに有効である。
  • メモリ:
    • エピソード記憶:過去の経験の記憶。
    • 手続き記憶:やり方(手順、スキル)の記憶。
    • 意味記憶:事実や知識の記憶。

なぜ効くか:モデルはコンテキストにないものにはアクセスできない。書き出すことで、コンテキストを膨らませずに、情報をいつでも使える状態にする。

選ぶ(Select)

必要な情報のみを選んで、コンテキストウィンドウに入れる。

  • 必要時取得(just-in-time):事前にすべてをコンテキストに入れない。軽量な識別子(ファイルパスやURLなど)を入れ、必要な時点でモデルに取得させる。
  • 段階的開示(progressive disclosure):最初に要約だけを見せ、必要に応じてモデルに詳細を取得させる(ファイル名、INDEX.md、YAMLフロントマターなど)。
  • 事前取得とハイブリッド:事前にすべて取得する(事前取得)こともできるが、両者のハイブリッドがよい場合が多い。
  • RAG:ナレッジベースを検索し、関連する文書をコンテキストに入れる。

なぜ効くか:その瞬間に実際に必要なトークンだけを入れる。「アテンション予算」を節約し、無関係な内容からのそらしを避ける。

圧縮する(Compress)

コンテキストを縮小する。

  • 要約:長い対話やツールの結果を要約する。
    • 再帰的:各部分を要約して結合する。
    • 階層的:階層ごとに要約する。
    • 境界で:セッションの終了やコンテキストの切り替えなどの境界で要約する。
  • トリミング:古い、または不要なメッセージを削除する。

なぜ効くか:コンテキストを圧縮することで、トークン数を減らしつつ重要な情報を残せる。コンテキストウィンドウに限界がある状況でも動作を続けられる。

分離する(Isolate)

コンテキストを分ける。

  • マルチエージェント:タスクを複数のエージェントに分け、それぞれに別のコンテキストを与える。
  • サンドボックス:コードやツールを隔離された環境で実行する。
  • 状態オブジェクト:共有状態をコンテキスト外のデータ構造に置き、各エージェントは必要な部分だけ参照する。

なぜ効くか:コンテキストを分離することで、タスク間の汚染を防ぎ、各エージェントのコンテキストを小さく、高シグナルな状態に保つ。

4 つの戦略の関係

4 つは排他的ではない。状況に応じて組み合わせる。共通する目標は、コンテキストを小さく、高シグナルな状態に保つことである。

6. 長時間タスクへの適用

長時間のタスク(長いコーディングセッションなど)は、コンテキストに負荷をかける。トークン数がコンテキストウィンドウを超えたり、コンテキストが汚染されたりする。Anthropic は、この制約に直接対処する 3 つの技術を提示した。

圧縮(Compaction)

圧縮は、コンテキストウィンドウの限界に近づいた対話を要約し、その要約で新しいウィンドウに再開始する技術である。

  • 過去の対話を要約し、要約からやり直す。
  • まず再現率(recall)を最大化し、その後に精度(precision)を上げる。つまり、まず重要な情報が失われないことを確かめ、それから要約を引き締める。
  • 古いツールの呼び出しと結果を消し、重要なものだけを残す。

圧縮は、対話中心のタスクに向く。

構造化ノート取り(Structured note-taking)

エージェントが重要な状態をノートファイルに書き、各ステップで参照する。

  • タスクリストを保持し、タスクの進捗を記録する。
  • 決定した制約や判断をノートに書き、状態が対話履歴だけに依存しないようにする。

ノート取りは、反復的な開発に向く。

※個人的にはタスクリストは tasklist.md を使っているが、まあ名前はなんでもよいのだろう。

サブエージェント(Sub-agents)

メインのエージェントが計画し、サブエージェントがクリーンなコンテキストウィンドウで作業し、要約を返す。

  • メインエージェントは全体像を持ち、サブエージェントがサブタスクを担当する。
  • サブエージェントのコンテキストにはメインの対話が含まれないため、小さく、焦点が絞られる。
  • サブエージェントは要約だけメインに返すため、メインのコンテキストは膨らまない。

サブエージェントは、並列な探索や独立したサブタスクに向く。

使い分け

  • 対話中心:圧縮。
  • 反復的な開発:構造化ノート取り。
  • 並列な探索:サブエージェント(マルチエージェント)。

7. 実践

コンテキストエンジニアリングは一度で完成するものではなく、反復的な作業である。

反復プロセス

次のサイクルを回す。

  1. デプロイ:初期のコンテキストでエージェントを動かす。
  2. 観察:実際の動作を観察する。
  3. 特定:期待からのずれを特定する。
  4. 改善:システムプロンプトと制約を改善する。
  5. テスト:改善を検証する。
  6. 繰り返す。

Prompt Engnieering Guide は「最大の性能改善は、システムプロンプトでツールの利用方法を明確に説明することからしばしば生まれる」としている。ツールのパラメータを定義するだけでは不十分である。

観察可能性(Observability)

反復するには、中身を見られる必要がある。

  • 決定のログ:モデルの決定と推論を記録する。
  • 状態の追跡:外部ストレージでタスクの状態変化を追う。
  • ツール呼び出しの記録:どのツールを、どんなパラメータで呼び、どんな結果が返ったかを記録する。
  • 中間ステップの確認:中間のステップを確認する。例えば Web 検索を呼び、実行結果の観察を得て、タスクの状態を更新する、という流れを見られるようにする。

よくある落とし穴

  • 過剰な制約:厳しすぎる指示は、モデルの柔軟性を奪い、エッジケースを処理できなくする。
  • 仕様不足:曖昧な指示は、モデルが推測で埋める原因になり、動作が不安定になる。
  • エラーケースの無視:失敗時の動作を規定しないと、エージェントが黙って進んでしまう。
  • ツールの肥大化:ツールを多く与えすぎると、モデルの選択が不安定になる。
  • 曖昧なプロンプト:曖昧な指示は、動作の不安定さにつながる。

評価

コンテキストエンジニアリングの効果を測定すべきである。

  • タスク完了率:タスクが目標に到達した割合。
  • 動作の一貫性:似た入力に対して、エージェントが似た動作をするか。
  • エラー率:誤ったツールの選択、誤ったパラメータなどの失敗の頻度。

8. ユーザーとしてのコンテキストエンジニアリング

ここまでは主に「エージェントを組む」立場で述べてきた。この章では、2〜7 章の原則をユーザーの立場からもう一度読み替える。

コーディングエージェントを使う場合

4〜6 章の技術は、コーディングエージェントの具体的な機能に対応している。

  • システムプロンプト / ルール:Claude Code の CLAUDE.md、Cursor や Windsurf のルールファイル。
  • 圧縮:コンテキストの上限に近づくと自動で要約する機能。
  • メモリ:重要な情報を保存し、再現する機能。
  • サブエージェント:サブタスクを別エージェントに任せる機能。

原則を理解していれば、どの状況でどの機能を使えばよいか判断できる。

タスク・出力形式・制約を明示する

  • 期待を明示する:タスク、出力形式、制約を具体的に書く。モデルの推測に委ねない。
  • 仕様不足を避ける:曖昧な指示は失敗の大きな原因である。暗黙の期待を言葉にする。

関連する資料だけ提示する

  • 文書はすべて見せず、タスクに必要なものだけを見せる。
  • 理由は、「アテンション予算」、最小の高シグナルなトークン集合、コンテキストの劣化である。すべて見せると、無関係な内容が関心を分散させ、誤った情報がモデルを誤った方向へ導く。

望ましい出力の例を見せる

  • 望ましい出力の例を 1〜2 個示す(few-shot)。
  • エッジケースの列挙はしない。代表的な少数の例がよい。

日付や期間を伝える

  • LLM の知識は過去に留まる(“knowledge cutoff” がある)ため、現在の日付を伝える。
  • 「直近のニュース」のような依頼では、基準日や期間を指定する。

出力を見て指示を改善する

  • 出力を確認し、問題があれば指示を改善する。

9. 結語

コンテキストは有限な資源である。何でも入れればよいものではない。モデルが賢くなるほど必要な指示は減るが、何をコンテキストに入れるかの選択の重要性は残る。コンテキストエンジニアリングは、限られたコンテキストウィンドウの中で、望ましい結果が得られる確率を最大化する最小の高シグナルなトークン集合を見つける仕事である。この文書ではその基礎を示した。

📚 参考文献