feat(cli): prune large bash outputs with SWE-Pruner - #12067
Conversation
|
Measured benchmark results I ran the same failing-test scenario with SWE-Pruner disabled and enabled, using the same main model and exact prompt in fresh sessions.
The fixture emitted 90 noisy passing traces and two intentional failures. In both runs, the main model reported both failing test names, both expected values, both received values, and the 90-passed/2-failed summary correctly. The pruned result kept 35 of 127 lines. An isolated VS Code self-test also confirmed the enabled setting, the |
|
Modeled cost and context impact This is an estimate rather than measured billing. I modeled a representative long coding session using current Kilo catalog rates for Fable as the main model ( The session contained 92 completed bash calls, 16 non-truncated outputs that met the pruning thresholds, and about 200K eligible output characters. Each eligible output remained in context for an average of roughly 80 later model turns. Existing read/grep pruning had also reduced four read results and one grep result. Using the measured bash retention ratio and a 60-80% selective-pruning rate for eligible shell output:
Estimated contribution to total pruning value was roughly 65-71% from bash, 28-34% from read, and less than 1% from grep. Grep output is already pattern-filtered, so the skimmer usually keeps most or all of it. Prompt caching is included in these percentages. It reduces recurring dollar savings by roughly 10x because historical output is billed at the cache-read rate, but it does not reduce the context-window benefit. Without caching, both the baseline cost and pruning savings would be substantially higher. The estimate has approximately ±20% uncertainty because destructively pruned read/grep output no longer retains the original text, so those token counts were reconstructed from kept/total line metadata. |
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Incremental review of commits since the last pass. This update simplifies the focus-question guidance in SWE-Pruner: the tool-specific Files Reviewed (3 files changed in this update)
Previous Review Summary (commit ed36326)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit ed36326)Status: No Issues Found | Recommendation: Merge Small, well-scoped change extending SWE-Pruner to bash output. The core logic ( Files Reviewed (26 files)
Reviewed by claude-sonnet-5-20260630 · Input: 26 · Output: 5.9K · Cached: 701.5K Review guidance: REVIEW.md from base branch |
|
@Drilmo I extended this feature to the bash tool. I think it makes a lot of sense, especially for noisy CI/test output this can safe quite a lot of $. In my testing grep seems to be very close to break even and not very useful. |
Follow-up: trace-based cost analysisI revisited the earlier modeled cost estimate using traces from a real, multi-step coding workload. This analysis intentionally reports only normalized pruning economics, not workload identity, prompts, task names, run IDs, total spend, or evaluation results. The earlier estimate projected a Normalized result
The percentages are same-trajectory counterfactual estimates. They isolate direct token economics and do not claim that an enabled and disabled run would follow identical reasoning or tool paths. Models and pricingThe primary coding model had expensive input and output tokens with a The skimmer was hardcoded to What the traces showed
Why the earlier model was optimisticThe earlier estimate primarily modeled eligible outputs with a high selective-pruning success rate and emphasized how retained context compounds across later turns. That compounding is real, but prompt caching changes its dollar value:
The earlier estimate also omitted two important primary-model costs:
This means a focus question can cost money even when the tool output is below the ConclusionThe cost issue is not DeepSeek V4 Flash pricing. It is that the current interface asks the expensive primary model to opt into pruning before output size is known, while the skimmer only produces useful pruning on a minority of eligible calls. SWE-Pruner still provides a context-window benefit for very large noisy output, and a small number of sessions saved materially. As a general cost optimization, however, this implementation did not pay for itself in the observed workload. Future work should avoid per-call primary-model focus-question generation for small outputs, reduce always-on schema text, improve the skimmer success rate, and persist skimmer usage/outcome metadata so cost can be measured directly rather than reconstructed. |
|
I read the full paper (https://arxiv.org/pdf/2601.16746). The short answer: the paper's approach is applicable, but Kilo's implementation diverges from the paper in the single most important dimension — the skimmer — and that divergence, combined with two factors the paper never models, explains why Kilo's economics came out the opposite of the paper's. What the paper actually does (vs. what Kilo built)
The interface ( Why the paper wins and Kilo doesn't — three concrete gaps1. The skimmer is a trained model, not a prompted LLM. This is the crux. The paper's 0.6B CRF reranker:
Kilo swapped that for DeepSeek prompted to output ranges. That directly produces the 51-of-251 success rate the retrospective flagged: a general chat model, untrained on the task, frequently replies 2. The paper never models prompt caching. Its cost tables (Table 1: cost −26.8%) count raw tokens. Kilo's retrospective found that with a 10× prompt-cache discount, the recurring dollar value of removed context shrinks ~10×, because historical tool output is billed at the cache-read rate anyway. So the paper's headline "39% token reduction → proportional cost saving" does not hold under caching — the token-window benefit survives (~2% in Kilo's trace), but the dollar benefit largely evaporates. The paper's benchmark agent (Mini SWE Agent) and setup don't involve the caching regime Kilo runs in. 3. The paper's win is read; Kilo's PR chased bash. The paper's entire motivation (Figure 2) is that read = 76.1% of tokens, execute (test/build) = 12.1%, edit = 11.8%. The validated win is pruning large file reads. Kilo extended pruning to arbitrary bash (test/CI output), which is the execute bucket the paper explicitly shows is small — and the retrospective found bash was where the always-on schema tax + per-call focus-question generation dominated, and where caching killed the savings. Kilo also confirmed grep is break-even (paper's method doesn't emphasize grep either). So — is it applicable? Yes, but with corrections. Ideas:Idea 1 (highest leverage): use the paper's actual trained skimmer, not a chat LLM. The authors open-sourced it ( Idea 2: refocus on read, drop/deprioritize bash and grep. The paper's evidence supports pruning large file reads. Kilo's own trace: read ≈ 28–34% of pruning value (positive), grep < 1% (break-even, already pattern-filtered), bash 65–71% but net-negative under caching. Matching the paper's actual scope (read-heavy) is likely net-positive even with a prompted skimmer. Idea 3: make pruning post-hoc / size-gated first (the earlier discussion). The paper generates a goal hint every round too, but its reads are almost always large source files, so the "focus question wasted on tiny output" problem barely bites. Kilo's mixed bash workload had 2,083 focus questions but only 251 large enough to skim — 88% wasted primary-model output. Deferring the pruning decision until size is known (hook into the existing Idea 4: frame and measure it as a context-window optimization, not a cost optimization. Under caching, the honest claim is the paper's secondary benefit: the paper also reports −18–26% rounds and +1.2–1.4pp success from a cleaner context, independent of token price. That's the durable value. The retrospective already asks for persisted skimmer outcome metadata (why 200/251 didn't prune) — do that first so you can measure success rate directly and validate whether a trained skimmer moves it. Bottom line: the paper is sound and directly relevant, but its results depend on (a) a trained 0.6B skimmer and (b) a read-dominated, non-cached measurement regime. Kilo reproduced the interface but substituted a prompted general LLM, extended to the wrong tool (bash), and runs under prompt caching. Fixing the skimmer (Idea 1) is the change most faithful to the paper and most likely to flip the economics; refocusing on read (Idea 2) is the cheapest partial fix without hosting a model. |
feat(cli): prune large bash outputs with SWE-Pruner
|
@Drilmo I would go ahead and sundown SWE pruning. It hasn't shown to save any costs in practice. In our testing it even increased costs and made sessions more unreliable. Is that fine with you? |
Large test, build, and diagnostic commands can add substantial noisy shell output to every later model request. Experimental SWE-Pruner currently reduces large read and search results, but agent-invoked shell output bypasses that context optimization.
This extends the same task-aware pruning path to bash calls while preserving the existing size gates, hard-truncation exclusion, timeout, and fail-open behavior. Successful pruning replaces both the persisted tool result and the shell metadata preview so all clients consume a consistent reduced result, and completed bash cards expose the existing kept/total indicator.
Focus guidance remains tool-agnostic and explains both when to use pruning and when to preserve full output. The agent selects pruning for specific evidence in potentially large or noisy output, but omits it for broad exploration, complete audits, or output that may be needed later. The skimmer respects concrete evidence and noise criteria, preserves complete local evidence blocks and nearby context needed to interpret them, and retains the full result when most output is relevant. Experimental settings copy now reflects shell support across locales.