If your long-running agent gets slower and dumber the longer it runs, the cause is almost never the model — it's that the context window has filled with stale tool output the model now has to read past on every turn. Context editing fixes this at the API level: it clears the oldest tool results server-side when the window fills, keeps the tool calls and the most recent results, and does it without you writing any client-side stripping logic. Here is the exact configuration, the two parameters that decide whether it helps, and the one mistake that silently doubles your bill.

The minimum working config#

Add one beta header and one context_management block. This is the whole thing:

response = client.beta.messages.create(
    model="claude-opus-5",
    max_tokens=4096,
    system=SYSTEM_PROMPT,
    tools=tools,
    messages=messages,
    betas=["context-management-2025-06-27"],
    context_management={
        "edits": [
            {
                "type": "clear_tool_uses_20250919",
                "trigger": {"type": "input_tokens", "value": 100_000},
                "keep": {"type": "tool_uses", "value": 3},
                "clear_at_least": {"type": "input_tokens", "value": 10_000},
                "exclude_tools": ["memory"]
            }
        ]
    }
)

That's it. When the accumulated input crosses 100,000 tokens, the API removes the oldest tool results, keeps the 3 most recent, replaces the cleared ones with a short placeholder, and guarantees each clearing event frees at least 10,000 tokens. The model still sees that a tool was called and that its output was removed — so it can simply call the tool again if it needs the data back. Nothing about your message-building loop changes.

The two parameters that actually matter#

Everything hinges on keep and clear_at_least. Get these wrong and context editing either does nothing or costs you money.

keep is how many of the most recent tool results survive every clear. Too low and you evict results the model still needs this turn, forcing redundant re-fetches; too high and you never free enough to matter. Three to four is the sane default for a search-heavy agent — enough that the current line of reasoning stays intact, low enough that a 40-turn history doesn't.

clear_at_least is the floor on how many tokens a single clear must free before it's allowed to fire. This is the parameter people skip, and skipping it is the expensive mistake below.

The mistake: forgetting that every clear re-writes your prompt cache#

Context editing is not free. Clearing tool results changes the prompt prefix, which invalidates the prompt cache from the clear point forward — the next call has to re-write those cached tokens. If you leave clear_at_least unset or tiny, clears fire on almost every turn and free only a few thousand tokens each time, and you pay the cache-rewrite penalty over and over for a rounding-error of savings.

clear_at_least exists precisely to stop this. Setting it to 10_000 means a clear won't fire unless it can free at least 10k tokens — enough that the tokens you save on input comfortably outweigh the one-time re-write cost. Rule of thumb: set clear_at_least to a multiple of your typical tool-result size, so each clear removes several results at once rather than trickling one out per turn.

Wire it to memory, or you'll clear away facts you needed#

Context editing only manages the live window. It cannot make a fact survive a context reset, and it will happily evict a tool result that contained the one number your agent needed three turns later. That's why the config above sets exclude_tools: ["memory"] — it tells the clearer never to touch memory-tool results — and why you should have the agent write durable specifics to the memory tool before they age out:

MEMORY_TOOL_SPEC = {"type": "memory_20250818", "name": "memory"}
tools = BASE_TOOLS + [MEMORY_TOOL_SPEC]
# The memory tool needs no beta header and no context_management entry.
# Facts written here live in files OUTSIDE the window and persist across resets.

The division of labor is the whole game: context editing drops re-fetchable tool output, the memory tool preserves the handful of facts that must not be lost, and compaction (a separate compact-2026-01-12 beta) summarizes the transcript when even the trimmed window gets long. We took apart when to reach for each — and the eval numbers behind the choice — in Context editing vs compaction vs the memory tool.

Verify it's working: read the response back#

Don't assume clears are firing. Every response reports what it did — inspect it:

cm = response.context_management
if cm and cm.applied_edits:
    for edit in cm.applied_edits:
        print("cleared tool uses:", edit.cleared_tool_uses)
        print("freed input tokens:", edit.cleared_input_tokens)

If applied_edits is empty on a long run, your trigger is higher than your traffic ever reaches — lower it. If clears fire every turn and cleared_input_tokens is small, your clear_at_least is too low — raise it. Tune from these two readings and nothing else; they tell you exactly whether the trade you're making is paying off.

The starting point that works: trigger 100k, keep 3, clear_at_least 10k, exclude_tools: ["memory"], memory tool attached and written to on every durable fact. Ship that, watch applied_edits for a day, and adjust one parameter at a time.