本番AI Agentのコンテキスト圧縮

メッセージ切り詰め、ツール結果の整理からHermes Agentの階層的Compactionまで

要約

AI Agentが検索、ファイル、端末、ブラウザ、データベースを繰り返し呼び出すと、コンテキストは増え続けます。問題は最終的に収まらなくなることだけではありません。各ターンの入力token、コスト、first-token遅延が増え、古いツール出力・重複ログ・解決済みの問題が有効情報を薄め、制約を忘れたり、同じツールを再実行したり、失敗済みの方法を試し直したりします。一方で履歴を乱暴に削除すれば、長いタスクの連続性が壊れます。

本番向けコンテキスト圧縮の目的は、できるだけ短い要約を作ることではありません。

Agentが正しく、安全に、検証可能な形で作業を続けるために必要な状態を、できるだけ少ないactive tokenで保持することです。

本稿は『深入理解 AI Agent:设计原理与工程实践』第2.7節を読解の軸とし、2026年7月までのOpenAI、Anthropic、LangChain v1、Google ADK、Hermes Agentの公式資料と現行ソースを再確認します。書籍の方法論、現行製品・フレームワーク、Hermes Agentのmainブランチの実挙動、本番へ直接適用できる工学的提案を区別します。

1. なぜコンテキスト圧縮が必要か

1.1 ハード制約:コンテキストウィンドウには限界がある

典型的なAgent loopは、ユーザー要求、モデルのツール呼び出し、ツール結果、分析、次のツール呼び出しを追加し続けます。ウィンドウを実際に圧迫するのは、ユーザーの発話よりも、数万tokenを返すWebページやPDF、大きなログ、多数のソースファイル、ブラウザのスナップショットとマルチモーダル添付、ファイル全文を含むツール引数、過去のreasoning・メタデータ・ベンダーのreplay fieldです。上限を超えればリクエストは失敗し得ます。上限未満でもセッションが健全とは限りません。

1.2 ソフト劣化:収まることと、うまく使えることは違う

LangChain v1は、履歴が収まっていても古く脱線した内容がモデルを妨げ、遅延とコストを増すと明記しています。Anthropicは、コンテキスト膨張で有効情報の利用率が下がる現象を context rot と呼びます。1 2

コンテキスト容量:まだ余裕がある
情報密度:継続的に低下する
モデルの注意:古いログ、重複結果、無関係な詳細に分散する

圧縮はcontext_length_exceeded回避だけでなく、各判断で見える情報密度を上げるためにも必要です。

1.3 長期Agentに必要なのは会話要約ではなくタスク引き継ぎ

「返金について話し、注文を調べ、助言した」という会話要約では作業を再開できません。必要なのはcheckpoint / handoffです。

active_goal: 返金APIの重複請求を修正する
constraints:
  - データベースschemaを変更しない
  - APIの後方互換性を保つ
completed:
  - 並行リクエストで重複請求を再現した
  - payment/idempotency.pyを特定した
  - idempotency key検証を追加した
failed_attempts:
  - Redis TTLだけではrace conditionが残る
verification:
  unit_tests: "47/50 passed"
  failing:
    - test_concurrent_refund
    - test_retry_after_timeout
    - test_duplicate_webhook
modified_files:
  - payment/idempotency.py
  - tests/test_refund.py
remaining:
  - 3件の並行テストを修正する
  - 完全な回帰テストを実行する

これは「今どの状態にあり、次のAgentターンがどう続けるか」を答えるものであり、「過去に何を話したか」ではありません。

2. 混同してはいけない4概念

コンテキスト圧縮 / Compaction

次のモデルターンで実際に見えるactive contextを変えます。古い内容を削除、外部化、または要約に置換します。

Prompt Cache

キャッシュは必ずしもコンテキスト長を減らしません。80,000 tokenのリクエストでも、同一の60,000-token prefixはprefill計算を再利用できます。キャッシュは「再計算しない」ため、圧縮は「ずっと持ち続けない」ためのものです。

長期記憶

