2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

コンテキストロット(Context Rot)とは?AIエージェント開発者が知るべき性能劣化の原因と対策

2
Posted at

はじめに

「コンテキストウィンドウが大きいほど高性能」と思っていませんか?

実は、LLMに 情報を与えれば与えるほど、回答精度が下がる という逆説的な現象が起きることがあります。これが コンテキストロット(Context Rot) です。

本記事では、AIエージェント開発において避けて通れないこの問題について、原因から対策まで解説します。

コンテキストロットとは

コンテキストロットとは、LLMが処理する入力コンテキストが長くなるにつれて、パフォーマンスが劣化する現象です。

技術的な上限(例:100万トークン)の範囲内であっても、コンテキストウィンドウが埋まるにつれてLLMの性能は低下します。

Stanfordの研究では、わずか20件のドキュメント(約4,000トークン)を与えただけで、LLMの精度が 70-75%から55-60%に低下 したと報告されています。情報が間違っているわけでも欠けているわけでもなく、モデルが単に注意を払わなくなるのです。

なぜ起こるのか?

Transformerアーキテクチャの制約

現代のLLMはTransformerアーキテクチャに基づいており、すべてのトークンが他のすべてのトークンに対して注意(Attention)を向けます。

\text{計算量} = O(n^2)

つまり、トークン数に対して 二乗のオーダー で計算量が増加します。

トークン数 追跡すべき関係の数
10,000 1億
100,000 100億
1,000,000 1兆

コンテキストが長くなるほど、モデルはペアワイズの関係を捕捉する能力が希薄化し、重要な情報への注意が散漫になります。

Lost-in-the-Middle問題

研究者たちは 「Lost-in-the-Middle(中間で失われる)」問題 を発見しました。

モデルは、コンテキストウィンドウの 最初と最後 に置かれた情報には高い精度で応答しますが、中間に埋もれた情報 は見落としやすくなります。同じ情報でも、配置位置によって精度が大きく変わるのです。

AIエージェントにおける影響

エージェントシステムでは、コンテキストロットの影響が特に深刻です。

エージェントが複数のステップを経てタスクを実行すると、コンテキストウィンドウは累積的に成長し、「注意の希薄化」が起こります。重要な制約が埋もれ、ツール選択がドリフトし始めます。

実際に起こる問題

  1. ツール選択のドリフト - 最初に与えられた指示を忘れ、不適切なツールを選択
  2. 制約の無視 - セキュリティ制約や出力形式の指定を見落とす
  3. フォーカスの喪失 - 本来のタスクから逸脱した行動を取る

対策

1. JIT(Just-in-Time)検索

すべての情報を事前にロードするのではなく、必要な時に必要な情報だけを取得 する戦略です。

# ❌ Bad: すべての情報を事前にロード
context = load_all_documents()
response = llm.generate(context + query)

# ✅ Good: 必要な時に必要な情報だけを取得
def jit_retrieve(query):
    relevant_docs = vector_db.search(query, top_k=3)
    return llm.generate(relevant_docs + query)

Claude Codeもこの戦略を採用しており、情報が関連するときにのみ取得することで、モデルの推論空間をクリーンに保っています。

2. コンテキスト圧縮(Compaction)

冗長な情報を取り除き、参照だけを保持する方法です。

# ❌ Bad: ファイル内容をすべて履歴に保持
chat_history.append({
    "role": "assistant",
    "content": f"Created file with content:\n{file_content}"  # 500行のコード
})

# ✅ Good: パスのみを保持(可逆的)
chat_history.append({
    "role": "assistant", 
    "content": "Output saved to /src/main.py"
})

Compactionは 可逆的 です。後でコードを読む必要があれば、ツールを使ってファイルを読み取れます。

3. コンテキスト要約(Summarization)

一定のトークン数(例:128kトークン)に達したら、LLMを使って履歴を要約します。

def summarize_if_needed(context, threshold=128000):
    if count_tokens(context) > threshold:
        # 最新のツール呼び出しは詳細を保持
        recent = context[-5:]
        # 古い部分は要約
        old_summary = llm.summarize(context[:-5])
        return old_summary + recent
    return context

要約は 非可逆的(Lossy) です。重要な情報が失われる可能性があるため、最新のやり取りは生のまま保持することが推奨されます。

4. マルチエージェント構成

複雑なタスクを小さなサブタスクに分割し、専門のサブエージェントに処理させます。

各エージェントは クリーンなコンテキスト で動作し、必要な結果のみを親エージェントに返します。これにより、コンテキストの肥大化を防げます。

5. Pre-Rot Threshold の設定

コンテキストロットが発生する前に、積極的に対策を実行します。

# モデルの公称上限ではなく、実効的な上限を設定
PRE_ROT_THRESHOLD = 256_000  # 1Mウィンドウでも256k以下で管理

def process_with_context_management(context, query):
    if count_tokens(context) > PRE_ROT_THRESHOLD:
        context = compact_or_summarize(context)
    return llm.generate(context + query)

モデルが100万トークンのコンテキストウィンドウを持っていても、性能劣化は多くの場合256k以下で始まります。APIエラーを待つのではなく、事前に対策を打ちましょう。

まとめ

問題 対策
情報過多による注意散漫 JIT検索で必要最小限の情報だけを提供
履歴の肥大化 Compactionで参照のみ保持
長期タスクでの性能劣化 要約とPre-Rot Thresholdの設定
複雑なワークフロー マルチエージェント構成で責務分離

コンテキストロットは、AIエージェント開発における「静かなる脅威」です。大きなコンテキストウィンドウを持つモデルでも、適切なコンテキストエンジニアリング なしには、その能力を十分に発揮できません。

「情報は多ければ多いほど良い」のではなく、「適切な情報を適切なタイミングで」 が、信頼性の高いAIエージェント構築の鍵です。

参考資料

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?