compression with a quality contract

CLI Reference

Every subcommand, its flags, and a real sample output. All commands work offline with zero API key — the bundled corpus is self-contained.

Global flag: distil --version prints the installed version.
Default trajectory: when --trajectory is omitted, the bundled sre-disk-incident sample trajectory is used.

distil bench

The corpus-wide CI gate. Iterates over all 7 trajectories, prices four strategies, runs the TOST non-inferiority gate on each, and confirms aggressive lossy compression is still rejected. Exits 0 only if every trajectory passes.

Flags

FlagDefaultDescription
--tokenizerheuristicheuristic (offline, zero deps) or anthropic (billing-grade count_tokens)
--pricingclaude-opus-4-8Model pricing to use (see pricing catalog)
--margin0.02TOST indifference margin (max tolerable mean score drop)
--alpha0.05Significance level for the non-inferiority test
--recordoffAppend corpus-aggregate savings to the local savings ledger
--corpusbundled corpusRun on a custom corpus dir (e.g. from distil ingest)
--savings-onlyoffReport token savings only; skip the decision-equivalence gate (for real-trace corpora without DECISION labels)
$ 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.

distil savings

Price four compression strategies on a single trajectory and show per-strategy cost, savings percentage, and cache hit tokens. The key result: naive compress + cache costs more than baseline because it busts the prefix cache.

Flags

FlagDefaultDescription
--trajectory, -tbundled samplePath to a trajectory JSON file
--tokenizerheuristicheuristic or anthropic (billing-grade)
--pricingclaude-opus-4-8Model pricing to use
--output-tokens-per-turn0Assumed output tokens per turn (for output cost accounting)
--recordoffAppend this run to the local savings ledger
$ distil savings --pricing claude-opus-4-8
model claude-opus-4-8   |   4 turns   |   tokenizer=heuristic (≈, not billing-grade)

strategy                               $ / run   vs baseline  cache hits
------------------------------------------------------------------------
baseline (no cache, no compress)       0.01524          0.0%           0
cache only                             0.01115         26.8%       1,028
naive compress + cache                 0.01691        -11.0%           0
distil (cache-aware lossless)          0.01019         33.1%       1,028
------------------------------------------------------------------------
distil cuts $0.01524 -> $0.01019 per run (33.1% cheaper), losslessly.
note: naive compression costs $0.01691 — 66% MORE than distil despite fewer tokens,
      because it busts the prefix cache.

distil certify

Run the TOST non-inferiority gate on a single trajectory and strategy. Exits 0 on PASS, 1 on FAIL. Use this as the unit-level quality check; use bench for the corpus-wide gate.

Flags

FlagDefaultDescription
--trajectory, -tbundled samplePath to a trajectory JSON file
--strategydistilStrategy to certify: distil, aggressive, naive, none
--runnerdeterministicdeterministic (offline, uses ground-truth markers) or anthropic (live model, requires key)
--margin0.02TOST indifference margin
--alpha0.05Significance level
$ 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)

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

  turn 0: DIVERGED
      baseline:   use_tool(bash, {"cmd":"df -h /"})
      compressed: use_tool(bash, {"cmd":"ls /"})
  turn 1: DIVERGED
  turn 2: DIVERGED
  turn 3: DIVERGED

decision-equivalence match rate: 0.0%
TOST non-inferiority (margin=0.02, alpha=0.05): mean diff=-1.000, p=1.0000

VERDICT: FAIL  (NOT certified — would degrade quality)

distil prune

Causal ablation: for each context block, remove it and replay the trajectory. Blocks that never change a decision are causally inert — provably free to drop.

Flags

FlagDefaultDescription
--trajectory, -tbundled samplePath to a trajectory JSON file
$ 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).

distil compress

Apply the distil strategy to a trajectory turn by turn and report the per-turn token reduction and overall reversibility status.

Flags

FlagDefaultDescription
--trajectory, -tbundled samplePath to a trajectory JSON file
--tokenizerheuristicheuristic or anthropic
$ distil compress
trajectory 'sre-disk-incident'  (4 turns, tokenizer=heuristic)

