Skip to content

Context Engineering for Long-Running Agents

An agent can have a large context window and still lose track of the task.

The problem is not only whether the next message fits. The context must contain the right information at the right time:

  • the current goal
  • relevant evidence
  • active constraints
  • recent decisions
  • tool results needed for the next step
  • enough progress state to continue

Everything else competes for the model’s attention and increases token cost.

Context engineering is the design of what enters the model’s working context, when it enters, how long it stays, and where durable information lives outside it.

For a beginner, it helps to think of context as the documents spread across a desk.

The desk may contain:

  • the current conversation
  • system and project instructions
  • files the agent has read
  • command output
  • tool definitions
  • skill content
  • summaries of previous work
  • results returned by subagents

The model uses this material to choose its next response. It does not mean every detail is permanently remembered.

As the desk fills, the system may:

  • remove old tool output
  • summarize older messages
  • start a fresh context
  • delegate work to another context
  • load reference material only when needed

Durable state must live somewhere more reliable than the current model request.

Do not put every kind of information into one long prompt.

StoreWhat belongs thereExample
Active contextInformation needed for the next decisionsCurrent bug, inspected files, latest test failure
Project instructionsStable rules used across tasksBuild commands, architecture conventions
On-demand knowledgeDetailed guidance needed for certain tasksDeployment skill, API reference
Durable artifactsEvidence and decisions that must survive context lossPlan, investigation notes, test report
Application stateAuthoritative workflow progressApproval status, job state, idempotency key

Subagents add a sixth useful location: an isolated temporary context that returns only a bounded result.

flowchart TD
    G["Goal and stable constraints"] --> A["Active agent context"]
    A --> R["Retrieve only relevant files and tools"]
    R --> W["Work and collect evidence"]
    W --> D{"Information still needed?"}
    D -->|"Needed now"| A
    D -->|"Reusable later"| K["Project instructions or skill"]
    D -->|"Task evidence"| F["Durable artifact"]
    D -->|"Independent subtask"| S["Subagent with isolated context"]
    S --> B["Bounded result"]
    B --> A
    A --> C{"Context becoming noisy or full?"}
    C -->|"No"| W
    C -->|"Yes"| M["Compact or start a focused handoff"]
    M --> A

Good context management is continuous. It is not a cleanup step performed only after the window is full.

A larger context window increases capacity. It does not guarantee good attention.

An agent can still struggle when context contains:

  • several obsolete plans
  • full logs when only one error matters
  • large generated files
  • duplicated instructions
  • tool schemas it will never use
  • findings from unrelated subagents
  • old assumptions that later evidence disproved

The useful question is not “Can this fit?” It is “Will this help the next decision?”

Do not preload an entire repository because the task might touch it.

A better sequence is:

  1. identify the question
  2. search for likely entry points
  3. read the smallest relevant files
  4. follow references when evidence requires it
  5. stop gathering when the decision is grounded

For a login failure, the agent may first inspect:

  • the failing request or test
  • the authentication entry point
  • the token validation path
  • related configuration

It does not need every UI component, migration, and deployment log.

On-demand discovery makes the context smaller and keeps the evidence connected to the current hypothesis.

Search tools are valuable because they narrow the information surface.

Useful searches include:

  • symbol or function names
  • error messages
  • configuration keys
  • test names
  • imports of a deprecated dependency
  • call sites of a public API

Repository search and code-intelligence tools often provide a better first step than embeddings for local source code because identifiers, paths, imports, and exact strings carry strong structure.

This does not make retrieval-augmented generation obsolete. Semantic retrieval remains useful for large knowledge bases, loosely worded documentation, or material without reliable identifiers. Choose retrieval from the shape of the information, not from a universal rule.

Tool output enters context too.

Weak:

Terminal window
npm test

This may produce thousands of irrelevant lines.

Better:

Terminal window
npm test -- auth-refresh.test.ts

Other useful controls:

  • request line ranges instead of whole large files
  • filter logs around the failure
  • return structured fields instead of complete API responses
  • cap search results
  • store large artifacts in files and return their paths
  • summarize repeated errors without hiding the first full example

A tool should provide enough evidence to act without flooding the model.

A task list is useful working state:

[done] reproduce refresh failure
[done] trace token validation
[in progress] add regression test
[pending] implement fix
[pending] run focused and integration checks

It helps the agent and user see:

  • what has been attempted
  • what remains
  • where the run is blocked
  • whether the task stopped prematurely

But conversation text is not an authoritative workflow database.

Persist important progress separately when:

  • work must survive process failure
  • several agents coordinate
  • approvals may take hours or days
  • side effects must not repeat
  • operators need an audit trail

Use a database, workflow engine, issue, pull request, or structured task file depending on the reliability requirement.

