ctxprune
Context compression for AI agents. A small token classifier deletes the least useful words from tool outputs, code, documents and chat before they reach an LLM. It is a successor to Microsoft's LLMLingua-2, built for agent text, and it never splits or re-spaces identifiers.
Model: darioooooo0o/ctxprune-small (Apache-2.0). Results and limitations are on the model card. Try it next to LLMLingua-2 on your own text: live demo.
pip install "ctxprune @ git+https://github.com/riceharvest/ctxprune" # CPU, ONNX; no torch needed
from ctxprune import Compressor
c = Compressor("darioooooo0o/ctxprune-small", backend="onnx")
c.compress(tool_output, rate=0.5)["text"] # keep ~50%
c.compress(tool_output, rate=0.33, force_protected=True)["text"] # never drop IDs/numbers/paths
ctxprune order.json --rate 0.5 # CLI, same thing
LangChain and LlamaIndex:
from ctxprune.integrations import CtxpruneDocumentCompressor # LangChain
retriever = ContextualCompressionRetriever(base_compressor=CtxpruneDocumentCompressor(rate=0.5),
base_retriever=base_retriever)
from ctxprune.integrations import CtxpruneNodePostprocessor # LlamaIndex
engine = index.as_query_engine(node_postprocessors=[CtxpruneNodePostprocessor(rate=0.5)])
Works inside LLMLingua too, once its tokenizer-detection fix is merged:
microsoft/LLMLingua#261 (upstream/llmlingua-subword-style.patch).
At 50% of tokens kept, an independent LLM answers 68.8% of held-out questions correctly from ctxprune's output vs 53.4% from LLMLingua-2-large's (91.8% uncompressed); at 33%, 53.4% vs 32.5%. Details, per-source results and limitations: model card.
By @imdariotoo.
Reproducing the model
Why: LLMLingua-2 (Microsoft, Mar 2024) was trained only on meeting transcripts under CC BY-NC-SA labels. On agent tool outputs it loses or mangles about half of all identifiers (UUIDs, IPs, paths, versions) and breaks JSON.
Pipeline
| step | script | where | notes |
|---|---|---|---|
| corpus | scripts/build_corpus.py |
CPU, ~2 min | ranged parquet reads from 8 permissive sources; split per repo/server/site |
| labels | scripts/label.py |
teacher LLM (scripts/teacher_up.sh) |
deletion-only compression, LCS-aligned to atoms; cached |
| train | scripts/train.py |
any torch device (we used an Intel Arc Pro B70) or CPU | token classifier, label 1 = keep (LLMLingua-2 convention) |
| quick eval | scripts/eval_quick.py |
CPU | identifiers lost, JSON validity, char ratio vs LLMLingua-2 |
| QA eval | scripts/eval_qa.py questions/answer |
teacher LLM | can a reader still answer from the compressed text |
scripts/run_v1.sh runs corpus and labels; scripts/after_label.sh runs everything after them.
Data sources (all permissive)
SWE-smith trajectories (MIT), SWE-rebench OpenHands trajectories (CC BY 4.0), Toucan-1.5M MCP tool calls (Apache-2.0), github-code-clean filtered to MIT/Apache/BSD/ISC files, FineWeb-Edu and FineWeb-2 (ODC-BY), oasst2 (Apache-2.0). Every chunk records its dataset, license and source reference. Teacher: Qwen3.8-27B GPTQ (Apache-2.0 outputs).
Training more after an eval
Nothing has to be redone:
- More data, same mix. Rerun
build_corpus.pyinto the same directory with a larger--total. Sampling is deterministic, and dataset revisions are pinned inchunks/revisions.json, so every source file becomes a superset of the old one. To weight a domain up, add--mix toucan_mcp=0.3. - Label only the new chunks. Rerun
label.py. The teacher cache is keyed by (prompt version, model, text), so old chunks come back from disk. - Continue training from the previous model:
train.py --data <dir> --init-from runs/v1-mmbert-small/final --out runs/v2-...(or--resumeto continue an interrupted run from its checkpoint).--dataaccepts several directories, to mix label sets. - Re-run evals. Question and answer caches mean only new contexts cost LLM calls.
Changing the teacher prompt bumps PROMPT_VERSION in ctxprune/teacher.py, which
invalidates the cache on purpose.
Tests
uv run pytest: atom round-trips, identifier atoms, CJK handling, LCS
alignment, chunk budgets, split stability and cache resume.
Metadata
Release files for ctxprune 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ctxprune-0.1.0.tar.gz | 26.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ctxprune-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 54.0 kB
Release files / ctxprune-0.1.0.tar.gz
| Download URL | ctxprune-0.1.0.tar.gz |
|---|---|
| Size | 26.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d5eb67b076ceece6e70191ea9b5d3640d0ecbc4431522dfc1422941a1cc76c52
|
|
BLAKE2b-256 checksum How to use checksums |
4481e865ad6a693c30aa42b50746bc70391e658ccc0dfd3638c5901598e2711f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.
Transparency logRelease files / ctxprune-0.1.0-py3-none-any.whl
| Download URL | ctxprune-0.1.0-py3-none-any.whl |
|---|---|
| Size | 27.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a2e06327db201d30719f4ed504a7e209fbbd71b9f8730888ecf8253acc042ba0
|
|
BLAKE2b-256 checksum How to use checksums |
229e9c2127d721a6df810f470903f163d5441d5bce6ddf97284863ce592df6fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.
Transparency log