Early-fault success goes from 0% to 100%; late-fault tokens fall from 7566.7 to 3694.4

Adaptive Skill Granularity for Coding Agents: Runtime Routing and Macro-to-Micro Recovery

Dingxuan Zhang, Yanhui Jiang, Jun Wang, Hefeng Zhou

cs.AI, cs.SE

2026-10-22

Runtime routing picks micro, macro, or downgrade. On 7 faults, early-failure success goes from 0% to 100%; selective recovery cuts late-failure tokens from 7566.71 to 3694.43.

What problem this solves

Coding agents store repeated procedures as skills: when to act, which tools to call, and how to tell that the job is finished. Retrieval, skill graphs, and fragments mined from old trajectories all happen before the run. Once execution starts, the agent still picks a granularity. One step can use micro tools, file reads, search, edits, and tests, or a macro skill that bundles those steps into a single call.

SWE-Skills-Bench reported that injected skills give uneven gains, can cost more, and can worsen software-engineering results when the abstraction does not fit the repository. Moving a module is a natural macro: move the file, rewrite imports, validate. A one-file patch is a poor fit. A missed precondition stops the macro. Micro-only execution spends tokens. Macro-only execution drops successes.

Method

Adaptive Skill Granularity edits the actions allowed at the current step. Micro mode keeps primitive tools. Macro mode keeps macro skills. Hybrid mode may call a macro first and, after an observable failure, drop to micro tools. The drop runs one way.

The controller fires before execution. It reads the prompt, metadata, and the initial workspace, and it does not read this run's verifier, so the route cannot see the ending. Features are structural counts: file mix, entity-like strings, AST size, imports, cross-file dependencies, and a refactor flag. A handwritten rule is the reference. The learned router is a decision tree with depth at most 4, fit offline to past success and token cost, saved as JSON, and walked node by node at runtime. A shallow tree can be audited when it sends a task to a macro. A second router decides whether a macro failure may recover.

A macro runs only with a contract: precondition, side effects, its own check, failure types, and a micro fallback. The prototype ships three handwritten macros: summarize a Python module, replace text and recheck, and move a module while updating imports. A finite-state machine handles recovery. Missing text, syntax or test failure, broken JSON, and injected faults all count as macro failures. With recovery on, the executor stays in the current workspace and switches to micro tools. With recovery off, the failure stops the run. The validator on the final workspace decides success. Automatic creation of new macros is not tested. A candidate must replay and must document side effects and a fallback.

Results

GranBench-Code has four families, simple, medium, refactor, and recovery, with a target of 20 tasks each. The published runs are a pilot: 12 tasks for fixed granularity and 7 for fault injection. Tools and verifiers stay fixed. Variants differ in the open action set.

VariantSuccessStepsTokensMacro useG-score
A-Micro1.0006.007217.750.0000.1667
B-Macro0.5832.713609.000.9160.4305
C-Heuristic0.7503.224097.670.8330.4103

On the 12 tasks, micro tools pass every case and cost the most: 6.00 steps and 7217.75 tokens. Macros use 2.71 steps and 3609.00 tokens, about half the micro token bill, at 58.3% success and 0.916 macro adoption. G-score divides success by successful steps and by token cost normalized to micro. Macros score 0.4305 and micro scores 0.1667. Those success rates sit too far apart for G-score to crown the macro policy.

Early faults with no recovery score 0.000. Steps and tokens for that cell are absent. Downgrade scores 1.000, with 6.86 steps, 11293.43 tokens, and a transition rate of 1.000. On late faults the edit is already in the workspace. No recovery scores 1.000 in 2.71 steps and 2440.14 tokens. Always downgrading also scores 1.000, at 5.71 steps and 7566.71 tokens, about 3 times the tokens.

Table 4 swaps the handwritten rule for a decision tree, again on 12 tasks. The rule scores 0.750, 3.11 steps, 4172.89 tokens, and matches empirical labels on 0.667 of tasks. The tree scores 1.000, 4.17 steps, 5518.33 tokens, matches empirical labels on 1.000, and matches the rule on 0.667. Tasks the rule sent to macros go to micro tools instead. The extra tokens buy a clean pass on this set.

With both routers on, every one of the 7 tasks scores 1.000 except early faults with no recovery.

TimingVariantTokensG-scoreTransitions
BeforeNo recoverynot reportednot reported0.000
BeforeAlways downgrade11293.430.08451.000
BeforeLearned full9763.570.10610.857
AfterNo recovery2280.001.18660.000
AfterAlways downgrade7566.710.21421.000
AfterLearned full3694.430.57200.143

Early faults stay perfect, tokens fall to 9763.57, and the transition rate is 0.857. Late faults already pass with no recovery at 2280.00 tokens. Always downgrading spends 7566.71. Selective recovery transitions on 0.143 of runs, spends 3694.43, and still scores 1.000.

Why it matters

The piece a coding-agent stack can copy is the granularity switch. Refactors start on a macro that has a fallback. Small edits stay on micro tools. The three macros are a prototype. The tree lives as JSON, failure types live in the state machine, and the run does not train anything online.

Early faults with no fallback score 0. Late faults that always fall back move tokens from 2280.00 to 7566.71. Selective recovery holds a perfect score at 3694.43, above the no-recovery bill and below the always-downgrade bill. The 100% routing figure is the tree on 12 tasks and the full controller on 7. Micro-only execution is also at 100% in this pilot, at 7217.75 tokens.

Limitations

The four-family, 80-task benchmark was not run. An unconstrained agent and an LLM router are named as baselines for a full study and have no results here. The shared LLM is never named. Confidence intervals appear in the contribution list and not in the tables.

On 12 tasks the tree matches empirical labels at 1.000, and no train/test split is reported. A depth-4 tree lined up with a dozen preferred labels says little about a new repository or a new model. The library holds three macros, all Python. Climbing back from micro tools to a macro, and switching modes in both directions, is untested. Fault timing is set by the harness. Late faults already pass with no recovery, so downgrade-on-every-error mostly adds tokens. Table 3 lists 2440.14 tokens for that cell and Table 5 lists 2280.00. They are separate figures.

Terms

Source

What people are saying

Related papers

All paper explainers