ユーザーの好み、業務上の事実、経験をセッションをまたいで残します。現在タスクの状態を置き換えたり、全履歴をsystem promptへ恒久的に詰め込んだりしてはいけません。

RAGとArtifact Retrieval

完全な原文はモデル外に保存し、active contextには要約、artifact_id、出所、再取得方法だけを置きます。圧縮の損失を抑える最も重要な基盤です。

3. 主なコンテキスト圧縮手法

本番システムは通常、安価なものから賢いものへ、複数手法を組み合わせます。

3.1 メッセージ切り詰めとsliding window

最近の一定メッセージ数またはtoken数だけを残し、system prompt、必要なら最初のタスク、最後の実ユーザー要求を保持します。tool_callと対応するtool_resultは分割しません。LangChain v1は、trim messages、永久削除、要約を短期記憶の基本パターンとして挙げます。1

追加LLM呼び出しが不要で高速・安価・決定的であり、要約幻覚もないため、overflowの最後の安全網になります。ただし早期の制約や決定が消え、重複呼び出しや失敗案の再試行を招きます。通常のチャット、独立性の高い単純ターン、または他方式のfallbackに向きます。

3.2 決定的フィルタリングとノイズ除去

コードで明確な低価値情報を削除します。重複ログ行、Webのナビゲーション・広告、空結果、処理済みstreaming delta、反復するstatus通知、再計算可能な統計、期限切れ進捗などです。

def should_drop(message) -> bool:
    return (
        message.is_empty
        or message.is_duplicate
        or message.kind in {"heartbeat", "stream_delta"}
        or message.expired
    )

LLMコストがなく、挙動が安定してテストしやすく、ほぼ全ての本番Agentで最初の層に置くべきです。規則で認識できるノイズだけを扱え、過剰削除の恐れがあり、履歴中間の書換えは以後のPrompt Cacheを壊します。

3.3 ツール結果の整理と降格

ツールを呼んだ記録は残し、巨大な結果本文だけを短い再取得可能な記録に置き換えます。

assistant:
  read_file("server.log")
tool:
  [read_file] server.log、50,000行;
  DatabaseTimeoutを127回、PermissionDeniedを3回検出;
  完全な内容:artifact://logs/run-103

AnthropicのContext EditingとTool-result Clearingはこの系統です。2 ツール集約型Agentで大きな効果があり、LLMなしでも意思決定の軌跡を保てます。ただし、ツールがなお利用可能で、同じ入力から同等の結果を得られ、再取得コストが許容でき、データ源が残る場合にのみ低損失です。リアルタイム価格、一回限りの認可、短命のWebページ、不可逆取引結果は回復できないことがあります。

3.4 大きな内容をArtifactへ外部化する

大きな対象を最初から主コンテキストに入れません。200 MBのログをファイル、object store、databaseに保存し、ID、型、サイズ、構造化統計、少量preview、利用可能なqueryだけを置きます。

artifact_id: "artifact://pytest/run-20260726-103"
type: "test_log"
lines: 58321
summary:
  passed: 128
  failed: 2
failures:
  - test_refund_timeout
  - test_duplicate_webhook
available_operations:
  - grep
  - read_lines
  - download

OpenAIは、大きなresourceをcontainer filesystemまたはdatabaseに置き、Agentが必要に応じてファイルを開きqueryを実行する方式を推奨しています。3 コード、端末ログ、ブラウザページ、PDF、DB結果、大きなJSON、画像、スクリーンショットに適しますが、Artifact Store、アクセス制御、ライフサイクル管理、安定した参照が必要です。

3.5 ローリング構造化要約

安定したheadを原文のまま残し、古いmiddleの軌跡をcheckpointへ圧縮し、最近のraw tailを残します。

System Prompt
+ 初期タスク / 重要制約
+ Structured Checkpoint
+ 最近の原文メッセージ

LangChain v1のSummarizationMiddleware、Google ADKのContext Compaction、Hermesのdefault compressorはこの設計です。1 4 5 目標、決定、進捗、未完了作業を維持しながら大きく縮められますが、本質的に有損で、追加LLMを要し、数値・path・error・境界条件を落とし得ます。要約の再要約はdriftも招きます。

