Jason McAffee ContextWhat the model is allowed to see

Contextengineering

Prompt engineering was about the words. Context engineering is about everything else that lands in the window on every call, and on a real repo that's the difference between 4.5 million tokens and 8,653.

Jason McAffee  ·  August 2026  ·  about a 14 minute read

everything a coding agent could want
4,563,545tokens, which is 23 context windows and $13.69 a turn
the same task, curated
8,653tokens, 4.3% of one window, 2.6 cents a turn
ratio
527xevery figure measured with cl100k_base over files on this machine

Scroll

01

What context engineering is

Context engineering is deciding what goes into the model's context window on every call, and just as importantly what stays out. That covers the system prompt, the tool definitions, the documents a retriever pulled in, the conversation so far, the notes the agent left itself last time, and whatever the last tool call dumped on the floor. Anthropic's definition is the set of strategies for curating and maintaining the optimal set of tokens during inference, which is a longer way of saying the same thing.

Where the term came from

Tobi Lutke posted it in June 2025, saying he liked context engineering over prompt engineering because it describes the core skill better, which is the art of providing all the context for the task to be plausibly solvable by the LLM. Karpathy agreed a week later and listed what's actually in there, which is task descriptions and explanations, few shot examples, RAG, related data, tools, state and history, compacting, etc. Within a few months it was the word everybody used.

Why it needed a different name

Prompt engineering describes a person typing a request, and in an agent loop almost nothing the model reads was typed by a person. A tool returns 40,000 tokens of JSON, a retriever pastes in six chunks, the harness re-sends the whole conversation on every turn, a sub-agent hands back its findings, etc. None of that is a prompt, all of it is context, and all of it is competing for the same fixed space. We wrote almost none of it and we're paying for every token of it.

A long strip of blank amber film unspooled across a pale grey surface and folded back over itself.
The window is a strip of fixed length. Everything you know is longer than it, so the whole job is choosing which frames go in.

What's in a window on a normal turn

Five kinds of thing compete for the space, and they behave completely differently. These five colors mean the same thing everywhere on this page.

Instructions

The system prompt, the house rules, the style guide, the CLAUDE.md or AGENTS.md at the root of the repo. Written once, re-sent on every single call, and the first thing that quietly grows to 20,000 tokens.

Tools

Every tool's name, description and JSON schema, whether or not the model uses it. Anthropic's guidance is a small set with minimal overlap, because ambiguous tools are where agents pick wrong.

Knowledge

The retrieved chunks, the file you opened, the PRD, the design tokens, the log slice. This is the part you get to choose on every turn, and it's where retrieval quality shows up.

History

Every previous message and every previous tool result, re-sent in full. It only grows, and it's the reason a long session gets worse rather than better.

Filler

The 3,000 lines of a file you needed 12 lines of, the stack trace repeated four times, the whole API spec when six operations were wanted, etc. All of it is true, and all of it is paying rent on space a useful token could have had.

Anthropic's own framing for this is an attention budget. The model has a finite one, every token spends some of it, and the goal is the smallest set of high signal tokens that still gets the job done.

02

Why a bigger window doesn't fix it

Everybody's first instinct is that the window will grow out of the problem. Gemini takes two million tokens, Claude takes a million, GPT takes hundreds of thousands, so paste it all in and let the model sort it out. That instinct doesn't survive anybody measuring it, and by now several people have.

Chroma ran the cleanest version of the test in July 2025. They took 18 frontier models, held the task difficulty constant, and varied only the input length. Every single one got less reliable as the input grew, and the decline was continuous rather than a cliff at the advertised limit. A model with a 200,000 token window is already worse at 50,000 than it was at 5,000.

A pale strip receding into blackness, stained and out of focus, crossed by one narrow band of cold light.
The advertised context length is where the model stops reading. It is not where it stops being reliable.

NoLiMa, and needle in a haystack without the word matching

The usual long context benchmark hides a keyword in a pile of text and asks the model to find it, which a model can pass by matching the words rather than understanding anything. Adobe Research's NoLiMa took the literal overlap out, so the question and the buried fact share no words and the model has to make the association itself.

Twelve models that all advertise at least 128,000 tokens were tested, and at 32,000 tokens ten of them scored under half of their own short-context baseline. GPT-4o went from 99.3% to 69.7%. Claude 3.5 Sonnet went from 87.6% to 29.8%. The paper's effective length column is the number worth planning against, which is the longest input where a model still holds 85% of its own baseline, and for most of them it's between 1,000 and 8,000 tokens.

Position matters too

