compression with a quality contract

Getting Started

Install in one command, verify the corpus gate passes in 60 seconds, then drop compression into your agent with a single wrap(client) call. No API key required for the first two steps.


Install

Distil ships as a PyPI package (distil-llm) with a stdlib-only core — zero runtime dependencies. The corpus is bundled in every distribution. Pick the format that fits your workflow.

Python 3.11+ required. Install Distil isolated from your system Python — modern macOS and Linux reject system-wide pip install with error: externally-managed-environment (PEP 668). All methods below are safe.
Zero install · recommended

uvx

Run straight from PyPI, no install step. Prereq: uv.

uvx --from distil-llm distil bench
Isolated CLI · recommended

pipx

Permanent install in its own venv — PEP 668-safe. Prereq: Python 3.11+, pipx (brew install pipx).

pipx install distil-llm
distil certify
macOS / Linux

Homebrew

Installs into an isolated keg — doesn't touch your Python. Prereq: Homebrew and git (third-party taps are cloned with git — run brew install git if you see Error: Git is unavailable).

brew install dshakes/tap/distil
distil bench
Container

Docker

Reproducible image, ideal for CI or sandboxed environments. Prereq: Docker.

docker build -t distil .
docker run distil bench
Single file

Zipapp (.pyz)

One portable executable — copy it anywhere. Prereq: Python 3.11+ (no install).

make pyz
python dist/distil.pyz bench
In a venv / project

pip

For embedding the library in your own project. Prereq: an active virtualenv.

python3 -m venv .venv && source .venv/bin/activate
pip install distil-llm
Node / TypeScript / other languages? Run distil proxy (or distil wrap -- <your-agent>) and point your SDK's baseURL at it. No code changes, any language. The CLI needs Python 3.11+; your app does not.

Billing-grade tokenizer (optional)

The default tokenizer is an offline heuristic — compression ratios are robust, but absolute dollar figures are approximate. For billing-grade token counts and live-model certification, install the live extra:

# with pipx (isolated):
pipx install 'distil-llm[live]'
# or one-off with uvx:  uvx --from 'distil-llm[live]' distil certify --runner anthropic
export ANTHROPIC_API_KEY=sk-ant-…
distil savings --tokenizer anthropic
distil certify --runner anthropic

60-second quickstart

Three commands cover the core workflow. All run against the bundled multi-domain corpus — no API key required. Run them in order the first time: bench to confirm savings and the gate pass, certify to inspect a single strategy, prune to see what's actually free to drop.

1. Benchmark savings across 7 domains

distil bench is the corpus-wide CI gate. It prices four strategies, certifies Distil is non-inferior on every trajectory, and confirms the gate rejects the aggressive lossy strategy. Run this in CI to catch any regression.

$ distil bench
corpus gate — 7 trajectories | model claude-opus-4-8 | tokenizer=heuristic

domain            trajectory               $ saved   distil   aggr  pruned
---------------------------------------------------------------------------
ops/sre           sre-disk-incident          33.1%     PASS   FAIL     615
coding            coding-bugfix              28.7%     PASS   FAIL     736
support           support-refund             32.6%     PASS   FAIL     765
research          research-synthesis         25.7%     PASS   FAIL     809
data-analysis     data-analysis-sql          18.1%     PASS   FAIL     965
devops            devops-rollback            25.0%     PASS   FAIL     857
finance           finance-reconcile          29.1%     PASS   FAIL    1014
---------------------------------------------------------------------------
aggregate: distil cuts $0.14212 -> $0.10402 (26.8% cheaper) losslessly; 5761 tokens prunable.

GATE: PASS — every trajectory certified non-inferior; aggressive rejected on all.

2. Certify a strategy

Run the TOST non-inferiority gate on a single trajectory and strategy. Exits 0 on pass, 1 on fail — plug it directly into any CI pipeline.