turn    before     after   saved
   0      1824      1312   28.1%
   1      1956      1401   28.4%
   2      2108      1518   28.0%
   3      2340      1689   27.8%

 ALL      8228      5920   28.1%

reversible: yes (Tier-0/1) — 3 blocks digested, originals recoverable locally

distil verify

Byte-fidelity gate: confirms every Tier-0/1 compression across the corpus is byte-reversible, and that frozen history never mutates between turns (append-only invariant). Exits 0 only if all checks pass.

No flags. Runs across the full bundled corpus.

$ distil verify
byte-fidelity gate — reversibility + append-only across the corpus

  sre-disk-incident        reversible + append-only: ok
  coding-bugfix            reversible + append-only: ok
  support-refund           reversible + append-only: ok
  research-synthesis       reversible + append-only: ok
  data-analysis-sql        reversible + append-only: ok
  devops-rollback          reversible + append-only: ok
  finance-reconcile        reversible + append-only: ok

FIDELITY: PASS — Tier-0/1 byte-reversible and history append-only across the corpus.

distil holdout

Holdout A/B savings measurement. Partitions the corpus into a control group (held out, not counted toward the headline) and a treatment group, reports savings with a bootstrap 95% confidence interval.

Flags

FlagDefaultDescription
--tokenizerheuristicheuristic or anthropic
--pricingclaude-opus-4-8Model pricing to use
--control-fraction0.2Fraction of corpus held out as control group
$ distil holdout
holdout A/B savings measurement (deterministic partition + bootstrap CI)

  treatment savings: 27.4% [95% CI: 24.1%–30.8%]
  control group mean savings: 26.1% (held out, not counted toward the headline)

distil reset

Archives the savings ledger to savings.jsonl.reset-<utc-timestamp> (non-destructive — history stays on disk for audit) so the statusline and distil stats restart from zero on current accounting (records booked only after a confirmed upstream 2xx). Use it when a ledger is dominated by pre-1.10 records, whose savings may be overstated — distil stats warns when that is the case. --shadow also archives and resets the decision-equivalence counter.

$ distil reset
savings ledger archived → ~/.distil/savings.jsonl.reset-20260705-213313Z
  651 runs, 114,079,320 tokens saved (643 pre-1.10 records) — kept for audit, no longer counted
fresh start: all new records use post-1.10 accounting (booked only after upstream 2xx).

distil leaderboard

Shows cumulative savings from all runs recorded via --record flags on savings and bench, plus genuine traffic recorded by distil proxy/wrap. Local-first; no data leaves the machine unless you opt in to community sharing (not currently enabled). Aliased as distil stats — both names run the identical command. If the ledger contains pre-1.10 records (booked before upstream success — savings may be overstated), the output says so and points to distil reset.

Flags

FlagDefaultDescription
--htmloffRender your savings ledger as a self-contained HTML page at this path
--jsonoffMachine-readable output: the full savings summary plus decision-equivalence/shadow-sample counts when shadow data exists
$ distil leaderboard
distil savings ledger — ~/.local/share/distil/ledger.jsonl

runs recorded:        12
total tokens saved:   42,816
total dollars saved:  $0.51234

by trajectory:
  corpus-aggregate             $0.38112
  sre-disk-incident            $0.13122

(local-first; community sharing is opt-in and not enabled.)

distil proxy

HTTP proxy that applies Distil compression to every LLM API request passing through it. Drop-in for any client that honours a base_url parameter — Anthropic SDK, OpenAI SDK, LiteLLM, LangChain, etc. As real traffic flows through it, the actual per-request token reduction is accumulated into your local ledger (see distil leaderboard) — genuine savings, numbers only, never content.

Flags

