0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude API の Context Editing で長時間エージェントのコンテキスト溢れを防ぐ実装 — プロンプトキャッシュ破壊と exclude_tools、3つのハマりどころ【2026】

0
Posted at

長時間動かすエージェントを Claude API で組むと、必ず「コンテキストが溢れる」壁にぶつかる。ツールを何十回も呼ぶうちに、過去のツール実行結果が会話履歴に積み上がって入力トークンを食い尽くすやつだ。

この記事では、その対策として用意されている Context Editing(コンテキスト編集) を Python から実装する手順と、自分が実際に踏んだハマりどころをまとめる。

対象と前提

  • 想定読者:Claude API でツール(function calling)を使ったエージェントを実装している人
  • 前提知識:Messages API とツール定義の基本、tool_use / tool_result ブロックの往復が分かること
  • 環境:Python 3.13 / anthropic SDK 0.6x 系 / Anthropic Messages API

ベータ機能なので、ヘッダ名やストラテジの版数文字列(-2025-XX-XX の部分)は更新されることがある。実装前に公式ドキュメントで現行値を確認すること。

TL;DR

  • context_management パラメータで、古い tool_result をサーバー側で自動的に間引ける
  • 入力トークンが閾値を超えたら発火 → 直近 N 回分のツール往復だけ残す、という設定を宣言的に書くだけ
  • ただし プロンプトキャッシュとの相性が最悪。何も考えずに入れるとコストが下がるどころか上がる

実装

最小構成はこれだけ。ベータヘッダを付けて context_management を渡す。

import anthropic

client = anthropic.Anthropic()

CONTEXT_MGMT = {
    "edits": [
        {
            "type": "clear_tool_uses_20250919",
            # 入力が 3 万トークンを超えたら発火
            "trigger": {"type": "input_tokens", "value": 30000},
            # 直近 3 往復のツール結果は必ず残す
            "keep": {"type": "tool_uses", "value": 3},
            # 一度発火したら最低 5000 トークン分はまとめて消す
            "clear_at_least": {"type": "input_tokens", "value": 5000},
            # ツールの「引数」も消すか(既定は False = 引数は残る)
            "clear_tool_inputs": False,
        }
    ]
}

resp = client.beta.messages.create(
    model="claude-sonnet-5",
    max_tokens=4096,
    betas=["context-management-2025-06-27"],
    tools=TOOLS,
    messages=messages,
    context_management=CONTEXT_MGMT,
)

消された分は本文が [cleared] 相当のプレースホルダに置き換わり、モデルには「ここは消した」という事実が伝わる。何回・何トークン消えたかはレスポンス側で取れる。

info = getattr(resp, "context_management", None)
if info and info.applied_edits:
    for e in info.applied_edits:
        print("cleared:", e.type, getattr(e, "cleared_tool_uses", None))

自分はこれをループの毎ターンでログに落として、どのタイミングで刈り取りが走ったかを追えるようにしている。

ハマりどころ 1:プロンプトキャッシュが毎回壊れる

これが一番痛かった。プロンプトキャッシュは「プレフィックスが完全一致していること」が条件で、会話の途中にある古い tool_result を消すと、そこから後ろのキャッシュが全部無効になる。

つまり刈り取りが走るたびにキャッシュミスが発生し、キャッシュ書き込み料金(通常の 1.25 倍)を払い直すことになる。小刻みに発火させると、削減した入力トークン以上に書き込みコストが乗る。

対策は clear_at_least を大きめに取ること。「発火したら最低これだけまとめて消す」という下限を設けて、刈り取り回数そのものを減らす。自分は trigger を高め(3 万〜5 万)・clear_at_least を 5000 以上にして、1 セッションで数回しか走らない設定に落ち着いた。ちまちま消すのが一番損。

ハマりどころ 2:残したいツール結果まで消える

keep は「直近 N 往復」という時間軸の指定でしかない。エージェントの序盤で読んだ仕様書やタスク定義が、いちばん重要なのに真っ先に消える、という事故が起きる。

{
    "type": "clear_tool_uses_20250919",
    "trigger": {"type": "input_tokens", "value": 30000},
    "keep": {"type": "tool_uses", "value": 3},
    # このツールの結果は刈り取り対象から除外する
    "exclude_tools": ["read_spec", "get_task_definition"],
}

exclude_tools にツール名を並べると、そのツールの tool_result は何ターン前だろうと残る。設計としては「消えても後から取り直せるツール」と「消えたら詰むツール」を最初に仕分けしておくのが正解だった。ファイル読み込み系は消してよく、ユーザーの指示や外部から一度きりで取得した値は残す。

ハマりどころ 3:extended thinking と併用すると挙動が読みにくい

thinking を有効にしていると、ツール往復の間に thinking ブロックが挟まる。ここで注意なのは、thinking ブロックは clear_tool_uses の対象ではないこと。消えるのはあくまで tool_result(と設定次第で tool_input)で、思考ブロックはそのまま残る。

「トークンが減るはずなのに思ったほど減らない」と悩んだら、内訳を疑ったほうがいい。自分は count_tokens で刈り取り前後を実測して、thinking が残っていることに気付いた。

# 刈り取り前後の入力トークンを比較する
python3 measure_context.py --before --after

thinking 側を減らしたいなら thinking.budget_tokens を絞るか、ツール往復が長引く設計自体を見直すことになる。別レイヤーの問題として切り分けるのが早い。

動作確認

検証は「わざと溢れさせる」のが手っ取り早い。数 KB のダミーテキストを返すだけのツールを 1 つ用意して、それを 10 回連続で呼ばせるループを回す。

  • trigger を 5000 くらいに下げておく
  • 毎ターン resp.usage.input_tokens を出力する
  • applied_edits が出たターンで入力トークンが階段状に落ちれば成功

自分の環境では、7 ターン目で発火して入力が約 4 割落ちた。閾値を跨いだ瞬間にガクッと下がるグラフが出れば、設定は効いている。

まとめ

  • Context Editing は context_management を渡すだけで、古いツール結果をサーバー側で自動的に間引ける
  • プロンプトキャッシュと同時に使うなら clear_at_least を大きく取り、刈り取り回数を減らす。小刻みな発火は逆効果
  • keep は時間軸でしか守れないので、消えたら困るツールは exclude_tools で明示的に除外する
  • thinking ブロックは刈り取られない。減らないときは内訳を実測して切り分ける
  • 検証はダミーツールで意図的に溢れさせ、applied_editsinput_tokens の階段を見るのが確実
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?