The best result is a denser context, not a universal reduction.
Several recent articles have discussed RTK and reported large gains from its use. Some of these claims treat raw command-output reduction as if it were the same as model-visible context reduction or lower token spending. That comparison can be misleading because a coding host may already clip, store, cache, or summarize the output before the model sees it. This article therefore uses a bounded set of controlled experiments to measure where RTK provides real value, where the gain becomes smaller, and where no size saving remains.
What RTK actually changes
RTK works before command output reaches the model. When the filter keeps the right details, this can give the model less repetitive text to process. The host may also limit one large tool result before it enters the conversation. The measured benefit must therefore be compared with what the host would deliver, not only with raw shell output.
All four checked diagnostic groups and exit code 1 remained in the compact result.
All three compiler symbols, source locations, and exit code 2 remained.
Standard and --nocapture modes kept names, values, totals, and exit 101.
127 noisy lines became one correct success summary.
Exact cumulative input fell across Claude Code, Copilot, and Codex host paths.
Claude clipped the native failure first; RTK still delivered a much smaller complete result.
Both native and RTK failures reached the same head-and-tail output envelope.
Practical takeaway: RTK can improve signal density and slow context growth, but the host sets the baseline. It helps most when the filtered result stays below the host's per-result limit. It can also replace a weak preview with a useful summary. It does not save context when both native and filtered results reach the same host limit.
.NET failure result: RTK intentionally kept the complete native log, so shell output expanded by 7.4%. In the separate Claude Code replay, both forms were reduced to 10,039 visible characters. RTK kept a structured summary at the tail, but it provided no model-visible size saving for this command.
A deterministic filter between the shell and the agent.
The agent still requests a normal development command. RTK selects a command-specific formatter, runs the child process, and keeps the child exit status. It returns a smaller result when safe filtering is available; a safety fallback may keep the native output. A path to the full captured output is shown when recovery is available.
rtk command selects a supported wrapper.
Where value comes from
- passing tests and progress lines are removed;
- repeated compiler and build messages are collapsed;
- failure names, locations, counts, and values stay visible;
- less tool text competes with source code and instructions.
Where value can be lost
- a formatter may remove a detail needed for the fix;
- a parser may report a count that conflicts with the native tool;
- recovery may require another command and another agent turn;
- unsupported commands may need an explicit generic filter.
Useful changes in the current build
| Area | Current behavior | User value |
|---|---|---|
| Savings reports | Raw reduction is separated from the output a configured host would normally deliver after its own size limit. | Large logs are less likely to produce overstated savings claims. |
| pytest options | The wrapper checks command flags, PYTEST_ADDOPTS, and common pytest configuration files before adding quiet mode. | Existing -q settings are not silently changed to a lower detail level. |
| Failure recovery | Failed filtered commands keep the child status and can show the captured full-output path. | An agent can detect failure correctly and recover details when the summary is incomplete. |
| Hook verification | Rewrite activity can be compared with RTK tracking records for a session. | Teams can check adoption instead of assuming every supported command was filtered. |
Large output reduction is not enough by itself.
Six command cases were run in fresh directories: five failures and one successful .NET build. The native and RTK paths used the same source and child-command options. All exit codes remained unchanged.
| Workload | Native | RTK | Change | First-result quality |
|---|---|---|---|---|
pytestpytest -s |
14,177 B 153 lines | 938 B 23 lines | −93.4% | Complete for the task Names, values, XFAIL/XPASS IDs, totals |
Cargo test--test-threads=1 |
4,846 B 157 lines | 817 B 21 lines | −83.1% | Complete for the task Three names, assertion values, totals |
Cargo test--nocapture --test-threads=1 |
4,718 B 150 lines | 696 B 11 lines | −85.2% | Complete for the task Three live panic blocks, values, totals |
CMake + Clangrtk err cmake --build … |
14,097 B 136 lines | 995 B 13 lines | −92.9% | Complete for the task Three symbols and three source locations |
.NET build: successdotnet build Success.csproj |
13,311 B 127 lines | 64 B 1 line | −99.5% | Complete for the task Correct success verdict and zero-error count |
.NET build: failuredotnet build Fixture.csproj |
15,388 B 133 lines | 16,531 B 141 lines | +7.4% | Complete but larger Native and RTK summaries both report three errors |
What these fixtures represent
The Python fixture prints 120 successful status records before three failures. The Rust
fixture contains 120 passing tests and three failing tests in standard and
--nocapture modes.
The C++ build prints 120 CMake status records before three Clang errors. The two .NET
projects use a custom MSBuild target with 120 high-importance messages; one succeeds and
one ends with three C# compiler errors. These controlled cases are not an estimate of
every project.
Python, Cargo, and .NET used dedicated RTK wrappers. CMake build and Clang-family
compiler commands now rewrite directly to the generic rtk err filter; the
measured C++ command used that same route.
One-result limits change the value of filtering before compaction begins.
Command output does not always move directly into the model context. A coding host may first keep it inline, replace it with a preview, or return a head-and-tail excerpt. Only then does the result join the session and later take part in compaction. RTK acts before both host stages, but its effective gain depends on what the host would deliver anyway.
Claude Code has separate paths for valid and failed results
Anthropic documents roughly 30,000 inline characters for a valid Bash result. Above that level, Claude receives a short preview from the start and a saved-file path. A failed command uses a smaller path: roughly 10,000 characters, taken from the head and tail, without a file path. The local Claude Code 2.1.222 build uses 30,000, 10,000, and an up-to-2,000-unit head preview at these boundaries. It uses JavaScript string length, not UTF-8 byte length, and stdout and stderr share the same accumulator.
| Generated command output | UTF-8 bytes | Count used by host | Valid-result treatment |
|---|---|---|---|
| 30,000 ASCII characters on stdout | 30,000 | 30,000 | Inline |
| 30,001 ASCII characters on stdout | 30,001 | 30,001 | Saved path plus head preview |
20,000 occurrences of é | 40,000 | 20,000 | Inline |
| 15,000 stdout + 15,001 stderr | 30,001 | 30,001 shared | Saved path plus head preview |
The probe commands ran locally. Their treatment was replayed from the verified local implementation. The authenticated Claude Code matrix then observed the same 10,039-unit failure envelope in live pytest tool results. These boundaries may change between releases.
What Claude would receive from the six command fixtures
The native and RTK commands were executed again. Their results were then passed through the local valid-or-failure delivery rule. The table counts visible command text, including the failure marker but excluding generated path and wrapper text. All selected diagnostic groups remained visible in both arms of these controlled fixtures.
| Workload | Native shell | RTK shell | Native visible | RTK visible | Visible change |
|---|---|---|---|---|---|
| pytest failure | 14,177 B | 938 B | 10,039 ch | 871 ch | −91.3% |
| Cargo failure | 4,846 B | 817 B | 4,859 ch | 830 ch | −82.9% |
Cargo --nocapture | 4,718 B | 696 B | 4,731 ch | 709 ch | −85.0% |
| C++ failure | 14,097 B | 995 B | 10,039 ch | 1,006 ch | −90.0% |
| .NET success | 13,311 B | 64 B | 13,311 ch | 64 ch | −99.5% |
| .NET failure | 15,196 B | 16,291 B | 10,039 ch | 10,039 ch | 0.0% |
Large valid-result test: a successful .NET fixture with 400 progress records produced 43,813 native characters. Claude's 1,961-character head preview did not contain the final success verdict, although a path to the full result was available. RTK returned a 64-character inline summary with the verdict and zero-error count. Here RTK's main value is immediate semantic completeness and avoiding a follow-up file read.
Direct context saving
When native and RTK output are both inline, the filtered size is close to the real model-visible reduction. Both Cargo cases and the smaller successful .NET build follow this pattern.
Host clipping plus RTK
When native output is already clipped but RTK stays inline, RTK still saves context and keeps facts together. The gain is smaller than the raw-byte claim. Pytest changed from 93.4% at the shell to 91.3% at Claude's result boundary.
No size saving
When both forms exceed the same failure limit, the host controls the delivered size. The failed .NET build reached 10,039 visible characters in both arms. Its RTK summary may help reading, but it did not reduce this input.
Recovery still matters
Claude provides a path for a large valid result, but not for a large failed result. A filtered failure should therefore expose its own full-output path when reliable recovery is required. The tested .NET fallback did not expose such a path.
The same model can behave differently in a different host
A model's context capacity and the host's delivery behavior are separate. Claude Sonnet 4.6 was therefore tested both in Claude Code and inside Copilot CLI. At six calls, RTK reduced cumulative input by 43.6% in Claude Code and 59.3% in Copilot. The difference does not come from model capacity alone: the hosts delivered the tool result and managed caches differently.
| Host | One large tool result | Long-session behavior | RTK contribution |
|---|---|---|---|
| Claude Code | Valid Bash results use roughly 30,000 inline characters, then a head preview and path. Failures use roughly a 10,000-character head-and-tail excerpt without a path. | The live Sonnet sessions reported a 200,000-token context window. Claude
clears older tool outputs first, then summarizes when needed.
/context shows usage and /compact summarizes on demand. |
RTK helps only relative to this delivered baseline. It cannot enlarge the model window or control later conversation summaries. |
| GitHub Copilot CLI | Output above 20 KiB is saved to a temporary file by default; the model gets a preview and path. | The measured host limit was 272,000 tokens for GPT-5.3-Codex and 200,000 for
Sonnet. Background compaction starts near 80%. The CLI pauses near 95% if
compaction has not completed. /compact is also available. |
Exact telemetry showed 17.3%, 38.9%, and 54.4% lower cumulative input after one, three, and six GPT-5.3-Codex calls. Sonnet reached 59.3% at six calls. |
| Codex | This review did not establish one shell-result boundary that applies to every Codex interface. | Automatic history compaction uses a configured token threshold or the model
default. /status shows usage and /compact summarizes. |
RTK can lower the tool-result contribution that the interface accepts, but the selected model and Codex host still control capacity and compaction. |
The context limits above came from the live session records. They describe the measured model and host versions, not every model available in those products.
What the scale means
Twenty identical native excerpts add 200,780 visible characters. The RTK form adds 17,420, avoiding 183,360 characters before session compaction.
This is a character-growth illustration, not a token or context-window prediction. Real sessions also contain prompts, code, tool definitions, and responses.
What changes before and after compaction
Per-result delivery happens first. RTK can reduce the inline result, replace an unhelpful preview with a focused summary, or do nothing to the delivered size when both forms hit the same limit. If the model then reads a saved full-output file, that extra read adds new content and can return some of the avoided pressure.
Session compaction happens later and considers the whole conversation. A smaller inline result can leave more room for code and earlier decisions, but RTK cannot choose when the host compacts or which earlier details its summary keeps. After compaction, RTK also cannot restore a fact that the host removed.
Reasoning limit: the live Claude task extracted known diagnostic facts; it did not repair code. All 18 Claude sessions gave the correct answer, but this does not prove better reasoning. The large successful .NET case showed that RTK can make a verdict immediately visible, but that case was a delivery replay rather than a live repair task.
The input benefit grows when tool results remain in the conversation.
The live study used exact host counters from Claude Code, GitHub Copilot CLI, and Codex. Each fresh session ran the same failing pytest suite one, three, or six times. The RTK arm used the tested release binary; the control arm called pytest directly. All 90 sessions returned the same correct diagnostic answer. The 45 matched pairs cover 332 verified shell calls and five host-and-model configurations.
| Host, model, and depth | Pairs | Control input | RTK input | Input reduction | Range across pairs | Output: control → RTK |
|---|---|---|---|---|---|---|
| Claude Code · Sonnet · 1 call | 3 | 51,677 | 45,484 | 12.0% | 11.96–12.01% | 429 → 539 |
| Claude Code · Sonnet · 3 calls | 3 | 133,473 | 94,437 | 29.3% | 29.23–29.27% | 1,012 → 1,174 |
| Claude Code · Sonnet · 6 calls | 3 | 315,567 | 178,080 | 43.6% | 43.39–43.70% | 1,775 → 2,173 |
| Codex · Sol · 1 call | 5 | 155,254 | 141,445 | 8.9% | 8.65–9.10% | 539 → 703 |
| Codex · Sol · 3 calls | 5 | 351,609 | 289,651 | 17.6% | 13.08–23.12% | 1,048 → 1,387 |
| Codex · Sol · 6 calls | 5 | 741,835 | 529,077 | 28.7% | 22.58–36.15% | 1,921 → 2,865 |
| Codex · Terra · 6 calls | 3 | 432,370 | 309,672 | 28.4% | 23.11–36.99% | 1,432 → 1,980 |
| Copilot · GPT-5.3-Codex · 1 call | 5 | 75,758 | 62,629 | 17.3% | 15.91–19.73% | 3,114 → 3,952 |
| Copilot · GPT-5.3-Codex · 3 calls | 5 | 219,203 | 133,908 | 38.9% | 37.06–40.75% | 4,163 → 4,288 |
| Copilot · GPT-5.3-Codex · 6 calls | 5 | 555,047 | 253,281 | 54.4% | 53.52–55.34% | 5,023 → 5,356 |
| Copilot · Sonnet · 6 calls | 3 | 340,785 | 138,875 | 59.3% | 59.17–59.33% | 1,686 → 2,178 |
The host changes how much RTK reaches the model
The same Claude Sonnet 4.6 model was tested in two hosts at six calls. Copilot delivered the complete 14,216-byte native result because each call stayed below its 20 KiB result gate. Claude Code delivered a 10,039-character failure excerpt. RTK stayed inline in both hosts. Cumulative input was 59.3% lower in Copilot and 43.6% lower in Claude Code.
This is not a ranking of the hosts. Their system prompts, tool schemas, cache placement, and auxiliary model work are different. It shows why a shell-output percentage cannot be reused as a token percentage. RTK acts first; the host then decides what enters each model call and what returns from cache.
Why a 93% tool-text reduction becomes a 9–59% input reduction
RTK removed about 93% of the full pytest tool result in Copilot and Codex. It did not remove the host system prompt, tool definitions, user request, model replies, or fixed session data. One Codex Sol call therefore used 8.9% less total input, while six calls used 28.7% less. The repeated result can be included again in later model steps, so the gap grows with session depth. Copilot GPT-5.3-Codex reached 54.4% at six calls. Claude Code reached 43.6% after its own failure clipping had already reduced the control arm.
Token spending has several parts
Total input alone is not a complete cost view. Cache reads, cache creation, ordinary new input, generated output, and reported reasoning output can use different rates. The table keeps these parts separate. Claude Code also reported a small auxiliary-model call, which is included in its totals.
| Host and model | Arm | Total input | Cache read | Cache create | Other input | Output | Reported reasoning |
|---|---|---|---|---|---|---|---|
| Claude Code · Sonnet 3 sessions | Control | 315,567 | 261,354 | 52,221 | 1,992 | 1,775 | not separate |
| RTK | 178,080 | 163,194 | 12,777 | 2,109 | 2,173 | not separate | |
| Codex · Sol 5 sessions | Control | 741,835 | 600,320 | 0 | 141,515 | 1,921 | 0 |
| RTK | 529,077 | 452,864 | 0 | 76,213 | 2,865 | 134 | |
| Copilot · GPT-5.3-Codex 5 sessions | Control | 555,047 | 371,712 | 0 | 183,335 | 5,023 | 3,860 |
| RTK | 253,281 | 198,656 | 0 | 54,625 | 5,356 | 3,327 | |
| Copilot · Sonnet 3 sessions | Control | 340,785 | 264,831 | 75,927 | 27 | 1,686 | not separate |
| RTK | 138,875 | 118,818 | 20,030 | 27 | 2,178 | not separate |
RTK input was lower in every one of the 45 matched pairs. Generated output moved in the other direction: its aggregate was higher with RTK in all eleven groups. The extra output was much smaller than the avoided input, but it must not be hidden in a spending claim. Reported reasoning tokens were mixed, and the Sonnet paths did not expose them as a separate exact field.
No single money value is stated because account and model rates can differ. A current estimate should price cache reads, cache creation, other input, and output separately. The input-reduction percentage must not be applied directly to a complete bill.
What was controlled: every session used a fresh fixture, conversation, and private RTK database. Arm order alternated. Shell events confirmed the requested number of commands, and all 166 RTK calls were recorded by RTK while all 166 control calls produced zero RTK records. Every model-visible test result contained the three real failed values; all 90 final answers were correct.
How RTK can influence model reasoning
RTK does not change the model itself. It changes the information available while the model decides what failed and what to do next. Four effects matter in the measured paths.
Less competition for attention
Removing passing tests and progress records puts failing names, values, and source locations closer together. This reduces the amount of unrelated text around the diagnostic facts, but it does not prove that the model reasons better.
More working context
A smaller tool result leaves more room for source code, instructions, and earlier decisions. Exact six-call input fell by 28.4–28.7% in Codex, 43.6% in Claude Code, and 54.4–59.3% in Copilot. At the shell boundary, twenty repeated pytest outputs avoided 264,780 bytes. The host can reduce or reshape this gain before model input.
Explicit structure
Grouped failures, locations, values, and totals reduce the search needed to compare related facts. All 45 RTK answers recovered the same required facts as the 45 control answers while receiving less total input in every matched pair.
Fidelity controls the benefit
A smaller result helps only when the next decision receives the required facts. The six command cases checked names, values, locations, codes, counts, and exit status. All selected groups remained present and consistent in the fresh runs.
Reasoning interpretation: the live task measured diagnostic extraction, not a multi-step code repair. It shows that RTK preserved the answer while reducing input. It does not show higher reasoning quality. Aggregate generated output increased in every group, reported reasoning tokens were mixed, and Sonnet did not expose a separate exact reasoning count. These counters do not show better reasoning.
RTK overhead is small beside a model call, but it is not zero.
Release benchmarks on the same machine put bare startup near 7 ms and rewrite paths near 14 ms. This local overhead is small compared with the 8–34 second live sessions, but RTK sessions were faster in only 19 of 45 pairs. Model latency did not improve consistently.
| Path or property | Result | Meaning |
|---|---|---|
rtk --version | 7.457 ms | Bare process startup median |
rtk rewrite "git status" | 14.032 ms | Rewrite process, including startup |
| Hook preview path | 13.685 ms | Local processing only |
| Release binary | 20.1 MiB | 21,071,232 bytes |
| One maximum RSS probe | 7.6 MiB | 8,011,776 bytes; single observation |
| Release tests | 3,018 passed | 10 ignored |
For large test and build outputs, a 7–14 ms local process is a reasonable trade for a much smaller tool result. For small commands that already return a few lines, the same fixed work may offer no useful gain.
RTK's main value is information density, not a universal saving.
Across six controlled commands, RTK consistently kept the selected facts and the child exit status. Five results became much smaller. The sixth, a failed .NET build, became larger at the shell because RTK kept the complete native log as a safety fallback. The Claude boundary replay changed the effective percentages and removed that size penalty: both .NET failure forms reached the same host excerpt. Shell reduction, host delivery, and fidelity must therefore be read as separate results.
Noisy output can become a focused diagnostic
Pytest output fell by 93.4%, standard Cargo by 83.1%, Cargo
--nocapture by 85.2%, and the C++ build by 92.9%. The compact forms still
contained the checked names, values, locations, codes, totals, and failure status.
For an agent, the useful change is not only fewer bytes: related failure facts arrive
together instead of being separated by more than one hundred progress records.
The benefit grows across repeated tool calls
Twenty pytest results avoided 264,780 raw shell bytes. Under the local Claude delivery rule, the same repeated results avoided 183,360 model-visible characters. This host-aware value is lower, but it still shows that repeated focused results grow more slowly before session compaction.
Less input can preserve the same task result
All 45 control sessions and all 45 RTK sessions answered the Python diagnostic task correctly. Exact input was lower in every pair. One-call aggregate reductions ranged from 8.9% to 17.3%; six-call reductions ranged from 28.4% to 59.3%. Aggregate output increased in every group, and wall time did not improve consistently.
Correctness can be more important than compression
The successful .NET build became one correct line, a 99.5% reduction. The failed build took the safer path: it kept the native diagnostics and added a matching summary, expanding shell output by 7.4%. Claude then reduced both failed forms to the same 10,039-character envelope. This is not a context-saving result for that host; the only possible benefit is the structured summary that remains at the tail.
What is established: RTK can reduce model-visible command text when its result is smaller than the host's delivered baseline. It can also put a final verdict in an inline result where a host preview omits it. It does not guarantee a saving when both paths cross the same host limit.
The live model study covers diagnostic extraction from the Python fixture. Rust, C++, and .NET were measured for command-output fidelity rather than model behavior.
RTK is strongest when noise is predictable and failures are structured.
Test runners and build tools often repeat successful status lines while the agent needs only a few failures. RTK has the clearest value in this pattern: the command remains the same, but the result is reshaped around the next debugging decision.
The Cargo --nocapture result makes the difference concrete. Native output used
150 lines. The RTK result used 11 lines and still showed each failing test, its panic
message, the assertion values, the final counts, and exit code 101. The model has less
text to search, but it receives the same facts needed to explain the failure.
Compiler workflows show the same pattern. CMake and Clang produced three source-level errors after 120 build messages; RTK returned the three symbols and locations in 13 lines. A successful .NET build collapsed to one verdict. When the .NET build failed, RTK emitted the full log instead. That protected the shell result, but Claude Code still reduced both native and RTK failures to its head-and-tail envelope. The current fallback is safe at the command boundary, not efficient for that host.
The effect on the model is therefore indirect but practical. RTK does not add reasoning ability. It reduces the search space around a decision and leaves more context for code, instructions, and earlier conclusions. In the live comparison, that smaller information load preserved answer correctness and lowered exact cumulative input, but it did not produce a consistent change in answer length or speed.
Bottom line: RTK is most useful as a local relevance layer for noisy, well-understood command families. The fresh data shows compact, consistent results for pytest, both Cargo modes, routed compiler filtering, and successful .NET builds. Failed .NET builds kept complete and consistent shell diagnostics but provided no model-visible size saving in the Claude replay. The command family and host together determine whether RTK provides compactness, better structure, recovery, or no useful gain.