Skip to main content
Architecture

Context Engineering: The Discipline That Replaced Prompt Engineering

Prompt engineering was the discipline of the last cycle. Context engineering is the discipline of this one. It is the recognition that what an LLM does is decided far more by what you put in its context window — the retrieved documents, the memory, the tool outputs, the system instructions, the order they appear in — than by the exact wording of the prompt itself. This is a practical look at what context engineering actually means as a body of technique, why it emerged, and how enterprise teams should organise around it.

Inductivee Team· AI EngineeringAugust 20, 202614 min read
TL;DR

TL;DR. Context engineering is the discipline of designing, populating, ordering, and managing everything the model sees at inference time — system instructions, retrieved context, tool outputs, agent memory, prior turns, examples — as a first-class artefact of the system. It is what production LLM teams call the thing they actually spend most of their time doing, once they realise 'the prompt' is a small slice of the actual input. The shift matters because it changes what you invest in: not clever phrasings but sound retrieval, disciplined memory, honest budgeting of tokens, and evaluation loops that catch context regressions before users do. This is the discipline that separates LLM prototypes from LLM systems.

Why the Name Changed

Prompt engineering, taken at face value, is about writing better prompts. That framing captured what mattered when the input to the model was one string — a user question, maybe a system message, and that was it. In 2023 it was the right framing. In 2026 it is a partial one.

A modern production LLM call has a system prompt, an accumulated conversation history, retrieved documents from RAG, tool outputs from prior turns, agent scratchpad reasoning, examples pulled from a few-shot store, structured data injected from your application, and maybe compressed memory summarising prior sessions. All of this is 'the context.' The prompt — the actual string you wrote — is one component. Often not the most consequential one.

Engineers running production LLM systems noticed that most of their failures were not prompt failures. They were context failures: the retrieval brought back the wrong document, the memory got stale, the tool output was 400 tokens of JSON when 40 tokens of summary was what the model needed, the system prompt was so long it dominated the model's attention. Fixing the prompt did nothing. Fixing what surrounded the prompt fixed everything.

The term 'context engineering' — popularised by Andrej Karpathy and taken up widely through 2025 — put a name on that reality. It is not a new discipline invented from scratch; it is the recognition that everything a working LLM team was already doing was better described as engineering the context than engineering the prompt.

What Actually Lives in the Context Window

It helps to enumerate. For a modern production agent, the context that reaches the model on any given turn typically contains, in order of appearance:

System instructions. The stable rules — what the assistant is, what it may not do, output format constraints, tool descriptions. This layer changes rarely. Its cost is amortised via prompt caching if you have wired it correctly.

Task-level guidance. For agents with distinct modes or roles, the mode-specific instructions — a triage agent's routing rubric, a specialist agent's domain guidance. Often loaded conditionally.

Retrieved knowledge. RAG payload. The chunks the retriever thinks are relevant to the current query. The single largest variable, both in token budget and in quality impact.

Working memory. A running summary of prior conversation turns, or of prior sessions for a long-lived agent. Compact by construction — a hundred to a few hundred tokens summarising a longer history.

Tool descriptions and prior tool outputs. For agents in the middle of a loop, the descriptions of available tools and the results of any tool calls made this turn or in recent turns. Grows quickly if not managed.

Few-shot exemplars. For tasks where you have curated golden input-output pairs, a small number of them injected as demonstrations. Effective, expensive if uncalibrated.

The immediate user turn. The actual current input.

Scratchpad / reasoning traces. For chain-of-thought or ReAct-style agents, the model's own working notes from this turn.

On a modern model with a 200k+ token window, all of this can technically fit. In practice, blindly filling the window is one of the most reliable ways to make model quality worse — attention is expensive, cost is linear, and the model's ability to find the relevant token in a very long context degrades measurably. The engineering discipline is deciding what belongs, in what order, at what fidelity, for this particular turn.

The Six Techniques That Make Up Context Engineering

Retrieval quality — the largest single lever

