1:1 mentoring with Big Tech AI engineers
Back to blog
By AgenticPrep TeamUpdated 10 min read

Context Engineering — Managing the Model's Working Memory

Prompt engineering tuned one message. Context engineering decides what is in the window on every call of a long agent run, and on current Claude models it does that without ever rewriting history.

context-engineeringcontext-windowagentsprompt-caching
Key idea

The model reads its whole context window again on every call, and an agent's history grows by every step. Context engineering is deciding what goes into each request: the stable parts first so the cache can read them, and one move (select, compress, write or isolate) for each part that grows.

Every call re-sends one request: keep the stable part first, give each growing part one move
ONE REQUEST, IN SEND ORDERONE MOVE PER PART THAT GROWSTool definitionsSystem promptMemory notescache breakpointHistory, append-onlygrows by every stepNewest turntool results, chunks, questionWRITEstate to files, read back on demandCOMPRESSserver compaction, context editingSELECTretrieve the slice this step needsISOLATEsubagent returns a short summaryStable parts first, growing parts last. Nothing already sent gets edited.

Prompt engineering tuned the wording of one message. An agent at step 30 has a different problem: its window is full of old tool output, and no wording fixes that. Anthropic calls the discipline context engineering. It sits between the harness (what the model can touch) and the loop (how the work repeats). The guide's Context Engineering section is the full lesson; this post is the map.

The window is re-read on every call

153.5Kinput tokens read by call 60 alone
4.8Minput tokens across all 60 calls
$9.57uncached input on Sonnet 5.5; $0.85 with caching

6,000 tokens of system prompt and tools, plus 2,500 tokens per step (the call and a whole-file result). Call n reads 6,000 + 2,500 × (n − 1). Sonnet 5.5 list prices of 2026-10-08: $2 per million input, $2.50 cache write, $0.10 cache hit.

The agent loop keeps no state except messages[], and it sends all of it every time. Current models have a 1M-token window, so overflow comes late. The bill and the quality loss come early. This run crosses the default 150,000-token compaction trigger at call 59.

106,00040 whole-file steps: 44,000 below the trigger
156,00060 whole-file steps: 6,000 past it
60,00060 grep-sized steps: well inside it

Interactive: add steps until the run crosses the 150,000-token compaction trigger, then swap whole-file steps for grep-sized ones.

Counts depend on the tokenizer. Claude 4.7 and later models produce about 30% more tokens for the same text than Sonnet 4.6 and earlier. If you measured 2,500 tokens a step on an older model, budget about 3,250 on Sonnet 5.5: a per-token price comparison understates the change.

Context rot: quality drops before the window is full

A full window gets worse before it overflows: the middle is read worst
highlowrecallstart: read wellmiddle: missedend: read wellstart of the contextend of the contextPut the goal and the rules where they are read well. Never bury them mid-window.

Long before a request is too long, it gets worse. Anthropic's docs call this context rot: accuracy and recall fall as tokens accumulate. The best-known measurement is “Lost in the Middle” (Liu et al., 2023): facts placed mid-context were recalled worst. It measured 2023 models, so treat the curve as a shape, not a number; the advice it gives still holds.

The tell

An agent that starts strong and then repeats tool calls, loses the goal or ignores a rule it followed earlier is almost never a model problem. Look at what is in its window before you reach for a bigger model.

Select: retrieve the smallest slice that answers the step

Select: the agent asks for two tables, not the whole schema
assistant
{"type": "tool_use", "name": "describe_table",
 "input": {"table": "orders"}}
stop_reason: "tool_use"
tool
orders(id uuid pk, customer_id uuid fk, status text,
       total_cents int, created_at timestamptz)
Two lines in the window instead of an 8,000-line schema in the system prompt.

Pasting the whole schema, the whole wiki or every file “just in case” is the most common mistake. Give the agent tools that fetch what a step needs, when it needs it: a search, a file read with line ranges, a describe_table. Good tool results are short by design. This is retrieval discipline from RAG, applied inside the loop.

Compress on the server, never by rewriting turns

Rewrite turns yourself the old habit
  • delete old tool results, summarise turns 1–40 in place
  • a 400 on the newest models (Fable 5.1, Opus 5.5) for accounts created on or after 2026-08-31
  • the cache misses from the edit onward
Let the server compress compaction, context editing
  • you send the history exactly as it grew
  • compaction summarises older turns into one block
  • context editing clears finished tool results and old thinking

Rule of thumb: on current Claude models, history is append-only. Shrinking it is the server’s job.

import anthropic

client = anthropic.Anthropic()
resp = client.beta.messages.create(
    model="claude-opus-5-5",
    max_tokens=16000,
    betas=["compact-2026-01-12"],
    context_management={"edits": [{"type": "compact_20260112"}]},
    tools=TOOLS,
    messages=messages,
)
# Append ALL of content: it can carry a compaction block.
messages.append({"role": "assistant", "content": resp.content})
if resp.stop_reason == "tool_use":
    messages.append({"role": "user", "content": run_tools(resp.content)})
