Перейти к содержимому
tech

Decompose the work, keep the window small

Open Graph card for the Recursive Decomposition skill

When you ask a coding agent to reason over a whole repository, a folder of product documents, or a set of PDFs that have to be compared with each other, the usual move is to load as much as possible into the context window and hope the model still sees the details. Zhang, Kraska, and Khattab, in Recursive Language Models (arXiv:2512.24601, December 2025; I am looking at v3), showed that this hope is misplaced. Quality falls as the prompt grows even when the text still fits, a degradation they name, following Hong et al. 2025, context rot: retrieval misses, details in a long document drop out, distant passages get glued together by guesswork, and reasoning over a large evidence set gets weaker while the answer still looks confident. Their fix is the same idea as treating a large file as an external environment rather than as a blob you swallow. The model peeks, slices, and calls itself over snippets, keeping the active window small. Recursive Decomposition is the Agent Skill I published so that Claude Code, Codex, Cursor, and the others would do that in an ordinary session. It sizes the input before anyone opens a file, filters with searches, splits what remains into independent batches of five to ten files, hands each batch to a sub-agent that answers and is forbidden to spawn more sub-agents, checks the merged answer against a small window of the original files, and assembles the write-up in code with paths and line numbers. MIT. Independent of the paper authors and of MIT. I first put the protocol out in January 2026; this note is from 28 August, when it became an installable skill after this journal existed.

What the paper measured

Figure 1 from Zhang, Kraska, and Khattab: GPT-5 versus RLM(GPT-5) on S-NIAH, OOLONG, and OOLONG-Pairs as input grows from 8k to 1M tokens

The paper is the literature the skill is built on, and it is worth sitting with Figure 1 and Table 1 rather than waving at “long context.” On the right, GPT-5 holds S-NIAH and then falls on OOLONG and OOLONG-Pairs as the prompt grows from 8k to 1M tokens; the red band is past its 272k window. RLM at depth one stays up through that band. BrowseComp-Plus is a multi-hop question-answering task whose inputs run from about six to eleven million tokens. GPT-5 as a base model hits the context limit and scores nothing useful. Compaction, the usual summarise-as-you-go scaffold, reaches 70.5 percent. RLM at depth one reaches 91.3 percent at 0.99 dollars average cost, with a standard deviation of 1.22. That is more expensive than compaction’s 0.57 dollars, and cheaper than a linear extrapolation of stuffing six to eleven million tokens into GPT-5-mini, which the paper puts between 1.50 and 2.75 dollars. They report the RLM beating compaction and retrieval by more than 29 percent on that row. OOLONG is a linear aggregation task at 131k tokens: GPT-5 scores 44.0, RLM with GPT-5 at depth one scores 56.0 (28.4 percent relative), and RLM with Qwen3-Coder picks up 33.3 percent over its own base. OOLONG-Pairs is the quadratic one, pairwise relations, and it is only about 32k tokens, well inside a million-token window. GPT-5 scores 0.1 F1. RLM at depth one reaches 58.0, and at depth three 76.0. Median RLM cost in Figure 11 sits comparable to or under the base model. The average can rise because trajectories are long-tailed (Observation 4), and the 95th percentile of runtime is dominated by sequential sub-calls. I did not rerun their experiments. Those numbers are theirs.

When it fires

That last OOLONG-Pairs row is why the skill does not wait for the input to overflow. Fit is a harness cap, not a quality guarantee. Pairwise work, multi-hop work, and any job of the form “list everything and do not miss an item” rot inside a window that still has room, so the skill fires on dense work even when the files would have fitted. It stays out of the way when the job is one file, one function, a single needle, or a one-page convert-to-markdown, because those you read directly. It also stays out when latency matters more than completeness, and when coordinating sub-agents would cost more than one honest read.

The protocol