Liu et al. found the shape in 2023 and called it lost in the middle. Put the fact the model needs at the start of a long input and it does well, put it at the end and it does well, put it in the middle and accuracy sags. It held across GPT-3.5, GPT-4, Claude, LongChat, MPT and Cohere Command, and it holds on models specifically built for long context.

So the thing you paste in at token 40,000 out of 120,000 is in the worst seat in the house, and you have no way of knowing which of your six retrieved chunks landed there.

start middle end high low

The shape of the lost in the middle effect, drawn from the paper's description rather than from its data points. Where the answer sits inside a long input changes how often the model finds it.

models Chroma tested
18every one degraded as input length grew
NoLiMa at 32K
10 of 12scored under half their own baseline
GPT-4o, NoLiMa
99.3 → 69.7base score against 32,000 tokens
LongMemEval prompt
113k vs 300full transcript against the relevant part, and the short one wins on every model

Why it happens

Anthropic's explanation is architectural rather than mysterious. Attention is pairwise, so n tokens means n squared relationships and the same attention has to stretch further the longer the input gets. Models also see far less training data at long lengths than short ones, so fewer of their parameters are specialized for holding a whole window together, and the position encoding tricks that let a model accept a longer sequence than it trained on degrade its sense of where things are.

None of that is a bug anybody's about to fix. It's the reason curation is the job.

03

The techniques

These are the seven moves we keep running into in every serious agent whose internals are public. They're not alternatives to each other, and a real agent runs most of them at once. Each one is the same window with different cells lit.

The taxonomy people usually quote is LangChain's four verbs, which are write, select, compress and isolate. The seven below are the same idea at the level you'd actually implement it.

04

Pack a window yourself

Here's one real task on one real codebase, which is my AI studio. An agent has been asked to change the Krea 2 edit controls in the UI, and there are six things it could be given. Every size below was measured with cl100k_base over the actual file on my machine, and each row names the file so you can go and count it yourself.

Switch the rows between everything and what it needs and watch the window.

tokens
0
of a 200k window
0%
cost per turn, uncached
$0.00
cost per turn, cached
$0.00

Prices are the ones Manus published for Claude Sonnet, which are $3.00 per million input tokens and $0.30 per million when the prefix is a cache hit. That 10x is why agents go to some trouble to keep the front of the window byte identical between turns. Manus also measured roughly a 100:1 ratio of input tokens to output tokens per agent turn, so on an agent the input side is the bill.

05

An open card index drawer packed with cards on end, one card raised above the rest.
Retrieval is the part of context you choose per turn. Everything else is either fixed or grows on its own.

Retrieval, semantic and lexical

The knowledge band is the only part of the window you get to decide fresh on every turn, so the quality of your retriever is most of the quality of your context. Two things go wrong here and they're opposites. Miss the right document and the model invents an answer. Return twelve documents when two were relevant and you've paid for the other ten in attention budget, and the useful one might land in the middle.

Use both kinds of search

Semantic search embeds the query and the chunks into vectors and returns what's closest in meaning, which is how you find the page about authentication when somebody asked about login. Lexical search, usually BM25, matches the actual words, which is how you find ERR_TOKEN_EXPIRED, a Jira key like PLAT-4412, a function name, a commit hash, etc. Embeddings are bad at exact identifiers and BM25 is bad at synonyms, so in an engineering corpus full of both prose and identifiers we want the two of them running together and their results merged.

Anthropic measured what each layer adds. Their baseline was a normal embedding retriever, and the failure rate is how often the right chunk wasn't in the top 20.

Give each chunk its context back

The other half of that result is what they called contextual retrieval. A chunk ripped out of the middle of a document loses everything the document was about, so a cheap model writes 50 to 100 tokens saying where this chunk sits, that gets prepended before the chunk is embedded and before it's indexed for BM25, and both retrievers get better. That's the step that takes failures from 5.7% to 3.7% on its own.

Retrieval failure rate, meaning how often the correct chunk was missing from the top 20. Anthropic's own benchmark across several datasets, so treat it as representative rather than a guarantee for your corpus. Lower is better.

Rerank, then cut hard

A retriever optimized for recall will hand you 20 candidates. A reranker is a slower model that scores each candidate against the query properly and reorders them, and in Anthropic's numbers it takes the failure rate from 2.9% down to 1.9%. Its more useful job is that it lets you keep the top 3 instead of the top 20 with a straight face, which is 17 chunks of attention budget you get back.

Permissions belong in the query

The moment a retriever spans Confluence, Slack, Jira and GitHub, it can put something in front of somebody who isn't allowed to see it, and a model will happily summarize a document nobody meant to share. The scoping has to happen inside the query, on the server, per requesting user, rather than by filtering the results afterwards. This is the whole reason Glean leads with a permissions-aware graph rather than with search quality.

