sieve-context 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. sieve_context-0.1.0/.env +3 -0
  2. sieve_context-0.1.0/.env.example +3 -0
  3. sieve_context-0.1.0/.gitignore +0 -0
  4. sieve_context-0.1.0/.python-version +1 -0
  5. sieve_context-0.1.0/CONTRIBUTING.md +16 -0
  6. sieve_context-0.1.0/LICENSE +21 -0
  7. sieve_context-0.1.0/PKG-INFO +310 -0
  8. sieve_context-0.1.0/README.md +261 -0
  9. sieve_context-0.1.0/SIEVE_LOGO.txt +9 -0
  10. sieve_context-0.1.0/examples/benchmark.json +52 -0
  11. sieve_context-0.1.0/examples/context.txt +16 -0
  12. sieve_context-0.1.0/main.py +64 -0
  13. sieve_context-0.1.0/pyproject.toml +88 -0
  14. sieve_context-0.1.0/sieve/__init__.py +29 -0
  15. sieve_context-0.1.0/sieve/benchmark.py +132 -0
  16. sieve_context-0.1.0/sieve/calibrate.py +140 -0
  17. sieve_context-0.1.0/sieve/cli.py +248 -0
  18. sieve_context-0.1.0/sieve/config.py +69 -0
  19. sieve_context-0.1.0/sieve/documents.py +123 -0
  20. sieve_context-0.1.0/sieve/integrations/__init__.py +1 -0
  21. sieve_context-0.1.0/sieve/integrations/langchain.py +62 -0
  22. sieve_context-0.1.0/sieve/llm.py +87 -0
  23. sieve_context-0.1.0/sieve/mcp/__init__.py +1 -0
  24. sieve_context-0.1.0/sieve/mcp/server.py +34 -0
  25. sieve_context-0.1.0/sieve/mcp/tools.py +79 -0
  26. sieve_context-0.1.0/sieve/metrics.py +21 -0
  27. sieve_context-0.1.0/sieve/models.py +125 -0
  28. sieve_context-0.1.0/sieve/scorer.py +72 -0
  29. sieve_context-0.1.0/sieve/sieve.py +245 -0
  30. sieve_context-0.1.0/sieve/ui.py +182 -0
  31. sieve_context-0.1.0/sieve/vector_store.py +86 -0
  32. sieve_context-0.1.0/sieve.yaml +27 -0
  33. sieve_context-0.1.0/sieve.yaml.example +27 -0
  34. sieve_context-0.1.0/tests/__init__.py +0 -0
  35. sieve_context-0.1.0/tests/test_calibrate.py +35 -0
  36. sieve_context-0.1.0/tests/test_documents.py +21 -0
  37. sieve_context-0.1.0/tests/test_langchain.py +30 -0
  38. sieve_context-0.1.0/tests/test_mcp.py +44 -0
  39. sieve_context-0.1.0/tests/test_metrics.py +20 -0
  40. sieve_context-0.1.0/tests/test_optimize.py +51 -0
  41. sieve_context-0.1.0/tests/test_sieve.py +46 -0
  42. sieve_context-0.1.0/uv.lock +2081 -0
  43. sieve_context-0.1.0/workspace/documents/APPL SEC FILINGS.pdf +0 -0
  44. sieve_context-0.1.0/workspace/documents/Apple_Sec_File.txt +2165 -0
  45. sieve_context-0.1.0/workspace/indexes/chunks.json +2662 -0
  46. sieve_context-0.1.0/workspace/indexes/embeddings.npy +0 -0