If you get the RAG payload wrong, no downstream prompt or model change recovers it. Hybrid search (BM25 + dense embeddings), reranking with a cross-encoder, query decomposition, and evaluation via a rubric like Ragas or DeepEval are all part of getting this right. Most 'the LLM hallucinated' complaints from users are actually 'the retriever brought back the wrong document, and the LLM answered from it faithfully' — an outcome that no prompt tweak can fix.

Ordering and structuring the context

Where in the context you place a piece of information affects how much attention the model gives it. Recent research and practical experience both confirm the 'lost in the middle' effect — information at the very start or very end of a long context is used more reliably than information buried in the middle. For long-context agents, structuring the payload with clear section headers, placing the most important retrieved content at the top or bottom, and repeating the critical instruction near the user turn are all techniques with measurable impact.

Memory design — what to keep, what to forget

A voice agent that has been running for twenty turns has a memory problem. So does a long-lived research agent, or a customer-support bot in a multi-turn conversation. The two patterns that work are hierarchical summarisation (compact summaries of increasingly older turns) and structured episodic memory (structured records of what happened, retrievable on demand rather than always-present). Whichever pattern, the principle is the same: unbounded conversation history is a bug, not a feature. Design the forgetting.

Tool output compression

When an agent calls a tool that returns 2,000 tokens of JSON, the model does not need all 2,000 tokens on the next turn. It needs the summary, or the specific fields it will act on. Wrap tools in a compression layer — either an LLM-driven summariser or a schema-projection step — that turns raw output into agent-consumable context. This is one of the highest-leverage optimisations in a mature agent: it directly cuts cost, latency, and 'lost in the middle' failures.

Budgeting the token spend

The context window is a budget, not a bucket. Allocate it explicitly: 500 tokens for system instructions, 2000 for retrieval, 500 for memory, 500 for tool descriptions, 200 for scratchpad, the rest for the user turn and headroom. When a budget line blows, prioritise ruthlessly — a truncated system prompt is almost always worse than truncated retrieval. Instrument every dimension of this budget in your traces so you can see when it drifts.

Prompt caching as a first-class concern

Anthropic and OpenAI both offer prompt caching where an unchanged prefix — system instructions, tool definitions, injected exemplars — can be reused at a fraction of the cost. Structure your context to maximise cache hits: stable content at the top, variable content at the bottom. For high-volume agents this alone can cut model costs by 50-90%. It also has quality implications — a cached system prompt cannot drift between calls the way an assembled-on-the-fly one can.

Where Each Concern Belongs in a Production Stack

ConcernWhere it livesOwner
System instructions, tool descriptionsVersion-controlled config or DSPy signaturesEngineering + product
Retrieval quality, chunking, rerankingRetrieval service (separate from agent)Data / ML engineering
Memory design (summarisation, episodic store)Agent framework layerEngineering
Tool output compressionTool wrapper or middlewareEngineering
Token budget per callConfig, enforced at runtime, alerted in observabilityEngineering + FinOps
Prompt caching layoutAI gateway or agent frameworkEngineering
Context evaluation metricsObservability platform + evaluation pipelineML / Quality
Policy about what may enter context (PII)Redaction middleware + governanceSecurity + compliance

The Evaluation Loop for Context Quality

Context engineering is not something you get right by intuition. It is something you get right by measurement, and specifically by measurement that separates retrieval quality from generation quality from context-structuring quality. A single 'accuracy' number is not enough because it does not tell you where to invest next.

The evaluation stack that works has three layers. Retrieval evaluation — recall@k, MRR, NDCG on a golden set of query-document pairs — tells you whether the retriever finds the right context. Wrong here means fix the retriever, not the prompt. Groundedness evaluation — for RAG, is every claim in the answer supported by the retrieved context — tells you whether the model is using the context it was given. Wrong here often means fix the prompt or the structuring, not the retrieval. Task quality — end-to-end, is the answer correct — tells you whether the whole thing is working, but only after you have separated the previous two.

The frameworks that support this well are Ragas, DeepEval, Inspect, and Langfuse's built-in evaluators. Wire them into your CI so a context regression fails the build before it fails a user.

