📒 problems 📖 glossary
Mock interview
46:30
ready
of 46:30
Lesson 77 · AI-product eng

Token budgets, caching, compaction

📖 Walk me through it — plain English

Let's define the words first. A large language model (LLM) is the AI behind tools like ChatGPT or Claude. Every time you talk to one, you send it text and it sends text back. The model doesn't read words — it reads tokens, which are chunks of text roughly the size of a syllable or short word (about 0.75 tokens per English word). The context window is the total pile of tokens the model can hold in its "working memory" at once — today that's around 200,000 tokens, which sounds enormous but fills up fast in a long conversation.

Here is the single most important fact to internalize, the on-ramp for everything below: the model only knows what is in its context window right now. It has no memory of your last conversation, no live access to your database, no idea what your code looks like — unless those things are sitting in the tokens you sent this turn. The window is a fresh desk wiped clean before every call, and you re-place onto it exactly the papers the model needs. So your job is curation: decide what to put on the desk, in what order, and what to leave off. That curation discipline has a name — context engineering: the practical craft of deciding what text to feed the model, in what order, so the result is cheap, fast, and accurate.

People often confuse this with prompt engineering, so let's separate them. Prompt engineering is about wording a single instruction well — phrasing the question, giving a role ("you are a careful editor"), asking for a specific format. Context engineering is the bigger discipline of assembling the whole pile of tokens around that instruction: which documents, which past turns, which examples, which tool outputs, and how they're ordered and trimmed. Prompt engineering is one ingredient; context engineering is the whole plate. It's "unglamorous" because it isn't a clever algorithm — it's the production discipline that turns a flashy demo into something you can actually afford to run for thousands of users. Anthropic asks about it directly for AI-product roles because two of the biggest levers here — prompt caching and compaction — are things they invented.

A quick tour of the parts of the pile, since the rest of the lesson uses these words. A system prompt is the standing instructions you set once — the model's role, rules, and tools; it usually comes first and rarely changes. The user prompt is the actual request for this turn — it changes every call. Tool results are text the model gets back after it calls a function you gave it (a database row, an API response, a file's contents); those land back in the context window and count toward the budget like everything else. Memory is any durable note you choose to carry forward across turns or sessions — a user's name, a decision made earlier — which you must explicitly re-inject, because the model won't remember it on its own.

Here's the everyday analogy. Imagine you're a lawyer briefing a busy expert who bills by the minute. Every page you hand them costs money, and the expert can only truly focus on so many pages before their attention gets fuzzy. So you don't dump the entire case file on their desk every meeting. You keep a fixed cover sheet they've already memorized (cheap to "re-read"), you hand over only the two pages relevant to today's question (not the whole 50-page contract), and when the meeting log gets too long you replace old back-and-forth with a one-paragraph summary. That is exactly what these techniques do for an LLM.

