コンテキストエンジニアリングとは:AIエージェント設計の要諦
はじめに
大規模言語モデル(LLM)を用いたアプリケーション開発では、「プロンプトエンジニアリング」が一般的な手法として用いられています。これは多くの場合、入力文を最適化する技法として理解されています。
Anthropic社のエンジニアリングチームは、こうした個別最適を超え、LLMに与える情報全体を設計対象とする「コンテキストエンジニアリング」という考え方を提示しています。
本記事では、有限なコンテキストウィンドウという制約のもとで、どの情報をどのように構成すべきかを整理します。LLMの振る舞いを安定させるための設計上の判断と、その具体例を示します。
コンテキストエンジニアリングの基本概念
コンテキストエンジニアリングとは、LLMに入力するトークン(テキストの最小単位)を最適化する技術です。単にプロンプトの書き方を工夫するだけでなく、システム全体でコンテキストをどう管理するかを設計します。
以下の図は、コンテキストエンジニアリングの全体像を示しています。
flowchart TD
A[コンテキストエンジニアリング] --> B[システムプロンプト]
A --> C[ツール定義]
A --> D[外部データ]
A --> E[会話履歴]
B --> F[コンテキストウィンドウ]
C --> F
D --> F
E --> F
F --> G[LLMによる推論]
style A fill:#4a90d9
style F fill:#51cf66
プロンプトエンジニアリングとの違い
プロンプトエンジニアリングは、LLMへの指示文(プロンプト)を効果的に書く技術です。一方、コンテキストエンジニアリングはより広い範囲を扱います。
コンテキストに含まれる要素は以下のとおりです。
- システムプロンプト:LLMの振る舞いを定義する基本指示です。
- ツール定義:LLMが呼び出せる外部機能の仕様です。
- 外部データ:検索結果やデータベースから取得した情報です。
- 会話履歴:これまでのやり取りの記録です。
プロンプトエンジニアリングがシステムプロンプトの最適化に焦点を当てるのに対し、コンテキストエンジニアリングはこれらすべての要素を統合的に設計します。
コンテキストウィンドウの制約
LLMには「コンテキストウィンドウ」と呼ばれる入力の上限があります。この制約があるため、すべての情報を一度に入力することはできません。
さらに重要なのは「コンテキストの劣化」という現象です。コンテキストウィンドウが長くなるほど、LLMの性能は低下していきます。これはTransformerアーキテクチャの特性に起因します。下記は長いコンテキストに対して性能が劣化する現象を 定量的に示している代表的な論文
flowchart LR
A[短いコンテキスト] --> B[高い精度]
C[長いコンテキスト] --> D[精度の低下]
style B fill:#51cf66
style D fill:#ff6b6b
人間が一度に多くのことを考えると集中力が散漫になるように、LLMも処理すべきトークンが増えると「注意力」が分散します。
効果的なコンテキストの構成要素
Anthropic社は、効果的なコンテキストを構成する3つの要素を挙げています。それぞれについて詳しく見ていきましょう。
システムプロンプトの設計
システムプロンプトは、LLMの振る舞いを定義する最も基本的な要素です。Anthropic社は「ゴルディロックスゾーン」を見つけることが重要だと述べています。
ゴルディロックスゾーンとは、「厳格すぎず、曖昧すぎない」最適な領域のことです。
flowchart TD
A[システムプロンプト設計] --> B{バランスの確認}
B -->|厳格すぎる| C[柔軟性の欠如]
B -->|曖昧すぎる| D[一貫性の欠如]
B -->|適切| E[ゴルディロックスゾーン]
C --> F[特定のケースで失敗]
D --> G[予測不能な動作]
E --> H[安定した高品質な出力]
style E fill:#51cf66
style H fill:#51cf66
具体的には、次の点が重要になります。
まず、情報は構造化して与えます。XMLタグやMarkdownの見出しを用い、プロンプトを意味的な単位に分割します。
次に、設計は最小限から始めます。初期段階では必要最低限の指示に留め、検証の過程で問題が顕在化した箇所のみを追加します。
最後に、ヒューリスティクス(経験則)を与えます。個別のルールを列挙するのではなく、LLMが判断の拠り所とできる原則を示します。
ツール定義の最適化
ツールとは、LLMが外部システムと連携するためのインターフェースです。ファイルの読み書き、Web検索、APIの呼び出しなどが該当します。
重要なのは、曖昧さのない仕様を与えることです。人間が見て判断に迷う定義では、LLMも適切にツールを選択できません。
設計上のポイントは次のとおりです。
-
自己完結させる
ツールの説明だけで用途と使い方が理解できる状態にします。 -
機能の重複を避ける
似た役割のツールが並ぶと、判断が不安定になります。 -
粒度を揃える
細かすぎれば呼び出しが増え、粗すぎれば柔軟性が失われます。
実例によるガイダンス
Few-shot promptingと呼ばれる手法は、依然として効果的です。これは、期待する動作の例をいくつか示すことで、LLMの振る舞いをガイドする方法です。
Anthropic社は、網羅的なエッジケースを列挙するよりも、多様で代表的な例を厳選することを推奨しています。例を通じて「こういう場面ではこう振る舞ってほしい」というパターンを示すのです。
コンテキストの取得と検索
すべての情報を事前にコンテキストに含めることは現実的ではありません。そこで重要になるのが、必要な情報を必要なタイミングで取得する仕組みです。
ジャストインタイム取得
従来のアプローチでは、関連しそうなデータをすべて前処理でコンテキストに含めていました。しかし、現代のアプローチでは「軽量な識別子」だけを保持し、実行時に動的にデータを取得します。
sequenceDiagram
participant Agent as エージェント
participant Context as コンテキスト
participant Tools as ツール
participant Data as 外部データ
Agent->>Context: 識別子のみ保持
Agent->>Agent: 必要なデータを判断
Agent->>Tools: データ取得を要求
Tools->>Data: クエリ実行
Data-->>Tools: 必要なデータのみ
Tools-->>Agent: 結果を返却
Agent->>Context: 必要な部分のみ追加
たとえばClaude Codeでは、大きなファイルを全部読み込むのではなく、headやtailコマンドで必要な部分だけを確認します。これにより、コンテキストウィンドウを効率的に使用できます。
段階的な情報開示
エージェントは探索を通じて必要なコンテキストを発見していきます。ファイル階層、命名規則、タイムスタンプなどの手がかりを使って、段階的に理解を深めていくのです。
この「段階的な情報開示」により、エージェントは層を重ねるように理解を組み立てていきます。一度にすべてを把握しようとするのではなく、必要に応じて情報を追加していく設計です。
ハイブリッド戦略
Anthropic社は、事前読み込みとジャストインタイム取得を組み合わせたハイブリッド戦略を推奨しています。
Claude Codeの例では、CLAUDE.mdファイルのような重要な情報は起動時に読み込みます。一方で、globやgrepなどのツールを使って、必要に応じてファイルを検索・取得します。
この組み合わせにより、速度と柔軟性のバランスを取ることができます。
長時間タスクへの対応手法
エージェントが長時間にわたるタスクを実行する場合、コンテキストウィンドウの管理がさらに重要になります。Anthropic社は3つの主要な手法を紹介しています。
コンパクション
コンパクションとは、会話がコンテキストの上限に近づいたときに、内容を要約して圧縮する手法です。
flowchart TD
A[長い会話履歴] --> B{上限に近づく}
B -->|Yes| C[重要な情報を抽出]
C --> D[要約を生成]
D --> E[新しいコンテキストで再開]
B -->|No| F[通常どおり継続]
style C fill:#4a90d9
style D fill:#4a90d9
重要なのは、何を残して何を捨てるかの判断です。Anthropic社は以下を保持することを推奨しています。
アーキテクチャに関する決定事項は必ず残します。
未解決のバグや問題点も保持します。
重要な実装の詳細は維持します。
一方で、冗長な出力やすでに解決済みの議論は削除できます。
構造化されたノート取り
エージェントがコンテキストウィンドウの外部にノートを書き出し、後から参照する手法です。
ClaudeがPokémonをプレイする実験では、エージェントは数千ステップにわたる正確な記録を維持し、戦略的なノートを発展させていきました。
このシンプルなパターンにより、エージェントは複雑なタスクの進捗を追跡し、重要なコンテキストを維持できます。
マルチエージェントアーキテクチャ
1つのエージェントがすべての状態を管理するのではなく、専門化したサブエージェントがそれぞれ焦点を絞ったタスクを処理します。
flowchart TD
A[メインエージェント] --> B[サブエージェント1]
A --> C[サブエージェント2]
A --> D[サブエージェント3]
B --> E[詳細な探索]
C --> F[詳細な探索]
D --> G[詳細な探索]
E --> H[要約を返却]
F --> H
G --> H
H --> I[メインエージェントが統合]
style A fill:#4a90d9
style I fill:#51cf66
各サブエージェントは広範な探索を行いますが、メインエージェントには凝縮された要約(通常1,000〜2,000トークン)だけを返します。
この設計により、関心事の明確な分離が実現します。詳細な検索コンテキストはサブエージェント内に隔離され、メインエージェントは結果の統合と分析に集中できます。
実装における選択指針
Anthropic社は、状況に応じた手法の選択について以下の指針を示しています。
コンパクションは、長時間の対話的なやり取りで会話の流れを維持したい場合に適しています。
ノート取りは、明確なマイルストーンがある反復的な開発タスクに向いています。
マルチエージェントアーキテクチャは、並列的な探索が効果を発揮する複雑な調査タスクに最適です。
どの手法を選ぶにしても、核心となる原則は変わりません。「望む結果の可能性を最大化する、最小限の高信号トークンの集合を見つけること」です。
終わりに
コンテキストエンジニアリングは、LLMを活用したアプリケーション開発における根本的なパラダイムシフトを表しています。プロンプトの書き方だけでなく、システム全体でコンテキストをどう管理するかを設計する思想です。
モデルの性能が向上するにつれて、細かい指示の必要性は減り、エージェントの自律性は高まっていきます。しかし、コンテキストを貴重で有限なリソースとして扱うという原則は、信頼性の高い効果的なエージェントを構築するうえで、今後も中心的な重要性を持ち続けるでしょう。
本記事がコンテキストエンジニアリングの理解の一助となれば幸いです。
参考リンク
本記事は、Anthropic社エンジニアリングブログの記事を翻訳・解説したものです。
Anthropic公式サイト
Claude公式ドキュメント
コメントを残す