A team of researchers from Microsoft Research and UC Berkeley have released TokenEconomizer, an open-source cost controller for coding agents. TokenEconomizer is a plugin that learns from past sessions in a repository to cut waste in later ones. It works with Claude Code, Codex, GitHub Copilot CLI and Pi. It does not touch model weights or agent code. On 277 SWE-Bench tasks, it lowered mean cost by 18.4% to 30.9% across 5 agent-model settings.
TL;DR
- Package: A standard-library Python package and agent plugins, with 3 switchable mechanisms.
- Runs on: Any machine running Claude Code, Codex, Copilot CLI or Pi with Python 3.10+. No GPU and no API key of its own.
- Performance: 18.4% to 30.9% lower mean SWE-Bench cost, and cheaper in all 30 repository-setting cells.
- Best: 30.9% lower cost on Claude Code with Opus 4.8 (33.2% when combined with RTK).
- Worst: Only 6.4% to 9.3% savings on ReposVul audits; Pass@1 drops 1.0 point on Opus 4.8.
Why do coding agents waste tokens?
Every agent turn re-bills the system prompt, every loaded tool schema and the full history. The research team profiled 60 SWE-Bench tasks across 6 repositories using Claude Code with Opus 4.8. They found 3 recurring sources of waste:
- Repeated discovery: once 5 tasks precede the current one, 30% of tool calls repeat an earlier action.
- Unused tools: 23 tool schemas load every turn. 16 are never called, and 3 cover 98% of calls.
- Failure loops: 10 failed runs were 17% of tasks but 32% of total spend.
They also tested 3 fixed open-source strategies: RTK, Serena and Aider’s RepoMap. None was cheaper everywhere. All 3 cut cost on Django and raised it on SymPy.
How does TokenEconomizer work?
TokenEconomizer is an external controller that treats the agent as a black box. It keeps a state per repository, built from completed traces. Before each task, it sets 3 policies through the prompt, the tool settings and the event stream.
1. Micro-skills
An LLM proposer turns trace digests into 1-line facts, such as the working test command. Each fact carries regex detectors that check later traces without a model call. A fact enters the prompt after 3 confirmations on tasks with non-overlapping edited files. Its need rate must also stay at or above 0.4. One contradiction counts as 5 confirmations, so wrong facts retire quickly.
2. Tool pruning
Shell, read, write and edit tools are always kept. Other tools are masked after 3 consecutive unused tasks, or when an LLM judge marks them irrelevant. The full catalog returns every 5 tasks for a re-audit. On Django with Claude Code, the first request on task 2 fell from 43,351 to 16,295 prompt tokens.
3. Failure-loop intervention
The controller learns a turn budget: 1.25 times the 90th percentile of successful run lengths. Cheap rule checks flag repeated failures or dense errors. An LLM judge then decides if the agent is stuck, at 0.7 confidence or higher. A stuck agent gets 1 redirect, then a stop if the loop recurs.
‘+m.w+’
‘+m.h+’
- ‘+m.l.map(function(x){return ‘
- ‘+x+’
‘}).join(”)+’
‘;q(‘.sbtn[data-s]’).forEach(function(b){b.classList.toggle(‘on’,+b.dataset.s==k)});rows(k);document.getElementById(‘te-mech’).animate&&document.getElementById(‘te-mech’).animate([{opacity:0},{opacity:1}],{duration:350});setTimeout(post,200)}
q(‘.sbtn[data-s]’).forEach(function(b){b.onclick=function(){clearInterval(timer);show(+b.dataset.s)}});
document.getElementById(‘te-play’).onclick=function(){clearInterval(timer);var k=0;show(0);timer=setInterval(function(){k++;if(k>2){clearInterval(timer);return}show(k)},2200)};
var D=[[‘Claude Code + Sonnet 5’,-23.6,1.3],[‘Claude Code + Opus 4.8’,-30.9,-1.0],[‘Codex + GPT-5.6 Terra’,-24.7,0.9],[‘Codex + GPT-5.6 Sol’,-26.1,1.6],[‘Copilot CLI + Sonnet 5′,-18.4,2.6]];
var mode=”cost”;
function bars(){var h=””;D.forEach(function(d){var v=mode==’cost’?d[1]:d[2];var w=mode==’cost’?Math.abs(v)/35*100:Math.abs(v)/3*100;var c=mode==’cost’?’var(–green)’:(v<0?’var(–red)’:’var(–blue)’);h+=’
‘});document.getElementById(‘te-bars’).innerHTML=h;setTimeout(function(){q(‘#te-bars b’).forEach(function(b){b.style.width=b.dataset.w+’%’})},60);setTimeout(post,300)}
q(‘.sbtn[data-m]’).forEach(function(b){b.onclick=function(){mode=b.dataset.m;q(‘.sbtn[data-m]’).forEach(function(x){x.classList.toggle(‘on’,x==b)});bars()}});
function cells(){q(‘.cells’).forEach(function(c){var bad=+c.dataset.bad,h=””;for(var i=0;i<30;i++)h+=’‘;c.innerHTML=h;var is=c.querySelectorAll(‘i’);is.forEach(function(x,i){setTimeout(function(){x.style.background=i