The four big moves the lesson lists map cleanly onto that:

  • Cache the stable prefix. Prompt caching means "save the work of reading a chunk of tokens so you don't pay to re-read it next call." If the unchanging part of your prompt — the system instructions, the tool definitions, the long background doc — always comes first, the model can reuse that prefix from cache at roughly 10% of the normal cost. Only the new bit at the end (the user's actual question) gets charged full price. Order matters: stable stuff first, then the changing user input last. (Caching keys on an exact prefix match, so even one edited word near the top busts the cache for everything after it.)
  • Token-budget your context. Treat tokens like a spending limit. More context is not automatically better — past a point the extra text is noise that drowns out the signal and actually makes answers worse. So you deliberately decide how many tokens each part of the prompt is allowed.
  • Compaction. In a long agent session the conversation eventually outgrows the window. Compaction (also called summarization) = replace the old turns with a short summary of them while keeping the most recent turns word-for-word. It's lossy (you throw away detail) but necessary, like replacing old meeting minutes with a recap.
  • Don't paste, retrieve. Instead of jamming a 50,000-token document into every single turn, store it elsewhere and fetch only the ~2,000 tokens that are relevant right now. That fetch-the-relevant-bit pattern is called RAG (retrieval-augmented generation): you retrieve matching snippets from a store and add them to the context so the model can generate an answer grounded in them. Getting good snippets depends on chunking — splitting big documents into bite-sized pieces ahead of time so you can fetch just the relevant ones instead of the whole file.

One more tool that quietly shapes context: few-shot examples. Instead of describing the format you want, you paste two or three worked input→output pairs right into the prompt; the model imitates the pattern. It's the cheapest way to steer behavior — but each example spends tokens, so it's a budget decision like everything else.

Two more facts worth fixing in your head. Time-to-first-token — how long before the model starts replying — grows roughly in step with how much input you send, because the model must "read" (prefill) all of it first; 100K tokens of input can mean a 5–10 second wait. And context rot: as a context window fills up, the model's overall ability to use it reliably degrades — a close cousin of the lost-in-the-middle effect, where facts placed in the middle of a long context are recalled worse than facts at the very start or very end. So put the important stuff early (or repeat it right next to the question), and keep stale context — outdated docs, resolved sub-tasks, dead tool output — out of the pile entirely.

Why does this matter so much? Because output tokens cost 3–5× more than input, and cached input costs about a tenth of uncached. Put those together and a thoughtful prompt layout can be a 10× difference in your bill per call — real money at scale. That's the "interview tell" at the bottom: when someone asks "how would you make this LLM feature cheaper," a weak answer is just "use a cheaper model." A strong answer names the levers in this lesson — prompt caching, retrieving instead of pasting, compacting long histories, and using small models for the easy sub-tasks.

The unglamorous skill that separates "I built a demo" from "I ran this in production." Context windows are huge but expensive; prompt caching is a 10× cost lever; compaction is required for long sessions. Anthropic specifically probes this for Applied AI / FDE — they invented prompt caching and the agent SDK's compaction.

A concrete example: assembling context for one task

Abstract rules stick better with a worked case. Say you're building a customer-support agent and a user types: "Why was I charged twice in March?" A naive build pastes the entire product manual, the full pricing page, and the whole 80-turn chat history into the window — tens of thousands of tokens, most of it irrelevant, and the actual question buried at the bottom. A context-engineered build assembles only what the task needs, ordered for both caching and attention:

# 1. STABLE PREFIX (cached — pay ~10% after the first call)
#    system prompt: role, tone, refund rules ............ ~800 tokens
#    tool definitions: lookup_charges, issue_refund ..... ~400 tokens
#    1-2 few-shot examples of a good support reply ....... ~600 tokens

# 2. RETRIEVED, TASK-SPECIFIC (changes per task)
#    RAG: the 2 manual chunks about double-charges ....... ~700 tokens
#    memory: this user is on the Pro plan, joined Jan .... ~80 tokens

# 3. RECENT HISTORY (compacted)
#    one-line summary of the older 78 turns ............. ~120 tokens
#    last 2 turns verbatim ............................... ~300 tokens

# 4. THE ACTUAL QUESTION (last, so it has the model's freshest attention)
#    "Why was I charged twice in March?" ................. ~12 tokens

# Total: ~3,800 tokens instead of ~60,000 — cheaper, faster,
# and the answer-relevant facts sit where attention is strongest.

Notice the shape: unchanging things first (so the cache catches them), task-specific retrieved facts in the middle, and the live question last. Then, crucially, the model calls lookup_charges; the resulting rows come back as a tool result appended to the context — more tokens to budget — and on the next turn you'd keep that result only if it's still load-bearing.

The cost/latency math (memorize)
  • Input tokens are cheaper than output; output is 3–5× input cost.
  • Prompt caching: cached input tokens are ~10% the cost of uncached. Cache hits = huge savings.
  • 200K-token context = ~$0.60 input / call at Sonnet-tier; ~$0.06 cached. 10× per call adds up.
  • Time-to-first-token grows ~linearly with input size. 100K context ≈ 5–10s prefill.
Cache the stable prefix

Order: [system + tools + long context] [user input]. The stable prefix caches; only the user-input suffix is uncached per call. Caching matches on an exact prefix, so editing one word near the top busts every cached token after it — keep the volatile parts at the end. Restructuring for cache hits is one of the highest-leverage optimizations.

Token-budget your context

Every byte of context costs money AND attention quality. "More context = better" is false past a point — too much noise drowns the signal. Decide up front how many tokens each section (system, retrieved docs, history, examples) is allowed, and enforce it by trimming or summarizing rather than letting the prompt grow unbounded.

Compaction strategies

Long agent sessions outgrow the window. Compaction = summarize old turns into a shorter summary; preserve recent turns verbatim. It is lossy (detail is discarded) but necessary — trigger it on a token threshold, and keep any facts the agent must not forget (IDs, decisions) in the summary explicitly.

Don't paste, retrieve

Pasting a 50K-token doc into context every turn is wasteful. RAG-retrieve the relevant 2K chunks instead. This requires chunking docs ahead of time and a retrieval step (keyword or embedding search) — the win is you pay for ~2K relevant tokens, not 50K mostly-irrelevant ones, on every turn.

Streaming + cancellation

Stream output tokens to UI as they arrive. Support cancellation server-side — a user who navigates away should kill the LLM call to save tokens.

Measure tokens, not chars

English text ≈ 0.75 tokens per word; code ≈ 0.3 tokens per char; CJK languages tokenize very differently. Use the actual tokenizer for budgeting.

Context rot

Beyond ~50% of the window, attention degrades (the lost-in-the-middle effect: middle positions are recalled worst). Important info should be early or repeated near the question, not buried in the middle. Also evict stale context — old docs, resolved sub-tasks, dead tool output — so it cannot mislead the model.

The core tradeoff: more context vs. relevance, cost, latency

Every decision in context engineering is the same tension. Adding more context can raise accuracy — until it doesn't. The instinct "when in doubt, give the model more" is wrong past a surprisingly low threshold, because three costs all climb at once with input size:

  • Relevance / quality. Irrelevant tokens are not free filler — they actively compete for the model's attention and trigger context rot. A tight, on-topic 3K-token context often beats a bloated 50K-token one on accuracy, not just on price.
  • Cost. You pay per input token every call. Doubling the context roughly doubles the input bill; at scale that is the difference between a viable product and a money pit.
  • Latency. Time-to-first-token rises ~linearly with input, because the model must prefill (read) all of it before emitting word one. Big contexts mean a slow, sluggish-feeling product.

Guidance: default to the smallest context that contains the facts the task needs, then add back only what measurably helps. Reach for retrieval before pasting, summarize history before it overflows, and put the few load-bearing facts where attention is strongest (start and end). Spend your token budget on signal; treat every extra token as guilty until proven useful.

Common pitfalls

  • Dumping everything "just in case." Pasting the whole manual, full chat history, and every tool result into each turn is the most common mistake. It costs the most, runs the slowest, and — because of context rot — often answers worst. Curate; don't hoard.
  • Stale context. Leaving outdated documents, a resolved sub-task's notes, or a tool result that's no longer true in the window will quietly steer the model wrong. Evict context the moment it stops being load-bearing.
  • Busting the cache by accident. Putting anything volatile (a timestamp, the user's name, a request ID) near the top of the prompt invalidates the cached prefix every call. Keep the stable prefix byte-for-byte identical; push the changing parts to the end.
  • Burying the instruction in the middle. The actual ask should sit at the end (or be repeated there), not be sandwiched between long pasted documents where lost-in-the-middle will eat it.
  • Budgeting in characters, not tokens. Code and non-English text tokenize very differently from English prose — measure with the real tokenizer or you'll silently overflow the window.
The interview tell: when asked "how would you reduce cost on this LLM feature," strong candidates name prompt caching, smaller models for sub-tasks, batch APIs, and shorter context — not just "use a cheaper model." Cost optimization is a real engineering skill they grade.

Takeaway: the model only knows what's in its context window, so context engineering is curation — put the right tokens in the right order. Cache the stable prefix (system + tools + long docs first), budget tokens deliberately, retrieve relevant chunks instead of pasting whole documents, and compact long histories before they overflow. Watch the three coupled costs of bigger context — relevance, money, latency — and keep load-bearing facts at the edges, never buried in the middle, never stale.

Go deeper (optional): Anthropic's engineering blog has primers on "prompt caching" and "effective context engineering for agents," and the original "Lost in the Middle" paper (Liu et al., 2023) documents the middle-of-context recall drop across model families.

→ Going deeper: Context engineering assumes you can write tight prompts. See Prompt engineering depth.