cd /news/ai-agents/how-save-game-context-compaction-fix… · home › topics › ai-agents › article
[ARTICLE · art-161877] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

How Save-Game Context Compaction Fixes Spec Drift in Multi-Step Coding Agents (-91.9% Input Tokens)

A developer's benchmark experiment (E12) found that compacting an AI coding agent's context into structured JSON checkpoints at each milestone—dubbed the "Save-Game" pattern—cut cumulative input tokens by 91.9% (35,869 to 2,922) and API cost by 72.2% ($0.0340 to $0.0095) compared with unbounded history accumulation. In a three-milestone power-grid telemetry pipeline run in an isolated Proxmox VM, the accumulated-history agent scored 18/20 on a hidden grading suite, failing two end-to-end tests after losing track of a spec detail mid-context, while the compaction agent passed 20/20.

by read6 min views4 publishedNov 1, 2026

💡 AI Labo Benchmark Series — Experiment E12 (Ranked #6 out of 41 Patterns)

This post is part of our empirical benchmark series testing AI coding agent harness patterns inside network-isolated Proxmox VMs against a hidden 20-case grading suite.

E12 (Backlog Candidate C008) e12-20261028-vm216-01 VM216 (ai-e12-216, 0 NICs, virtio-serial QGA relay, systemd UID separation)gemini-3.8-flash (thinkingLevel: LOW)/compact at Milestones) — When an AI coding agent tackles a multi-step engineering task across several modules, keeping every prior file dump, telemetry log, and intermediate code output inside a single growing messages[] array (Unbounded Context Accumulation) causes two compounding problems:

6,556 ➔ 11,769 ➔ 17,544 input tokens). To test the solution—Milestone Context Compaction (the "Save-Game" Pattern)—we benchmarked a 3-milestone power-grid telemetry and carbon-credit clearing pipeline (Milestone 1: collector.py ➔ Milestone 2: clearing.py ➔ Milestone 3: dispatch.py) inside isolated Proxmox VM VM216:

AccumulatedHistoryRunner): VERBOSE_TELEMETRY_AUDIT_DUMP) into one continuous chat thread ( 0 compactions).MilestoneCompactionRunner): 120-token structured JSON checkpoint (SAVE_GAME_COMPACTION_V1) Mode A's accumulated history (35,869 cumulative input tokens) suffered a classic Lost-in-the-Middle failure on Milestone 2 (clearing.py), forgetting to apply .strip().upper() to contract_tier and failing 2 out of 20 hidden E2E tests (18 / 20, 90.0%). Mode B's Save-Game Milestone Compaction kept every turn under 1,400 input tokens (2,922 cumulative input tokens, -91.9% reduction), cut API cost by -72.2% ($0.0340 ➔ $0.0095), and achieved a flawless 20 / 20 (100%) pass.

Metric Mode A: Accumulated History ( AccumulatedHistory ) Mode B: Milestone State Compaction ( MilestoneCompaction ) Delta / Improvement
Hidden Grading Suite Score (20 Cases) 18 / 20 (90.0% — failed 2 E2E cases) 20 / 20 (100% Perfect Pass) +10.0 pt (Zero spec drift)
Context Compactions (compactions) 0 compactions 2 compactions (After M1 & M2) Reset history at each milestone gate
Turn 1 Input Tokens (M1: collector.py) 6,556 tokens ($0.00725 ) 650 tokens ($0.00290) -90.1% reduction
Turn 2 Input Tokens (M2: clearing.py) 11,769 tokens ($0.01247 ) 1,388 tokens ($0.00461) -88.2% reduction
Turn 3 Input Tokens (M3: dispatch.py) 17,544 tokens ($0.01429 ) 884 tokens ($0.00195) -95.0% reduction on final turn
Cumulative Input Tokens (promptTokenCount) 35,869 tokens 2,922 tokens -91.9% (12.28x token efficiency)
Cumulative Output Tokens (candidatesTokenCount) 1,894 tokens 1,937 tokens Equivalent code generation volume
LLM Calls (model_calls) 3 calls 3 calls (1 per milestone) Identical call count
Elapsed Execution Time (elapsed_seconds) 24.81 sec 22.52 sec -9.2% (1.10x faster)
Estimated API Cost (estimated_micro_usd) $0.0340 (34,005 micro-USD ) $0.0095 (9,457 micro-USD) -72.2% (3.60x cheaper)
+-------------------------------------------------------------------------+
| Proxmox Isolated VM216 (0 NICs, virtio-serial QGA, systemd UID split)   |
|  Target Task: 3-Milestone Power Grid & Carbon Clearing Pipeline         |
|               (M1: collector.py --> M2: clearing.py --> M3: dispatch.py)|
|                                                                         |
|  +-------------------------------------------------------------------+  |
|  | Mode A: AccumulatedHistoryRunner (No Compaction)                  |  |
|  |  - Turn 1 (M1): 6,556 in  --> collector.py PASS                   |  |
|  |  - Turn 2 (M2): 11,769 in --> Audit logs drown out M2 spec!       |  |
|  |                               Forgets contract_tier.strip().upper()|  |
|  |  - Turn 3 (M3): 17,544 in --> Cumulative 35,869 input tokens      |  |
|  |  --> Final Score: 18 / 20 (Crashes on lowercase/padded tiers!)    |  |
|  +-------------------------------------------------------------------+  |
|                                                                         |
|  +-------------------------------------------------------------------+  |
|  | Mode B: MilestoneCompactionRunner (Save-Game JSON Compaction)     |  |
|  |  - Turn 1 (M1): 650 in   --> collector.py PASS                    |  |
|  |  - [Compaction #1]: Discards raw logs; writes 120-tok JSON state  |  |
|  |  - Turn 2 (M2): 1,388 in --> Fresh context nails all M2 rules!    |  |
|  |  - [Compaction #2]: Updates verified_contracts in JSON checkpoint |  |
|  |  - Turn 3 (M3): 884 in   --> Cumulative 2,922 input tokens (-91.9%)| |
|  |  --> Final Score: 20 / 20 (100% Perfect Pass)                     |  |
|  +-------------------------------------------------------------------+  |
+-------------------------------------------------------------------------+

AccumulatedHistory): The Missing .strip().upper() on Turn 2 Inspecting accum-bundle.json (Mode A's final submitted code) reveals a textbook example of Attention Dilution:

collector.py) station_id and grid_zone. clearing.py) VERBOSE_TELEMETRY_AUDIT_DUMP_M1 plus the full Turn 1 code had bloated the prompt to 11,769 tokens`` contract_tier via

