A document a research agent drops at the synthesis step was still paid for at every earlier stage that carried it. Drop it right after fetch and it costs nothing downstream. That is the finding in a new arXiv paper on staged pruning, and prune-early is our earliest-stage implementation of it: it scores each fetched document for relevance, removes near-duplicates and off-topic noise before anything expensive runs, and on our worked fan-out hands 26% less context to the next stage. That 26% is saved again at every stage that would have carried the full set.
What we did
A long-horizon research agent works in stages: it fans out and fetches, then screens, then synthesises, then writes. The usual instinct is to trim the context late, right before the big synthesis call, because that is where the bill looks largest. The paper's point is that this is the wrong place. Pruning at any stage helps, but pruning early helps most, because a document you drop after fetch is removed from every later stage at once. Drop it late and you already paid to carry it through all the earlier ones.
prune-early is that earliest stage, and it is one file with no dependencies. Given the query and the raw fetched documents, before they go anywhere, it does four things. It scores each document for relevance with BM25-lite, a plain lexical signal with no embeddings and no network. It drops off-topic noise the search dragged in, using a floor set relative to the top result so a page that matches the query on one incidental word still gets cut. It removes near-duplicate fetches, the same story syndicated across three sites, keeping the higher-scoring copy. Then it trims the lowest-scoring tail to a token budget. What comes out is the smaller head worth carrying.
The worked example ships with it. A ten-document fan-out for one research query loses two off-topic results and one syndicated duplicate, and the context handed to the next stage is 26% smaller. The number itself is modest and honest, measured on that corpus. The point is where the saving lands: not once, but at every stage that would otherwise have carried the full set, so a four-stage pipeline banks it four times.
Why it was worth doing
This is the complement to the floor we shipped a fortnight ago. budget-floor is a hard stop: when a runaway loop crosses a cost or iteration cap, it raises and halts. That is the safety net for when spend goes wrong. prune-early is the other side of the same problem: it makes spend go up more slowly in the first place, by never carrying tokens the answer was never going to use. One stops you falling, the other means you approach the edge far more slowly. A research agent wants both.
It also lands on a theme that turned up twice in one morning's reading: a staged-pruning paper on arXiv and a cost-aware model router from NVIDIA, both pointing at the same lever, which is that the cheapest token in a long-horizon agent is the one you never carry. We already had the stop. This is the part that keeps the meter down between stops.
What's still off
Relevance here is lexical, not semantic. BM25-lite catches the noise a keyword never touches, and it is fast and free, but it will miss a document that is on-topic in meaning yet shares no words with the query. The cheap layer is a high-recall prior, not a final judge; a semantic scorer using embeddings is injectable on top for the murky cases, at the cost of a model call and a dependency we deliberately kept out of the base.
And it prunes whole documents, not the passages inside them, and the token figure is a chars-per-four estimate unless you pass a real tokeniser. The wiring into our live research crons, Otto's daily pull and the deep research harness, is the follow-up, not this ship: the module is built and tested, calibrating a sensible budget per agent is the next step. Sixteen tests, no network, one file that sits at the front of the pipeline.