$ distil certify --strategy distil
certifying strategy 'distil' on 'sre-disk-incident' (runner=deterministic)

  turn 0: ok
  turn 1: ok
  turn 2: ok
  turn 3: ok

decision-equivalence match rate: 100.0%
TOST non-inferiority (margin=0.02, alpha=0.05): mean diff=+0.000, p=0.0000

VERDICT: PASS  (certified non-inferior)

3. Discover causally inert blocks

distil prune ablates each context block, replays the trajectory, and identifies what never changed a decision. Those blocks are provably free to drop — not heuristically likely, provably safe.

$ distil prune
causal ablation over 'sre-disk-incident' — what is free to drop?

block                  occ   tokens  verdict
doc-0                    4      312  PRUNE (causally inert)
doc-1                    4      303  PRUNE (causally inert)
obs-0                    4      234  keep (changed a decision)
obs-1                    4      198  keep (changed a decision)
system                   4      218  keep (changed a decision)

tokens provably free to drop: 615 across 2 block(s).

Drop-in adoption: wrap(client)

The fastest path to production compression — no changes to your call sites. Wrap your existing Anthropic client once and every subsequent messages.create call is transparently compressed and cache-pinned.

import anthropic
from distil.adapters.anthropic import wrap

# One-line drop-in — no call-site changes needed
client = wrap(anthropic.Anthropic())

# Works exactly like the original client
response = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=1024,
    system="You are a helpful assistant.",
    messages=[{"role": "user", "content": "Analyse this log output…"}],
)

The wrapper applies Tier-0 lossless transforms (JSON minification, run-length collapse) and Tier-1 reversible digests to large tool results. It also pins the stable system prefix for cache-control so repeated calls get the ~10× cache-read discount automatically.

No call-site changes. The wrapper is a pure structural proxy — it duck-types against any object that exposes a messages.create(**kwargs) method. It imports nothing from the Anthropic SDK itself, so it also works in test environments where the SDK is not installed.

Alternative: provider proxy

Prefer a network-level approach that works with any SDK, framework, or language? See the Adapters page for distil proxy.


Use it on your workflow — recipes

Pick the row that matches you. Every command is real; watch it work with distil leaderboard (genuine cumulative savings) and the x-distil-* response headers.

Coding agents — Claude Code · Codex · Gemini CLI

Wrap the agent; its traffic routes through compression with zero code change.

# subscription/OAuth-safe (ToS-safe, no tool injection)
distil wrap --lossless-only -- claude
# interactive: model sees content un-digested (Tier-0 only)
distil wrap --lossless-only --verbatim -- claude
# PAYG: aggressive reversible digest; the model recovers detail on demand
distil wrap --expand -- claude
# coding sessions with re-reads: send the diff, not the whole file
distil wrap --session-delta -- claude

Any SDK app — chatbots, RAG, agents, batch (non-coding)

# standalone proxy — point any base_url SDK at it, any language
distil proxy
distil proxy --upstream https://generativelanguage.googleapis.com   # Google Gemini
# or in-process, no sidecar (LiteLLM / LangChain)
from distil.integrations import litellm as distil_litellm
distil_litellm.completion(model="claude-opus-4-8", messages=[...])

See it, prove it, get more out of it

GoalCommand
Watch genuine savings accumulatedistil leaderboard · live distil gateway dashboard
Live decision-equivalence on real trafficdistil proxy --shadow 0.05distil shadow-stats
Certify on your domaindistil ingest --input prod.jsonl --out ./mycorpusdistil conformal --corpus ./mycorpus
Let agents recover digested detail (MCP)distil mcp — exposes distil_compress/_expand/_savings
Live savings in your Claude Code status lineinstall the plugins/distil plugin → distil statusline
Self-improving keep policydistil learn / distil online (flywheel; only ever gets more conservative)
Rule of thumb. Subscription / interactive → --lossless-only (add --verbatim). PAYG / autonomous → default digest (add --expand). Coding sessions with re-reads → add --session-delta.

What to read next