compression with a quality contract

Token Economics

Before you reach for a compression tool, understand the thing it compresses. This is the whole story — what a token is, where an agent quietly burns thousands of them, why multi-turn loops get expensive faster than you'd guess, every family of compression that has been invented to fight back, and exactly where Distil fits — applied in tiers, certified to change nothing the model decides.

The one-sentence version. An LLM charges by the token; an agent re-sends its whole history every turn, so cost grows with the square of the conversation; compression removes tokens the answer doesn't depend on; and the only honest compression is the kind you can prove didn't change the model's decision. Distil is the proof-carrying version of that idea.

1. What a token actually is

A token is not a character and not a word. It is a subword unit — the atomic chunk a model reads and predicts. Modern models build their vocabulary with Byte-Pair Encoding (BPE): start from individual bytes, then greedily merge the most frequent adjacent pair over and over until you hit a target vocabulary size. Frequent words collapse into one token; rare words fall back to a handful of subword pieces. There is no <unknown> — every possible string is representable, in any language.

RAW STRING (a tool result) {"status":"ok","rows":2} BPE tokenizer 13 TOKENS — STRUCTURE COSTS EXTRA {" status ":" ok "," rows ": 2 } Only ok and 2 are signal. The braces, quotes and keys are pure overhead — and you pay for every one. CHARACTERS PER TOKEN — DENSITY VARIES BY CONTENT ~4.0 English prose 100 tokens ≈ 75 words. The efficient case. ~2.5 Source code camelCase, operators & indentation split hard. ~2.0 JSON / logs Punctuation-dense. The same bytes cost ~2× the tokens.

Three consequences fall straight out of how BPE works, and they drive everything below:

Distil counts honestly. Distil ships a tokenizer abstraction that prefers the real model tokenizer when present and falls back to a calibrated heuristic otherwise — so the CLI's savings numbers reflect what you'll actually be billed, not a convenient approximation. See Concepts for why we measure decisions, not bytes.

2. Where the tokens go — anatomy of one agent request

Here is the part most cost surprises come from. A single agent turn is not "the user's question." The API is stateless, so every turn re-sends the entire working set. A typical request, before the model has read a single word of your actual task, already carries:

One request to the model — token budget Widths ≈ proportions commonly seen in tool-heavy agents. The query you care about is the sliver on the right. System prompt Tool schemas Message history Tool results persona, rules every tool's JSON schema — often the biggest block all prior turns, resent verbatim ← your query A 5-server tool setup can spend ~55,000 tokens before the task is read.

The biggest, most-overlooked sources of waste, with the hardest public numbers we have:

The opportunity. Notice that almost none of those tokens are the task. They're scaffolding, repetition, and verbose machine output — exactly the material a model's decision usually doesn't depend on. That gap between "tokens sent" and "tokens that change the answer" is the entire space compression operates in.

3. The multi-turn tax: why cost is quadratic

Single-turn cost is linear and boring. Multi-turn is where bills explode — and the shape is quadratic, not linear. Because each turn re-bills all the tokens before it, the cumulative cost of an n-turn loop is the sum 1 + 2 + … + n = n(n+1)/2 = O(n²). A four-turn conversation costs 4 + 3 + 2 + 1 = 10× the first turn's tokens — not 4×.

Cumulative billed input across a conversation Each turn re-sends everything before it. The area under the curve is what you pay. 0 turn 1turn 2turn 3 turn 4turn 5turn 6 Naïve — fresh input every turn (1.0×) Cached prefix — repeated tokens read at 0.1× N TURNS n(n+1) 2 = O(n²)

Two more mechanics make this concrete:

Try it: the cost of a loop

Real arithmetic — no marketing. This computes the n(n+1)/2 input cost from your inputs, using live catalog pricing and the documented cache multipliers (0.1× read / 1.25× write). The "with Distil" line applies a flat lossless reduction to fresh tokens; the default 26.8% is Distil's measured corpus aggregate (see Research). Assumptions are shown so you can check the math.

