LLMアプリケーションの品質を左右する要因は、単一の「うまいプロンプト」から、より広い設計問題へと移りつつある。Anthropicは2025年9月29日のEngineering記事で、プロンプト(指示文)に加えて、ツール、外部データ、履歴、MCP、実行時状態などを含む「推論時コンテキスト」全体を最適化する考え方を「コンテキストエンジニアリング」として整理した。
またLangChainは2025年7月2日のブログで、コンテキストエンジニアリングを「各ステップでコンテキストウィンドウに何を入れ、何を外し、どう配置するか」という運用技術としてまとめ、write / select / compress / isolateという枠組みで実装パターンを分類している。
本稿の主題は、流行語の紹介ではない。AIエージェント(LLM + ツール + ループ)が長時間・多段のタスクを実行する際に、コンテキストが「有限な計算資源」であり、かつ「性能が劣化し得る入力」でもある点を前提として、設計と運用の具体策をまとめる。
プロンプトエンジニアリングの限界と、コンテキストエンジニアリングの射程
プロンプトエンジニアリングは、主に「指示文(特にsystem)をどう書くか」「例(few-shot)をどう置くか」を中心に最適化してきた。一方、エージェントはツール呼び出しで観測(observation)を蓄積し、履歴が肥大化し、途中生成物が増える。そこで問題になるのは、文章の巧拙よりも次の問いである。
- どの情報を、どの順序で、どの形式で、どの頻度でモデルに見せるべきか
- その決定を毎ターン繰り返し、破綻なく運用できるか(コスト/遅延/安定性)
Anthropicは、コンテキストエンジニアリングを「推論時に投入する最適なトークン集合をキュレーションし維持する戦略」と定義し、プロンプト外の要素(ツール、外部データ、履歴など)が重要になることを明示している。
長文コンテキストは万能ではない。たとえばChromaは2025年7月14日の技術レポートで、入力トークン数が増えるにつれ、モデルの振る舞いが非一様に不安定化し得ること(context rot)を報告している。さらに「Lost in the Middle」(2023年7月6日初版投稿)は、関連情報が長文の中央に埋もれると性能が落ちる傾向(lost-in-the-middle)を示した。したがって、コンテキストを増やすほど賢くなる、とは限らないという前提に立つ必要がある。
実行時コンテキストの「部品表」: 何を設計対象にするのか
エージェントの入力(モデルが見るトークン)は、概ね次の部品から合成される。重要なのは、部品の追加は足し算ではなく、注意資源と予算の取り合いになる点である。
- 安定プレフィクス: system指示、ツール定義、フォーマット規約など(できるだけ固定)
- タスク状態: 目的、制約、進捗、ToDo、失敗履歴、意思決定の根拠
- 外部知識: RAG、ドキュメント、コード、DBクエリ結果(必要時にロード)
- メモリ: セッション内メモ(scratchpad)、長期メモリ(ユーザ嗜好、規約)
- 観測ログ: ツールの生結果、エラー、サンドボックス出力(肥大化しやすい)
この部品表を前提に、実装では「write / select / compress / isolate」を組み合わせるのが実務的である(LangChainの分類)。Manusの2025年7月18日のブログも、ファイルシステムを外部メモリとして扱い、URLやパスなどの参照を残して可逆圧縮(restorable compression)に寄せる考え方を述べている。
実装パターン: write / select / compress / isolate をコードに落とす
ここでは、コーディング/調査型エージェントで再現性が高い実装パターンを、設計意図とともに整理する。
1) Write: 外部化(ファイル/DB/メモリ)して「参照」を残す
Anthropicは2025年9月29日の記事で、コーディングエージェントが巨大なデータを丸ごと入れず、ファイルパスやクエリ等の識別子を保持し、必要時にツールでロードする「just in time」を紹介している。Manusも同様に、ファイルシステムを「究極のコンテキスト」として扱う方針を述べる。
2) Select: そのターンに必要な断片だけを選ぶ
選択は検索(embedding/キーワード)だけではない。手元のコードベースなら、直近で触ったファイル、変更差分、エラー周辺、依存関係グラフなど、タスク固有の「重要度シグナル」が存在する。Anthropicが挙げるように、フォルダ階層やファイル名、タイムスタンプといったメタデータ自体が、選択のヒューリスティクスになる。
3) Compress: 要約・刈り込み・ツール結果のクリア
長期タスクでは、いずれコンテキストは上限に近づく。Anthropicは、履歴が上限に近づいた際に要約で再起動するcompactionや、ツール結果のクリアを「低リスクの軽量圧縮」として挙げている。ポイントは、単なる短縮ではなく、設計判断・未解決点・次アクションの保持である。
4) Isolate: 役割分割(サブエージェント)と状態オブジェクトで衝突を防ぐ
LangChainは、コンテキストの隔離としてマルチエージェントや、ランタイム状態(state object)を挙げる。状態は「LLMに見せるフィールド」と「見せないが保持するフィールド」を分離でき、重い成果物(長いログ、バイナリ、ページ全文)を外に置ける。
プロンプト管理は「コンテキスト管理」の一部になる
コンテキストエンジニアリングが主役になると、プロンプト管理も「文面の版管理」だけでは足りなくなる。少なくとも次の3層を管理対象にする必要がある。
- 安定プレフィクス: system指示、ツール定義、出力フォーマット(キャッシュ効率と一貫性のために固定)
- 動的テンプレート: そのターンの目的、制約、参照リスト、入力データのサマリ(毎ターン変わる)
- 選択ロジック: 何をロードし、どれを捨て、いつ圧縮するか(コード側の実装)
特に運用で効くのは、「安定プレフィクスをいじらない」という規律である。Manusは2025年7月18日のブログで、KVキャッシュのヒット率が遅延とコストに直結し、プレフィクスが1トークン変わるだけでもキャッシュが無効化され得るとして、冒頭へのタイムスタンプ挿入のようなアンチパターンを挙げている。
コーディングエージェントの具体策: コンテキストビルダーを設計する
実装の中心は「プロンプトを書く人」ではなく、コンテキストを組み立てる関数である。以下は、実務で使える最小構成の疑似コードである(概念実装)。
type ContextPart = { key: string; tokens: number; content: string };
type BuildInput = {
goal: string;
userMessage: string;
todo: string;
recentFiles: { path: string; summary: string }[];
memory: { title: string; value: string; priority: number }[];
retrieved: { source: string; snippet: string; score: number }[];
lastErrors: string[];
};
function buildContext(input: BuildInput, maxTokens: number): ContextPart[] {
// 1) Stable prefix: system + tools. Keep as constant as possible for cache efficiency.
const parts: ContextPart[] = [];
parts.push({ key: 'system', tokens: 900, content: '...system instructions...' });
parts.push({ key: 'tools', tokens: 1200, content: '...tool schemas...' });
// 2) Recitation: keep goal/todo near the end to fight lost-in-the-middle.
parts.push({ key: 'goal', tokens: 120, content: input.goal });
parts.push({ key: 'todo', tokens: 200, content: input.todo });
// 3) Select: keep only top memory/retrieval items.
const mem = input.memory
.sort((a, b) => b.priority - a.priority)
.slice(0, 5)
.map((m) => ({ key: 'memory', tokens: 160, content: m.title + ': ' + m.value }));
parts.push(...mem);
const ret = input.retrieved
.sort((a, b) => b.score - a.score)
.slice(0, 6)
.map((r) => ({ key: 'retrieved', tokens: 220, content: '[' + r.source + '] ' + r.snippet }));
parts.push(...ret);
// 4) Just-in-time: include summaries + identifiers (paths), not full file contents.
const files = input.recentFiles.slice(0, 5).map((f) => ({
key: 'file',
tokens: 220,
content: f.path + '\n' + f.summary,
}));
parts.push(...files);
// 5) Errors are high-signal: keep a small window.
const errs = input.lastErrors.slice(0, 3).map((e) => ({ key: 'error', tokens: 120, content: e }));
parts.push(...errs);
// 6) Budget: if exceeded, compress low-priority parts (not the stable prefix).
while (parts.reduce((s, p) => s + p.tokens, 0) > maxTokens) {
const idx = parts.findIndex((p) => p.key === 'retrieved' || p.key === 'file');
if (idx === -1) break;
parts.splice(idx, 1);
}
// 7) User message last.
parts.push({ key: 'user', tokens: 200, content: input.userMessage });
return parts;
}
この設計で重要なのは、(1)安定プレフィクスを固定し、(2)動的部分を「選択と圧縮」で管理し、(3)目標やToDoを末尾へ再掲(recitation)して注意を誘導する点である。Manusはtodo.mdで目的を再唱して注意を誘導する設計を述べている(2025年7月18日)。
FAQ
コンテキストエンジニアリングは、プロンプトエンジニアリングを不要にするのか?
不要にはしない。Anthropicが述べるように、コンテキストエンジニアリングはプロンプトエンジニアリングの自然な発展として位置づけられる。system指示の明確化は前提であり、その上で「推論時に何を載せるか」を毎ターン設計・運用するのが追加の仕事になる。
RAGを入れればコンテキスト問題は解決するのか?
解決しない。検索で文脈を増やせても、投入トークンが増えるほど注意資源を消費し、性能が非一様に劣化し得るという報告がある。検索は「select」の一手段であり、圧縮や隔離、外部化と組み合わせて運用する必要がある。
なぜ「安定プレフィクス」が重要なのか?
キャッシュ(KV cache / prefix cache)や一貫性の観点である。Manusは2025年7月18日のブログで、プレフィクスが微小に変化するだけでキャッシュが無効化され得るとし、タイムスタンプの混入などをアンチパターンとして挙げている。
コーディングエージェントで最初に効く改善は何か?
「全文を入れる」設計をやめ、識別子(パス、クエリ、URL)を保持し必要時にロードすること、ツール結果のクリアやcompactionを入れること、そして目標/ToDoの再掲である。いずれも実装が比較的軽く、長期タスクでの劣化を抑えやすい。
コンテキストエンジニアリングの評価はどう行うべきか?
コスト/遅延(入力トークン、キャッシュ率)と品質(成功率、再試行回数、誤ツール呼び出し、復旧能力)をトレースで追う必要がある。LangChainは観測可能性と評価を用意し、変更が性能を悪化させないか検証する重要性を述べている(2025年7月2日)。
参考文献
- Effective context engineering for AI agents — Anthropic, 2025-09-29
- Context Engineering — LangChain Blog, 2025-07-02
- Context Engineering for AI Agents: Lessons from Building Manus — Manus, 2025-07-18
- Context Rot: How Increasing Input Tokens Impacts LLM Performance — Chroma Research, 2025-07-14
- Lost in the Middle: How Language Models Use Long Contexts — arXiv, 2023-07-06