06

What it's worth, measured

Most writing about context engineering stops at the advice. Here are the four results I found where somebody put a number on it, including the one that disagrees with the others.

Each of these is the team's own benchmark on their own workload, so they're evidence rather than proof, and the disagreement between the second and third is real and unresolved.

Reading the disagreement

Anthropic and Cognition ran into the same wall from different sides, and I think both results are right about their own workload. Research is a wide shallow problem where the sub-agents mostly don't need to agree with each other, so paying 15 times the tokens to search in parallel pays off. Writing code is a narrow deep problem where every decision constrains the next one, and two agents that never saw each other's reasoning will produce two halves that don't fit.

Anthropic says this themselves, that multi-agent is a poor fit for most coding tasks and for anything needing shared context. So the rule I'd take out of it is to split by context rather than by task, and only when the pieces don't need to agree.

What Manus learned building it four times

They rebuilt their agent framework four times and named the process Stochastic Graduate Descent. Their most useful findings are mechanical rather than clever. Never remove a tool mid-session, mask its logits instead, because deleting it invalidates the KV cache for everything after it. Keep the file system as the real memory and treat the window as a working set. Rewrite the todo list every few steps so the goal stays in recent attention across a task that averages 50 tool calls. And leave the failures in, because an agent that can see its own stack trace stops repeating the call, and one whose mistakes you cleaned up does it again.

07

What I'm building

I'm putting the tools we actually work in behind one retrieval layer, which is Confluence, Slack, Miro, Figma, GitHub, Jira, Datadog and Harness, indexed into one database with both semantic and lexical search over it. The point isn't a better search box for people. It's that my agent can go and get the specific thing it needs without me finding it first, which is the just in time pattern from section 03 with our own systems behind it.

Atlassian surveyed 12,000 knowledge workers and 200 executives for their State of Teams 2025 report and found teams losing a quarter of their time looking for answers. An agent pays that same tax, and it pays it in tokens.

Confluence

PRDs, specs, runbooks, architecture decisions, the onboarding page nobody's read since 2023

semantic

Figma

Frames, components, the spacing and color tokens, and which screen the PRD is actually talking about

semantic + exact

Jira

Tickets, acceptance criteria, the comment where somebody changed the requirement

lexical keys

Slack

The thread where the decision was really made, and the incident channel

semantic + recency

GitHub

Code, PRs, review comments, the commit range between two deploys

lexical symbols

Datadog

Logs, traces, metrics and monitors, sliced to the window around an alert

query, not index

Harness

What shipped, when, and to which environment

query, not index

Miro

The whiteboard from the kickoff, which is often the only place the shape of a thing was drawn

semantic

Datadog and Harness are queried live rather than indexed, because a log line from three weeks ago is worthless and a log line from four minutes ago is the whole answer. Everything else is indexed, chunked with its own context written back onto it, and scoped to the requesting person on the server.

Use case one, building a UI from the PRD

The ask

"Build the empty state for the integrations page"

Today this means I go and find the PRD, find the right Figma frame, read the spacing off it by hand, and then describe it to the agent in prose that loses most of it.

Retrieval

Two lookups instead of a paste

The agent asks for the PRD section about integrations and gets 900 tokens rather than the whole 3,872 token document, then asks for the frame the PRD links to and gets its layout and tokens rather than the file.

Grounding

The design system itself

The spacing, radius and color tokens come from the same place the app compiles from, so the agent writes var(--space-4) rather than 16px, and the result matches because it's the same number.

Result

Pixel accurate on the first pass

The speed matters less than the round trip that disappears, which is the one where I look at the result, notice the padding is wrong, and go back and measure the Figma frame by hand.

Eight small flat tiles of different pale materials laid out in an evenly spaced row.
Eight sources, one index. The connectors are the easy half. Chunking, permissions and freshness are the half that decides whether it works.
A single amber indicator lamp lit on a dark instrument panel in an otherwise black room.
The page fires at 3am. The useful question is what the agent has already done by the time you've opened the laptop.

Use case two, the on-call bot

t+0s

The page fires

A Datadog monitor trips. The agent gets the alert and starts working before anybody has acknowledged it.

t+30s

It pulls the narrow slice

The error logs and traces for that service in the window around the alert, the Harness deploys in the last few hours, and the GitHub commit range between the last good deploy and this one.

t+2m

It looks for the same thing happening before

The Slack incident channels and the Jira history for that service, because most pages at 3am are something that already happened once, and somebody wrote down what they did.

t+8m

A PR and a written hypothesis

By the time I sit down there's a summary of what changed, what the logs say, what happened last time, and a pull request I can read in two minutes and either approve or throw away.

