microsoft / microsoft/amplifier
Compaction thrash loop: sub-agent with oversized working set loops for hours (463 compactions, ~31.8M tokens) with no circuit breaker; cache hits permanently drop to 0 after first compaction
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 3.1k
- Forks
- 261
- Avg merge
- 3h 28m
- Merged PRs (30d)
- 13
Description
Summary
A delegated sub-agent (explorer-type, spawned via delegate) whose working context exceeded the compaction threshold entered a stable pathological loop: compaction evicted its accumulated findings → the agent re-read the same files to recover them → context refilled → compaction fired again.
In the observed session the loop ran 463 compaction cycles over 108 minutes (roughly one every 14 seconds), consuming 31.8M input tokens ($41) to ultimately produce a two-sentence answer. No mechanism detected the lack of forward progress or halted the agent. The parent session simply saw a delegate call that hadn't returned yet.
The task itself was trivial (determine what icon files a repo needs); the actual implementation work after the explorer returned took ~4 minutes.
Observed behavior (from the sub-session's events.jsonl)
- 1,771 tool calls in one sub-session: 887 file reads, 652 bash commands, 169 greps — with the same handful of files re-read dozens of times each
- 475 provider round-trips
- 463 context compactions in 108 minutes
- ~31.8M input tokens consumed (~$41 at list price) for a task whose useful output was two sentences
- Prompt cache permanently collapsed: after the first compaction,
cache_read_tokensdropped to 0 and never recovered — every subsequent request was a full uncached re-send. This is the cost multiplier: the same work with healthy cache hits would have been roughly $1. - The loop terminated only by luck: the agent happened to emit its final answer during a window where enough context survived compaction.
Reproduction conditions
The trigger is any delegated agent whose minimum working set exceeds the post-compaction context budget:
- Delegate a broad investigation (here: "investigate these two repositories" in a single explorer delegation — one Python CLI repo plus one Rust codebase)
- The agent issues 4–8 parallel file reads per step; context balloons past the compaction threshold quickly (observed: ~238K tokens against a ~203K budget within the first 90 seconds)
- Compaction fires and evicts the older half of the findings
- The agent no longer remembers what it read, so it re-reads the same files (the same README, pyproject.toml, build script, and source files recur throughout the trace)
- Context refills; go to 3
The loop is self-sustaining — there is no state from which it naturally recovers, because the agent's working set never fits in the post-compaction budget.
Why this is a platform bug and not just a bad delegation
Yes, the delegation was over-broad (two repos in one explorer), and narrower scoping avoids the problem. But the platform behavior is the issue:
- The system has a stable failure attractor with unbounded wall-clock time and unbounded cost, and no detection or escape mechanism.
- It fails silently from the parent session's perspective — no warning, no progress signal, no cost signal, for nearly two hours.
- The compaction ↔ cache interaction multiplies the damage: once compaction rewrites history, cache hits go to zero for the remainder of the sub-session, so every thrash cycle is billed at full context price.
Expected behavior / suggested mitigations
Any of these would bound the damage:
- Compaction-loop circuit breaker — if compaction fires more than N times (e.g. 5) in a sub-session without forward progress, abort the agent and return partial findings with an explanatory note to the parent.
- Duplicate-work detection — an agent re-reading the same file it has already read multiple times post-compaction is a strong thrash signal; surface it or count it toward the breaker.
- Cache-health canary —
cache_read_tokens: 0sustained across many consecutive requests indicates the session is thrashing and will not recover on its own. - Budget ceilings on delegated agents — configurable wall-clock / token / cost caps per sub-session so the worst case is bounded regardless of failure mode.
Possible companion issue
Even outside a thrash loop, "the first compaction permanently kills prompt-cache hits for the remainder of the sub-session" may deserve its own investigation as a cost bug, if that behavior is general and not specific to this failure mode.
Diagnostics
The signature is easy to spot in a sub-session's events.jsonl:
- compaction events at a regular, rapid cadence (every ~10–20s)
cache_read_tokensfalling off a cliff to 0 immediately after the first compaction and staying there- the same file paths recurring in read-tool calls throughout the trace
Environment
- Root session on an OpenAI GPT-5-class model via the OpenAI provider; failure occurred inside a delegated explorer sub-session
- Linux (WSL2), amplifier-app-cli
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the delegated sub-session’s events.jsonl and trace the compaction, cache-read, and delegation handling that produces the repeated cycle. Reproduce the rapid compaction and repeated file reads, then verify that the sub-agent stops or reports partial findings once thrashing or its resource budget is exceeded.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- ai-infra-agents, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100