elif resp.stop_reason != "end_turn":     # max_tokens, pause_turn, refusal
    handle_stop(resp)

Threshold compaction fires at 150,000 input tokens by default (minimum 50,000). The docs now recommend the on-demand variant (beta compact-2026-09-04) where it is available: your code picks the moment, and it can keep recent turns word for word.

The trap is appending only the text: the compaction block rides in resp.content, and dropping it makes the agent forget silently. Writing your own summary is still valid on other providers, or by starting a new conversation from it. The details, including what compaction costs, are in Context Management.

Write durable state outside the window

  1. Plan to a fileThe agent writes the checklist to MIGRATION.md.
  2. Do one itemOnly that item’s files enter the window.
  3. Tick it offProgress lives on disk, not in history.
  4. Read the next itemNever the record of everything already done.

The window is working memory: fast, small and gone when the session ends. Anything that must outlive it goes outside: a plan file, a task list, a CLAUDE.md of project conventions, or the API’s memory tool, which lets Claude read and write files you store. The window stays lean because the memory is not in it. Which kind of memory lives where is in Agent Memory.

Isolate side work whose output dwarfs its answer

40files the subagent reads in its own window
12lines of call sites it returns to the parent
~15×tokens of chat for multi-agent systems (Anthropic, 2025)

“Find every call site of the deprecated auth() helper” runs in a subagent with a fresh window. The parent sees the list, never the files. Isolation buys a clean window, not a cheaper task: Anthropic’s research system used about 15 times the tokens of a chat. Use it where the main window would otherwise flood, as in Hierarchical Delegation.

Order the request for the cache

ChangeEffectDo this
A timestamp in the system promptmisses on every callput it in the newest turn
An edit to an earlier turnmisses from the editappend a turn instead
A tool added mid-sessionthe whole cache missesfreeze tools at start

The cache matches a prefix in one order: tools, then system, then messages. One changed byte invalidates everything after it. That is why the hero puts the stable sources first. On Sonnet 5.5 a cache hit costs 0.05× of input, which is how the run above drops from $9.57 to $0.85. Check usage.cache_read_input_tokens on every call; the mechanics are in Prompt Caching.

Worked example: a refactor at call 60

Without the moves 2,500 tokens a step
  • call 60 reads 153.5K tokens, mostly stale file dumps
  • crosses the compaction trigger at call 59
  • 4.8M input tokens: $9.57 uncached, $0.85 cached
  • re-reads auth.ts a third time and redoes the login flow
With them 900 tokens a step
  • grep finds 12 call sites; the subagent did the search
  • call 60 reads 59.1K tokens; no compaction needed
  • 2.0M input tokens: $3.91 uncached, $0.34 cached
  • progress lives in MIGRATION.md: login and signup done

Same model, same task. The only difference is what was allowed into the window.

Input only, Sonnet 5.5 list prices of 2026-10-08, each call writing its new tail to the 5-minute cache and reading the rest. Per-step sizes are illustrative.

Common mistakes

Treating a 1M window as permission to stuff it. Appending resp.content[0].text after enabling compaction. Clearing tool results every turn “to save tokens”, which turns every request into a cache write. Quoting token budgets measured on an older tokenizer.

Interview angle

“The agent’s context window is full after 10 tool calls. What do you do?” Name the source that grew, then the move: shorter tool results (select), server-side clearing or compaction (compress), a plan file (write), a subagent (isolate). Say that you never edit sent history on current models, and that caching fixes the bill, not the quality.

Check yourself
Your agent is at call 50 on Opus 5.5 and the history is too long. A teammate proposes deleting the oldest 20 tool results client-side. What goes wrong?

On the newest models history is append-only: editing earlier turns invalidates the thinking blocks after them, and accounts created on or after 31 August 2026 get a 400. Even where it is accepted, the prompt cache misses from the edit onward. Use server-side context editing (clear_tool_uses) or compaction instead; the client keeps sending the full history.

Caching cut the run's input bill from $9.57 to $0.85. Is the context problem solved?

No. Caching makes re-reading cheap, not short. The model still reads 153.5K tokens on call 60, and recall still sags in the middle. Cost and quality are separate budgets; select, compress, write and isolate shrink both.

A search over 40 files would add 60K tokens to the main window. Which move, and what does it cost?

Isolate it in a subagent: it burns its own window and returns a short list. The main window stays clean, but total tokens go up, not down (Anthropic measured multi-agent systems at about 15 times the tokens of a chat), so isolate work whose output is much larger than its answer.

Recap
  • Every call re-reads the whole request; history grows by every step, so cost and quality both degrade early.
  • Context rot starts long before overflow: keep the goal and rules where they are read well.
  • Four moves: select what a step needs, compress history on the server, write state to files, isolate side work.
  • History is append-only on current Claude models: compaction and context editing are how it shrinks.
  • Put stable sources first so the cache reads them; caching makes re-reading cheap, not short.

Next: Context Engineering — budget each request type from measured usage, source by source.

Enjoyed this post? The full curriculum has 149 sections, system design problems, and AI-reviewed practice runs.

See the full guide