A Concrete Context Assembly Pattern

python
# context_assembler.py — explicit budget, cached prefix, structured layout

from dataclasses import dataclass

@dataclass
class ContextBudget:
    system: int = 500
    tools: int = 500
    memory: int = 500
    retrieval: int = 2000
    scratchpad: int = 300
    user_turn: int = 500
    headroom: int = 200

    @property
    def total(self) -> int:
        return sum([self.system, self.tools, self.memory, self.retrieval,
                    self.scratchpad, self.user_turn, self.headroom])


def assemble_context(
    *,
    system_prompt: str,        # STABLE — top of context, cached
    tool_descriptions: str,     # STABLE — cached
    session_memory: str,        # slowly-changing summary
    retrieved_chunks: list[str],
    user_turn: str,
    scratchpad: str,
    budget: ContextBudget = ContextBudget(),
) -> list[dict]:
    """Assemble the messages payload with explicit budget enforcement.

    Layout for cache-friendliness:
      1. System instructions (stable, cached)
      2. Tool descriptions (stable, cached)
      3. Session memory (slowly-changing)
      4. Retrieval context (per-turn)
      5. Scratchpad (per-turn)
      6. User message (per-turn)
    """
    # ---- Enforce budgets (truncation preferred over silent overflow) ----
    system_prompt = truncate_tokens(system_prompt, budget.system)
    tool_descriptions = truncate_tokens(tool_descriptions, budget.tools)
    session_memory = summarise_to_budget(session_memory, budget.memory)
    retrieved_chunks = rank_and_pack_to_budget(retrieved_chunks, budget.retrieval)
    scratchpad = truncate_tokens(scratchpad, budget.scratchpad)
    user_turn = truncate_tokens(user_turn, budget.user_turn)

    # ---- Anthropic cache_control: stable prefix cached for 90% cost reduction ----
    system_blocks = [
        {
            'type': 'text', 'text': system_prompt,
            'cache_control': {'type': 'ephemeral'},
        },
        {
            'type': 'text', 'text': f'\n\n## Available tools\n{tool_descriptions}',
            'cache_control': {'type': 'ephemeral'},
        },
    ]

    # ---- User turn assembled fresh each call ----
    user_content = f'''## Session context
{session_memory}

## Retrieved knowledge
{format_chunks(retrieved_chunks)}

## Scratchpad
{scratchpad}

## User
{user_turn}'''

    return [
        {'role': 'system', 'content': system_blocks},
        {'role': 'user', 'content': user_content},
    ]

Common Anti-Patterns We See

In every enterprise engagement we join partway through, we see the same recurring context anti-patterns.

The first is the unbounded system prompt. Every incident produces a new sentence tacked onto the system prompt until it is 4,000 tokens of accreted rules the model no longer follows. Fix: version the system prompt, move behavioural rules into evaluations that catch violations, keep the prompt tight.

The second is retrieval that returns raw source documents. The retriever returns entire PDF pages, or entire wiki articles, or long tool outputs verbatim. Fix: chunk aggressively, rerank ruthlessly, project down to the specific fields the agent will act on.

The third is memory that never forgets. Every prior turn is included in every subsequent turn, and by turn twenty the model is drowning in its own noise. Fix: hierarchical summarisation, or explicit episodic store retrieval.

The fourth is cache-unfriendly ordering. Content that changes on every call is placed at the top of the context, invalidating the cache and multiplying model costs. Fix: stable prefix, variable suffix, always.

The fifth is treating token spend as free. Context grows call after call, no one is watching, and one day the model bill triples. Fix: budgets in code, alerts on p95 context size, dashboards owned by someone.

Warning

A larger context window is not a free upgrade. Frontier models with 200k+ token windows are marketed as 'you can now include everything.' The measurement is more nuanced. Model quality on long-context tasks degrades as you fill the window — the effect is real, measurable, and larger than most teams expect. Doubling the retrieval payload will more often make the model worse than better. The discipline is not to use the biggest window; it is to use the smallest one that contains what the model actually needs.

How Context Engineering Interacts with the Rest of the Stack