$0
Naïve — no caching, no compression
$0
With prompt caching (prefix read @ 0.1×)
$0
With caching + Distil lossless (−26.8%)

Assumptions: input-token cost only (output excluded for clarity); prefix is cacheable and byte-stable; per-turn input = prefix + accumulated history; cached line writes the prefix once at 1.25× then reads it at 0.10× while the growing tail stays fresh; Distil line additionally removes 26.8% of fresh tokens losslessly. Illustrative — your numbers depend on your traffic.

4. Compression, the whole family tree

"Compression" is an umbrella over a dozen genuinely different ideas, each trading a different amount of quality risk for savings. The single most common mistake in this space is conflating them — input-token compression (fewer tokens enter the model), KV-cache compression (the prompt is read in full; the retained attention memory shrinks), and cost reduction (same tokens, cheaper compute) are three different axes. Here is the honest map.

Risk vs. savings — where each family sits more savings → ↑ more quality risk certified-safe band — provably no decision change Lossless minify / dedup / RLE Retrieval (RAG) & semantic cache Extractive pruning (drop low-info tokens) Abstractive summary / rolling memory Learned keep/drop classifier Soft-prompt / gist vectors KV-cache eviction (H2O, SnapKV) — memory, not tokens
Lossless · mechanical

Make the same bytes cost fewer tokens

Whitespace and JSON normalization, key shortening, de-duplication, run-length collapse, compact serialization. Risk: essentially zero — information is preserved exactly. The ceiling is modest, but it is free savings you should always take first.

Extractive prompt compression

Drop the least-informative tokens

Score each token's informativeness (self-information / perplexity) and prune the bottom. Systems like Selective Context and the LLMLingua family reach 2–20× on prose. Risk: real — a low-surprisal but load-bearing token (a negation, a constraint) can be dropped, and output is often human-unreadable.

Abstractive · summarization

Rewrite the context shorter

Summarize retrieved docs or older turns into a compact form (RECOMP; rolling-summary agent memory; OS-style tiered memory like MemGPT). High ratios. Risk: lossy — specific facts, numbers and entities can be distorted or dropped, and errors compound across turns.

Retrieval as compression

Keep knowledge outside the window

RAG and semantic caching hold the corpus in an index and pull only the top-k per query — lossy compression of a whole knowledge base into what fits. Risk: retriever-bounded — a missed chunk becomes a hallucination; a too-loose semantic-cache hit returns a stale answer.

KV-cache compression

Shrink the attention memory, not the input

H2O, Scissorhands, SnapKV, StreamingLLM keep only "heavy-hitter" or recent keys/values in GPU memory. Different axis: the model still reads every input token, so this cuts memory/latency, not your input bill. Eviction is permanent — a wrongly-dropped key can't return.

Soft-prompt / gist

Compress context into learned vectors

Gisting, AutoCompressors and ICAE fold a long prompt into a few learned "summary" vectors (up to ~26× reported). Risk: model-specific & trained — the artifact only works for the model it was trained on, and reconstruction is lossy.

And two cost-reduction cousins that aren't token compression at all: speculative decoding (a small draft model proposes tokens the big model verifies in parallel — provably identical output, 2–3× faster) and model cascades / routing (FrugalGPT, RouteLLM — try a cheap model first, escalate only when needed). They lower cost without removing tokens, and they compose cleanly with everything above.

5. Why training a small model helps

The most effective compressors stopped using fixed heuristics and started learning. The root idea is knowledge distillation (Hinton et al., 2015): train a small "student" to imitate a large "teacher," using the teacher's soft probabilities — which carry far richer signal than a one-hot label.

Applied to compression, the move is to reframe it as per-token keep/drop classification. LLMLingua-2 is the clean example: take a small bidirectional encoder (XLM-RoBERTa, ~355M params), and train it on labels distilled from GPT-4 — prompt GPT-4 to compress text by word-removal only, then mark each original token "keep" or "drop." A trained classifier beats a perplexity heuristic for three concrete reasons:

