TokenEconomizer

TokenEconomizer

Experience-driven black-box cost control for coding agents

Aaron J. Li1 Weijia Xu2 Chandan Singh2 Zixiao Chen3 Jeevana Priya Inala2 Charlotte Siska3 Acar Tamersoy3 Bin Yu1 Ion Stoica1 Michel Galley2 Jianfeng Gao2

1UC Berkeley2Microsoft Research3Microsoft Security

UC Berkeley UC Berkeley Microsoft Microsoft
18.4–30.9%lower mean cost on SWE-Bench, across five agent–model combinations
30 / 30cheaper than default in all 6 repositories × 5 agent–model combinations
4 of 5agent–model combinations where Pass@1 also improves

1 Motivation

Coding agents are built for task success, not token efficiency

Every turn re-bills the agent's whole context: its instructions, every tool description, and the task so far. Developers often use agents on the same codebase for many tasks, and each finished task shows what that environment needs: what the agent had to look up, which tools it actually used, and where it got stuck. Cost-saving approaches mostly treat each task on its own and rarely carry this experience forward.

What one task is billed for, turn by turn
    Schematic: each row is one turn's billed context; hatched parts are replayed from earlier turns.

    Three kinds of recurring waste

    From 60 profiled SWE-Bench runs of an unmodified agent, each matched by one strategy:

    1Rediscovering the same facts

    30% of tool calls repeat an earlier task's action once a repository has five or more tasks behind it.

    → Micro-skill injection

    2Paying for unused tools

    16 of the 23 tool descriptions billed on every turn are never called.

    → Tool pruning

    3Getting stuck on failures

    The 17% of tasks that fail take 32% of the spend.

    → Failure-loop intervention

    Why not a fixed strategy?

    On the same 60 tasks, we tried three popular open-source plugins, with one configuration for every repository. None of them learns from earlier tasks.

    RTKCompresses command output

    Rust Token Killer runs each shell command through a filter that condenses its output, such as test logs, listings, and diffs, before the agent sees it. The agent's tools and prompt stay the same.

    github.com/rtk-ai/rtk
    SerenaAdds code-navigation tools

    An MCP server backed by language servers. It adds symbol-level tools, such as finding a definition or its references, and the agent is told to prefer them over its own file reading and search.

    github.com/oraios/serena
    RepoMapAdds a repository map

    Aider's repository map ranks files and symbols by how central they are, favoring names in the task, and adds the top signatures (up to 2,048 tokens) to the agent's instructions, where they are billed on every turn.

    aider.chat/docs/repomap.html

    All three cut cost on Django and raise it on SymPy; on scikit-learn only RTK helps, and on Sphinx only RepoMap. No fixed strategy is cheaper everywhere, so TokenEconomizer learns what to do in each repository instead.

    Cost change of each fixed strategy, by repository
      60 profiled SWE-Bench tasks, 10 per repository, relative to default execution. Below zero is cheaper.
      Show the numbers

      2 Method

      How TokenEconomizer works

      An external controller that acts only through what the agent already exposes. After every task, it updates three policies for the next one.

      ControllerTokenEconomizerkeeps a state \(S_i\) for each repository, built from the tasks completed before \(\tau_i\)
      Coding agentLeft unchangedsame model and agent code; runs task \(\tau_i\) with what the controller sets

      1Micro-skill injection

      Instructions and detectors distilled from completed traces, gated by evidence

      Knowledge · instruction prefixbetween tasks
      system and agent instructions+ micro-skillstask \(\tau_i\)

      only the activated skills are added

      2Tool pruning

      Masks tools that recent tasks left unused or that are judged irrelevant; shell, read, and edit are always kept

      Interface · loaded tool setbefore each task
      shellreadeditgrepgittestwebjupyterbrowsermcp:*not loaded

      3Failure-loop intervention

      Learns the repository's turn budget, then redirects a repeated failure once, and stops the run if it persists

      Control · live rolloutduring the rollout
      … edittestrepeated failures … redirect editteststill repeating … stop edittestnever run
      Learning from each task. The completed trace \(\xi_i\) of every task updates all three meta-strategies, giving the state \(S_{i+1}\) used for the next task \(\tau_{i+1}\).
      Step by step: what each meta-strategy does, and its settingsexpand

      TokenEconomizer treats the agent as a black box. It acts only through what the harness already exposes, namely the instruction prefix, the loaded tools, and the live event stream, and never changes model weights or agent-loop code. Tasks \(\tau_1,\ldots,\tau_n\) in an environment arrive in order. Before task \(\tau_i\), the controller reads the repository state \(S_{i-1}\) distilled from the tasks completed so far and sets three policies:

      \[(\Delta P_i,\ \mathcal{U}_i,\ B_i) \;=\; \mathcal{C}(\tau_i,\ S_{i-1})\]

      \(\Delta P_i\): the micro-skills activated for this task  ·  \(\mathcal{U}_i\): the tools loaded  ·  \(B_i\): the turn budget that calibrates the failure-loop guard. The controller can always leave the default configuration in place, and its own model calls are charged to the task that triggers them.

      1

      Micro-skill injection

      Knowledge · between tasks
      1. Propose

        Every \(T=5\) tasks, an LLM proposer turns digests of recent traces into one-line facts about the repository, each with executable detectors.

      2. Check every trace

        After each task, the detectors test whether the trace confirmed or contradicted each fact, and whether the task needed it. No model call is involved.

      3. Inject selectively

        A fact enters the prompt only after \(n=3\) tasks with non-overlapping edits confirm it, and only while its need rate, the share of tasks exercising it that needed it, stays at or above \(\rho=0.4\).

      4. Retire on contradiction

        Support decays older evidence by a factor \(\gamma=0.8\) per task, and one contradiction counts as \(\lambda=5\) confirmations. Once the support drops below zero, the fact is retired for good.

      2

      Tool pruning

      Interface · before each task
      1. Protect the core

        Tools for shell execution and for reading, writing, and editing files are always kept.

      2. Mask on evidence

        A tool is masked once \(k=3\) consecutive tasks have left it uncalled.

      3. Mask on relevance

        An LLM judge reviews each never-called tool against the task description, with links to the repository's pull requests, issues, commits, and files masked out.

      4. Re-audit

        Every \(R=5\) tasks, the full catalog is restored, and a tool called during a re-audit is never masked again.

      3

      Failure-loop intervention

      Control · during the rollout
      1. Learn a turn budget

        The \(p\)-th percentile (\(p=90\)) of the turn counts of the repository's successful runs so far, times a margin \(\beta=1.25\):

        \[B_i=\beta\cdot Q_p\bigl(\{|\xi_j| : j<i,\ y_j=1\}\bigr)\]
      2. Watch cheaply

        After each tool call, rule-based checks look for repeated failures, dense errors, or a run past \(B_i\). No model call is involved.

      3. Judge, then redirect

        An LLM judge reads a digest of recent actions. If it finds the agent stuck with confidence at least \(c=0.7\), the agent is redirected with a summary of what it has tried; if the loop recurs, the run ends.

      4. Backstop

        At \(\kappa B_i\) turns, with \(\kappa=2.5\), a forced stop applies when edit churn, dense errors, and a repeated failure occur together.

      The values given are the settings used in our experiments. The same values serve every agent, model, and repository; they were fixed in development runs before the main experiments, and the other benchmarks change only what their task streams require. Each one can be changed to suit a deployment: for example, a smaller \(n\) or \(k\), or a smaller \(\beta\) or \(\kappa\), acts sooner and saves more, at a higher risk of a wrong decision.

      3 Results on SWE-Bench

      Consistent savings in every combination we evaluated

      Five agent–model combinations on the same 277 SWE-Bench tasks from 6 repositories, run in each repository's order. Costs include every controller call.

      Highlight one agent–model combination

      Applies to both charts. Click a method in the frontier legend to hide it.

      The savings are consistent

      Cost change for each repository under each combination. TokenEconomizer is cheaper in all 30.

      View data

      Adaptation expands the frontier

      Cost and Pass@1 change from default. TokenEconomizer variants form the frontier at or above default Pass@1.

        Full results

        Cost change from default and Pass@1, in %, with standard deviations. Bold: best per column among methods above default Pass@1; faded: Pass@1 below default.

        Highlight in the table

        Savings accumulate over the task stream

        Cumulative cost change over each repository's tasks (Claude Code). Starting with no traces, every repository is cheaper by the sixth task.

          Ablation: each meta-strategy aloneexpand

          Claude Code. Tool pruning saves the most on its own because it acts on every turn; none alone matches the combination, and Pass@1 stays within 3 points of default.

          4 Generalization

          Savings carry over to web development and security auditing

          Web-Bench builds one project task by task; in the security benchmarks every task is a new repository, so micro-skills are off.

          5 Examples

          What the controller does in real runs

          Nine examples from the paper's appendix, all on SWE-Bench. Pick one.

          Citation

          Cite this work

          @misc{li2026tokeneconomizer,
            title         = {{TokenEconomizer}: Experience-Driven Black-Box Cost Control for Coding Agents},
            author        = {Li, Aaron J. and Xu, Weijia and Singh, Chandan and Chen, Zixiao and
                             Inala, Jeevana Priya and Siska, Charlotte and Tamersoy, Acar and
                             Yu, Bin and Stoica, Ion and Galley, Michel and Gao, Jianfeng},
            year          = {2026},
            eprint        = {2610.22732},
            archivePrefix = {arXiv},
            primaryClass  = {cs.CL},
            url           = {https://arxiv.org/abs/2610.22732}
          }