Context Engineering for Long-Running Agents
Techniques that keep multi-turn agents from degrading: compaction, structured notes, and sub-agent isolation.
The problem
Long-running agents fail in a characteristic way: not with a crash, but with slow drift. Early decisions get forgotten, tool outputs pile up, and the model starts optimizing against stale context.
The context window is a finite budget. Every token competes for attention, and relevance decays with distance from the edges.
Four techniques that work
1. Compaction, not truncation
Summarize and restart rather than chopping the tail. Preserve in the summary:
- The active goal and its acceptance criteria
- Decisions made and rejected (rejected options get re-proposed otherwise)
- Unresolved blockers with owners
- File paths and identifiers actually in play
Naive truncation keeps recent noise and drops old intent — exactly backwards.
2. Structured scratchpads
Keep state outside the window, in files the agent re-reads rather than remembers:
progress.md # what is done, what is in flight
decisions.md # choices + rationale, append-only
blockers.md # what is stuck and why
Append-only logs beat mutable state: the history itself is context.
3. Sub-agent isolation
Spawn a sub-agent for a self-contained sub-task. It gets a clean window, burns its own tokens exploring a dead end, and returns only the conclusion. This is the single highest-leverage move for keeping the main thread clean.
4. Just-in-time retrieval
Ship pointers (paths, queries, IDs), not payloads. Read files at the moment they matter. Pre-loading “everything that might be relevant” is how windows fill before work starts.
Measuring whether it is working
Watch these instead of vibes:
| Signal | Healthy | Degrading |
|---|---|---|
| Context size | Stable across turns | Monotonic growth |
| Repeat questions | Rare | Agent re-asks resolved items |
| Reverted work | Rare | Re-proposing rejected approaches |
| File churn | Focused | Touching unrelated modules |
If the agent re-proposes an approach it already rejected, your compaction is dropping decision history — fix the summary template before blaming the model.