@@ -0,0 +1,3 @@
1
+ SIEVE_LLM_PROVIDER=google
2
+ SIEVE_GOOGLE_API_KEY=AQ.Ab8RN6JJ7gbeuc0dXf4IC9KrRvNgkKmoy5duKKB1xqKZK9kY8w
3
+ SIEVE_GOOGLE_MODEL=gemini-3.5-flash-lite
@@ -0,0 +1,3 @@
1
+ SIEVE_LLM_PROVIDER=google
2
+ SIEVE_GOOGLE_API_KEY=your-api-key-here
3
+ SIEVE_GOOGLE_MODEL=gemini-3.5-flash-lite
Binary file
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,16 @@
1
+ # Contributing to Sieve
2
+
3
+ Thank you for your interest in contributing to Sieve!
4
+
5
+ ## Getting Started
6
+
7
+ 1. Fork the repository
8
+ 2. Clone your fork locally
9
+ 3. Install dependencies using `uv`: `uv sync`
10
+ 4. Run tests: `uv run pytest`
11
+
12
+ ## Guidelines
13
+
14
+ - Follow existing style. We recommend using `ruff` and `black`.
15
+ - Write tests for new features.
16
+ - Ensure the benchmark suite (`sieve benchmark`) still functions correctly and metrics are honest.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sieve Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,310 @@
1
+ Metadata-Version: 2.5
2
+ Name: sieve-context
3
+ Version: 0.1.0
4
+ Summary: Cut retrieved context your RAG application sends to LLMs using local cross-encoder filtering.
5
+ Project-URL: Homepage, https://github.com/kuhinthewuh/Sieve
6
+ Project-URL: Repository, https://github.com/kuhinthewuh/Sieve
7
+ Project-URL: Issues, https://github.com/kuhinthewuh/Sieve/issues
8
+ Author-email: Kushaagra Patel <kushaagra.patel@outlook.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: ai,context compression,cross-encoder,developer tools,embeddings,information retrieval,llm,mcp,nlp,prompt compression,rag,retrieval augmented generation,semantic search
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: numpy>=1.24.0
23
+ Requires-Dist: pydantic>=2.0.0
24
+ Requires-Dist: python-dotenv>=1.0.0
25
+ Requires-Dist: pyyaml>=6.0
26
+ Requires-Dist: rich>=13.0.0
27
+ Requires-Dist: sentence-transformers>=3.0.0
28
+ Requires-Dist: tiktoken>=0.7.0
29
+ Requires-Dist: typer>=0.9.0
30
+ Provides-Extra: all
31
+ Requires-Dist: beautifulsoup4>=4.12.0; extra == 'all'
32
+ Requires-Dist: google-genai>=0.5.0; extra == 'all'
33
+ Requires-Dist: mcp>=1.0.0; extra == 'all'
34
+ Requires-Dist: pymupdf>=1.23.0; extra == 'all'
35
+ Provides-Extra: dev
36
+ Requires-Dist: build>=1.0.0; extra == 'dev'
37
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
38
+ Requires-Dist: twine>=5.0.0; extra == 'dev'
39
+ Provides-Extra: docs
40
+ Requires-Dist: beautifulsoup4>=4.12.0; extra == 'docs'
41
+ Requires-Dist: pymupdf>=1.23.0; extra == 'docs'
42
+ Provides-Extra: google
43
+ Requires-Dist: google-genai>=0.5.0; extra == 'google'
44
+ Provides-Extra: langchain
45
+ Requires-Dist: langchain-core; extra == 'langchain'
46
+ Provides-Extra: mcp
47
+ Requires-Dist: mcp>=1.0.0; extra == 'mcp'
48
+ Description-Content-Type: text/markdown
49
+
50
+ # Sieve
51
+
52
+ ```text
53
+ ____ ___ ______ _______
54
+ / ___|_ _| ____\ \ / / ____|
55
+ \___ \| || _| \ \ / /| _|
56
+ ___) | || |___ \ V / | |___
57
+ |____/___|_____| \_/ |_____|
58
+ ```
59
+
60
+ > **Less noise. Better retrieval.**
61
+ > *Sift the signal from your retrieval pipeline.*
62
+
63
+ [![PyPI version](https://img.shields.io/pypi/v/sieve-context.svg)](https://pypi.org/project/sieve-context/)
64
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
65
+ [![Python: 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
66
+
67
+ **Sieve** is a lightweight, post-retrieval context optimizer for Retrieval-Augmented Generation (RAG). It runs locally between your retriever and your LLM, evaluating retrieved sentences with a cross-encoder to prune irrelevant noise before generation.
68
+
69
+ ```text
70
+ Retriever ──► [ Retrieved Chunks ] ──► Sieve (Local Cross-Encoder) ──► [ Pruned Context ] ──► LLM
71
+ ```
72
+
73
+ Your vector database over-retrieves by design: embedding top-k similarity search returns large blocks of text where often only a few sentences answer the query. Sieve removes the noise, preserves document metadata, and passes a physically smaller, denser prompt to your downstream model.
74
+
75
+ ---
76
+
77
+ ## Why Sieve?
78
+
79
+ Every irrelevant token retrieved into your prompt creates measurable friction:
80
+ - **Cost:** You pay per input token on hosted APIs (OpenAI, Anthropic, Gemini, Groq).
81
+ - **Latency:** Prompt processing time grows with input token volume.
82
+ - **Attention Degradation:** Irrelevant sentences compete with crucial facts for the model's attention budget ("lost in the middle" effect).
83
+ - **Zero API Key Requirement:** Filtering runs locally on your machine using a compact cross-encoder (`ms-marco-MiniLM-L-6-v2`). Your LLM API keys are never needed for context compression.
84
+
85
+ ---
86
+
87
+ ## Installation
88
+
89
+ Install via pip:
90
+
91
+ ```bash
92
+ pip install sieve-context
93
+ ```
94
+
95
+ ### Optional Extras
96
+
97
+ - **LangChain Integration:**
98
+ ```bash
99
+ pip install "sieve-context[langchain]"
100
+ ```
101
+ - **Model Context Protocol (MCP) Server:**
102
+ ```bash
103
+ pip install "sieve-context[mcp]"
104
+ ```
105
+ - **Document Ingestion (PDF & HTML):**
106
+ ```bash
107
+ pip install "sieve-context[docs]"
108
+ ```
109
+ - **All Capabilities:**
110
+ ```bash
111
+ pip install "sieve-context[all]"
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Quickstart
117
+
118
+ ### 1. Document-Level Optimization (Preserving Metadata)
119
+
120
+ Pass retrieved documents directly into `Sieve.optimize()`. Sieve filters sentences while maintaining each document's identity and metadata:
121
+
122
+ ```python
123
+ from sieve import Document, Sieve
124
+
125
+ sieve = Sieve(threshold=0.5)
126
+
127
+ retrieved_docs = [
128
+ Document(
129
+ text=(
130
+ "Apple Inc. reported total net sales of $391,035 million in fiscal year 2024. "
131
+ "Apple Park's main circular building features solar panels generating 17 megawatts."
132
+ ),
133
+ metadata={"source": "apple-10k.pdf", "page": 28}
134
+ ),
135
+ Document(
136
+ text="Steve Jobs co-founded Apple in Los Altos in 1976. iPhone net sales reached $201,183 million.",
137
+ metadata={"source": "apple-10k.pdf", "page": 31}
138
+ )
139
+ ]
140
+
141
+ result = sieve.optimize(
142
+ query="What was Apple's total net sales and iPhone sales in 2024?",
143
+ documents=retrieved_docs,
144
+ )
145
+
146
+ # Ready-to-inject string for your LLM prompt
147
+ print(result.context)
148
+
149
+ # Filtered documents preserving metadata
150
+ for doc in result.documents:
151
+ print(doc.metadata, "->", doc.text)
152
+
153
+ # Inspect exact token and reduction metrics
154
+ print(f"Original tokens: {result.metrics.original_tokens}")
155
+ print(f"Retained tokens: {result.metrics.filtered_tokens}")
156
+ print(f"Reduction: {result.metrics.reduction_percent}%")
157
+ print(f"Latency: {result.metrics.filtering_latency_ms} ms")
158
+ ```
159
+
160
+ ---
161
+
162
+ ### 2. Direct String Filtering
163
+
164
+ If you have a raw context string:
165
+
166
+ ```python
167
+ from sieve import filter_context
168
+
169
+ result = filter_context(
170
+ query="What was Apple's 2024 revenue?",
171
+ context="Apple's fiscal 2024 revenue reached $391,035 million. The cafeteria serves lunch daily.",
172
+ threshold=0.5,
173
+ max_tokens=500,
174
+ )
175
+
176
+ print(result.filtered_context)
177
+ # Output: "Apple's fiscal 2024 revenue reached $391,035 million."
178
+ ```
179
+
180
+ ---
181
+
182
+ ### 3. LangChain Integration
183
+
184
+ Drop Sieve into your existing LangChain retrieval chains as a document compressor:
185
+
186
+ ```python
187
+ from sieve.integrations.langchain import SieveCompressor
188
+
189
+ compressor = SieveCompressor(threshold=0.5)
190
+ optimized_docs = compressor.compress_documents(retrieved_docs, query="Apple 2024 revenue")
191
+ ```
192
+
193
+ ---
194
+
195
+ ### 4. Model Context Protocol (MCP)
196
+
197
+ Sieve includes a native MCP server for Claude Desktop, Cursor, and any MCP-compliant agent.
198
+
199
+ Start the server:
200
+
201
+ ```bash
202
+ sieve-mcp
203
+ ```
204
+
205
+ Or configure it in your `claude_desktop_config.json`:
206
+
207
+ ```json
208
+ {
209
+ "mcpServers": {
210
+ "sieve": {
211
+ "command": "sieve-mcp"
212
+ }
213
+ }
214
+ }
215
+ ```
216
+
217
+ #### Available MCP Tools
218
+
219
+ 1. **`sieve_filter`**:
220
+ - Inputs: `query` (str), `context` (str), `threshold` (float, default 0.5), `max_tokens` (optional int).
221
+ - Returns: Filtered context string, token counts, reduction percentage, and filtering latency.
222
+ 2. **`sieve_score`**:
223
+ - Inputs: `query` (str), `context` (str).
224
+ - Returns: Unfiltered sentence-by-sentence relevance scores (0 to 1) for inspectability.
225
+ 3. **`sieve_stats`**:
226
+ - Returns cumulative session statistics: total calls, tokens processed, tokens pruned, and average reduction.
227
+
228
+ ---
229
+
230
+ ## Sieve Calibrate
231
+
232
+ How aggressively can you filter context before answer accuracy degrades?
233
+
234
+ **Sieve Calibrate** sweeps a spectrum of thresholds across a benchmark dataset of `{question, context, expected_answer}` cases, evaluating answer preservation at each threshold to compute the **minimum sufficient context**.
235
+
236
+ Run calibration from the CLI:
237
+
238
+ ```bash
239
+ sieve calibrate --benchmark examples/benchmark.json --thresholds 0.20,0.35,0.50,0.65,0.80 --offline
240
+ ```
241
+
242
+ Example output:
243
+
244
+ ```text
245
+ SIEVE CALIBRATION RESULTS
246
+ +---------------------------------------------------------------------+
247
+ | Threshold | Context Kept | Accuracy | Correct | Avg Latency |
248
+ |-------------------+--------------+----------+---------+-------------|
249
+ | — (WITHOUT SIEVE) | 100.0% | 100.0% | 10/10 | 0.0ms |
250
+ | 0.20 | 38.1% | 100.0% | 10/10 | 0.3ms |
251
+ | 0.35 | 38.1% | 100.0% | 10/10 | 0.3ms |
252
+ | 0.50 | 38.1% | 100.0% | 10/10 | 0.3ms |
253
+ | 0.65 | 38.1% | 100.0% | 10/10 | 0.3ms |
254
+ | 0.80 | 38.1% | 100.0% | 10/10 | 0.3ms |
255
+ +---------------------------------------------------------------------+
256
+
257
+ Minimum sufficient context: Threshold 0.20, 38.1% of context retained, 100.0% accuracy.
258
+ ```
259
+
260
+ ---
261
+
262
+ ## Configuration & Parameters
263
+
264
+ | Parameter | Type | Default | Description |
265
+ | :--- | :--- | :--- | :--- |
266
+ | `threshold` | `float` | `0.50` | Sigmoid-squashed cross-encoder logit cutoff (0.0 to 1.0). Sentences below this score are pruned. |
267
+ | `max_tokens` | `int` or `None` | `None` | Optional token budget limit for the retained context. |
268
+ | `context_window`| `int` | `0` | Number of neighboring sentences within the same document to retain around high-scoring hits. |
269
+ | `model_name` | `str` | `cross-encoder/ms-marco-MiniLM-L-6-v2` | Hugging Face cross-encoder model ID. |
270
+
271
+ ---
272
+
273
+ ## Architecture & How It Works
274
+
275
+ 1. **Sentence Segmentation:** Text is parsed into discrete sentences without external NLP runtime dependencies.
276
+ 2. **Local Batch Cross-Encoding:** Query and sentence pairs are evaluated in parallel batches with `cross-encoder/ms-marco-MiniLM-L-6-v2`. The model is loaded once per process and reused.
277
+ 3. **Thresholding & Context Preservation:** Sentences scoring above the threshold are selected. Optional `context_window` preserves adjacent sentences to maintain numerical and pronoun coherence.
278
+ 4. **Original Order Reconstruction:** Retained sentences are reconstructed in their original document order to preserve narrative flow for the LLM.
279
+ 5. **Deterministic Metrics:** Token reductions are measured locally via `tiktoken` (`cl100k_base`).
280
+
281
+ ---
282
+
283
+ ## Limitations
284
+
285
+ - **Sentence-level granularity:** Sieve operates at sentence boundaries. It does not rewrite or partially redact sentences.
286
+ - **Cross-Encoder Inference Time:** Running a local neural model adds 50ms–300ms of local compute depending on CPU/GPU hardware.
287
+ - **Non-probability scoring:** Scores are sigmoid-squashed cross-encoder logits for ranking; a score of 0.8 represents ranking confidence, not an absolute statistical probability.
288
+ - **Tabular Data:** Regex sentence segmentation is designed for narrative prose and reports; complex ASCII/markdown tables should be handled prior to sentence chunking.
289
+
290
+ ---
291
+
292
+ ## Contributing
293
+
294
+ Contributions are welcome! Please open an issue or pull request on GitHub:
295
+ - **Repository:** [https://github.com/kuhinthewuh/Sieve](https://github.com/kuhinthewuh/Sieve)
296
+ - **Issues:** [https://github.com/kuhinthewuh/Sieve/issues](https://github.com/kuhinthewuh/Sieve/issues)
297
+
298
+ To set up development:
299
+ ```bash
300
+ git clone https://github.com/kuhinthewuh/Sieve.git
301
+ cd Sieve
302
+ pip install -e ".[dev,all]"
303
+ pytest
304
+ ```
305
+
306
+ ---
307
+
308
+ ## License
309
+
310
+ This project is licensed under the [MIT License](LICENSE).
@@ -0,0 +1,261 @@
1
+ # Sieve
2
+
3
+ ```text
4
+ ____ ___ ______ _______
5
+ / ___|_ _| ____\ \ / / ____|
6
+ \___ \| || _| \ \ / /| _|
7
+ ___) | || |___ \ V / | |___
8
+ |____/___|_____| \_/ |_____|
9
+ ```
10
+
11
+ > **Less noise. Better retrieval.**
12
+ > *Sift the signal from your retrieval pipeline.*
13
+
14
+ [![PyPI version](https://img.shields.io/pypi/v/sieve-context.svg)](https://pypi.org/project/sieve-context/)
15
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
16
+ [![Python: 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/)
17
+
18
+ **Sieve** is a lightweight, post-retrieval context optimizer for Retrieval-Augmented Generation (RAG). It runs locally between your retriever and your LLM, evaluating retrieved sentences with a cross-encoder to prune irrelevant noise before generation.
19
+
20
+ ```text
21
+ Retriever ──► [ Retrieved Chunks ] ──► Sieve (Local Cross-Encoder) ──► [ Pruned Context ] ──► LLM
22
+ ```
23
+
24
+ Your vector database over-retrieves by design: embedding top-k similarity search returns large blocks of text where often only a few sentences answer the query. Sieve removes the noise, preserves document metadata, and passes a physically smaller, denser prompt to your downstream model.
25
+
26
+ ---
27
+
28
+ ## Why Sieve?
29
+
30
+ Every irrelevant token retrieved into your prompt creates measurable friction:
31
+ - **Cost:** You pay per input token on hosted APIs (OpenAI, Anthropic, Gemini, Groq).
32
+ - **Latency:** Prompt processing time grows with input token volume.
33
+ - **Attention Degradation:** Irrelevant sentences compete with crucial facts for the model's attention budget ("lost in the middle" effect).
34
+ - **Zero API Key Requirement:** Filtering runs locally on your machine using a compact cross-encoder (`ms-marco-MiniLM-L-6-v2`). Your LLM API keys are never needed for context compression.
35
+
36
+ ---
37
+
38
+ ## Installation
39
+
40
+ Install via pip:
41
+
42
+ ```bash
43
+ pip install sieve-context
44
+ ```
45
+
46
+ ### Optional Extras
47
+
48
+ - **LangChain Integration:**
49
+ ```bash
50
+ pip install "sieve-context[langchain]"
51
+ ```
52
+ - **Model Context Protocol (MCP) Server:**
53
+ ```bash
54
+ pip install "sieve-context[mcp]"
55
+ ```
56
+ - **Document Ingestion (PDF & HTML):**
57
+ ```bash
58
+ pip install "sieve-context[docs]"
59
+ ```
60
+ - **All Capabilities:**
61
+ ```bash
62
+ pip install "sieve-context[all]"
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Quickstart
68
+
69
+ ### 1. Document-Level Optimization (Preserving Metadata)
70
+
71
+ Pass retrieved documents directly into `Sieve.optimize()`. Sieve filters sentences while maintaining each document's identity and metadata:
72
+
73
+ ```python
74
+ from sieve import Document, Sieve
75
+
76
+ sieve = Sieve(threshold=0.5)
77
+
78
+ retrieved_docs = [
79
+ Document(
80
+ text=(
81
+ "Apple Inc. reported total net sales of $391,035 million in fiscal year 2024. "
82
+ "Apple Park's main circular building features solar panels generating 17 megawatts."
83
+ ),
84
+ metadata={"source": "apple-10k.pdf", "page": 28}
85
+ ),
86
+ Document(
87
+ text="Steve Jobs co-founded Apple in Los Altos in 1976. iPhone net sales reached $201,183 million.",
88
+ metadata={"source": "apple-10k.pdf", "page": 31}
89
+ )
90
+ ]
91
+
92
+ result = sieve.optimize(
93
+ query="What was Apple's total net sales and iPhone sales in 2024?",
94
+ documents=retrieved_docs,
95
+ )
96
+
97
+ # Ready-to-inject string for your LLM prompt
98
+ print(result.context)
99
+
100
+ # Filtered documents preserving metadata
101
+ for doc in result.documents:
102
+ print(doc.metadata, "->", doc.text)
103
+
104
+ # Inspect exact token and reduction metrics
105
+ print(f"Original tokens: {result.metrics.original_tokens}")
106
+ print(f"Retained tokens: {result.metrics.filtered_tokens}")
107
+ print(f"Reduction: {result.metrics.reduction_percent}%")
108
+ print(f"Latency: {result.metrics.filtering_latency_ms} ms")
109
+ ```
110
+
111
+ ---
112
+
113
+ ### 2. Direct String Filtering
114
+
115
+ If you have a raw context string:
116
+
117
+ ```python
118
+ from sieve import filter_context
119
+
120
+ result = filter_context(
121
+ query="What was Apple's 2024 revenue?",
122
+ context="Apple's fiscal 2024 revenue reached $391,035 million. The cafeteria serves lunch daily.",
123
+ threshold=0.5,
124
+ max_tokens=500,
125
+ )
126
+
127
+ print(result.filtered_context)
128
+ # Output: "Apple's fiscal 2024 revenue reached $391,035 million."
129
+ ```
130
+
131
+ ---
132
+
133
+ ### 3. LangChain Integration
134
+
135
+ Drop Sieve into your existing LangChain retrieval chains as a document compressor:
136
+
137
+ ```python
138
+ from sieve.integrations.langchain import SieveCompressor
139
+
140
+ compressor = SieveCompressor(threshold=0.5)
141
+ optimized_docs = compressor.compress_documents(retrieved_docs, query="Apple 2024 revenue")
142
+ ```
143
+
144
+ ---
145
+
146
+ ### 4. Model Context Protocol (MCP)
147
+
148
+ Sieve includes a native MCP server for Claude Desktop, Cursor, and any MCP-compliant agent.
149
+
150
+ Start the server:
151
+
152
+ ```bash
153
+ sieve-mcp
154
+ ```
155
+
156
+ Or configure it in your `claude_desktop_config.json`:
157
+
158
+ ```json
159
+ {
160
+ "mcpServers": {
161
+ "sieve": {
162
+ "command": "sieve-mcp"
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ #### Available MCP Tools
169
+
170
+ 1. **`sieve_filter`**:
171
+ - Inputs: `query` (str), `context` (str), `threshold` (float, default 0.5), `max_tokens` (optional int).
172
+ - Returns: Filtered context string, token counts, reduction percentage, and filtering latency.
173
+ 2. **`sieve_score`**:
174
+ - Inputs: `query` (str), `context` (str).
175
+ - Returns: Unfiltered sentence-by-sentence relevance scores (0 to 1) for inspectability.
176
+ 3. **`sieve_stats`**:
177
+ - Returns cumulative session statistics: total calls, tokens processed, tokens pruned, and average reduction.
178
+
179
+ ---
180
+
181
+ ## Sieve Calibrate
182
+
183
+ How aggressively can you filter context before answer accuracy degrades?
184
+
185
+ **Sieve Calibrate** sweeps a spectrum of thresholds across a benchmark dataset of `{question, context, expected_answer}` cases, evaluating answer preservation at each threshold to compute the **minimum sufficient context**.
186
+
187
+ Run calibration from the CLI:
188
+
189
+ ```bash
190
+ sieve calibrate --benchmark examples/benchmark.json --thresholds 0.20,0.35,0.50,0.65,0.80 --offline
191
+ ```
192
+
193
+ Example output:
194
+
195
+ ```text
196
+ SIEVE CALIBRATION RESULTS
197
+ +---------------------------------------------------------------------+
198
+ | Threshold | Context Kept | Accuracy | Correct | Avg Latency |
199
+ |-------------------+--------------+----------+---------+-------------|
200
+ | — (WITHOUT SIEVE) | 100.0% | 100.0% | 10/10 | 0.0ms |
201
+ | 0.20 | 38.1% | 100.0% | 10/10 | 0.3ms |
202
+ | 0.35 | 38.1% | 100.0% | 10/10 | 0.3ms |
203
+ | 0.50 | 38.1% | 100.0% | 10/10 | 0.3ms |
204
+ | 0.65 | 38.1% | 100.0% | 10/10 | 0.3ms |
205
+ | 0.80 | 38.1% | 100.0% | 10/10 | 0.3ms |
206
+ +---------------------------------------------------------------------+
207
+
208
+ Minimum sufficient context: Threshold 0.20, 38.1% of context retained, 100.0% accuracy.
209
+ ```
210
+
211
+ ---
212
+
213
+ ## Configuration & Parameters
214
+
215
+ | Parameter | Type | Default | Description |
216
+ | :--- | :--- | :--- | :--- |
217
+ | `threshold` | `float` | `0.50` | Sigmoid-squashed cross-encoder logit cutoff (0.0 to 1.0). Sentences below this score are pruned. |
218
+ | `max_tokens` | `int` or `None` | `None` | Optional token budget limit for the retained context. |
219
+ | `context_window`| `int` | `0` | Number of neighboring sentences within the same document to retain around high-scoring hits. |
220
+ | `model_name` | `str` | `cross-encoder/ms-marco-MiniLM-L-6-v2` | Hugging Face cross-encoder model ID. |
221
+
222
+ ---
223
+
224
+ ## Architecture & How It Works
225
+
226
+ 1. **Sentence Segmentation:** Text is parsed into discrete sentences without external NLP runtime dependencies.
227
+ 2. **Local Batch Cross-Encoding:** Query and sentence pairs are evaluated in parallel batches with `cross-encoder/ms-marco-MiniLM-L-6-v2`. The model is loaded once per process and reused.
228
+ 3. **Thresholding & Context Preservation:** Sentences scoring above the threshold are selected. Optional `context_window` preserves adjacent sentences to maintain numerical and pronoun coherence.
229
+ 4. **Original Order Reconstruction:** Retained sentences are reconstructed in their original document order to preserve narrative flow for the LLM.
230
+ 5. **Deterministic Metrics:** Token reductions are measured locally via `tiktoken` (`cl100k_base`).
231
+
232
+ ---
233
+
234
+ ## Limitations
235
+
236
+ - **Sentence-level granularity:** Sieve operates at sentence boundaries. It does not rewrite or partially redact sentences.
237
+ - **Cross-Encoder Inference Time:** Running a local neural model adds 50ms–300ms of local compute depending on CPU/GPU hardware.
238
+ - **Non-probability scoring:** Scores are sigmoid-squashed cross-encoder logits for ranking; a score of 0.8 represents ranking confidence, not an absolute statistical probability.
239
+ - **Tabular Data:** Regex sentence segmentation is designed for narrative prose and reports; complex ASCII/markdown tables should be handled prior to sentence chunking.
240
+
241
+ ---
242
+
243
+ ## Contributing
244
+
245
+ Contributions are welcome! Please open an issue or pull request on GitHub:
246
+ - **Repository:** [https://github.com/kuhinthewuh/Sieve](https://github.com/kuhinthewuh/Sieve)
247
+ - **Issues:** [https://github.com/kuhinthewuh/Sieve/issues](https://github.com/kuhinthewuh/Sieve/issues)
248
+
249
+ To set up development:
250
+ ```bash
251
+ git clone https://github.com/kuhinthewuh/Sieve.git
252
+ cd Sieve
253
+ pip install -e ".[dev,all]"
254
+ pytest
255
+ ```
256
+
257
+ ---
258
+
259
+ ## License
260
+
261
+ This project is licensed under the [MIT License](LICENSE).
@@ -0,0 +1,9 @@
1
+
2
+
3
+
4
+ ███████╗██╗███████╗██╗ ██╗███████╗
5
+ ██╔════╝██║██╔════╝██║ ██║██╔════╝
6
+ ███████╗██║█████╗ ██║ ██║█████╗
7
+ ╚════██║██║██╔══╝ ╚██╗ ██╔╝██╔══╝
8
+ ███████║██║███████╗ ╚████╔╝ ███████╗
9
+ ╚══════╝╚═╝╚══════╝ ╚═══╝ ╚══════╝