checkpointにはhistorical_taskgoalconstraintscompleted_actionsactive_stateblockedkey_decisionsresolved_questionsrelevant_filescritical_contextremaining_worksource_refsなどを推奨します。「少し変更し、問題が少し残る」という散文では不十分です。

3.6 タスク認識型圧縮

単に履歴を要約させるのではなく、現在のタスク、いま答えるべき問い、確認済み事実、未確定事項、改変禁止のfield、将来追跡すべきsourceを入力します。情報密度が上がり、既知・未知・衝突・次の行動を分けられるため、Deep Research、調査、debug、受入基準が明確なCoding Agent、長い業務処理に向きます。一方、短期目標に過剰適合し、タスク変更後に削除済み情報が再び重要になる危険があります。

3.7 引用付き・追跡可能な要約

重要な事実ごとにsource handleを残します。

facts:
  - claim: "サービスは14:32以降timeoutを起こし始めた"
    source_ids:
      - "artifact://logs/prod-103#L820-L912"
    confidence: high
    verified: true

要約自体は有損でもsource indexは可能な限り無損です。企業RAG、法務、金融、研究、運用、データ分析など、citationとauditが必要な場面に向きます。stable Artifact ID、権限、保持が必要で、引用があることは要約の正しさを保証しません。

3.8 ベンダー提供のネイティブCompaction

OpenAI。 Responses APIはresponses.compactによるネイティブcompactionを提供し、Agents SDKのOpenAIResponsesCompactionSessionが利用します。type=compaction itemには不透明なencrypted_contentが入ることがあり、Codexは長時間coding taskの継続にこの機構を使います。3 6 7 モデル訓練と内部状態に適合し実装コストも低い一方、監査が難しくvendor lock-inがあります。低遅延用途では、stream終了を阻害し得る自動圧縮より、idle時またはturn間の手動圧縮が適することがあります。

Anthropic。 Anthropicは長い会話でserver-side Compactionを推奨し、再送可能なcompaction blockを生成します。Context Editingはツール結果など特定内容を細かく扱います。これらはbetaであり、現在の公式資料を確認すべきです。8 2 server側token計算、明示的message type、要約指示のカスタマイズを得られますが、有損でありAPI変更の可能性があります。default promptを完全に置き換えるなら、開発者が完全な保持規則を用意しなければなりません。

単一vendorに深く結び付き迅速に導入したいならnative compactionを先に評価します。監査、cross-vendor、厳密なfield制御が必要ならclient-side structured checkpointを使います。clientがcanonical stateを維持し、providerがmodel trajectoryを管理する併用も可能です。

3.9 TokenレベルPrompt Compression

LLMLingua、LongLLMLingua、LLMLingua-2は、新しい要約を書くのではなく、低情報量のtokenやphraseを削除・並べ替えます。

original:   The system encountered a very serious database connection timeout.
compressed: system encountered serious database connection timeout

LLMLinguaは小型言語モデルでtoken重要度を評価し、LLMLingua-2はtoken classificationとして圧縮を扱います。9 10 自然言語のRAG背景、議事録、原文へ戻れる資料には使えますが、否定、限定、正確な数値を落とし、JSON、コード、SQL、tool parameterを壊す恐れがあります。2026年の大規模実測は、入力長、圧縮率、hardwareが一致するときだけend-to-end加速が得られ、他ではcompressorのoverheadが利得を相殺し得ると示しました。11

Tool Call JSON、Tool Resultの構造field、コードとSQL、UUID、hash、path、port、安全方針、hard business constraint、金額、日付、法的文言は、専用評価なしに圧縮してはいけません。

3.10 子Agentによるコンテキスト隔離

これは事後圧縮というより、ノイズを主コンテキストに入れない方法です。検索子Agentが多数のファイルを読みgrepを実行し、入口ファイル、重要関数、call site、test位置、confidenceだけを返します。主Agentは高密度の結論だけを扱えます。コード検索と複数sourceの調査に特に有効ですが、完全なtask説明、追加モデル呼び出し、reportの漏れ、より複雑なschedule・timeout・error処理を要します。