Files are useful for information that must survive compaction or a new session:

  • approved requirements
  • architecture decisions
  • investigation findings
  • migration maps
  • lists of changed files
  • test commands and results
  • unresolved risks

A useful handoff artifact is concise enough to reload but specific enough to verify:

# Current Goal
Preserve login across token refresh without weakening expiry checks.
# Confirmed Evidence
- `src/auth/refresh.ts` accepts the old token.
- `src/auth/session.ts` rejects the refreshed session.
- Focused reproduction: `npm test -- refresh-session.test.ts`
# Decision
Keep validation in the session service. Do not add a client-side retry.
# Remaining Work
- Add the failing regression case.
- Implement the scoped server fix.
- Run auth integration tests.

Do not save every intermediate thought. Save facts, decisions, evidence, and unfinished work.

Stable instructions and on-demand procedures have different context costs.

Use project-level instructions for rules that usually matter:

  • package manager
  • build and test commands
  • high-level architecture
  • repository-wide conventions
  • files that must not be edited

Use skills for detailed procedures needed only for certain tasks:

  • release process
  • incident response
  • document generation
  • security-review checklist
  • product-specific API workflow

Loading a full deployment manual into every debugging session wastes context. Keeping a critical repository rule only in an optional skill risks missing it.

Current Claude Code documentation follows this distinction: CLAUDE.md is persistent context, while skill descriptions are visible for routing and full skill content loads when used.

A subagent starts with a separate context, performs a bounded task, and returns a result.

This is useful when a subtask generates information the main agent does not need to retain:

  • reading a large set of documentation
  • scanning many files for one pattern
  • reviewing a diff for one risk category
  • running and interpreting a verbose test suite
  • comparing independent implementation options
flowchart LR
    M["Main context<br/>goal and decisions"] --> P["Delegation prompt<br/>scope and output contract"]
    P --> S["Subagent context<br/>independent reads and tools"]
    S --> O["Bounded result<br/>findings and evidence"]
    O --> M

The delegation prompt should contain:

  • the exact question
  • allowed scope
  • relevant starting evidence
  • required output format
  • what not to do

Do not copy the whole parent conversation automatically. The isolation is useful only when the subagent receives a curated task.

Keep work in the main context when:

  • several phases depend on the same detailed history
  • the task needs frequent user clarification
  • the change is small
  • the subagent would need to rediscover everything
  • the returned summary would omit information required for implementation

Subagents reduce context pressure, but they introduce delegation cost and another place for misunderstandings.

Use A Verification Subagent As A Context Boundary

Section titled “Use A Verification Subagent As A Context Boundary”

Verification is a strong candidate for isolated context because it can generate much more information than the main coding agent needs.

A browser-verification run may contain:

  • accessibility snapshots for several pages
  • screenshots and video frames
  • network request and response details
  • browser-console output
  • application logs
  • database queries
  • several failed attempts
  • a complete Playwright trace

Putting all of this into the main coding loop can push out the original goal and implementation decisions.

Instead, give a verification subagent:

  • the acceptance criteria
  • the application entry point
  • a safe test environment
  • the relevant test identity or fixture
  • permission to inspect but not silently redefine success
  • an output contract
flowchart LR
    M["Main agent<br/>goal and implementation"] --> C["Verification contract<br/>journey and expected evidence"]
    C --> S["Verification subagent<br/>browser, API, logs, and state"]
    S --> A{"Criteria satisfied?"}
    A -->|"No"| F["Bounded failure report<br/>reproduction and evidence links"]
    A -->|"Yes"| P["Pass report<br/>checks and retained artifacts"]
    F --> M
    P --> M

The subagent can investigate extensively while the parent receives a bounded result:

Status: failed
Scenario:
Submit feedback and confirm it survives a refresh.
Observed:
- POST /api/feedback returned 201.
- Success message appeared.
- Entry disappeared after refresh.
Likely boundary:
Persistence, not browser rendering.
Evidence:
- trace: artifacts/feedback-persistence.zip
- server log: artifacts/api.log#L84
Recommended next check:
Inspect the write transaction and development database connection.

This report contains enough evidence for the main agent’s next decision without copying the complete browser trajectory.

The verification subagent should not quietly:

  • change the acceptance criteria
  • update snapshots merely to make them pass
  • modify production code while claiming to be an independent verifier
  • reuse contaminated state from the implementation run
  • hide checks it could not perform

When repair is allowed, record it as a separate role or phase. The system should preserve which evidence came from the original result and which came after a fix.

Use this pattern when:

  • verification is verbose
  • browser or integration work uses different tools
  • the main task already has a long implementation history
  • an independent pass/fail perspective is valuable
  • several verifiers can safely inspect different risk areas

Keep verification in the main context when the check is one fast command and its output directly guides the next edit. Spawning another agent for every unit test adds latency and loses useful continuity.

