The short version: A long-running agent does not fail because the model got weak — it fails because its one shared context window fills with stale tool output until the model can no longer see what matters. Anthropic ships four first-party levers for that, and the common mistake is treating them as competitors and picking one. They are a division of labor, and you wire all four into a single loop. Order them by what a loss costs you: subagents keep bulky separable work out of the window entirely, context editing evicts the cheap re-fetchable tool results that do land, compaction compresses the coherent thread when even that fills, and the memory tool persists the specifics you cannot afford to lose — written before compaction can summarize them away. Isolate, edit, compact, persist. This is the how-to companion to our two comparison pieces: context editing vs compaction vs the memory tool and subagents vs compaction — where those draw the lines, this one wires them together.

The one rule: order by cost of loss#

Every lever throws something away. Sort them by how much the loss hurts, cheapest first, and the composition writes itself:

  1. A subagent loses nothing from the orchestrator — the bulky work happens in a separate window and never arrives. Cheapest, so it runs outermost.
  2. Context editing loses old tool results, which are re-fetchable. Cheap, because the agent can just call the tool again.
  3. Compaction loses verbatim detail — it summarizes and the specifics the summary omits are gone. Lossy, so it runs last among the in-window levers.
  4. The memory tool loses nothing — it writes outside the window — but it costs a tool round-trip. It runs across the other three: persist the irreplaceable before compaction reaches it.

Hold that order in mind and the code is mechanical.

1. Isolate the bulky work in a subagent#

The orchestrator should never let a research sweep or a file exploration dump its intermediate results into the shared window. Hand it to a subagent: it gets a genuinely fresh window, does the work, and returns only its final message. In the Claude Agent SDK you declare subagents as an agents map and expose the Agent tool so the parent can delegate.

import { query } from "@anthropic-ai/claude-agent-sdk";

const result = query({
  prompt: "Audit the repo for unhandled promise rejections and summarize.",
  options: {
    // Each value is an AgentDefinition. `description` tells Claude when to
    // delegate; `prompt` is the subagent's system prompt. The ONLY channel from
    // parent to child is the Agent-tool prompt string — pass paths + decisions in it.
    agents: {
      "code-scout": {
        description: "Explores the codebase and returns a short findings list. Use for any broad file sweep.",
        prompt: "You are a code scout. Search thoroughly, return only a ranked findings list — no raw file dumps.",
        tools: ["Grep", "Read", "Glob"],
      },
    },
    // The parent needs the Agent tool to invoke a subagent at all.
    allowedTools: ["Agent", "Read", "Write"],
  },
});

The scout can read fifty files; the orchestrator's window sees one clean paragraph. (Note the rename: the delegation tool was Task before Claude Code v2.1.63 and is Agent after — match both if you detect delegations.)

2. Evict re-fetchable tool results with context editing#

For the tool output that does land in the main loop — a big API response, a long log — turn on context editing so the API clears old results as the window fills. It keeps the most recent N, replaces older ones with a placeholder (so the model knows a call happened), and the result stays re-fetchable.

resp = client.beta.messages.create(
    model="claude-opus-4-8",
    betas=["context-management-2025-06-27"],
    context_management={
        "edits": [{
            "type": "clear_tool_uses_20250919",
            "keep": 3,            # keep the last 3 tool results verbatim
            "clear_at_least": 5000,  # don't fire unless it frees ≥5k tokens
        }]
    },
    tools=tools,
    messages=messages,
)

The clear_at_least guard matters: clearing rewrites the cached prompt prefix and invalidates the cache, so you only want it to fire when it frees enough tokens to be worth the re-write.

3. Persist the irreplaceable to memory — before compaction#

This is the highest-leverage line in the whole loop. Compaction is lossy; anything it summarizes away is gone. So the moment the agent learns a specific it must not lose — an account id, an exact number, a decision — it writes that to a memory file, which lives outside the window and survives every reset.

# The memory tool is just another tool the model can call. Enable it, and instruct
# the agent to write durable facts as it goes — do NOT wait until the window is full.
tools = [{"type": "memory_20250818", "name": "memory"}, *your_tools]

SYSTEM = """When you learn a fact that must survive a context reset — an id, an exact
figure, a firm decision — immediately write it to /memories/facts.md with the memory
tool. Assume the transcript will be summarized and the specifics dropped."""

Sequence is everything: memory-write then compaction. Anthropic's own cookbook kept 3 of 3 high-level facts through a compaction pass but 0 of 3 obscure ones — persist the obscure ones first and the summary is free to drop them.

4. Let compaction compress the coherent remainder#

With subagents keeping bulk out, editing evicting the cheap losses, and memory holding the irreplaceable, compaction has the easy job: summarize the long, coherent reasoning thread when the window still fills. In the SDK it is a server-side setting — no client-side summarization bookkeeping.

context_management={
    "edits": [
        {"type": "clear_tool_uses_20250919", "keep": 3, "clear_at_least": 5000},
        {"type": "compact"},   # summarize the transcript when the window fills
    ]
}

Do not pick one lever. Assign each loss to the mechanism whose loss is cheapest — and write the specifics to memory before compaction can summarize them away.

Wire it together#

The finished shape of a long-running agent: an agents map plus the Agent tool so bulky subtasks run isolated; a context_management block that first clears re-fetchable tool results and then compacts the coherent thread; and a memory tool with a system instruction to persist irreplaceable specifics as they appear. Four levers, one loop, configured together. The composition — not any single lever — is why Anthropic's numbers move from 29% with editing alone to 39% once memory joins it. Start with the memory instruction; it is the cheapest change and the one that stops the most painful failure, the agent that forgets the one fact it needed.