LESSON 30分

ストーリー

田中VPoE
「ペルソナと制約を設計した。でもシステムプロンプトにどんどん情報を詰め込むと、あっという間にコンテキストウィンドウの上限に達してしまう。」
あなた
「コンテキストウィンドウって、LLMが一度に処理できるトークン数の上限ですよね?」
田中VPoE
「そう。例えばGPT-4は128Kトークン、Claudeは200Kトークンだ。多いように見えるが、システムプロンプト、会話履歴、入力データを全て含めると、意外とすぐに上限に近づく。」
あなた
「限られたスペースをどう使うかが重要なんですね。」
田中VPoE
「まさに。コンテキストの優先順位付けと圧縮戦略を学ぼう。」

コンテキストウィンドウの構造

[コンテキストウィンドウ]
┌─────────────────────────────┐
│ システムプロンプト           │ ← 固定(ペルソナ・制約・指示)
├─────────────────────────────┤
│ 参照データ(RAG等)          │ ← 動的(検索結果、ドキュメント)
├─────────────────────────────┤
│ 会話履歴                    │ ← 蓄積(過去のやり取り)
├─────────────────────────────┤
│ ユーザーの現在の入力         │ ← 動的(最新のメッセージ)
├─────────────────────────────┤
│ 生成用の余白                │ ← 出力用に確保
└─────────────────────────────┘

トークン配分の目安

要素推奨割合128Kモデルでの目安
システムプロンプト5-10%6K-13Kトークン
参照データ20-40%26K-51Kトークン
会話履歴20-30%26K-38Kトークン
ユーザー入力5-10%6K-13Kトークン
生成余白20-30%26K-38Kトークン

情報の優先順位

コンテキストに入れる情報には明確な優先順位をつける。

優先度マトリクス

優先度情報タイプ
必須システムプロンプト(ペルソナ・制約)役割定義、禁止事項
直近の会話(最新2-3ターン)ユーザーの直前の質問と回答
タスクに直接関連する参照データ対象商品の情報
過去の会話の要約「顧客はPC購入を検討中」
古い会話の詳細3ターン以上前の全文
間接的に関連する参照データ関連商品の情報

圧縮戦略

戦略1: 会話履歴の要約

長い会話履歴をそのまま保持するのではなく、要約して圧縮する。

会話管理ルール:
- 直近3ターンの会話はそのまま保持
- 4ターン以上前の会話は要約して保持
- 要約形式: 「[要約] ユーザーは〇〇について質問。△△と回答済み。」

例:
[要約] ユーザーはノートPCの購入を検討中。予算は15万円。
用途はプログラミングとWeb開発。メモリ16GB以上を希望。
3機種を提案し、MacBook Airに興味を示している。

User: バッテリーの持ちはどのくらいですか?
Assistant: MacBook Air M3のバッテリーは...
User: 保証はつきますか?

戦略2: 参照データの選択的注入

全てのデータを入れるのではなく、関連性の高いデータのみを注入する。

RAG(Retrieval-Augmented Generation)の流れ:

1. ユーザーの質問を分析
2. 関連するドキュメントを検索(ベクトル検索)
3. 上位3-5件のみをコンテキストに注入
4. LLMが参照データを元に回答

コンテキスト注入テンプレート:
---
以下の参照情報に基づいて回答してください。
参照情報にない内容は「情報がありません」と回答してください。

[参照情報]
{検索結果の上位3件}

[ユーザーの質問]
{質問}
---

戦略3: システムプロンプトの最適化

システムプロンプトの冗長な部分を削減する。

# 冗長な例(200トークン)
あなたはNetShop社で働くカスタマーサポートのスタッフです。
お客様に対して丁寧に対応してください。
お客様の質問に対して、正確な情報を提供してください。
分からないことは分からないと正直に伝えてください。
お客様を怒らせないように注意してください。

# 圧縮版(80トークン)
あなたはNetShop社のサポートスタッフです。
ルール: 丁寧語使用 / 正確な情報のみ回答 / 不明点は「確認します」と応答

動的コンテキスト管理

スライディングウィンドウ方式

interface ConversationManager {
  systemPrompt: string;        // 固定
  summary: string;             // 圧縮された過去の会話
  recentMessages: Message[];   // 直近N件の会話
  contextData: string;         // 参照データ
}

function manageContext(manager: ConversationManager, maxTokens: number): string {
  const systemTokens = countTokens(manager.systemPrompt);
  const outputReserve = maxTokens * 0.25;  // 出力用25%確保
  const available = maxTokens - systemTokens - outputReserve;

  // 優先順位順にコンテキストを構築
  let context = manager.systemPrompt;
  let remaining = available;

  // 1. 直近の会話(必須)
  const recentText = formatMessages(manager.recentMessages.slice(-3));
  remaining -= countTokens(recentText);

  // 2. 参照データ(重要)
  if (remaining > 0) {
    const contextText = truncate(manager.contextData, remaining * 0.6);
    remaining -= countTokens(contextText);
    context += contextText;
  }

  // 3. 要約(余裕があれば)
  if (remaining > 0) {
    context += truncate(manager.summary, remaining);
  }

  context += recentText;
  return context;
}

コンテキストウィンドウの落とし穴

落とし穴説明対策
中間部分の情報喪失LLMは先頭と末尾の情報を重視し、中間部分を軽視する傾向がある重要な情報を先頭か末尾に配置
不要な情報のノイズ無関係な情報が混入すると精度が低下関連性フィルタリングを実施
トークン超過上限を超えるとエラーまたは切り捨て事前にトークン数を計算

情報配置の最適化

[先頭] システムプロンプト(最重要の制約) ← 常に読まれる
[中間] 参照データ、過去の会話要約 ← 重要度が下がる
[末尾] 直近の会話、ユーザーの質問 ← 常に読まれる

まとめ

項目ポイント
コンテキスト構造システムプロンプト/参照データ/会話履歴/入力/生成余白
優先順位必須→高→中→低で情報をトリアージ
圧縮戦略会話要約、選択的注入、プロンプト最適化
配置重要情報は先頭か末尾に配置(中間は注意)

チェックリスト

  • コンテキストウィンドウの構造とトークン配分を理解した
  • 情報の優先順位マトリクスを設計できる
  • 3つの圧縮戦略を実践できる
  • 動的コンテキスト管理の仕組みを把握した
  • 情報配置の最適化(先頭・末尾の重要性)を理解した

次のステップへ

次は「システムプロンプトパターン集」として、業務別の具体的なシステムプロンプトの型を学ぼう。


推定読了時間: 30分