Context engineering is not a standalone discipline. It shows up as a specific concern at every layer of a production LLM system, and organising around it changes how those layers are built.

At the retrieval layer it means treating retrieval quality as a first-class KPI, not an afterthought. Retrieval that returns the wrong thing is a context-engineering failure with a downstream cost.

At the agent framework layer it means picking a framework whose primitives make context assembly explicit. Pydantic AI and DSPy both expose the assembled context; frameworks that hide it behind heavy abstractions make context engineering harder.

At the gateway layerLiteLLM or equivalent — it means using prompt-caching-aware routing and normalising the shape of the request so caching actually works.

At the observability layerLangfuse or LangSmith — it means capturing the full assembled context, not just the user turn, on every trace. The number of teams whose observability captures only the input and output and cannot debug a bad answer because they cannot see what the model actually saw is unfortunately large.

At the governance layer it means treating what goes into the context as a policy decision. PII in retrieval chunks, secrets in tool outputs, confidential data in memory — these are all context-engineering concerns as much as they are security ones.

How to Organise Around Context Engineering

Make it someone's job

Not one person's entire job, but explicitly part of someone's remit. In our experience the discipline lives most naturally with the ML platform engineer or applied ML engineer who owns retrieval, memory, and evaluation as a coherent set. When those three sit with the same person, context quality improves fast; when they are scattered across teams, they degrade.

Instrument before you optimise

You cannot fix what you cannot see. Before spending a sprint on context refactoring, spend a day on instrumentation: assembled-context capture in every trace, per-section token accounting, retrieval quality metrics wired to a dashboard. Then optimise where the data says to.

Treat context as versioned artefact

System prompts, tool descriptions, retrieval configs, memory templates — all in version control, all versioned, all rolled back the same way as any code change. Free-text 'let me just tweak the prompt' is what produces the accreted-mess anti-pattern.

Evaluate the layers separately

Retrieval quality, groundedness, task success — three different metrics, three different diagnostic conclusions. A single accuracy number is a symptom, not a cause. Build the evaluation stack that lets you tell them apart.

Seven Decisions Worth Making Before Your Next Deploy

  • Explicit context budget. Write down the tokens each section gets. Enforce in code. Alert when p95 drifts.
  • Cache-friendly layout. Stable prefix at the top (system, tools, exemplars), variable content at the bottom (retrieval, scratchpad, user turn). Wire up prompt caching on the provider that supports it.
  • Retrieval is a service. Own it separately. Evaluate it separately. Not every agent needs the same retrieval config, but every retrieval config needs its own quality gate.
  • Design the forgetting. Decide the memory strategy up front — hierarchical summary, episodic store, sliding window. Unbounded history is a bug.
  • Compress tool outputs. Wrap noisy tools in a summarisation or projection layer. Do not let 2,000 tokens of JSON pollute every subsequent turn.
  • Trace the full context. Your observability platform must capture what the model actually saw, not just what the user typed. Anything less is debugging blind.
  • Layered evaluation. Retrieval quality, groundedness, task success — three separate metrics on three separate dashboards. Treat single-number scoring as a smell.

How To Introduce Context Engineering Into an Existing System

The retrofit that works, in order. First, instrument: capture assembled context on every trace, add per-section token counts, wire retrieval metrics if you have RAG. Second, audit: read a hundred real traces and note the anti-patterns you actually see — the unbounded system prompt, the raw-JSON tool outputs, the memory that never forgets. Third, budget: assign a target token count per section, enforce in code, alert on drift. Fourth, cache: reorder the context so the stable prefix is genuinely stable, wire up the provider's prompt caching. Fifth, evaluate: separate retrieval, groundedness, and task-success metrics; wire them into CI. Sixth, iterate: each fix on this list, in this order, produces measurable improvement. Skipping to step five without doing one through four rarely does.

The discipline is not glamorous — it is not a new model release, it is not a new framework. It is the boring work of making sure the context that reaches the model is the smallest, most relevant, most cache-friendly, most measured version of what the model needs. That work is what separates LLM prototypes from LLM systems.