The risk that comes with learning. A trained compressor internalizes its training distribution and fails quietly. The documented failure modes are real: out-of-distribution regression; over-compression dropping exactly the load-bearing tokens (high-information tokens are often the most important, yet get pruned at the same rate); and task-dependent fragility (classification and code degrade far harder than summarization). Past a point, aggressive compression flips from cost-saving to cost-increasing as garbled outputs trigger retries. This is the central reason a learned keep-model must be gated, never trusted blindly — which is exactly what §7 is about.

Distil takes this learning seriously but conservatively: it ships a built-in heuristic keep-model, a zero-dependency logistic keep-model, and an optional ONNX transformer keep-model you can train on your own traces — and critically, it trains on causal labels (what actually changed the agent's decision under ablation), then lets a model graduate only if it passes the non-inferiority gate. A keep-model can make Distil better; it can never make it worse.

6. Proving it didn't hurt

Every technique above can quietly degrade quality, and the failure is often invisible — the output still looks reasonable. So the load-bearing question isn't "how much did you save?" It's "how do you know the model still makes the same decision?" Three things to internalize:

7. How Distil applies all of this — in tiers

Distil's design choice is to apply the safe techniques aggressively, the risky ones only under proof, and to refuse anything it can't certify. That's the tier ladder. Each rung saves more and risks more — and a rung is only allowed to ship if it clears the gate above it.

⛓ Quality contract — non-inferiority (TOST) gate No tier ships unless the agent's decisions are certified statistically not-worse. Fails → fall back a rung. must pass ↓ 0 Tier 0 — Lossless JSON minify · whitespace · de-dup · run-length collapse. Byte-recoverable. Always on. risk: none applied to every request 1 Tier 1 — Reversible digest Verbose tool output replaced by a compact digest + handle the agent can expand on demand. Reconstructable. risk: bounded reversible by construction Certified — Causal / counterfactual pruning Ablation finds context the decision doesn't depend on; cache-aware & keep-model guided. Kept only if it passes the gate. risk: gated to zero certified per run

The pieces that make the ladder work — each documented in depth on Techniques:

# See the certified frontier and what's safe to take on your own corpus
distil eval
distil bench            # lossless + causal savings, with the non-inferiority verdict
distil proxy --port 8788 # drop-in; records genuine savings as real traffic flows
distil leaderboard      # your real cumulative savings (local, private)

8. A practical playbook

Independent of any tool, this is the order of operations that saves the most for the least risk:

Do first — free wins

  • Stabilize your prefix. Put the system prompt and tool schemas first and keep them byte-identical; move anything volatile (timestamps, IDs) after the last cache breakpoint. This alone can 10× the discount on repeated tokens.
  • Turn on prompt caching and verify hits via the cache-token counts.
  • Minify structured payloads losslessly before they enter context.
  • Prune dead tool definitions — every unused schema is paid on every turn.

Then — measured wins

  • Digest verbose tool output reversibly; let the agent expand on demand instead of carrying full dumps forever.
  • Compact or summarize stale history — but treat summaries as lossy and keep recent turns verbatim.
  • Prune causally, not by surprisal — remove what the decision doesn't depend on.
  • Certify every aggressive step with a non-inferiority test; if it can't pass, don't ship it.
  • Measure genuine savings on real traffic, not a synthetic corpus.

9. Where the field is heading

The frontier as of 2025–2026, in one breath:

The throughline. Every serious advance in this field is the same move: find the tokens the outcome doesn't depend on, and stop paying for them — without changing the outcome. Distil's contribution is to make that last clause a proof, applied in tiers, measured on your real traffic. Start with Install & Quickstart, then read Concepts and Techniques for the depth behind each rung.

Further reading

Primary sources behind this page — verified, for the curious: