Free open-source RAG compression middleware. Drop-in API for LLM pipelines.
Project description
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
WinnowRetrieverdrop-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 Winnow
client = Winnow()
result = client.compress(
text=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 WinnowRetriever
retriever = WinnowRetriever(
base_retriever,
compression_ratio=0.5
)
docs = retriever.get_relevant_documents("your question")
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
โ โโโ client.py # Winnow
โ โโโ langchain.py # WinnowRetriever
โโโ 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file winnow_compress-0.2.2.tar.gz.
File metadata
- Download URL: winnow_compress-0.2.2.tar.gz
- Upload date:
- Size: 9.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
803e7c5781eb60ab87cd4c2850fcba8e06c311ac71179cbb23c0d626d81c0b39
|
|
| MD5 |
ebe68e5f21b6de9afe4ce35f1e2748d0
|
|
| BLAKE2b-256 |
ca2a9c5431166e00dbd99e20ed2a3e62942c4004c0e4d402eda5768ce8b30d8b
|
File details
Details for the file winnow_compress-0.2.2-py3-none-any.whl.
File metadata
- Download URL: winnow_compress-0.2.2-py3-none-any.whl
- Upload date:
- Size: 6.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4cc0e3b245a85048b4812ff00f232479254a955318a8446e190a75c8e4284b30
|
|
| MD5 |
691b90dc86f2fdfcec9a8132a3c4f7bf
|
|
| BLAKE2b-256 |
1f3bd2f2cabf5e436687693da503d7a14df3c05b299f48f63389a29283d20e85
|