evret 0.0.1b0__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.
- evret-0.0.1b0/LICENSE +20 -0
- evret-0.0.1b0/PKG-INFO +363 -0
- evret-0.0.1b0/README.md +308 -0
- evret-0.0.1b0/pyproject.toml +77 -0
- evret-0.0.1b0/setup.cfg +4 -0
- evret-0.0.1b0/src/evret/__init__.py +53 -0
- evret-0.0.1b0/src/evret/errors.py +15 -0
- evret-0.0.1b0/src/evret/evaluation/__init__.py +13 -0
- evret-0.0.1b0/src/evret/evaluation/dataset.py +139 -0
- evret-0.0.1b0/src/evret/evaluation/evaluator.py +62 -0
- evret-0.0.1b0/src/evret/evaluation/results.py +63 -0
- evret-0.0.1b0/src/evret/integrations/__init__.py +6 -0
- evret-0.0.1b0/src/evret/integrations/langchain.py +66 -0
- evret-0.0.1b0/src/evret/integrations/llamaindex.py +66 -0
- evret-0.0.1b0/src/evret/metrics/__init__.py +19 -0
- evret-0.0.1b0/src/evret/metrics/average_precision.py +35 -0
- evret-0.0.1b0/src/evret/metrics/base.py +64 -0
- evret-0.0.1b0/src/evret/metrics/hit_rate.py +26 -0
- evret-0.0.1b0/src/evret/metrics/mrr.py +31 -0
- evret-0.0.1b0/src/evret/metrics/ndcg.py +48 -0
- evret-0.0.1b0/src/evret/metrics/precision.py +27 -0
- evret-0.0.1b0/src/evret/metrics/recall.py +30 -0
- evret-0.0.1b0/src/evret/py.typed +1 -0
- evret-0.0.1b0/src/evret/retrievers/__init__.py +16 -0
- evret-0.0.1b0/src/evret/retrievers/base.py +38 -0
- evret-0.0.1b0/src/evret/retrievers/chroma.py +108 -0
- evret-0.0.1b0/src/evret/retrievers/milvus.py +125 -0
- evret-0.0.1b0/src/evret/retrievers/qdrant.py +96 -0
- evret-0.0.1b0/src/evret/retrievers/weaviate.py +198 -0
- evret-0.0.1b0/src/evret/utils.py +91 -0
- evret-0.0.1b0/src/evret.egg-info/PKG-INFO +363 -0
- evret-0.0.1b0/src/evret.egg-info/SOURCES.txt +34 -0
- evret-0.0.1b0/src/evret.egg-info/dependency_links.txt +1 -0
- evret-0.0.1b0/src/evret.egg-info/requires.txt +41 -0
- evret-0.0.1b0/src/evret.egg-info/top_level.txt +1 -0
- evret-0.0.1b0/tests/test_utils.py +61 -0
evret-0.0.1b0/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kaivid Labs
|
|
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 copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
evret-0.0.1b0/PKG-INFO
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: evret
|
|
3
|
+
Version: 0.0.1b0
|
|
4
|
+
Summary: A focused retriever evaluation framework with standard ranking metrics.
|
|
5
|
+
Author: Evret Contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/example/evret
|
|
8
|
+
Project-URL: Repository, https://github.com/example/evret
|
|
9
|
+
Keywords: retrieval,rag,evaluation,metrics,information-retrieval
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: fastembed>=0.8.0
|
|
23
|
+
Requires-Dist: qdrant-client>=1.17.1
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
26
|
+
Provides-Extra: qdrant
|
|
27
|
+
Requires-Dist: qdrant-client>=1.9.0; extra == "qdrant"
|
|
28
|
+
Provides-Extra: chroma
|
|
29
|
+
Requires-Dist: chromadb>=0.5.0; extra == "chroma"
|
|
30
|
+
Provides-Extra: weaviate
|
|
31
|
+
Requires-Dist: weaviate-client>=4.16.0; extra == "weaviate"
|
|
32
|
+
Provides-Extra: milvus
|
|
33
|
+
Requires-Dist: pymilvus>=2.4.0; extra == "milvus"
|
|
34
|
+
Provides-Extra: langchain
|
|
35
|
+
Requires-Dist: langchain-core>=0.2.0; extra == "langchain"
|
|
36
|
+
Provides-Extra: llamaindex
|
|
37
|
+
Requires-Dist: llama-index-core>=0.10.0; extra == "llamaindex"
|
|
38
|
+
Provides-Extra: all
|
|
39
|
+
Requires-Dist: qdrant-client>=1.9.0; extra == "all"
|
|
40
|
+
Requires-Dist: chromadb>=0.5.0; extra == "all"
|
|
41
|
+
Requires-Dist: weaviate-client>=4.16.0; extra == "all"
|
|
42
|
+
Requires-Dist: pymilvus>=2.4.0; extra == "all"
|
|
43
|
+
Requires-Dist: langchain-core>=0.2.0; extra == "all"
|
|
44
|
+
Requires-Dist: llama-index-core>=0.10.0; extra == "all"
|
|
45
|
+
Provides-Extra: integration
|
|
46
|
+
Requires-Dist: pytest>=8.0.0; extra == "integration"
|
|
47
|
+
Requires-Dist: qdrant-client>=1.9.0; extra == "integration"
|
|
48
|
+
Requires-Dist: chromadb>=0.5.0; extra == "integration"
|
|
49
|
+
Requires-Dist: weaviate-client>=4.16.0; extra == "integration"
|
|
50
|
+
Requires-Dist: pymilvus>=2.4.0; extra == "integration"
|
|
51
|
+
Requires-Dist: langchain-core>=0.2.0; extra == "integration"
|
|
52
|
+
Requires-Dist: llama-index-core>=0.10.0; extra == "integration"
|
|
53
|
+
Requires-Dist: testcontainers>=4.8.0; extra == "integration"
|
|
54
|
+
Dynamic: license-file
|
|
55
|
+
|
|
56
|
+
<div align="center">
|
|
57
|
+
|
|
58
|
+
# ๐ฏ Evret
|
|
59
|
+
|
|
60
|
+
**A focused, lightweight retriever evaluation framework with standard Information Retrieval metrics**
|
|
61
|
+
|
|
62
|
+
[](https://www.python.org/downloads/)
|
|
63
|
+
[](https://opensource.org/licenses/MIT)
|
|
64
|
+
[](https://github.com/psf/black)
|
|
65
|
+
[](https://badge.fury.io/py/evret)
|
|
66
|
+
[](https://github.com/example/evret/actions)
|
|
67
|
+
[](CONTRIBUTING.md)
|
|
68
|
+
|
|
69
|
+
Evret brings standard Information Retrieval metrics to your RAG and search systems. Evaluate retrievers with Hit Rate, Recall, Precision, MRR, NDCG, and Average Precision in just a few lines of code. Built for simplicity, extensibility, and seamless integration with vector databases and AI frameworks.
|
|
70
|
+
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## ๐ Overview
|
|
76
|
+
|
|
77
|
+
**Evret** is a modern Python framework designed for evaluating retrieval systems in RAG (Retrieval-Augmented Generation) pipelines and search applications. It provides:
|
|
78
|
+
|
|
79
|
+
- **Standard IR Metrics**: Hit Rate, Recall, Precision, MRR, NDCG, and Average Precision
|
|
80
|
+
- **Vector Database Support**: Native adapters for Qdrant and other vector databases
|
|
81
|
+
- **Framework Integration**: Seamless adapters for LangChain
|
|
82
|
+
- **Production-Ready**: Type-safe, well-tested, and optimized for real-world use cases
|
|
83
|
+
|
|
84
|
+
Whether you're building a semantic search engine, evaluating RAG systems, or benchmarking retrieval models, Evret gives you the tools to measure what matters.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## ๐ Quick Start
|
|
89
|
+
|
|
90
|
+
### Installation
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
pip install evret
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
For optional integrations:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Install all optional integrations
|
|
100
|
+
pip install evret[all]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 5-Minute Evaluation
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from evret import EvaluationDataset, Evaluator, HitRate, MRR, NDCG
|
|
107
|
+
# Load your evaluation dataset
|
|
108
|
+
dataset = EvaluationDataset.from_json("eval_data.json")
|
|
109
|
+
|
|
110
|
+
# Evaluate your retriever
|
|
111
|
+
evaluator = Evaluator(
|
|
112
|
+
retriever=my_retriever,
|
|
113
|
+
metrics=[HitRate(k=5), MRR(k=10), NDCG(k=10)]
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
results = evaluator.evaluate(dataset)
|
|
117
|
+
print(results.summary())
|
|
118
|
+
|
|
119
|
+
# Export results
|
|
120
|
+
results.to_json("results.json")
|
|
121
|
+
results.to_csv("results.csv")
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Minimal Metrics Example
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from evret import HitRate, Recall, Precision, MRR, NDCG, AveragePrecision
|
|
128
|
+
|
|
129
|
+
retrieved = [
|
|
130
|
+
["doc_1", "doc_5", "doc_2", "doc_9"],
|
|
131
|
+
["doc_8", "doc_7", "doc_6", "doc_3"],
|
|
132
|
+
]
|
|
133
|
+
relevant = [
|
|
134
|
+
{"doc_1", "doc_2"},
|
|
135
|
+
{"doc_3"},
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
metrics = [HitRate(k=3), Recall(k=3), Precision(k=3), MRR(k=3), NDCG(k=3)]
|
|
139
|
+
|
|
140
|
+
for metric in metrics:
|
|
141
|
+
score = metric.score(
|
|
142
|
+
retrieved_by_query=retrieved,
|
|
143
|
+
relevant_by_query=relevant,
|
|
144
|
+
)
|
|
145
|
+
print(f"{metric.name}: {score:.4f}")
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## ๐ Local Development Setup
|
|
151
|
+
|
|
152
|
+
Use `uv` for local development:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
uv venv
|
|
156
|
+
source .venv/bin/activate
|
|
157
|
+
uv pip install -e .
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Install all optional integrations:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
uv pip install -e ".[all]"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Run tests:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
pytest
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## ๐ Documentation
|
|
175
|
+
|
|
176
|
+
Evret docs use MkDocs with Material theme.
|
|
177
|
+
|
|
178
|
+
Install docs dependencies:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
uv pip install -e ".[docs]"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Run docs locally:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
mkdocs serve
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Build static docs:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
mkdocs build
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## ๐ Metrics
|
|
199
|
+
|
|
200
|
+
Evret supports all standard Information Retrieval metrics:
|
|
201
|
+
|
|
202
|
+
| Metric | Description | Use Case |
|
|
203
|
+
|--------|-------------|----------|
|
|
204
|
+
| **Hit Rate@k** | % of queries with at least one relevant doc in top-k | Binary relevance, recall-focused |
|
|
205
|
+
| **Recall@k** | % of relevant docs found in top-k | Comprehensive retrieval |
|
|
206
|
+
| **Precision@k** | % of top-k results that are relevant | Precision-focused systems |
|
|
207
|
+
| **MRR@k** | Mean Reciprocal Rank of first relevant doc | Single-answer retrieval |
|
|
208
|
+
| **NDCG@k** | Normalized Discounted Cumulative Gain | Rank-aware binary relevance quality |
|
|
209
|
+
| **Average Precision@k** | Area under precision-recall curve | Overall ranking quality |
|
|
210
|
+
|
|
211
|
+
### Usage Example
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
from evret import HitRate, Recall, Precision, MRR, NDCG, AveragePrecision
|
|
215
|
+
|
|
216
|
+
metrics = [
|
|
217
|
+
HitRate(k=5),
|
|
218
|
+
Recall(k=10),
|
|
219
|
+
Precision(k=5),
|
|
220
|
+
MRR(k=10),
|
|
221
|
+
NDCG(k=10),
|
|
222
|
+
AveragePrecision(k=10),
|
|
223
|
+
]
|
|
224
|
+
|
|
225
|
+
# Score a single query
|
|
226
|
+
retrieved = ["doc_1", "doc_5", "doc_2"]
|
|
227
|
+
relevant = {"doc_1", "doc_2"}
|
|
228
|
+
|
|
229
|
+
for metric in metrics:
|
|
230
|
+
score = metric.score(
|
|
231
|
+
retrieved_by_query=[retrieved],
|
|
232
|
+
relevant_by_query=[relevant],
|
|
233
|
+
)
|
|
234
|
+
print(f"{metric.name}: {score:.4f}")
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## ๐ Integrations
|
|
240
|
+
|
|
241
|
+
### Qdrant Vector Database
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
from evret.retrievers import QdrantRetriever
|
|
245
|
+
|
|
246
|
+
retriever = QdrantRetriever(
|
|
247
|
+
collection_name="docs",
|
|
248
|
+
query_encoder=embed_query,
|
|
249
|
+
url="http://localhost:6333",
|
|
250
|
+
id_field="doc_id",
|
|
251
|
+
)
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### LangChain Integration
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
from evret.integrations import LangChainRetrieverAdapter
|
|
258
|
+
|
|
259
|
+
# Wrap any Evret retriever for use in LangChain
|
|
260
|
+
lc_retriever = LangChainRetrieverAdapter(evret_retriever=retriever, k=5)
|
|
261
|
+
docs = lc_retriever.invoke("what is RAG?")
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## ๐ Examples
|
|
267
|
+
|
|
268
|
+
### Basic Evaluation Pipeline
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
from evret import EvaluationDataset, Evaluator, HitRate, MRR
|
|
272
|
+
|
|
273
|
+
dataset = EvaluationDataset.from_json("eval_data.json")
|
|
274
|
+
evaluator = Evaluator(retriever=my_retriever, metrics=[HitRate(k=5), MRR(k=10)])
|
|
275
|
+
results = evaluator.evaluate(dataset)
|
|
276
|
+
|
|
277
|
+
results.to_json("results.json")
|
|
278
|
+
results.to_csv("results.csv")
|
|
279
|
+
print(results.summary())
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Custom Retriever
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
from evret.retrievers import BaseRetriever
|
|
286
|
+
from evret import RetrievalResult
|
|
287
|
+
|
|
288
|
+
class MyCustomRetriever(BaseRetriever):
|
|
289
|
+
def retrieve(self, query: str, k: int) -> list[RetrievalResult]:
|
|
290
|
+
self._validate_k(k)
|
|
291
|
+
# Your retrieval logic here
|
|
292
|
+
return [
|
|
293
|
+
RetrievalResult(doc_id="doc_1", score=0.95, metadata={"text": "..."}),
|
|
294
|
+
RetrievalResult(doc_id="doc_2", score=0.87),
|
|
295
|
+
]
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Run Examples Locally
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
# Basic evaluation example
|
|
302
|
+
python examples/evaluate_retriever.py
|
|
303
|
+
|
|
304
|
+
# Jupyter notebook quickstart
|
|
305
|
+
jupyter notebook examples/langchain_rag_evaluation.ipynb
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## ๐งช Testing
|
|
311
|
+
|
|
312
|
+
### Run Unit Tests
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
pytest
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Run Integration Tests
|
|
319
|
+
|
|
320
|
+
Integration tests require Docker to be running:
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
# Start Docker Desktop/daemon first, then run:
|
|
324
|
+
EVRET_RUN_INTEGRATION=1 pytest -m integration
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
This will spin up Docker containers for Qdrant and Chroma to run end-to-end tests.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## ๐ License
|
|
332
|
+
|
|
333
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## ๐ค Contributing
|
|
338
|
+
|
|
339
|
+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## ๐ Citation
|
|
344
|
+
|
|
345
|
+
If you use Evret in your research, please cite:
|
|
346
|
+
|
|
347
|
+
```bibtex
|
|
348
|
+
@software{evret2026,
|
|
349
|
+
title={Evret: A Focused Retriever Evaluation Framework},
|
|
350
|
+
author={lucifertrj},
|
|
351
|
+
year={2026},
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
<div align="center">
|
|
358
|
+
|
|
359
|
+
**Built with โค๏ธ for the RAG and IR community**
|
|
360
|
+
|
|
361
|
+
[GitHub](https://github.com/example/evret) โข [Issues](https://github.com/example/evret/issues) โข [Discussions](https://github.com/example/evret/discussions)
|
|
362
|
+
|
|
363
|
+
</div>
|
evret-0.0.1b0/README.md
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# ๐ฏ Evret
|
|
4
|
+
|
|
5
|
+
**A focused, lightweight retriever evaluation framework with standard Information Retrieval metrics**
|
|
6
|
+
|
|
7
|
+
[](https://www.python.org/downloads/)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://github.com/psf/black)
|
|
10
|
+
[](https://badge.fury.io/py/evret)
|
|
11
|
+
[](https://github.com/example/evret/actions)
|
|
12
|
+
[](CONTRIBUTING.md)
|
|
13
|
+
|
|
14
|
+
Evret brings standard Information Retrieval metrics to your RAG and search systems. Evaluate retrievers with Hit Rate, Recall, Precision, MRR, NDCG, and Average Precision in just a few lines of code. Built for simplicity, extensibility, and seamless integration with vector databases and AI frameworks.
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## ๐ Overview
|
|
21
|
+
|
|
22
|
+
**Evret** is a modern Python framework designed for evaluating retrieval systems in RAG (Retrieval-Augmented Generation) pipelines and search applications. It provides:
|
|
23
|
+
|
|
24
|
+
- **Standard IR Metrics**: Hit Rate, Recall, Precision, MRR, NDCG, and Average Precision
|
|
25
|
+
- **Vector Database Support**: Native adapters for Qdrant and other vector databases
|
|
26
|
+
- **Framework Integration**: Seamless adapters for LangChain
|
|
27
|
+
- **Production-Ready**: Type-safe, well-tested, and optimized for real-world use cases
|
|
28
|
+
|
|
29
|
+
Whether you're building a semantic search engine, evaluating RAG systems, or benchmarking retrieval models, Evret gives you the tools to measure what matters.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## ๐ Quick Start
|
|
34
|
+
|
|
35
|
+
### Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install evret
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
For optional integrations:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Install all optional integrations
|
|
45
|
+
pip install evret[all]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 5-Minute Evaluation
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from evret import EvaluationDataset, Evaluator, HitRate, MRR, NDCG
|
|
52
|
+
# Load your evaluation dataset
|
|
53
|
+
dataset = EvaluationDataset.from_json("eval_data.json")
|
|
54
|
+
|
|
55
|
+
# Evaluate your retriever
|
|
56
|
+
evaluator = Evaluator(
|
|
57
|
+
retriever=my_retriever,
|
|
58
|
+
metrics=[HitRate(k=5), MRR(k=10), NDCG(k=10)]
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
results = evaluator.evaluate(dataset)
|
|
62
|
+
print(results.summary())
|
|
63
|
+
|
|
64
|
+
# Export results
|
|
65
|
+
results.to_json("results.json")
|
|
66
|
+
results.to_csv("results.csv")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Minimal Metrics Example
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from evret import HitRate, Recall, Precision, MRR, NDCG, AveragePrecision
|
|
73
|
+
|
|
74
|
+
retrieved = [
|
|
75
|
+
["doc_1", "doc_5", "doc_2", "doc_9"],
|
|
76
|
+
["doc_8", "doc_7", "doc_6", "doc_3"],
|
|
77
|
+
]
|
|
78
|
+
relevant = [
|
|
79
|
+
{"doc_1", "doc_2"},
|
|
80
|
+
{"doc_3"},
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
metrics = [HitRate(k=3), Recall(k=3), Precision(k=3), MRR(k=3), NDCG(k=3)]
|
|
84
|
+
|
|
85
|
+
for metric in metrics:
|
|
86
|
+
score = metric.score(
|
|
87
|
+
retrieved_by_query=retrieved,
|
|
88
|
+
relevant_by_query=relevant,
|
|
89
|
+
)
|
|
90
|
+
print(f"{metric.name}: {score:.4f}")
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## ๐ Local Development Setup
|
|
96
|
+
|
|
97
|
+
Use `uv` for local development:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
uv venv
|
|
101
|
+
source .venv/bin/activate
|
|
102
|
+
uv pip install -e .
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Install all optional integrations:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
uv pip install -e ".[all]"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Run tests:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pytest
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## ๐ Documentation
|
|
120
|
+
|
|
121
|
+
Evret docs use MkDocs with Material theme.
|
|
122
|
+
|
|
123
|
+
Install docs dependencies:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
uv pip install -e ".[docs]"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Run docs locally:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
mkdocs serve
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Build static docs:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
mkdocs build
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## ๐ Metrics
|
|
144
|
+
|
|
145
|
+
Evret supports all standard Information Retrieval metrics:
|
|
146
|
+
|
|
147
|
+
| Metric | Description | Use Case |
|
|
148
|
+
|--------|-------------|----------|
|
|
149
|
+
| **Hit Rate@k** | % of queries with at least one relevant doc in top-k | Binary relevance, recall-focused |
|
|
150
|
+
| **Recall@k** | % of relevant docs found in top-k | Comprehensive retrieval |
|
|
151
|
+
| **Precision@k** | % of top-k results that are relevant | Precision-focused systems |
|
|
152
|
+
| **MRR@k** | Mean Reciprocal Rank of first relevant doc | Single-answer retrieval |
|
|
153
|
+
| **NDCG@k** | Normalized Discounted Cumulative Gain | Rank-aware binary relevance quality |
|
|
154
|
+
| **Average Precision@k** | Area under precision-recall curve | Overall ranking quality |
|
|
155
|
+
|
|
156
|
+
### Usage Example
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from evret import HitRate, Recall, Precision, MRR, NDCG, AveragePrecision
|
|
160
|
+
|
|
161
|
+
metrics = [
|
|
162
|
+
HitRate(k=5),
|
|
163
|
+
Recall(k=10),
|
|
164
|
+
Precision(k=5),
|
|
165
|
+
MRR(k=10),
|
|
166
|
+
NDCG(k=10),
|
|
167
|
+
AveragePrecision(k=10),
|
|
168
|
+
]
|
|
169
|
+
|
|
170
|
+
# Score a single query
|
|
171
|
+
retrieved = ["doc_1", "doc_5", "doc_2"]
|
|
172
|
+
relevant = {"doc_1", "doc_2"}
|
|
173
|
+
|
|
174
|
+
for metric in metrics:
|
|
175
|
+
score = metric.score(
|
|
176
|
+
retrieved_by_query=[retrieved],
|
|
177
|
+
relevant_by_query=[relevant],
|
|
178
|
+
)
|
|
179
|
+
print(f"{metric.name}: {score:.4f}")
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## ๐ Integrations
|
|
185
|
+
|
|
186
|
+
### Qdrant Vector Database
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from evret.retrievers import QdrantRetriever
|
|
190
|
+
|
|
191
|
+
retriever = QdrantRetriever(
|
|
192
|
+
collection_name="docs",
|
|
193
|
+
query_encoder=embed_query,
|
|
194
|
+
url="http://localhost:6333",
|
|
195
|
+
id_field="doc_id",
|
|
196
|
+
)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### LangChain Integration
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
from evret.integrations import LangChainRetrieverAdapter
|
|
203
|
+
|
|
204
|
+
# Wrap any Evret retriever for use in LangChain
|
|
205
|
+
lc_retriever = LangChainRetrieverAdapter(evret_retriever=retriever, k=5)
|
|
206
|
+
docs = lc_retriever.invoke("what is RAG?")
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## ๐ Examples
|
|
212
|
+
|
|
213
|
+
### Basic Evaluation Pipeline
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from evret import EvaluationDataset, Evaluator, HitRate, MRR
|
|
217
|
+
|
|
218
|
+
dataset = EvaluationDataset.from_json("eval_data.json")
|
|
219
|
+
evaluator = Evaluator(retriever=my_retriever, metrics=[HitRate(k=5), MRR(k=10)])
|
|
220
|
+
results = evaluator.evaluate(dataset)
|
|
221
|
+
|
|
222
|
+
results.to_json("results.json")
|
|
223
|
+
results.to_csv("results.csv")
|
|
224
|
+
print(results.summary())
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Custom Retriever
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
from evret.retrievers import BaseRetriever
|
|
231
|
+
from evret import RetrievalResult
|
|
232
|
+
|
|
233
|
+
class MyCustomRetriever(BaseRetriever):
|
|
234
|
+
def retrieve(self, query: str, k: int) -> list[RetrievalResult]:
|
|
235
|
+
self._validate_k(k)
|
|
236
|
+
# Your retrieval logic here
|
|
237
|
+
return [
|
|
238
|
+
RetrievalResult(doc_id="doc_1", score=0.95, metadata={"text": "..."}),
|
|
239
|
+
RetrievalResult(doc_id="doc_2", score=0.87),
|
|
240
|
+
]
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Run Examples Locally
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Basic evaluation example
|
|
247
|
+
python examples/evaluate_retriever.py
|
|
248
|
+
|
|
249
|
+
# Jupyter notebook quickstart
|
|
250
|
+
jupyter notebook examples/langchain_rag_evaluation.ipynb
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## ๐งช Testing
|
|
256
|
+
|
|
257
|
+
### Run Unit Tests
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
pytest
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Run Integration Tests
|
|
264
|
+
|
|
265
|
+
Integration tests require Docker to be running:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# Start Docker Desktop/daemon first, then run:
|
|
269
|
+
EVRET_RUN_INTEGRATION=1 pytest -m integration
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
This will spin up Docker containers for Qdrant and Chroma to run end-to-end tests.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## ๐ License
|
|
277
|
+
|
|
278
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## ๐ค Contributing
|
|
283
|
+
|
|
284
|
+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## ๐ Citation
|
|
289
|
+
|
|
290
|
+
If you use Evret in your research, please cite:
|
|
291
|
+
|
|
292
|
+
```bibtex
|
|
293
|
+
@software{evret2026,
|
|
294
|
+
title={Evret: A Focused Retriever Evaluation Framework},
|
|
295
|
+
author={lucifertrj},
|
|
296
|
+
year={2026},
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
<div align="center">
|
|
303
|
+
|
|
304
|
+
**Built with โค๏ธ for the RAG and IR community**
|
|
305
|
+
|
|
306
|
+
[GitHub](https://github.com/example/evret) โข [Issues](https://github.com/example/evret/issues) โข [Discussions](https://github.com/example/evret/discussions)
|
|
307
|
+
|
|
308
|
+
</div>
|