Compaction replaces older conversation material with a shorter summary.

It is useful, but it cannot preserve every detail. A good compacted handoff should retain:

  • the current objective
  • acceptance criteria
  • non-goals and safety boundaries
  • files read or changed
  • commands and meaningful results
  • confirmed facts
  • decisions and their evidence
  • unresolved questions
  • the next concrete step

Do not assume that an instruction mentioned near the start of a long chat will survive unchanged. Stable rules belong in project instructions; task decisions belong in durable artifacts.

Current Claude Code documentation says it first clears older tool outputs and then summarizes conversation history when needed. It also allows compact instructions that tell the system what the summary should preserve.

Sometimes a fresh session is better than repeatedly summarizing a crowded one.

Use a handoff when:

  • the task is moving from research to implementation
  • the original context contains many rejected hypotheses
  • a new specialist needs only approved conclusions
  • compaction repeatedly refills immediately
  • the remaining work is now independently understandable

A handoff is not “start over.” It is:

  1. produce a grounded task artifact
  2. open a clean context
  3. load the artifact and relevant files
  4. verify its claims against the repository
  5. continue from the documented state

This reduces inherited noise while preserving evidence.

A difficult codebase task often needs more than one handoff. Research, planning, implementation, and verification use different evidence and produce different kinds of noise.

Keeping every phase in one conversation means the implementation context may contain:

  • abandoned explanations from early exploration
  • large search results and file dumps
  • several versions of the plan
  • corrections that conflict with earlier instructions
  • implementation details that are no longer relevant to verification

A more deliberate workflow gives each phase a focused context and a reviewed artifact from the previous phase.

flowchart LR
    R["Research current code"] --> RA["Verified research artifact"]
    RA --> G1{"Human review"}
    G1 --> P["Plan the change"]
    P --> PA["Reviewed implementation plan"]
    PA --> G2{"Human approval"}
    G2 --> I["Implement in a focused context"]
    I --> T["Tests and runtime evidence"]
    T --> V["Independent verification"]

The fresh context does not have to be a completely new chat. It can be:

  • a new session loaded with the reviewed artifact
  • a deliberately compacted session with explicit preservation instructions
  • an isolated subagent assigned one bounded phase

The important property is that the next phase receives approved conclusions rather than the entire transcript that produced them.

Research answers: What does the current system actually do?

The agent should inspect the live repository, trace the relevant execution path, and identify existing conventions before proposing changes. Broad exploration can happen in isolated subagents, but their conclusions must include references that the main agent or a human can verify.

A useful research artifact records:

  • the exact problem and observed behavior
  • relevant files, symbols, configuration, and tests
  • the current control flow or data flow
  • dependencies and ownership boundaries
  • facts confirmed by code or runtime evidence
  • inferences that still need validation
  • unresolved questions and likely risks

File paths and symbol names are usually more durable than line numbers, which move as the repository changes. Line references can help reviewers, but they should not be the only evidence.

Research should avoid designing the solution prematurely. Its purpose is to produce a compact, evidence-backed model of the current system.

Before planning begins, review the artifact:

  1. Can its important claims be traced to code, tests, logs, or documentation?
  2. Does it distinguish verified facts from assumptions?
  3. Did it inspect adjacent patterns instead of studying one file in isolation?
  4. Are important unknowns visible rather than silently guessed?

An incorrect research artifact can make a detailed plan confidently wrong.

Planning answers: Given the verified current state, what should change?

The planning context needs the approved research artifact, the goal, constraints, and only the code required to resolve remaining design questions. It does not need every search result from the research phase.

A useful implementation plan includes:

  • the intended behavior and acceptance criteria
  • exact files and symbols expected to change
  • ordered implementation steps
  • interface, schema, and data-flow changes
  • compatibility, migration, security, and failure concerns
  • tests and runtime checks for each important behavior
  • explicit non-goals
  • rollback or recovery steps when the change is risky

The plan should be detailed enough that implementation does not have to rediscover the architecture. It should not pretend that every line can be predicted before editing begins.

Human review at this boundary is especially valuable. Reviewers can correct the scope, challenge architectural assumptions, and confirm that the verification plan tests the real requirement before code changes make those mistakes more expensive.

Phase 3: implementation consumes the reviewed plan

Section titled “Phase 3: implementation consumes the reviewed plan”

Implementation answers: Can the approved change be made and verified against the current repository?

Start with:

  • the reviewed plan
  • stable project instructions
  • the necessary current files
  • acceptance criteria and safety boundaries
  • the commands used to verify the change

The implementation agent must still check the plan against the repository. Another contributor may have changed a file, a symbol may have moved, or research may have missed an important constraint.