4. 比較

手法損失追加LLM圧縮力主なリスク適する場面
Sliding window高いなし重要履歴を失う単純chat、最後のfallback
決定的filter低いなし低〜中ruleの誤削除全Agentの第1層
Tool-result cleanup条件付きで低損失なし高い再取得不能tool-heavy Agent
Artifact外部化低いなし非常に高い参照切れfile、log、page、image
構造化ローリング要約あり非常に高い漏れとdrift汎用長時間Agent
タスク認識要約中〜高あり非常に高いtask切替で不足research、debug、coding
引用付き要約比較的低いあり中〜高基盤の複雑さenterprise、audit
Native compaction実装依存server側非常に高い不透明性、lock-in単一vendorの長タスク
Token-level圧縮小型model高い厳密構造を壊す自然言語RAG
子Agent隔離低いあり非常に高いreport漏れcoding、Deep Research

5. 本番の最適解:一つを選ばず階層pipelineを設計する

完全な原始軌跡 / Artifact Store
1. Admission Control:大きな内容を入口で外部化し、構造化previewを返す
2. Deterministic Cleanup:重複除去、ノイズ削除、再取得可能なtool resultの整理
3. Canonical State Projection:TODO、count、phase、verificationをコードで保持
4. Structured Compaction:古いmiddleをtask checkpointへ
5. Recent Raw Tail
6. LLM

モデルのコンテキストを唯一の事実源にしてはいけません。PostgreSQL、LangGraph State、Redisなどに決定的で検証可能なcanonical stateを置き、完全なartifactを別に保存し、簡潔なactive projectionだけをモデルへ渡します。

順序はcheap-firstです。重複除去、明確なノイズ削除、大対象の外部化、tool resultの降格、state bar、LLM要約、全量Compaction。要約は結論を保つ一方、最新対話の微妙な語調、指示対象、暫定状態は苦手なので、最近のraw tailを常に残します。tool callとresultは完全なgroupで保持します。

50%、70%、80%を固定値として写してはいけません。安全なtriggerは、context window、予約output、想定tool burst、safety margin、system promptとtool schema、multimodal添付、vendor replay fieldを考慮します。hysteresis、圧縮後のtarget水位、minimum reclaim、cooldown、無効圧縮circuit breakerも設定します。

圧縮はatomicに行います。messageを複製し、複製上で圧縮し、checkpointとmessage構造を検証してから一度にcommitします。失敗したら原sessionを残し、alert、cooldown、summary model切替を行います。path、URL、UUID、commit hash、issue番号、DB primary key、金額、日付、port、完全なerror code、test名、versionなどの厳密identifierは、free-form要約に任せず、コードで抽出・構造化保存するか原文保持します。履歴要約には時刻とtask境界を付け、最新の実ユーザーmessageを最高権威にします。

6. Hermes Agent:階層圧縮の実例

6.1 差し替え可能なContext Engine

Hermesはコンテキスト管理をContextEngineとして抽象化します。defaultは有損のContextCompressorで、LCMなど別engineはpluginで明示的に選びます。モデルごとのwindowやcache特性、監査・保真性の要求、戦略の独立評価と置換を考えると、agent loopへ圧縮を固定で書くより合理的です。5

6.2 二層のtrigger

公式資料は、Agent処理前に約85%で働くGateway Session Hygieneの安全網と、Agent Loop内で実API tokenを使い、文書上のdefaultが50%のContextCompressorを説明します。しかし「default 50%」は全modelの実際の圧縮点ではありません。現行資料とsourceには、modelごとのoverride、512K未満windowでのraise-only 75% floor、特定Codex routeの自動調整、Codex app-serverのnative thread compactionがあります。5 12

6.3 現行sourceの決定的な事前圧縮