Somebody has already shown this works

Datadog shipped exactly this and wrote up how they built it. Bits AI investigates every alert the moment it fires, forms hypotheses about the cause, tests each one against live telemetry, and recurses into sub-hypotheses until it runs out. The design decision they call out is the one this whole article is about, which is that the agent looks at the telemetry bearing on one hypothesis at a time rather than at all of the available telemetry at once. They benchmark it against real labelled incidents from hundreds of their own teams, and they're claiming time to resolution down by up to 95%.

08

Who sells this

The category grew a market in about eighteen months. Every card links to the primary source, and where a number is a company's own claim rather than a published benchmark I say so.

Two shapes are competing here. One is a horizontal layer that indexes everything and answers questions itself, and the other is a protocol that hands your context to whichever agent you already use.

Glean

The horizontal context layer

100+ connectors

Hybrid search over a permissions-aware knowledge graph across everything a company uses, with agents on top of it. Reported at a $7.2B valuation and $300M ARR in May 2026, which makes it the clearest evidence that this is a category and not a feature.

glean.com

Atlassian

Rovo and the Teamwork Graph

75+ tools indexed

They already own Jira and Confluence, so their play is to index everything around them into one graph and then expose it to outside agents over MCP rather than only to their own chat.

atlassian.com

Onyx

Self-hosted, MIT licensed

40+ connectors

The open source version of the same idea, which matters if your corpus is the kind of thing you'd rather not ship to somebody else's cloud. Enterprise search, agents and MCP tool use, running on your own hardware.

onyx.app

Sourcegraph

Code context at monorepo scale

Every branch indexed

A continuously updated index of every repository, branch and revision, where an exhaustive search returns an exact total rather than a ranked guess. That distinction matters when the agent's next move depends on there being no other callers.

sourcegraph.com

MCP

The wire format everybody agreed on

~9,650 servers

Anthropic published it in November 2024 with about 50 servers. The official registry listed 9,652 in May 2026, and OpenAI, Google, Microsoft and Salesforce all support it. It's the reason a context layer no longer has to be the thing you chat with.

modelcontextprotocol.io

Datadog

Context engineering as a product

One hypothesis at a time

Bits AI investigates every alert on arrival against live telemetry. Their published engineering write-up is the most concrete account I've found of curating context for an agent in production, and they benchmark it on real labelled incidents.

datadoghq.com

Anthropic

Agentic search over an index

grep, not embeddings

Claude Code mostly doesn't pre-index your repo. It runs the searches a person would run, reads the files it decides it needs, and keeps the paths rather than the contents. Slower per step, and it never goes stale.

anthropic.com

Manus

The practitioner's write-up

Four rewrites

The most useful thing published on this so far, because it's all mechanics: cache hit rates, tool masking, the file system as memory, reciting the goal, and keeping the failures in the window.

manus.im

09

Where I'd start

If you're building an agent and you want to spend your time where it pays, this is the order I'd do it in.

Count what you're sending. Most of us have never measured a real turn. Run cl100k_base over your assembled context and find out how much of it is tool schemas and re-sent history, because it's usually more than you'd guess.

Cut the tools before you cut anything else. They're re-sent on every call, they're the cheapest thing to remove, and a smaller set makes the agent choose better as well as costing less.

Hand back identifiers, not contents. A tool that returns a file path and a line range costs 20 tokens. One that returns the file costs 3,000, and the agent only wanted to know where to look.

Run both retrievers and rerank. Contextual chunking, semantic and lexical together, then a reranker so you can keep three results instead of twenty. That's the 5.7% to 1.9% from section 05, and none of it needs a different model.

Compact deliberately. Decide what a summary must always preserve, which is usually the decisions, the constraints and the open questions, and write that rule down rather than letting a generic summarizer pick.

Then measure it again. ACE, Anthropic and Datadog all got their results by benchmarking against real labelled work rather than by reasoning about what should help.

The one thing I'd argue with

The advice you'll hear most often is to put everything in and let the model figure it out, on the grounds that the windows keep getting bigger. Chroma tested 18 models and every one got worse with length. NoLiMa tested twelve that advertise 128,000 tokens and ten of them were under half their own baseline at 32,000. The windows are getting bigger and the models are not getting better at using them, so the gap between what you can send and what you should send is widening rather than closing.

everything, on one real task
4,563,545tokens, 23 windows, $13.69 a turn
curated, same task
8,653tokens, 4.3% of one window, 2.6 cents
retrieval failures
5.7% → 1.9%contextual chunks, hybrid search, reranking
cached vs uncached input
$0.30 vs $3.00per million tokens, so the front of the window should never move