When implementation must depart from the plan:

  1. record the new evidence
  2. explain why the approved step is no longer correct
  3. update the plan or request another decision
  4. continue only when the deviation is understood

This prevents the plan from becoming an unquestioned stale specification.

Verification should produce bounded evidence rather than another long narrative.

Record:

  • commands or scenarios executed
  • meaningful pass and failure results
  • acceptance criteria covered
  • behavior that could not be tested
  • residual risks and follow-up work

For high-risk work, an independent verification context is useful because it receives the requirement and resulting change without inheriting every implementation assumption. The code, tests, and observed runtime behavior remain authoritative; the research and plan artifacts are supporting evidence.

Do not carry forward:

  • raw search output already represented by confirmed findings
  • full subagent transcripts
  • rejected hypotheses
  • obsolete plan drafts
  • repetitive corrections
  • logs unrelated to the remaining decision

The goal is not the smallest possible prompt. It is the smallest context that still preserves the evidence, intent, constraints, and next decision.

Consider a repository-wide dependency migration.

  • migration goal and non-goals
  • dependency graph
  • batch definitions
  • accepted architectural decisions
  • integration status
  • blockers that affect several batches
  • one batch contract
  • owned files
  • prerequisite changes
  • verification commands
  • relevant conventions
  • batch status
  • commits or pull requests
  • verification evidence
  • discovered exceptions
  • integration order
  • full transcripts from every worker
  • unrelated file contents
  • repeated logs already captured in artifacts
  • obsolete migration plans

This is why parallel agents need task and repository isolation, not merely more context windows.

Every available tool adds at least a name and description; some runtimes add the full schema.

Large tool catalogs can:

  • consume tokens before work begins
  • make tool selection harder
  • introduce overlapping descriptions
  • expose capabilities unrelated to the task

Use:

  • small task-specific tool sets
  • deferred tool loading where supported
  • precise names and descriptions
  • subagent-specific tool permissions
  • MCP toolset selection instead of enabling every server

Claude Code currently defers full MCP schemas by default and loads them through tool search when needed. Other hosts may load every schema eagerly, so verify the behavior of the runtime you deploy.

Useful measurements include:

  • tokens loaded before the first user request
  • file and tool-output tokens added per turn
  • number and size of tool results
  • compaction frequency
  • repeated reads of the same material
  • number of active tool definitions
  • subagent input and returned-summary size
  • failures after compaction or handoff
  • decisions lost between sessions

Token count is not the only signal. A smaller context can still be poor if it omits the requirement or contains an incorrect summary.

FailureCauseBetter approach
Load the whole repositoryCapacity is mistaken for relevanceSearch, then read on demand
Paste complete logsRaw output is treated as evidenceFilter and preserve the key failure
Put every rule in project instructionsAlways-loaded context grows without limitMove task-specific procedures to skills
Put critical rules only in skillsOptional content may not loadKeep mandatory rules always available
Delegate with a vague promptSubagent must guess the real questionGive scope, evidence, and output contract
Return a complete subagent transcriptIsolation benefit is lostReturn bounded findings and references
Treat compaction as perfect memorySummaries omit detailsPersist facts and decisions in artifacts
Use conversation as workflow stateRestarts can lose progressStore authoritative state outside the model
Keep extending a polluted sessionRejected hypotheses remain influentialCreate a verified handoff to a fresh context

Before a long run:

  • Define the goal, acceptance criteria, and non-goals.
  • Identify stable project instructions.
  • Keep optional procedures in on-demand skills or docs.
  • Scope tools to the task.
  • Decide where task state and evidence will be persisted.
  • Define when to delegate, compact, or hand off.

During the run:

  • Search before reading large areas.
  • Bound command and API output.
  • Update progress from evidence.
  • Save confirmed decisions outside the conversation.
  • Remove or supersede stale assumptions.
  • Keep subagent results concise and verifiable.

Before a handoff:

  • Record the current objective.
  • List files read and changed.
  • Preserve test commands and results.
  • Distinguish facts from assumptions.
  • Record decisions and remaining risks.
  • State the next concrete action.
  • Context is temporary working space, not authoritative long-term memory.
  • Relevance matters as much as context-window capacity.
  • Gather evidence on demand instead of preloading everything.
  • Bound tool output and store large artifacts outside the conversation.
  • Keep stable rules, optional procedures, task evidence, and workflow state in different stores.
  • Use subagents to isolate verbose independent work, not to avoid clear task ownership.
  • Use a verification subagent when browser traces, logs, and runtime evidence would overwhelm the implementation context.
  • Treat compaction as a lossy handoff.
  • Start a fresh context when a verified artifact is cleaner than another summary.
  • Separate complex work into research, planning, implementation, and verification contexts with reviewed artifacts between them.
  • Measure context behavior instead of assuming a larger window solves the problem.

Diagram viewer