LLM要約の前に、現行mainはbyte完全一致のtool resultを重複除去し、古い巨大resultをtool固有の1行要約にし、terminal command、exit code、line数、file path、read offset、content size、search条件、hit数を保持します。巨大なTool Call parameterはJSONを有効に保って切り詰め、深刻なpressure下では保護tail内の完了済み巨大outputも降格し、古いimageをplaceholderへ置換し、trimされたSkillには決定的reload markerを挿入します。12

6.4 Head / Middle / Tailと境界付き要約入力

Hermesはsystem promptと初期anchorをheadとして原文保持し、古いtask軌跡のmiddleを要約し、token budgetと最小message数で最近tailを保護します。境界はtool callとresultのpairを保つようにします。現行mainは無制限のmiddle全体を要約modelへ送らず、各message本文とtool-call argumentをtruncateし、要約用全sequenceを約160,000文字に制限しつつ先頭・末尾を残して省略印を付けます。要約は圧縮内容の約20%を目標とし、output上限は旧12,000ではなく現在10,000 tokenです。12

6.5 Agent handoff、旧タスクの再起動防止、失敗処理

Historical Task SnapshotはGoal、Constraints & Preferences、Completed Actions、Active State、Blocked、Key Decisions、Resolved Questions、Relevant Files、Critical Context、Pruned Skillsを含み、具体的path、commandと結果、test通過・失敗数、error、技術判断、環境・process、Skill reload指示を重視します。12

要約はREFERENCE ONLYと印付けされます。最新の実ユーザーmessageだけが現在タスクの権威であり、過去に完了した要求を再実行してはいけません。新しいstopundonever mindは古いplanを止めます。task anchorは例や要約からでなく、実ユーザーmessageから決定的に抽出されます。

次回Compactionでは旧要約と新しい完了作業、error、verificationを合わせ、進行中を完了へ移し、古い状態を更新します。現行sourceには、圧縮境界のredaction、URL credentialとsecretの除去、inline thinking除去、空要約検出、認証・network等の失敗時abort、cooldown、fallback count、anti-thrashing、providerの実tokenによる事後検証、tool call/resultのorphan cleanupがあります。12

長所はcheap-first、対象を絞ったtool result降格、最近軌跡の原文保持、構造化handoff、cache考慮、model別threshold、交換可能compressor、失敗経路の厚さです。リスクは、構造化要約もなお有損でdriftすること、source更新が高水準文書より速いこと、弱い補助summary model、巨大な静的system/tool prefix、低すぎるthresholdによる頻繁な圧縮とcache失効です。

7. LangChain v1 / LangGraph v1での実装

7.1 単純な場合:SummarizationMiddleware

from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware
from langgraph.checkpoint.memory import InMemorySaver

agent = create_agent(
    model="gpt-5.4",
    tools=[],
    middleware=[
        SummarizationMiddleware(
            model="gpt-5.4-mini",
            trigger=("tokens", 40_000),
            keep=("messages", 20),
        )
    ],
    checkpointer=InMemorySaver(),
)

これはprototypeと一般chatには適します。本番ではmemoryではなくPostgreSQLなど永続的checkpointerを使うべきです。1

7.2 Tool-heavy Agent:階層custom middleware

from typing import TypedDict


class AgentState(TypedDict):
    messages: list
    active_goal: str
    constraints: list[str]
    todo: list[dict]
    tool_counts: dict[str, int]
    modified_files: list[str]
    verification: dict
    artifact_refs: list[dict]
    compaction_version: int
from copy import deepcopy


def compact_context(messages, state, policy):
    original = messages
    working = deepcopy(messages)
    working = deduplicate_tool_results(working)
    working = externalize_large_payloads(working)
    working = demote_old_refetchable_tool_results(working)
    working = strip_old_images(working)

    if estimate_tokens(working) < policy.trigger_tokens:
        return working

    head, middle, tail = split_head_middle_tail(
        working,
        keep_recent_messages=policy.keep_recent_messages,
        keep_recent_tokens=policy.keep_recent_tokens,
        preserve_tool_pairs=True,
    )
    try:
        checkpoint = summarize_middle(
            middle=middle,
            canonical_state=state,
            required_exact_fields={
                "paths", "ids", "hashes", "errors", "test_names", "amounts", "dates",
            },
        )
        validate_checkpoint(checkpoint, state)
    except Exception:
        return original

    compacted = sanitize_tool_pairs(head + [checkpoint.to_message()] + tail)
    return compacted if estimate_tokens(compacted) < estimate_tokens(original) else original