What the agent actually does in a session follows Section 5 of the paper, where current models acting as RLMs probe the input and then split the work, turned into a protocol an Agent Skill can enforce. Before anyone opens a file, the session sizes the input: file count from glob or find, lines from wc -l, bytes from ls -lh, page count from pdfinfo when the files are PDFs. Then it filters with searches, never with a recursive tree listing as a substitute, chaining file type, then keyword, then meaning, which is the same idea as the paper’s small loop that keeps only files matching (database|connection|auth) and only then reads. What remains is chunked by natural units (a function, a class, a section) when those exist, by line ranges on files over 2,000 lines or 50 KB, or by keyword partitions so that all error handling sits in one batch and all route definitions in another. Recursion is one level. The parent writes the batch count, launches one parallel wave of sub-agents, each with a self-contained brief that includes the files, the question, and the output schema, merges, and only then starts another wave if batches remain. Sub-agents answer and do not launch sub-agents. The paper’s OOLONG-Pairs F1 moves from 58.0 at depth one to 76.0 at depth three on GPT-5, so extra depth is real on that model, but Qwen3-Coder-480B-A35B makes syntax errors that spread into sub-calls, and on that class of model depth two and three can score worse than depth one (Table 1, Figure 4b), which is why the skill stays at depth one. After the merge, verification pulls the cited locations, re-reads only those, and if the answer disagrees with the files, re-reads the disagreement instead of adding a second layer of delegation. Synthesis is programmatic: structured notes, deduplication, categories, then the write-up with paths and line numbers. The main context never holds more than five files without a written batch plan, and the same span never appears in two sub-agents, because the partition is done once and the batches are disjoint.

PDFs and Office files

PDFs and Office files are the case that used to dump a binary into the window. The skill converts first, preferring local anydoc (npx -y @firecrawl/anydoc FILE -o .firecrawl/out.md) and grepping the markdown. If anydoc exits 3, the pages are scans, and the next step is --ocr hosted or cloud firecrawl parse, which caps at 50 MB and about one credit per page. Files over 100 pages or 30 MB get split before parse. A one-page convert job is anydoc or parse alone, not this skill.

The mortgage eval

I test that path on a corpus I do not copy into the repo. The fixture is a git submodule, tccao/mortgage-doc-rag (MIT): 131 public-domain mortgage PDFs, about 63 MB. CI does not clone it; missing files print SKIP, not ERROR. The prompt is the same with the skill and without: size the tree, do not load a PDF binary, how many files, total bytes, the ten largest, convert at most three of those, recover titles from the markdown, depth one. With the skill, size-first took 0.02 seconds. anydoc on two digital PDFs took 1.64 seconds and recovered the titles (Appraisal of Real Property; TILA-RESPA Integrated Disclosure). The largest file is a four-page scan, urar_form_1004_epa_scan.pdf, 1,639,534 bytes. anydoc exited 3. firecrawl parse took 15.45 seconds and returned Uniform Residential Appraisal Report. Naive pdftotext on all 131 files took 1.65 seconds and extracted 0 bytes; on that scan it extracted 4 bytes and no title. The naive path is faster and blind on scans. The skill is slower because it OCRs the one file pdftotext cannot read, which is the file the prompt asked about. bash .github/scripts/eval-skill.sh check validates trigger queries and, if the submodule is present, PDF count, a byte floor, and the largest filename. score compares with-skill and without-skill agent runs. Trigger queries live in evals/trigger-queries.json. Gold for the corpus eval wants decomposed: true, depth: 1, subagents_spawned_subagents: false, at least 131 PDFs, and urar_form_1004_epa_scan.pdf in the largest list.

How a session looks

If you want pictures of the protocol rather than another README, “find all error handling” is glob the sources, grep catch|throw|Error|except, batch the hits by module, one sub-agent per batch with a fixed report schema, and a merge with file references. “What features are planned across all PRDs” is glob the documents, size them, lock an extraction schema (name, priority, status, quarter), one sub-agent per group, then deduplicate and spot-check three entries against the sources. “Summarise every TODO” is grep TODO|FIXME|HACK, group by module, extract context and priority, and produce a list. Long output is generated section by section, stored, then stitched, which is how an RLM writes past a model’s output limit in the paper.

Install

Install with the skills CLI:

npx skills add massimodeluisa/recursive-decomposition-skill

Listed at skills.sh/massimodeluisa/recursive-decomposition-skill. Add -g for a user-level install, or -a claude-code (or another agent) to target one. /recursive-decomposition applies the protocol to the current task. /recursive-decomposition src/ sizes that path first. If a default is wrong, Edit on GitHub.