Skip to main content

Free open-source RAG compression middleware. Drop-in API for LLM pipelines.

Project description


title: Winnow emoji: ๐ŸŒพ colorFrom: yellow colorTo: blue sdk: docker app_port: 7860 pinned: false

Winnow ๐ŸŒพ

Open-source RAG prompt compression middleware. Keep the signal. Drop the noise.

Built with FastAPI, LLMLingua-2, and tiktoken. MIT licensed, self-hostable, pip installable.

๐ŸŒ trywinnow.vercel.app ยท ๐Ÿ“ฆ PyPI ยท ๐Ÿค— HuggingFace Space ยท โญ GitHub


๐ŸŽฏ What is Winnow?

Winnow sits between your vector database and your LLM. It takes raw retrieved document chunks, compresses them using LLMLingua-2 token-level scoring guided by your query, and returns a shorter context that preserves answer-relevant content โ€” cutting token costs by ~50% with less than 3% accuracy loss.

โœจ Key Features

  • ๐Ÿ—œ๏ธ Token Compression: Cuts retrieved context by ~50% using LLMLingua-2
  • ๐ŸŽฏ Query-Guided: Compression is steered by your question โ€” relevant tokens survive
  • ๐Ÿ”’ Protected Words: Mark phrases that must never be removed
  • โš–๏ธ Ratio Control: Tune aggressiveness from 0.1 (light) to 0.9 (heavy)
  • ๐Ÿ”Œ OpenAI-Compatible Proxy: Drop-in /v1/chat/completions โ€” zero code changes
  • ๐Ÿฆœ LangChain Integration: Native WinnowCompressor drop-in wrapper
  • ๐Ÿณ Self-Hostable: Single Docker command, no API key required
  • ๐Ÿ“ฆ Pip Installable: pip install winnow-compress

๐Ÿ“Š Benchmarks

Tested on SQuAD with LLMLingua-2. Baseline F1: 78.4. Avg latency: ~85ms.

Preset Ratio Tokens In Tokens Out Reduction F1 Score F1 Drop
Light 0.7 420 294 ~30% 77.6 <1 pt
Balanced 0.5 420 210 ~50% 76.1 2.3 pt
Aggressive 0.3 420 147 ~65% 73.4 5.0 pt

๐Ÿš€ Quick Start

# Self-host in one command
docker run -p 8000:8000 itsaryanchauhan/winnow

API live at http://localhost:8000 ยท Docs at http://localhost:8000/docs

๐Ÿ“– Full Integration Examples (Docker, pip, LangChain, REST, OpenAI Proxy)

Option 1 โ€” Self-host with Docker

docker run -p 8000:8000 itsaryanchauhan/winnow

Option 2 โ€” pip install

pip install winnow-compress
from winnow import compress

result = compress(
    input_text,
    compression_ratio=0.5,
    rag_mode=True,
    question="What is the warranty period?"
)

print(result["output"])
print(result["original_tokens"])     # e.g. 420
print(result["compressed_tokens"])   # e.g. 210
print(result["ratio"])               # e.g. 0.5
print(result["estimated_savings_usd"])    # e.g. 0.000525

Option 3 โ€” LangChain Drop-in

from winnow.langchain import WinnowCompressor

compressor = WinnowCompressor(ratio=0.5)
compressed_docs = compressor.compress_documents(docs, query)

Option 4 โ€” REST API (curl)

curl -X POST http://localhost:8000/v1/compress \
  -H "Content-Type: application/json" \
  -d '{
    "input": "your retrieved chunks here",
    "compression_ratio": 0.5,
    "rag_mode": true,
    "question": "what is the capital of France?",
    "protected_strings": ["Paris", "France"]
  }'

Option 5 โ€” OpenAI-Compatible Proxy

Zero code changes if you already use the OpenAI SDK โ€” just swap the base URL:

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"
)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": your_prompt}]
)

Request Parameters

Field Type Required Description
input string โœ… Text or context to compress
question string โŒ Optional query for RAG-guided compression
compression_ratio float โŒ Compression ratio 0.1โ€“0.9. Default: 0.5
protected_strings string[] โŒ Words/phrases that must not be removed
rag_mode boolean โŒ Enable question-guided compression. Default: false

Response Fields

Field Type Description
output string The compressed output
original_tokens int Token count before compression
compressed_tokens int Token count after compression
ratio float Actual ratio achieved
estimated_savings_usd float Estimated USD saved (gpt-4o pricing)

Batch Compression

curl -X POST http://localhost:8000/v1/compress/batch \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": ["chunk one...", "chunk two..."],
    "compression_ratio": 0.5,
    "rag_mode": true,
    "question": "your query"
  }'

๐Ÿ“ Project Structure

Winnow/
โ”œโ”€โ”€ app/               # FastAPI application
โ”‚   โ””โ”€โ”€ main.py        # API routes and server
โ”œโ”€โ”€ winnow/            # pip package
โ”‚   โ”œโ”€โ”€ __init__.py    # compress() function
โ”‚   โ””โ”€โ”€ langchain.py   # WinnowCompressor
โ”œโ”€โ”€ benchmarks/        # SQuAD benchmark scripts and results
โ”œโ”€โ”€ tests/             # Test suite
โ”œโ”€โ”€ website/           # Next.js website (trywinnow.vercel.app)
โ”œโ”€โ”€ Dockerfile
โ””โ”€โ”€ pyproject.toml

๐Ÿ”Œ API Endpoints

Method Endpoint Description
POST /v1/compress Compress a single context
POST /v1/compress/batch Compress multiple contexts
POST /v1/chat/completions OpenAI-compatible proxy with auto-compression
GET /health Health check

๐Ÿ› ๏ธ Built With

  • API: FastAPI + Python
  • Compression: microsoft/llmlingua-2-xlm-roberta-large-meetingbank
  • Tokenizer: tiktoken (cl100k_base)
  • Deploy: Docker + HuggingFace Spaces

๐Ÿ‘ค Author

Created by Aryan Chauhan (@itsaryanchauhan)

๐Ÿ“ž Get in Touch

Have questions or suggestions? Open an issue on the GitHub repository.


MIT License ยท Live Demo ยท HuggingFace Space

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

winnow_compress-0.2.1.tar.gz (9.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

winnow_compress-0.2.1-py3-none-any.whl (6.5 kB view details)

Uploaded Python 3

File details

Details for the file winnow_compress-0.2.1.tar.gz.

File metadata

  • Download URL: winnow_compress-0.2.1.tar.gz
  • Upload date:
  • Size: 9.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for winnow_compress-0.2.1.tar.gz
Algorithm Hash digest
SHA256 425d3031a4729f1ae4c769cda81b72382cbc07873dc582ec7e05c1b0fb0cdc6c
MD5 bdd6f30f617212d776defa8a35a06610
BLAKE2b-256 0e66a1aff25df2c255293e6ac12d5cae8dfcaba79df502f3abcd877c1c503365

See more details on using hashes here.

File details

Details for the file winnow_compress-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for winnow_compress-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 74f9f057f407e7a9a555ac1668eeead63b63fa9625dce64489b60ae2d2e55b68
MD5 722a9b766a7bafe35c211cdc19f4cc9b
BLAKE2b-256 102ce95a0d9f981455c3e072c31c187af38a30893cef4ed6b0e252d749759540

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page