FlagDefaultDescription
--host127.0.0.1Interface to bind on
--port8788Port to listen on
--upstreamhttps://api.anthropic.comReal LLM API base URL to forward to
--lossless-onlyoffPolicy mode: Tier-0 verbatim only — no lossy output-shaping, no tool injection (--expand), no Tier-1 digest stubs. Folds directly into verbatim (no separate --verbatim needed). Use for subscription / OAuth sessions.
--verbatimoffSkip the Tier-1 digest; Tier-0 only (JSON minify + collapse exact-duplicate runs). Interactive-safe, lower savings. Use where distil_expand recovery is unavailable.
--shape-outputoffEnable generation-side verbosity shaping: light (conservative) or aggressive. Injects a role:"system" directive before the request. Gated by --lossless-only: shaping is skipped when --lossless-only is set. No subscription key detection.
--expandoffInject the distil_expand tool so the model can pull digested blocks back on demand
--shadowoffShadow-mode sampling rate (0–1): re-run a fraction of requests uncompressed to measure live decision-change rate
--session-deltaoffEnable cross-turn cache-delta encoding (deduplicates repeated stable blocks across the session)
--asyncoffUse the async aiohttp backend (distil/aproxy.py) for high-concurrency streaming. Requires pip install 'distil-llm[async]'. Same compression behavior; async event loop handles thousands of concurrent sessions.
--pricingclaude-opus-4-8Model used to price the genuine dollar savings recorded to the ledger
--no-recordoffDo not record genuine savings to the local ledger
$ distil proxy --port 8788 --upstream https://api.anthropic.com
distil proxy listening on http://127.0.0.1:8788
  → upstream: https://api.anthropic.com
  → recording genuine savings → distil leaderboard

Point your SDK at the proxy:

# Anthropic SDK
client = anthropic.Anthropic(base_url="http://localhost:8788")

# OpenAI-compatible client
client = openai.OpenAI(base_url="http://localhost:8788/v1")

# LiteLLM
response = litellm.completion(api_base="http://localhost:8788", ...)

The proxy adds up to 9 response headers (not all appear on every request):

All other paths and HTTP methods are forwarded unchanged.

See Adapters for the full story on in-process vs. proxy adoption.

distil wrap

The zero-config way to route an existing agent or CLI through Distil. distil wrap starts the proxy on an ephemeral local port, injects ANTHROPIC_BASE_URL into the child process's environment, runs your command to completion, then tears the proxy down — flushing genuine savings to your ledger. No code change, no manual env wiring, no leftover server.

# Run any base-url-honoring agent with compression transparently applied
$ distil wrap -- claude -p "summarize this repo"
distil wrap → proxy http://127.0.0.1:54xxx (upstream https://api.anthropic.com)
  → ANTHROPIC_BASE_URL=http://127.0.0.1:54xxx
  → recording genuine savings → distil leaderboard
# ... your command runs, every request compressed ...

# Lossless-only policy mode (Tier-0 verbatim only, no tool injection, no Tier-1 stubs — for subscription / OAuth)
$ distil wrap --lossless-only -- my-agent --task build

Everything after -- is the command and its arguments, run verbatim. The child's exit code is propagated. Use --env-var to point a different variable at the proxy (e.g. an OpenAI-compatible tool), and the same --upstream, --lossless-only, --verbatim, --shape-output, --pricing and --no-record flags as distil proxy.

Flags

FlagDefaultDescription
--host127.0.0.1Bind address for the ephemeral proxy
--upstreamhttps://api.anthropic.comReal LLM API base URL to forward to
--env-varANTHROPIC_BASE_URLEnvironment variable to point at the proxy in the child process
--lossless-onlyoffPolicy mode: Tier-0 verbatim only — no lossy output-shaping, no tool injection (--expand), no Tier-1 digest stubs. Folds directly into verbatim (no separate --verbatim needed). Use for subscription / OAuth sessions.
--verbatimoffSkip the Tier-1 digest; Tier-0 only. Interactive-safe, lower savings.
--shape-outputoffGeneration-side verbosity shaping (gated by --lossless-only)
--pricingclaude-opus-4-8Model used to price genuine dollar savings recorded to the ledger
--no-recordoffDo not record genuine savings to the local ledger
--expandoffInject the distil_expand tool so the model can pull digested blocks back on demand
--session-deltaoffEnable cross-turn cache-delta encoding