stateと要約を分離します。tool_counts、verificationの件数、artifact sourceのような信頼できる事実はコードが更新し、要約modelはそれらを非構造化履歴とともに次のターン向けに整理するだけにします。

8. Trigger thresholdの選び方

割合をそのままコピーせず、次のbudgetを使います。

context window
- 最大想定output
- 次ターンで最大のtool result
- system promptとtool definition
- multimodal budget
- safety margin
= 最後に許されるinput水位

real/rough prompt token、static prefix、recent tail、summary、tool result、artifactized tokenを監視し、trigger_tokenstarget_tokens_after_compactionminimum_reclaim_tokenscooldown_secondsmax_compactions_per_taskineffective_compaction_limitを設定します。

9. 圧縮システムの評価

圧縮率だけを測ってはいけません。タスク完了率、次の行動の一致、元のユーザー目標・安全制約・業務制約・未完TODO・失敗案の保持、厳密ID/path/hashの忠実性、citationの追跡性、圧縮後の重複tool call、多回圧縮後のdriftを測ります。入力token、Compaction自身のcost、first-tokenとend-to-end遅延、Prompt Cache、Artifact再取得、100ターン当たりの圧縮回数、無効圧縮、失敗とfallback比も測ります。

summary model timeout、空のsummary、429/ quota不足、認証失敗、圧縮後も上限超過、tool call/resultの切断、最新ユーザーの「停止」と旧要約の実行中taskの衝突、summary中secret、繰返し要約によるcommit hash改変、削除済みresultの再取得不能、画像/Base64の反復流入を必ず試験します。

10. 選択ガイド

通常chat:最近messageのtrim + 軽量rolling summary + session database
Coding Agent:file/logのArtifact化 + tool result降格 + 構造化task checkpoint
             + path/hashのプログラム保存 + 検索子Agentの隔離
Deep Research:検索結果の外部化 + task-aware要約 + 各factのsource
               + retrieval子Agent隔離 + 必要に応じnative Compaction
高リスク業務:Canonical State database + Event Log + 監査可能な構造化要約
             + Tool Result参照 + コード層hard constraint
低遅延real time:決定的cleanup優先 + idle時Compaction + 小さいrecent tail

11. 以前の説明への修正

現行の証拠により、Hermesの50%は普遍的triggerではないこと、旧tool outputを汎用placeholderへ替えるだけではないこと、要約inputには境界がありoutput ceilingは12Kでなく10Kであること、失敗時にmiddleを黙って捨てるという表現は不正確なこと、Tool-result Clearingは天然に無損ではないこと、native Compactionの不透明性はvendorごとに異なること、研究上のPrompt Compression高速化は本番性能の約束ではないこと、Google ADKがtokenとevent-window両方を支援していることを明確にすべきです。

12. 最終提案

1. 原始データ全体をPromptの外に保存する。
2. 大きなtool resultを入口からArtifact化する。
3. 重複除去、ノイズ削除、Canonical Stateはコードで扱う。
4. 古く再取得可能なtool resultを降格する。
5. 測定済みthresholdで構造化task checkpointを作る。
6. 最近のraw tailを残す。
7. 要約にsource handleを付け、厳密identifierを守る。
8. 圧縮失敗時は元sessionを保持する。
9. hysteresis、cooldown、無効圧縮circuit breakerを使う。
10. 圧縮率でなくタスク成功率で評価する。

モデルに帳簿全体を背負わせないでください。信頼できる現在状態、再取得可能な証拠index、そして十分に完全な最近の現場を渡してください。

参考資料

確認日:2026-07-26。Agent API、model、frameworkは急速に変化するため、本番導入前にvendor公式資料と固定した依存versionのsourceを再確認してください。