If you would like help — auditing an existing agent's context and identifying the highest-leverage fixes, designing the retrieval or memory layers for a new system, wiring evaluation metrics into your existing observability platform, or picking between Pydantic AI and DSPy for a workload that needs disciplined context engineering — talk to us. We have run this playbook across dozens of enterprise LLM deployments, and the diagnostic almost always finds the same handful of high-leverage fixes.

Frequently Asked Questions

Is context engineering just a rebrand of prompt engineering?

It is a broadening. Prompt engineering framed the input to the model as the prompt string; context engineering recognises that the actual input is the whole assembled context — system instructions, retrieval, memory, tool outputs, exemplars, the user turn. The rebrand matters because it changes where you invest: from clever phrasings to sound retrieval, disciplined memory, honest token budgets, and measured evaluations.

How is this different from RAG?

RAG is one piece of context engineering — the retrieval piece. Context engineering is the umbrella discipline that also includes system instructions, memory design, tool output compression, prompt caching, budgeting, and the ordering of everything in the context window. A well-designed RAG pipeline is necessary for good context but not sufficient — teams with excellent retrieval often still have context problems everywhere else.

Do we need to change frameworks to adopt context engineering?

Usually not. What you change is discipline, instrumentation, and evaluation — not the framework. That said, frameworks whose primitives make context assembly explicit (Pydantic AI, DSPy, and the raw provider SDKs) support the discipline better than frameworks that hide context assembly behind heavy abstractions. If you are hitting a wall, framework choice is one variable, but not the first.

How much does prompt caching actually save?

It depends on your traffic pattern and how well the stable prefix is designed. For high-volume agents with substantial stable content (system prompt + tool definitions + exemplars — 2-5k tokens), Anthropic and OpenAI cache hits can cut model cost by 50-90% and materially cut latency. For low-volume or highly variable calls, savings are more modest. The pattern is worth wiring up correctly on any high-volume agent.

How do we deal with 'lost in the middle'?

Two techniques. First, structure the context with clear section headers so the model can navigate it. Second, place the most important information at the top or the bottom rather than the middle. For very long contexts, consider whether the whole payload is actually needed — a smaller, better-curated context typically outperforms a larger one. Evaluate before assuming a larger window is helping.

Does context engineering matter for agentic loops as much as for single-shot calls?

More, actually. In an agentic loop the context grows on every turn — tool outputs, scratchpad reasoning, memory summaries — and the growth compounds. Without disciplined tool output compression, memory summarisation, and budget enforcement, an agent that started at 3k tokens on turn one can be at 30k tokens by turn ten, with cost and quality suffering visibly. Every technique here matters more for agents than for one-shot calls.

How do we prove to leadership that context work is worth the investment?

Instrument first, then show two numbers before and after. Cost per successful task usually drops 30-70% when a mature context-engineering pass is run against a system that has never had one. Task quality metrics — groundedness for RAG, task-success for agents — typically improve by measurable margins. Both numbers land as line items on the same dashboard executives already look at. The investment pays back on cost alone; the quality improvement is the bonus.

Written By

Inductivee Team — AI Engineering at Inductivee

Inductivee Team

Author

Agentic AI Engineering Team

The Inductivee engineering team — a remote-first group of multi-agent orchestration specialists, RAG pipeline architects, and data liquidity engineers who have shipped 40+ agentic deployments across 25+ enterprises since 2012. Our writing is grounded in what we actually build, break, and operate in production.

Agentic AI ArchitectureMulti-Agent OrchestrationLangChainLangGraphCrewAIMicrosoft AutoGen
LinkedIn profile

Inductivee is a remote-first agentic AI engineering firm with 40+ production deployments across 25+ enterprises since 2012. Our engineering content is written by active practitioners and technically reviewed before publication. Compliance: SOC2 Type II, HIPAA, GDPR, ISO 27001.

Ready to Build This Into Your Enterprise?

Inductivee engineers agentic systems, RAG pipelines, and enterprise data liquidity solutions. Let's scope your project.

Start a Project