A system prompt, a set of demonstrations, chain of thought and a vote across sampled reasoning paths are all decisions about a single call, and every one of them assumes that the material the model needs is already in front of it. That assumption holds until a feature has to answer from a policy document, a customer's history and the result of a lookup at the same time, and at that point the wording of the instruction stops being the hard part.
The field noticed and renamed itself over about a fortnight in mid 2025. On 19 June 2025 Tobi Lütke, the chief executive of Shopify, posted that context engineering was a better name for the skill than prompt engineering, because the work is supplying everything a task needs before the model can plausibly solve it. Andrej Karpathy endorsed the term on 25 June 2025 and described the job as filling the context window with the right material for the next step and nothing else. The practice was then written down at length, by LangChain in a four part breakdown on 2 July 2025 and by Anthropic's applied team in a long working definition on 29 September 2025.
A rename is worth this much attention only when it moves the difficulty somewhere else, and this one did. Prompt engineering is a writing problem, and a person can get good at it by reading their own prompts carefully. Context engineering, by contrast, is a retrieval, budgeting and eviction problem, and it is solved in code that runs before the call goes out.
The sections below set out what the rename changed and name the seven kinds of material that reach a model on one call. They then show one request as a bare prompt and again as an assembled context, put the assembly into code, and finish with the place prompt engineering now occupies.
What the rename actually changed
Three things moved when the name changed, and each one has a consequence a team can feel.
The unit of work became the call. A prompt is a string a person edits, while a context is an object a program builds for every request, out of parts that arrive from different systems at different times. Editing a string is a pull request, and building an object is a component with tests of its own.
The interesting failures stopped being wording failures. A prompt fails because it was ambiguous, whereas a context fails for reasons that have nothing to do with wording. The right passage was never retrieved, or forty turns of history pushed the policy into the middle of the window, or a tool result from ten minutes ago contradicts one from a minute ago and nothing resolved the conflict.
The budget became a first class concern. Every part of an assembled context has a token cost on every single call, paid in money and in latency, and the parts compete. The next page is entirely about that competition.
Everything that reaches a model on one call
Seven kinds of material show up in a production context, and they arrive from seven different places.
| Part of the context | Where it comes from | What decides its size |
|---|---|---|
| System instructions | A prompt registry, at a pinned version | The team, and it grows after every incident |
| Tool definitions | The tool registry, filtered by role | How many tools the model is offered |
| Retrieved passages | A search over the document index | The number of chunks kept and how long each is |
| Long term memory | The customer or account record | What the team chose to persist between sessions |
| Conversation history | Earlier turns of this session | How long the session has been running |
| Tool results | Calls the model made during this turn | The API on the other side of the call |
| The user's message | The person, just now | The person |
Only the first row is written in advance by anybody. The other six arrive at run time in sizes nobody chose, which is why an assembled context has to be built by code that can measure and cut.
One request as a prompt and as a context
The difference is easiest to see on a request small enough to read in full.
PROMPT ONLY. Everything the answer depends on has to already be in the
model's weights, and none of it is.
A customer is asking whether their order can still be cancelled.
Write a reply.
ASSEMBLED CONTEXT. The same request, with every part labelled and its
source named.
[SYSTEM, prompt registry, version 14, 180 tokens]
You handle order questions for Northwind. Apply only the rules inside
<policy> tags. Never state a refund amount. If the customer asks for a
person, reply with the single word HANDOFF.
[TOOLS, tool registry, filtered to this role, 140 tokens]
get_order(order_id) returns status, placed_at, dispatched_at, total
cancel_order(order_id, reason) returns confirmation_id
[POLICY, document index, 2 chunks kept from 8 retrieved, 610 tokens]
Clause 4.2 An order may be cancelled at no charge until it is marked
dispatched.
Clause 4.7 A dispatched order follows the returns process, and the
cancellation clause no longer applies to it.
[MEMORY, customer record, 40 tokens]
Tier business. Two cancellations in the last 90 days.
[HISTORY, last 3 turns kept, earlier turns summarised, 220 tokens]
Customer asked about delivery on 2 March and was told 5 March.
[TOOL RESULT, get_order("41822"), 60 tokens]
status=dispatched placed_at=2026-03-02T09:14Z
dispatched_at=2026-03-03T18:02Z total=59.97
[QUESTION, typed by the customer just now, 12 tokens]
Can I still cancel order 41822?
The instruction is 180 of the 1,262 tokens going into that call, which is about one part in seven. The remaining six sevenths are the output of six decisions. Somebody chose to retrieve eight passages and keep two. Somebody chose to keep three turns of history and summarise the rest. Somebody chose to expose two tools out of a registry that holds eleven, and somebody chose to put the cancellation count in front of the model at all.
Each of those decisions can be wrong in a way the reply will not reveal. If clause 4.7 had failed to retrieve, the model would have seen only clause 4.2, found a cancellable order under it and written a confident and wrong answer with the right tone.
Assembling a context in code
Written out, the assembly is a short function with a decision on nearly every line.
def build_context(session, question, budget):
"""Assemble one call. Every line here is a choice, and every choice
has a token cost the budget has to cover."""
parts = [
registry.get("order_support", version=14), # system
render_tools(tools.for_role("order_support")), # 2 of 11
memory.for_customer(session.customer_id), # persisted
summarise_if_long(session.history, keep_last=3), # compressed
]
passages = index.search(question, k=8) # cast wide
passages = rerank(question, passages)[:2] # then narrow
parts.append(render_passages(passages))
parts.append(render_tool_results(session.tool_results))
parts.append(f"<question>\n{question}\n</question>")
return fit(parts, budget) # the next page is about this line
Two lines in that function carry most of the quality. The search and the rerank decide whether the answer is present at all, which is the subject of pages ten and eleven. The call to fit decides what happens when the parts add up to more than the window allows, and that decision has four possible shapes, which page eight sets out.
Prompt engineering as one component of the work
Nothing established so far stopped being true. A system prompt still needs lines a test could fail, demonstrations still teach the boundaries that an instruction can only argue about, and the temperature has to match whatever consumes the output. All of it now runs inside a larger job, and it is that larger job which owns the failures reaching customers.
The relationship is easiest to state as a ratio. On the call above, prompt engineering owns 180 tokens and context engineering owns 1,082. On a coding agent forty steps into a task, the instruction is a rounding error and the context is the entire product.
That context arrives as one sequence with a hard limit on its length, and every part of it is competing for the same finite room. What that limit is, what each claim on it costs, and what happens when the claims add up to more than the budget, are the next three pages.