distil output-savings

Measure the realized output-token reduction from --shape-output. Reads a JSONL file of {"baseline": ..., "shaped": ...} pairs and reports the A/B result with a bootstrap 95% confidence interval.

Flags

FlagDefaultDescription
--inputbundled fixturePath to a JSONL file of {"baseline": ..., "shaped": ...} pairs
$ distil output-savings --input shaped_pairs.jsonl
output-token A/B — n=8 turns

  baseline mean output tokens:   487
  shaped   mean output tokens:   134

  reduction: 72.5%  [95% CI: 67.5%–77.1%]  (illustrative)
  answer preserved: 100%  (semantic match gate, n=8)

distil ingest

Convert a recorded Anthropic or OpenAI request log (JSONL) into a Distil trajectory. One input file produces one trajectory — there is no session grouping. Real-trace corpora have no DECISION labels, so the offline gate is savings-only; certify quality live with distil certify --runner anthropic.

Flags

FlagDefaultDescription
--inputrequiredPath to the JSONL log file (Anthropic or OpenAI request format)
--out./ingested-corpusOutput directory where the trajectory will be written
--provideranthropicanthropic or openai — selects the input format
--modelclaude-opus-4-8Model name to tag the trajectory with (must be in the pricing catalog)
$ distil ingest --input prod.jsonl --out ./mycorpus
ingesting prod.jsonl → ./mycorpus

corpus written to ./mycorpus/

$ distil bench --corpus ./mycorpus --savings-only
corpus gate — savings-only (no DECISION labels)

  aggregate savings: 28.3%  [95% CI: 25.1%–31.6%]
  note: certify with --runner anthropic for a live quality gate.

distil perf

Throughput benchmark: measures raw distil-compression rate and in-process adapter latency. Runs a tight loop of compress() calls with the bundled trajectory and reports throughput (ops/sec) and p50/p95/p99 latency.

Flags

FlagDefaultDescription
--iterations200Number of compression iterations to run
$ distil perf
distil performance benchmark

  compressor throughput:   ~27,000 distil-compressions/sec
  in-process adapter p50:  0.006 ms
  in-process adapter p95:  0.011 ms
  in-process adapter p99:  0.018 ms

  (measured on Apple M-series, CPython 3.12, bundled sre-disk-incident trajectory)

distil gateway

