Stop Paying Frontier-Model Prices for Agent I/O
The expensive part of an AI coding session is not always the difficult part. A frontier model may spend most of its context reading four thousand lines to locate one pattern, then spend premium output tokens reproducing a test structure that already exists twenty times in the repository. The judgment is valuable. The transport is not.
Spotify’s Portal team built a small experiment around that mismatch. Its shunt plugin keeps Claude Code as the coordinator, but diverts two predictable kinds of work to cheaper, narrowly instructed workers: reading large files and producing pattern-based boilerplate. The published benchmark reports 82–94% fewer coordinator tokens for large-file reading, with a mean reduction of 90% across three read scenarios.
The headline is attractive, but the architecture is more useful than the number. It combines a hard routing policy, tiny command-line adapters, reusable agent definitions, and a clear boundary around what must remain with the stronger model. This is not a general claim that small models can replace frontier models. It is a design for preventing the frontier model from doing work that never needed its judgment.
Context is a working set, not a storage system
A coding agent needs enough evidence to decide what to do. It does not need every byte involved in gathering that evidence.
When an agent reads a large source file directly, the complete tool result enters the conversation. Those tokens can help with the immediate question, but they also occupy the working context used by later turns. Read a source file, its tests, two interfaces, and a configuration file, and the session may carry a large amount of text whose only purpose was to establish a few facts.
That creates three costs. The obvious one is billed input. The second is attention: relevant details must compete with old file contents on subsequent turns. The third is compaction. Once the conversation approaches its context limit, the client has to summarize or discard earlier material, which can erase precisely the decisions the developer wanted to preserve.
The better unit to retain is often a compact observation: which class owns the behavior, which methods touch the database, which tests establish the convention, and where the relevant section begins. The raw corpus can stay outside the coordinator’s context unless an edit requires exact text.
That is the key separation in shunt. The cheaper worker consumes the bulk input. The coordinator consumes the answer.
Portal modes turn workers into configuration
The worker side is built with AiKA modes. A mode is a declarative agent definition: a name, instructions, optional model choice, resource limits, visibility, and an optional set of MCP tools. Spotify’s documentation also supports processors for planning, answer formatting, verification, confidence scoring, and context management.
That makes a mode closer to a versioned operational role than an open-ended chat. The bulk-reader role is told to read supplied files, answer one question, emit concise structured bullets, and avoid everything the caller did not ask for. The code-writer role receives a specification plus a required reference file and is told to match the reference’s conventions while returning code without explanation.
Narrow instructions matter because delegation only saves coordinator tokens when the result is smaller and cleaner than the source material. A worker that writes a friendly preamble, repeats the task, wraps code in fences, and appends a long explanation pushes avoidable text back across the boundary. Output discipline is part of the interface contract.
Modes also separate the routing decision from the worker implementation. The plugin can continue calling bulk-reader while an administrator changes the underlying model, temperature, prompt, or attached tools. Public modes can be shared across a workspace, while a user’s private mode with the same name takes precedence during server-side resolution. Teams can therefore publish a sensible default without preventing local specialization.
The Portal AI Plugins repository exposes these workflows through the Portal CLI actions registry. The invocation is ephemeral: each call stands alone, and the worker does not preserve the conversation server-side. Re-sending a file on a follow-up still costs worker tokens, but it does not refill the coordinator’s more valuable context.
Three layers make routing reliable
Putting “use a cheaper model for large files” in a project instruction file is a suggestion. It may work until the agent decides that a direct read looks easier. Shunt makes the important part enforceable with three layers.
The first layer is a pair of PreToolUse hooks. Before a full Read, check-file-size counts the target’s lines. A file over the configured threshold—350 lines by default—is blocked, and the tool result directs Claude to the bulk-reader skill. Targeted reads with an offset or limit still pass because the agent has already narrowed the evidence it needs.
The second hook inspects shell commands. It catches broad uses of cat, head, tail, less, and more against large files, but allows targeted pipelines and redirections. This prevents the simple bypass where the agent stops using its read tool and streams the same file through a shell command.
The second layer is transport. The bulk-read and code-write scripts accept named arguments, build the request, invoke the Portal action, unwrap errors, and clean the response. Files are wrapped in XML elements carrying their paths so boundaries remain unambiguous. The agent calls a stable command instead of improvising JSON and shell quoting on every delegation.
The third layer is guidance. Skills describe when the commands apply and show their exact syntax. Guidance alone is soft; hooks alone can only say no. Together, the skill presents the preferred path when the hook closes the expensive one.
This combination is a general pattern for agent systems:
- Put non-negotiable cost or safety rules in deterministic code.
- Hide transport details behind a small, testable interface.
- Teach the model how and when to use that interface.
Each layer has one job. The hook decides whether the attempted operation is allowed. The script performs the integration. The skill supplies semantic judgment.
The threshold is an economic boundary
Delegation is not free. It adds serialization, a network round trip, queueing, another model call, and a response that the coordinator must inspect. For a 90-line file, direct reading may be both faster and cheaper. For a 7,000-line source-and-test pair, paying that fixed overhead can be a good trade.
The line threshold is therefore not merely a guardrail; it is a crude cost model. It approximates the point where the expected tokens avoided exceed the cost and latency of another invocation.
A production threshold should be measured rather than copied. File length is only a proxy for token count. Minified code, generated schemas, prose, and sparse source files have very different token densities. Cached prompts can change input economics. Worker pricing and latency change by provider. A team should record at least source tokens, returned tokens, wall time, failure rate, and how often the coordinator has to reopen the original file.
An adaptive router could use those observations to choose a path by estimated tokens instead of lines. It might raise the threshold when the worker is slow, lower it for generated files, or bypass delegation when a cached prefix makes a direct read cheap. The current 350-line rule has a different virtue: developers can predict it, explain it, and debug it.
Why boilerplate is a separate path
Large reads make input expensive. Boilerplate makes output expensive.
For a routine test file, the coordinator may first read an existing test, then generate hundreds of lines that repeat its fixtures, naming, assertions, and cleanup. Shunt’s code-write path sends a specification and reference file to the worker and can write the result directly to disk. The coordinator does not need to consume its own generated file as conversational output.
The required reference is the most important constraint. “Write tests for UserService” invites generic code. “Write tests for UserService using OrderServiceTest as the reference” provides a local grammar: framework, imports, fixture lifecycle, naming, assertion style, and failure conventions. The worker performs constrained imitation rather than free-form design.
This path is intentionally less enforceable than bulk reading. The plugin can reliably detect an oversized file before a read, but it cannot know from a prompt alone whether a requested implementation is boilerplate or architecture. code-writer therefore depends on the coordinator recognizing a predictable task. That is a sensible limit. False-positive delegation of a delicate implementation would cost more than the output tokens it saved.
Direct-to-disk output also changes verification. Saving context is not permission to trust the file. The coordinator should inspect the diff, run formatting and tests, and bring any surprising section back into its own context. Delegation moves production; it does not move accountability.
Keep reasoning where the evidence converges
The original experiment names four categories that should remain with the frontier model: debugging, editing, small-file work, and architectural decisions.
Debugging is difficult to summarize before the cause is known. A cheap reader may report surface patterns while omitting the interaction that creates a race, leak, or invalid state transition. Architecture is similar: the work is choosing between competing constraints, not extracting facts from a file.
Editing requires exact local evidence. A summary can identify the relevant method, but a patch needs the actual signature, nearby control flow, formatting, and current line content. Shunt handles this by allowing targeted reads. The worker performs reconnaissance; the coordinator opens the discovered region and makes the change.
The right mental model is not “smart model versus cheap model.” It is evidence compression followed by judgment:
- Workers scan, classify, extract, translate, and reproduce known patterns.
- The coordinator sets the goal, resolves ambiguity, reasons across evidence, edits sensitive code, and verifies the result.
That division also limits failure impact. A worker receives a bounded corpus and one narrow question. It does not need the full conversation, broad repository permissions, or every tool attached to the main agent. The Model Context Protocol architecture follows a related separation: hosts coordinate context and security while focused servers expose specific capabilities. In both cases, narrower interfaces make composition easier to understand.
Read the benchmark as a routing result
The repository’s benchmark covers a 162,000-line Java monorepo. A 4,014-line file falls from 33,684 coordinator tokens to 5,737. A 7,408-line source-and-test pair falls from 75,990 to 4,148. A 1,281-line cross-service task falls from 16,221 to 821. Those reductions are 82%, 94%, and 94%, producing the reported 90% mean for bulk reads.
These are project measurements published with the plugin, not an independent benchmark or a universal discount. They show that the chosen tasks had a high compression ratio: a worker could turn a large corpus into a small useful answer. Results will change with repository language, question complexity, model choice, response rules, caching, and how often the coordinator must request exact follow-up context.
The more durable metric is useful coordinator tokens per completed task. A routing system has failed if it reports a 95% token reduction but causes repeated calls, worse patches, missed defects, or long idle waits. Cost, latency, and correctness have to be measured together.
Spotify’s plugin includes hook, transport, and end-to-end evaluations in addition to the benchmark. That is the right direction. Routing policy is production code. A small shell parsing change can create an escape hatch, block a legitimate targeted command, or send too much data through an operating system’s argument-size limit.
Build a router from the boundary inward
The useful way to adopt this pattern is to begin with one task that has all four properties: frequent, high-volume, easy to specify, and easy to verify. Large-file question answering is a strong first candidate. Translation, documentation normalization, generated configuration, and conventional tests may follow.
For each route, define:
- The trigger: size, command shape, file type, or explicit skill call.
- The worker contract: exact inputs, concise output form, and refusal conditions.
- The escape hatch: targeted reads or an explicit coordinator override.
- The verifier: tests, schema validation, diff review, or a stronger model pass.
- The telemetry: tokens, time, retries, reopen rate, and accepted-result rate.
Then make the boundary visible. If a hook blocks an operation, its message should explain why and provide the next command. If a worker times out, the coordinator should know whether to split the request, retry, or perform the task directly. Silent routing is difficult to trust because developers cannot connect a delay or quality change to its cause.
Finally, treat all worker output as untrusted input. A delegated summary can be wrong, and a delegated code file can compile while violating a hidden invariant. Give workers the least authority they need, keep secrets and unrelated context out of their prompts, and place deterministic validation after generation wherever possible.
The coordinator should spend tokens on decisions
Model routing is often described as infrastructure: gateways, provider tables, queues, and billing dashboards. Shunt demonstrates a smaller and more practical layer. A hook can intercept a costly action, a script can call a named worker, and a skill can teach the coordinator when that worker is appropriate.
The important optimization is not simply replacing an expensive token with a cheaper token. It is changing what crosses the coordinator boundary. Whole files become findings. Repeated patterns become files on disk. The conversation retains intent, decisions, and the evidence necessary to verify them.
That is a useful standard for any coding-agent workflow: pay the strongest model to resolve uncertainty. Do not pay it to be a pipe.
Further reading
- Portal by Spotify cut my Claude Code token usage by 90%, the original experiment and its design constraints.
- Spotify Portal AI Plugins, including shunt’s hooks, scripts, skills, evaluations, and benchmark table.
- AiKA modes, the mode fields, MCP tool attachment, processors, visibility, and context controls.
- Claude Code hooks, the lifecycle events and command-hook model used for enforcement.
- Model Context Protocol architecture, the host/client/server separation behind composable tools and context.