def settle_grid(readings, contract_tier="BASE", credit_offset=0):
    if not isinstance(readings, list) or len(readings) == 0:
        raise ValueError("readings must be a non-empty list")
    if contract_tier not in ALLOWED_TIERS:
        raise ValueError(f"contract_tier must be one of {ALLOWED_TIERS}")

Because of that single omitted .strip().upper(), Mode A crashed with a ValueError on two hidden E2E integration tests that passed padded/lowercase tier strings (contract_tier=" green " in e2e_01 and contract_tier="hydro" in e2e_02).

MilestoneCompaction): The Exact Save-Game JSON Checkpoint In Mode B, as soon as Milestone 1 (collector.py) passed verification, the harness wiped the raw conversation history and started Turn 2 with this compact SAVE_GAME_COMPACTION_V1 JSON checkpoint:

{
  "checkpoint_type": "SAVE_GAME_COMPACTION_V1",
  "completed_modules": ["collector.py"],
  "history_compacted": true,
  "milestone_completed": 1,
  "next_target_module": "clearing.py",
  "verified_contracts": {
    "collector.collect_readings": "PASS (returns list of dicts with station_id, grid_zone in NORTH/SOUTH/WEST, mwh_units>0, rate_cents>=0, 0<=carbon_bps<=1500, non-mutating)"
  }
}

Because Turn 2 ran in a fresh 1,388-token context containing only the verified upstream contract and Milestone 2's specification, Mode B had zero attention dilution—properly implementing clean_tier = contract_tier.strip().upper() and passing all 20 / 20 test cases:

Test Case Group Verification Target Mode A ( Accumulated ) Mode B ( Save-Game Compact )
collector_01 –collector_06 Milestone 1: Non-mutation, type checks, bounds ( 0..1500 bps) 6 / 6 PASS 6 / 6 PASS
clearing_01 –clearing_08 Milestone 2: First-seen order, 400 vs 401 bps levy,12000 tier boundary 8 / 8 PASS 8 / 8 PASS
e2e_01_green_below_12000_minus_zero_and_at_separator E2E: Normalize contract_tier=" green " + @ delimiter + -0 ❌ FAIL ( ValueError) ✅ PASS
e2e_02_hydro_levy_and_credit_dispatch E2E: Normalize contract_tier="hydro" + 20% discount + credit offset ❌ FAIL (ValueError) ✅ PASS
e2e_03 –e2e_06 E2E: Zero rate cents, line order preservation, cross-stage error propagation 4 / 4 PASS 4 / 4 PASS
Total 20 Hidden Cases 18 / 20 (90.0%) 20 / 20 (100%)

When building multi-step agent workflows (or using /compact in interactive coding agents):

Lost-in-the-Middle) starts happening well above 10,000–15,000 tokens of noisy tool logs. Compact E05 (Subagent Folding), natural-language summaries often drop exact type contracts. Instead, record a structured JSON object containing completed_modules, verified_contracts (exact function signatures & invariants), and next_target_module. E20): MEMORY.md``E21): E16): E19): E14):

── more in #ai-agents 4 stories · sorted by recency
── more on @proxmox 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-save-game-contex…] indexed:0 read:6min 2026-11-01 · —