Managed multi-tenant HTTP gateway with per-tenant token and dollar accounting, a live auto-refreshing dashboard at /distil/dashboard, and a JSON stats API at /distil/stats. Extends the basic proxy with tenant identification and savings attribution. Default port is 8789 (distinct from distil proxy's 8788).

Flags

FlagDefaultDescription
--host127.0.0.1Interface to bind on. Pass 0.0.0.0 for network-accessible deployments.
--port8789Port to listen on.
--upstreamhttps://api.anthropic.comReal LLM API base URL (set once at startup, cannot be overridden per-request).
--pricingclaude-opus-4-8Model pricing key for per-tenant dollar accounting.
--lossless-onlyoffPolicy mode: Tier-0 verbatim only — no lossy output-shaping, no tool injection (--expand), no Tier-1 digest stubs. Folds directly into verbatim (no separate --verbatim needed). Use for subscription / OAuth sessions.
--verbatimoffSkip the Tier-1 digest; Tier-0 only. Interactive-safe, lower savings.
--admin-tokenunset (env DISTIL_GATEWAY_TOKEN)Bearer token required for /distil/stats and /distil/dashboard. Mandatory for those routes on non-loopback binds — without it, /distil/* is disabled entirely rather than left open.
--trust-tenant-headeroffHonor the client-supplied x-distil-tenant header for accounting. Off by default: tenant identity is derived from the credential hash, never a client-writable header, so no caller can book its traffic under another tenant's line.
$ distil gateway --port 8789 --upstream https://api.anthropic.com
distil gateway listening on http://127.0.0.1:8789
  dashboard: http://127.0.0.1:8789/distil/dashboard
  → upstream: https://api.anthropic.com

Tenant identification: by default, a stable anonymized key hash (anon-<sha256(credential)[:8]>) derived from x-api-key or authorization, falling back to "default" when no credential is present. The client-supplied x-distil-tenant header is ignored unless the operator opts in with --trust-tenant-header — otherwise any caller could write that header and book its usage under a different tenant's accounting line. Raw API keys are never stored or logged.

$ curl -s http://127.0.0.1:8789/distil/stats | python3 -m json.tool
{
  "tenants": [
    {
      "tenant": "team-search",
      "requests": 142,
      "tokens_saved": 52416,
      "dollars_saved": 0.026208,
      "pct_saved": 28.44
    }
  ],
  "totals": {
    "requests": 142,
    "tokens_saved": 52416,
    "dollars_saved": 0.026208,
    "pct_saved": 28.44
  }
}

See Deploy & Security → Managed gateway for the full deployment guide including multi-tenant setup and security model.


distil train-transformer

Fine-tune a token-classification transformer (default: google/bert_uncased_L-2_H-128_A-2, ~4 MB) for line keep/drop and export it to ONNX. Requires the train extras: pip install 'distil-llm[train]'. The resulting checkpoint is specific to your corpus text distribution — retrain on your own traces for best production results.

Default keep-model is the logistic classifier. The LogisticKeepModel (built-in, zero deps, 96.4% acc / 0.98 F1) is the default for all users. Run train-transformer only when you have a corpus of real traces and want to upgrade to the ONNX transformer adapter.

Flags

FlagDefaultDescription
--outdistil-keep-transformerOutput directory. Receives model.onnx, tokenizer files, and metrics.json.
--base-modelgoogle/bert_uncased_L-2_H-128_A-2HuggingFace model ID to fine-tune. Swap for distilbert-base-uncased for higher accuracy at larger size.
--epochs3Number of training epochs.
$ pip install 'distil-llm[train]'

$ distil train-transformer --out ./my-keep-model
Epoch 1/3  train_loss=0.4821
Epoch 2/3  train_loss=0.2134
Epoch 3/3  train_loss=0.1589
Exported ONNX to ./my-keep-model/model.onnx
Accuracy=0.9630  F1=0.9812
Load with: TransformerKeepModel.from_pretrained('./my-keep-model/model.onnx', './my-keep-model')

Output layout in --out directory:

A demo checkpoint trained on the bundled corpus (96.3% acc / 0.98 F1) is attached to the v0.1.0 release. See Techniques → Keep-model codec for the full design.


distil eval

The certified compression frontier — the proof artifact no competitor publishes. Sweeps compression aggressiveness levels, measures (token savings, decision-equivalence) per level over the corpus, and marks which are certified by the non-inferiority gate. Locates the cliff past which lossy compression starts dropping agent decisions, with distil sitting safely inside the certified region.

Flags

FlagDefaultDescription
--corpusbundled corpusCustom corpus dir (e.g. from distil ingest on benchmark traces)
--runnerdeterministicdeterministic (offline, structural equivalence) or anthropic (live model, requires API key)
--outoffWrite the raw curve as a timestamped JSONL file to this directory
$ distil eval
certified compression frontier  (runner=deterministic)

level                   savings   equiv  certified  curve
--------------------------------------------------------------------------
distil (cache-aware)       8.4%    100%    ✔ PASS   ██
truncate@1200              7.2%     79%       ✘ —    ██
truncate@700              20.0%     36%       ✘ —    ████
truncate@300              41.3%      0%       ✘ —    █████████
--------------------------------------------------------------------------

distil: 8.4% savings @ 100% decision-equivalence — certified.
certified ceiling: 8.4% savings (beyond this, lossy compression drops decisions and the gate rejects it).

See Research & Frontier → Certified compression frontier for the full design.


distil benchmark

Head-to-head against the competing technique families — sliding-window truncation, extractive importance pruning, abstractive summarization, naive minification — each a faithful reference implementation, all scored through the same decision-equivalence + non-inferiority gate and the same cache-aware cost model. Ranks by certified dollar savings; lossy methods that drop decisions are disqualified however much they saved. Register a real external tool to verify. See the Benchmark page for the standings and methodology.

Flags

FlagDefaultDescription
--externalmodule:function[:Name] — register a real compressor (list[str]→list[str] over per-turn block texts), measured on the identical axes. Repeatable.
--corpusbundled corpusCustom corpus dir (e.g. ingested benchmark traces)
--runnerdeterministicdeterministic (offline) or anthropic (live model)
--pricingclaude-opus-4-8Model pricing for the cache-aware cost model
--tokenizerheuristicheuristic or anthropic (billing-grade)
--margin0.02TOST non-inferiority margin
--alpha0.05Significance level for the non-inferiority test
--html / --outoffRender the standings as HTML / write raw results JSONL
$ distil benchmark
compression benchmark  (model=claude-opus-4-8, runner=deterministic, corpus gate)

technique                tok save  $ save  equiv  certified  reversible
---------------------------------------------------------------------------------
distil-causal               33.8%   37.4%   100%     ✔ PASS       lossy
truncate-tail               26.9%   33.0%    25%    ✘ fails       lossy
summarize                   19.7%   24.2%     0%    ✘ fails       lossy
distil-lossless              8.4%   10.3%   100%     ✔ PASS  byte-exact
extractive-prune             7.4%    9.0%    68%    ✘ fails       lossy
---------------------------------------------------------------------------------

LEADER (certified $ savings): distil-causal — 37.4% cheaper, 100% decision-equivalent.

distil frontier

The savings-vs-equivalence dial. 100% decision-equivalence is the certified-safe default; relax the target and Distil spends a bounded divergence budget (floor((1−target) × turns) turns) on the highest-value turns, falling back to byte-exact everywhere else. The trade is explicit and reported — never hidden. Trace the full curve with distil frontier.

Flags

FlagDefaultDescription
--targets1.0,0.97,0.95,0.90,0.80Comma-separated equivalence targets in (0,1]
--corpusbundled corpusCustom corpus dir
--runnerdeterministicdeterministic or anthropic (live model)
--samples3Majority-vote samples for the anthropic runner
$ distil frontier --corpus benchmarks/corpus_xl
savings-vs-equivalence dial  (runner=deterministic)

   target   achieved equiv  token savings   curve
----------------------------------------------------------------------
     100%             100%          58.1%   ████████████████
      95%             100%          58.1%   ████████████████
      80%              82%          62.9%   ██████████████████
----------------------------------------------------------------------

distil conformal

The Decision-Equivalence Risk Certificate (DERC). You choose a risk budget — a maximum decision-change rate α — and Distil certifies the most aggressive compression level whose risk is provably below it, distribution-free and finite-sample, via conformal risk control (Learn-Then-Test / Conformal Risk Control). Unlike the dial, this is a statistical guarantee with a confidence level, calibrated on your own traffic. See Research & Frontier → DERC.

Flags

FlagDefaultDescription
--alpha0.05Risk target: max tolerable decision-change rate
--delta0.05LTT failure probability; confidence is 1−δ (ignored by CRC)
--methodlttltt (high-probability bound) or crc (expected-rate bound)
--corpusbundled corpusCalibration corpus dir (use your own traffic via distil ingest)
--runnerdeterministicdeterministic or anthropic (live model)
--samples3Majority-vote samples for the anthropic runner
$ distil conformal --corpus benchmarks/corpus_xl --alpha 0.05
Decision-Equivalence Risk Certificate (DERC)

  method      : LTT  (Learn-Then-Test)
  risk target : α = 0.05  (max allowed decision-change rate)
  confidence  : 95%  (1 − δ)
  calibration : n = 320 turns,  runner = deterministic
----------------------------------------------------------------
  ✔ CERTIFIED  'lossless'  →  57.4% token savings

distil online

One self-distilling round: collects causal labels from your corpus (certified-safe drops discovered by the ablation engine), retrains the logistic keep-model, and promotes the new weights only if they pass the non-inferiority gate on every trajectory. Never-regressing by construction — a cycle that would degrade quality is silently discarded.

Flags

FlagDefaultDescription
--corpusbundled corpusCorpus dir of traffic to learn from. Use distil ingest to convert real logs first.
--promote-tooff (dry run)If certified, write the new weights as a LogisticKeepModel-compatible JSON file to this path.
$ distil online --corpus ./mycorpus --promote-to ./weights/keep_model.json
self-distilling round — keep-model learns from causal labels, gated by non-inferiority

  n_labels: 286
  accuracy: 0.873
  f1: 0.932
  certified: True
  promoted: True

See Research & Frontier → Self-distilling keep-model for the full loop design.


distil federated-leaderboard

Build a verifiable federated savings leaderboard from HMAC-signed, content-free savings aggregates. Verifies each submission's signature and counts only certified savings toward headline totals — savings you can verify. No prompt or response text ever leaves the contributing instance.

Flags

FlagDefaultDescription
--dirrequiredDirectory containing submissions.jsonl (one signed aggregate per line)
--keysoffPath to a JSON file mapping instance_id → HMAC key. Submissions with no matching key are rejected.
--htmloffWrite a self-contained leaderboard HTML page to this path
$ distil federated-leaderboard \
    --dir ./submissions \
    --keys ./instance-keys.json \
    --html ./leaderboard.html
verifiable savings — 3 verified instance(s), 0 rejected

  totals (certified only): {'tokens_saved': 142816, 'dollars_saved': 0.071408, 'runs': 47, 'instances': 3}
  leaderboard html → ./leaderboard.html

See Research & Frontier → Verifiable federated telemetry for the signing model and ed25519 upgrade path.


distil certify-trajectories

The trajectory-level risk certificate — bounds end-to-end task degradation, not per-step decision-equivalence. Reads a JSONL of matched full/compressed task runs and certifies P(degradation risk ≤ alpha) ≥ 1-delta using Conformal Risk Control (Hoeffding–Bentkus), the invariant that transfers to real task success where per-step certificates (DERC) can't. See Concepts → The trajectory-level certificate for the full framing and honest assumptions.

Flags

FlagDefaultDescription
outcomesrequiredPath to a JSONL file of matched runs, one object per line: {"task_id": ..., "full_success": bool, "compressed_success": bool}
--alpha0.05Maximum end-to-end degradation risk to certify
--delta0.05Confidence budget — certificate holds at confidence 1−δ
--jsonoffMachine-readable output: the full certificate fields plus statement
$ distil certify-trajectories outcomes.jsonl --alpha 0.05 --delta 0.05
distil trajectory-risk certificate

  matched trajectories : 200
  observed degradation : 0.50%
  risk bound (1-δ)     : 3.20%
  certified (α=0.05, δ=0.05) : True

  With confidence 95%, compression degrades at most 5.0% of tasks the full
  context would have solved (observed 0.50% over 200 matched trajectories).
  Valid under: future trajectories exchangeable with calibration; loss =
  measured end-to-end task outcome; calibration held out from compressor
  tuning; recalibrate on drift

Refuses to certify (exit 1, not a false PASS) below min_n=20 matched trajectories — a certificate from a handful of samples is noise dressed up as a guarantee. Exits 0 only when certified is true.


distil onboard

One command to set up distil and learn to use it. Detects your environment — OS, package managers, agent CLIs (Claude Code / Codex / Gemini), how distil is installed, the optional anthropic extra, and whether you're on a flat-rate Claude subscription — then wires the savings status line and prints a next-steps guide tailored to what it found: how to route the detected agent (subscription-safe vs metered), validate outcomes with shadow mode, watch savings on the dashboard, run the test gate, and re-verify with distil doctor. --dry-run changes nothing; works on macOS and Windows.


distil default

Make distil the default for your agent so you don't type distil wrap every session. Writes a single managed, marked, backed-up, idempotent block to the shell rc distil detects for this machine — zsh (.zshrc), bash (.bashrc/.bash_profile), fish (config.fish), or PowerShell ($PROFILE) — using the correct syntax for each (alias / function / export / set -gx). An explicit $SHELL wins over file-existence guesses, and the command prints what it detected (shell, rc, agent, mode) rather than acting blind. --always-on instead installs a persistent proxy service (launchd / systemd) plus ANTHROPIC_BASE_URL so every base-URL-honoring SDK routes through distil — universal, but a daemon you keep alive and a single point of failure if it's down. --undo removes whichever is installed; --agent, --mode, --rc override the detected defaults. distil onboard offers it interactively.


distil offboard

Remove distil's footprint — the inverse of distil onboard. Undoes the shell default (the distil default alias/env block), stops and removes the always-on proxy service, and unwires the status line from Claude Code settings — asking before each (non-interactive without --yes removes nothing). Your savings ledger and shadow data are kept unless you pass --purge. It can't uninstall the running package itself, so it prints the exact uninstall command for how distil was installed (pipx / uv / pip). A foreign status line (one you set yourself) is left untouched.


distil dashboard

Live terminal dashboard of your cumulative savings — a framed panel with Unicode bars for token-trim and decision-equivalence, original → compressed tokens and cost, a recent-decisions strip, and per-trajectory bars. Uses the alternate screen (like htop): redraws in place and restores your prompt on exit. --once prints a single frame; --interval sets refresh seconds. On a flat-rate subscription the dollar figures are dropped automatically (DISTIL_SUBSCRIPTION overrides).


distil statusline

One compact line, designed to be a segment inside your own composite status line — every character earns its place:

# a proxy session is active (or was, within the last 4h)
distil · ▼75.0K −62% $0.31 · Σ27.0M

# no recent session — falls back to the lifetime figure
distil · Σ27.0M saved −50% $96.10

is tokens saved and −N% the trim rate of the active scope — the current proxy session while one is live (last activity <4h ago), lifetime otherwise; Σ is the lifetime tokens-saved figure, shown as a compact suffix next to a live session or as the headline when idle. The dollar figure only appears on metered/PAYG billing (dropped entirely on a flat-rate subscription) and only when it's non-zero. Dropped by design: the orig→compressed pair (derivable from the trim %), run counts, and any equivalence rate under 25 shadow samples — eq 100.0% (1) is noise wearing a number. Once shadow has ≥25 samples, an eq N.N% (n) segment appears; its color is alarm-only, not decoration — calm brand hue while ≥99%, warning under 99%, alarm under 95%. Full breakdown: distil stats / distil dashboard. Wire it with distil setup or the plugin.


distil shadow-stats

Report the live decision-equivalence measured by shadow mode on real traffic: the percentage of sampled requests where the agent's chosen next action was identical with vs without compression, and how many samples that's based on. Start sampling with distil wrap --shadow 0.1 -- claude.

Flags

FlagDefaultDescription
--jsonoffMachine-readable output: samples, changes, decision_change_rate, decision_equivalence

distil doctor

Diagnose a distil setup end-to-end: distil/Python version, the savings ledger (subscription-aware), shadow-validation status, an in-process proxy round-trip self-test (proves the proxy machinery works with no network), the optional anthropic extra and API key, and — for Claude Code — status-line wiring and subscription detection. Exits non-zero if any check fails, so it doubles as a setup gate.

Flags

FlagDefaultDescription
--no-coloroffDisable ANSI colors in the check list
--jsonoffMachine-readable output (CI-gateable): {"checks": [...], "ok": bool}, one object per check with name/status/detail/hint

distil setup

Wire the distil savings status line into Claude Code's settings.json in one step. Idempotent (no-op if already wired), never clobbers an existing status line without --force (which backs it up first), and preserves all other settings.


Full CI gate

$ make gate
# Runs: tests + corpus non-inferiority (distil bench) + byte-fidelity (distil verify)

pytest ... 181 passed in 4.2s
corpus gate: PASS
fidelity gate: PASS