retrieval-evaluator 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 (50) hide show
  1. retrieval_evaluator-0.1.0/LICENSE +21 -0
  2. retrieval_evaluator-0.1.0/MANIFEST.in +1 -0
  3. retrieval_evaluator-0.1.0/PKG-INFO +419 -0
  4. retrieval_evaluator-0.1.0/README.md +353 -0
  5. retrieval_evaluator-0.1.0/pyproject.toml +118 -0
  6. retrieval_evaluator-0.1.0/retrieval_evaluator/__init__.py +142 -0
  7. retrieval_evaluator-0.1.0/retrieval_evaluator/cli.py +743 -0
  8. retrieval_evaluator-0.1.0/retrieval_evaluator/config.py +248 -0
  9. retrieval_evaluator-0.1.0/retrieval_evaluator/dashboard/__init__.py +0 -0
  10. retrieval_evaluator-0.1.0/retrieval_evaluator/dashboard/app.py +152 -0
  11. retrieval_evaluator-0.1.0/retrieval_evaluator/dashboard/data.py +107 -0
  12. retrieval_evaluator-0.1.0/retrieval_evaluator/dashboard/inspector.py +309 -0
  13. retrieval_evaluator-0.1.0/retrieval_evaluator/dashboard/metrics.py +60 -0
  14. retrieval_evaluator-0.1.0/retrieval_evaluator/dashboard/results.py +178 -0
  15. retrieval_evaluator-0.1.0/retrieval_evaluator/data/EXAMPLE/corpus.jsonl +31 -0
  16. retrieval_evaluator-0.1.0/retrieval_evaluator/data/EXAMPLE/meta.json +8 -0
  17. retrieval_evaluator-0.1.0/retrieval_evaluator/data/EXAMPLE/qrels.tsv +12 -0
  18. retrieval_evaluator-0.1.0/retrieval_evaluator/data/EXAMPLE/queries.jsonl +12 -0
  19. retrieval_evaluator-0.1.0/retrieval_evaluator/database/numpy_index.py +75 -0
  20. retrieval_evaluator-0.1.0/retrieval_evaluator/database/vector_index.py +46 -0
  21. retrieval_evaluator-0.1.0/retrieval_evaluator/database/weaviate_db.py +263 -0
  22. retrieval_evaluator-0.1.0/retrieval_evaluator/dataset/beir.py +461 -0
  23. retrieval_evaluator-0.1.0/retrieval_evaluator/dataset/chunk_sources.py +397 -0
  24. retrieval_evaluator-0.1.0/retrieval_evaluator/dataset/dataset_builder.py +190 -0
  25. retrieval_evaluator-0.1.0/retrieval_evaluator/dataset/document_selection.py +119 -0
  26. retrieval_evaluator-0.1.0/retrieval_evaluator/dataset/importer.py +230 -0
  27. retrieval_evaluator-0.1.0/retrieval_evaluator/dataset/query_generation.py +355 -0
  28. retrieval_evaluator-0.1.0/retrieval_evaluator/dataset/source_validation.py +85 -0
  29. retrieval_evaluator-0.1.0/retrieval_evaluator/evaluation/__init__.py +0 -0
  30. retrieval_evaluator-0.1.0/retrieval_evaluator/evaluation/chunk_merging.py +69 -0
  31. retrieval_evaluator-0.1.0/retrieval_evaluator/evaluation/embedder.py +450 -0
  32. retrieval_evaluator-0.1.0/retrieval_evaluator/evaluation/embedders_evaluation.py +345 -0
  33. retrieval_evaluator-0.1.0/retrieval_evaluator/evaluation/metrics.py +111 -0
  34. retrieval_evaluator-0.1.0/retrieval_evaluator/evaluation/run_id.py +50 -0
  35. retrieval_evaluator-0.1.0/retrieval_evaluator/py.typed +0 -0
  36. retrieval_evaluator-0.1.0/retrieval_evaluator/templates.py +92 -0
  37. retrieval_evaluator-0.1.0/retrieval_evaluator/utils/cache.py +17 -0
  38. retrieval_evaluator-0.1.0/retrieval_evaluator/utils/constants.py +19 -0
  39. retrieval_evaluator-0.1.0/retrieval_evaluator/utils/device.py +24 -0
  40. retrieval_evaluator-0.1.0/retrieval_evaluator/utils/json_io.py +45 -0
  41. retrieval_evaluator-0.1.0/retrieval_evaluator/utils/logger.py +33 -0
  42. retrieval_evaluator-0.1.0/retrieval_evaluator/utils/paths.py +14 -0
  43. retrieval_evaluator-0.1.0/retrieval_evaluator/utils/retry.py +151 -0
  44. retrieval_evaluator-0.1.0/retrieval_evaluator.egg-info/PKG-INFO +419 -0
  45. retrieval_evaluator-0.1.0/retrieval_evaluator.egg-info/SOURCES.txt +48 -0
  46. retrieval_evaluator-0.1.0/retrieval_evaluator.egg-info/dependency_links.txt +1 -0
  47. retrieval_evaluator-0.1.0/retrieval_evaluator.egg-info/entry_points.txt +2 -0
  48. retrieval_evaluator-0.1.0/retrieval_evaluator.egg-info/requires.txt +51 -0
  49. retrieval_evaluator-0.1.0/retrieval_evaluator.egg-info/top_level.txt +1 -0
  50. retrieval_evaluator-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Max Belitsky
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 @@
1
+ prune tests
@@ -0,0 +1,419 @@
1
+ Metadata-Version: 2.4
2
+ Name: retrieval-evaluator
3
+ Version: 0.1.0
4
+ Summary: Evaluate embedding models (HuggingFace, OpenAI, Cohere) on your own RAG corpus
5
+ Author-email: Max Belitsky <md.belitsky@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/MaxBelitsky/retrieval-evaluator
8
+ Project-URL: Source, https://github.com/MaxBelitsky/retrieval-evaluator
9
+ Project-URL: Issues, https://github.com/MaxBelitsky/retrieval-evaluator/issues
10
+ Project-URL: Changelog, https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/CHANGELOG.md
11
+ Keywords: rag,retrieval,embeddings,evaluation,benchmark,information-retrieval,vector-search
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
19
+ Classifier: Intended Audience :: Developers
20
+ Classifier: Intended Audience :: Science/Research
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: numpy>=1.26.0
25
+ Requires-Dist: pyyaml>=6.0.2
26
+ Requires-Dist: pandas>=2.2.0
27
+ Provides-Extra: weaviate
28
+ Requires-Dist: weaviate-client>=4.14.4; extra == "weaviate"
29
+ Provides-Extra: qdrant
30
+ Requires-Dist: qdrant-client>=1.9.0; extra == "qdrant"
31
+ Provides-Extra: dashboard
32
+ Requires-Dist: altair>=5.0.0; extra == "dashboard"
33
+ Requires-Dist: streamlit>=1.45.1; extra == "dashboard"
34
+ Provides-Extra: dataset
35
+ Requires-Dist: accelerate>=1.7.0; extra == "dataset"
36
+ Requires-Dist: langchain>=1.2.15; extra == "dataset"
37
+ Requires-Dist: scikit-learn>=1.6.1; extra == "dataset"
38
+ Requires-Dist: sentence-transformers>=4.1.0; extra == "dataset"
39
+ Provides-Extra: openai
40
+ Requires-Dist: openai>=1.0.0; extra == "openai"
41
+ Requires-Dist: langchain-openai>=1.0.0; extra == "openai"
42
+ Provides-Extra: anthropic
43
+ Requires-Dist: langchain-anthropic>=1.0.0; extra == "anthropic"
44
+ Provides-Extra: cohere
45
+ Requires-Dist: cohere>=5.0.0; extra == "cohere"
46
+ Provides-Extra: hf
47
+ Requires-Dist: accelerate>=1.7.0; extra == "hf"
48
+ Requires-Dist: sentence-transformers>=4.1.0; extra == "hf"
49
+ Provides-Extra: datasets
50
+ Requires-Dist: datasets>=2.0.0; extra == "datasets"
51
+ Provides-Extra: all
52
+ Requires-Dist: accelerate>=1.7.0; extra == "all"
53
+ Requires-Dist: altair>=5.0.0; extra == "all"
54
+ Requires-Dist: cohere>=5.0.0; extra == "all"
55
+ Requires-Dist: datasets>=2.0.0; extra == "all"
56
+ Requires-Dist: langchain>=1.2.15; extra == "all"
57
+ Requires-Dist: langchain-anthropic>=1.0.0; extra == "all"
58
+ Requires-Dist: langchain-openai>=1.0.0; extra == "all"
59
+ Requires-Dist: openai>=1.0.0; extra == "all"
60
+ Requires-Dist: qdrant-client>=1.9.0; extra == "all"
61
+ Requires-Dist: scikit-learn>=1.6.1; extra == "all"
62
+ Requires-Dist: sentence-transformers>=4.1.0; extra == "all"
63
+ Requires-Dist: streamlit>=1.45.1; extra == "all"
64
+ Requires-Dist: weaviate-client>=4.14.4; extra == "all"
65
+ Dynamic: license-file
66
+
67
+ <h1 align="center">retrieval-evaluator</h1>
68
+
69
+ <p align="center"><b>Evaluate embedding models on the corpus your RAG system actually serves.</b></p>
70
+
71
+ <p align="center">
72
+ <a href="https://github.com/MaxBelitsky/retrieval-evaluator/actions/workflows/ci.yml"><img src="https://github.com/MaxBelitsky/retrieval-evaluator/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
73
+ <a href="https://pypi.org/project/retrieval-evaluator/"><img src="https://img.shields.io/pypi/v/retrieval-evaluator.svg" alt="PyPI"></a>
74
+ <a href="https://pypi.org/project/retrieval-evaluator/"><img src="https://img.shields.io/pypi/pyversions/retrieval-evaluator.svg" alt="Python versions"></a>
75
+ <a href="https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT license"></a>
76
+ </p>
77
+
78
+ <p align="center">
79
+ <img src="https://raw.githubusercontent.com/MaxBelitsky/retrieval-evaluator/main/docs/assets/demo-terminal.gif" alt="retrieval-evaluator demo" width="90%">
80
+ </p>
81
+
82
+ `retrieval-evaluator` is a focused toolkit for comparing retrieval choices on private or domain-specific corpora. It can:
83
+
84
+ - evaluate HuggingFace, OpenAI, and Cohere embedders against BEIR-format relevance judgments;
85
+ - bootstrap a synthetic evaluation set from JSONL, Weaviate, Qdrant, or a custom Python source;
86
+ - compare exact semantic retrieval by default, or semantic/BM25/hybrid retrieval with Weaviate; and
87
+ - save reproducible run artifacts for per-query inspection in a Streamlit dashboard.
88
+
89
+ It evaluates retrieval, not answer generation. Synthetic queries are useful for bootstrapping, but they are not a substitute for real user queries and human relevance judgments.
90
+
91
+ ## Quick start
92
+
93
+ Use Python 3.10 or newer, preferably in a virtual environment. Install the local HuggingFace embedder and dashboard features:
94
+
95
+ ```bash
96
+ pip install "retrieval-evaluator[hf,dashboard]"
97
+ ```
98
+
99
+ Run the bundled multilingual help-center benchmark with an English embedding model:
100
+
101
+ ```bash
102
+ retrieval-evaluator eval \
103
+ --collections EXAMPLE \
104
+ --model sentence-transformers/all-MiniLM-L6-v2
105
+ ```
106
+
107
+ The first run downloads the model (about 90 MB). A representative result is:
108
+
109
+ ```text
110
+ embedder collection alpha R@1 R@3 R@5 R@10 MRR@10
111
+ sentence-transformers/all-MiniLM-L6-v2 EXAMPLE 1.000 0.417 0.583 0.667 0.833 0.529
112
+ ```
113
+
114
+ Open the saved rankings and inspect individual hits and misses:
115
+
116
+ ```bash
117
+ retrieval-evaluator dashboard
118
+ ```
119
+
120
+ In **Inspector**, select **Failures** to examine missed queries. Expand a missing relevant passage to compare what should have been retrieved with the actual results.
121
+
122
+ The dashboard binds to `127.0.0.1` by default because run artifacts can contain
123
+ private corpus text. Use `--host` only when you intentionally want another interface,
124
+ and apply appropriate network access controls.
125
+
126
+ ![retrieval-evaluator dashboard](https://raw.githubusercontent.com/MaxBelitsky/retrieval-evaluator/main/docs/img/dashboard.png)
127
+
128
+ The example deliberately includes German and Spanish queries: the English-only model misses some of them. Compare it with a multilingual embedder to see whether the misses recover.
129
+
130
+ From a source checkout, the equivalent setup is:
131
+
132
+ ```bash
133
+ uv sync --extra hf --extra dashboard
134
+ uv run retrieval-evaluator eval --collections EXAMPLE --model sentence-transformers/all-MiniLM-L6-v2
135
+ uv run retrieval-evaluator dashboard
136
+ ```
137
+
138
+ Contributors should use `uv sync --locked --all-extras --group dev`.
139
+
140
+ ## What the metrics mean
141
+
142
+ Metrics are macro-averaged over every positively judged query in `qrels.tsv`. A query with no ranking is a miss.
143
+
144
+ | Metric | Meaning |
145
+ |---|---|
146
+ | `R@K` | Hit rate: fraction of queries with at least one relevant chunk in the top K. |
147
+ | `Recall@K` | Mean fraction of each query's relevant chunks retrieved in the top K. |
148
+ | `R_all@K` | Fraction of queries for which all relevant chunks appear in the top K. |
149
+ | `MRR@K` | Mean reciprocal rank of the first relevant chunk in the top K. |
150
+
151
+ With one relevant chunk per query, `R@K` and `Recall@K` are identical. None of these metrics measures answer correctness, faithfulness, latency, or cost.
152
+
153
+ ## Evaluate your own judged data
154
+
155
+ If you already have queries and relevance labels, use them. The required layout is standard BEIR:
156
+
157
+ ```text
158
+ eval_data/
159
+ my-collection/
160
+ corpus.jsonl
161
+ queries.jsonl
162
+ qrels.tsv
163
+ ```
164
+
165
+ See the [Bring Your Own Dataset guide](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/docs/byod.md) for the schema, official split layout, CSV/JSONL conversion, and public BEIR datasets.
166
+
167
+ Convert existing CSV data:
168
+
169
+ ```bash
170
+ retrieval-evaluator import-dataset \
171
+ --format csv \
172
+ --corpus chunks.csv \
173
+ --queries qa.csv \
174
+ --corpus-id-field id \
175
+ --corpus-text-field text \
176
+ --query-id-field id \
177
+ --query-text-field question \
178
+ --relevant-id-field chunk_id \
179
+ --output eval_data/my-collection
180
+
181
+ retrieval-evaluator eval --collections my-collection \
182
+ --model intfloat/multilingual-e5-base \
183
+ --query-prompt "query: " --passage-prompt "passage: "
184
+ ```
185
+
186
+ Importing directly from the Hugging Face Hub requires `pip install "retrieval-evaluator[datasets]"` and `--format hf`.
187
+
188
+ ## Bootstrap a dataset from existing chunks
189
+
190
+ When judged queries do not exist yet, `build-dataset` can select diverse documents, generate synthetic questions from their chunks, and write a BEIR dataset. All chunks from the selected documents remain retrieval candidates, including chunks whose questions fail or are skipped by `--chunk-limit` (default: 200 questions). The generated corpus is a sampled subset of the source collection. For the default OpenAI flow:
191
+
192
+ ```bash
193
+ pip install "retrieval-evaluator[dataset,openai]"
194
+ export OPENAI_API_KEY="..."
195
+ ```
196
+
197
+ Put one JSON object per line in `raw_data/source_collections/support_docs.jsonl`:
198
+
199
+ ```json
200
+ {"chunk_id":"c1","document_id":"doc-1","position":0,"lang":"en","content":"Chunk text."}
201
+ ```
202
+
203
+ Validate the source and mapping without making model calls or writing an evaluation dataset:
204
+
205
+ ```bash
206
+ retrieval-evaluator build-dataset \
207
+ --collections support_docs \
208
+ --source-type jsonl \
209
+ --jsonl-root raw_data/source_collections \
210
+ --id-field chunk_id \
211
+ --text-field content \
212
+ --doc-id-field document_id \
213
+ --chunk-id-field position \
214
+ --language-field lang \
215
+ --dry-run
216
+ ```
217
+
218
+ For remote Qdrant or Weaviate sources, validation may populate the configured local
219
+ source cache even in `--dry-run` mode.
220
+
221
+ Then run the build:
222
+
223
+ ```bash
224
+ retrieval-evaluator build-dataset \
225
+ --collections support_docs \
226
+ --output-dir eval_data \
227
+ --source-type jsonl \
228
+ --jsonl-root raw_data/source_collections \
229
+ --id-field chunk_id \
230
+ --text-field content \
231
+ --doc-id-field document_id \
232
+ --chunk-id-field position \
233
+ --language-field lang \
234
+ --llm-model openai:gpt-4o
235
+ ```
236
+
237
+ The source chunk is recorded as relevant to its generated question. Review generated questions before treating scores as a decision gate: synthetic language can preserve lexical clues, miss realistic ambiguity, and overstate production quality. Add real queries and additional judgments as soon as they are available.
238
+
239
+ Passage text is sent to the configured LLM during query generation. OpenAI and Cohere embedding providers also receive the text they embed; HuggingFace embedding runs locally.
240
+
241
+ ### Data handling
242
+
243
+ Evaluation stores each passage's full text and metadata in plaintext under
244
+ `run_details/<run-id>/corpus_meta.jsonl`. Generated BEIR datasets likewise contain
245
+ corpus text under the configured evaluation dataset directory. Qdrant and Weaviate
246
+ source checks and dataset builds may cache full exported source payloads under
247
+ `settings.raw_chunks_cache_dir` (default: `raw_data/`); those caches remain until you
248
+ delete them. Protect these directories with the same access and retention controls as
249
+ the source corpus. The default paths are excluded by this repository's `.gitignore`.
250
+
251
+ ### Other chunk sources
252
+
253
+ The same pipeline supports:
254
+
255
+ - `weaviate`: reads a remote/source collection; install `[weaviate]`;
256
+ - `qdrant`: scrolls point payloads; install `[qdrant]`;
257
+ - `jsonl`: reads local files and has no connector dependency; and
258
+ - `callable`: imports your function, class, or object for any other store.
259
+
260
+ Run `retrieval-evaluator init`, edit `config/retrieval-evaluator.yaml`, then use `retrieval-evaluator check-source --collections NAME` before an expensive build. The full schema is in the [annotated config reference](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/config/retrieval-evaluator.example.yaml).
261
+
262
+ ## Retrieval backends
263
+
264
+ `numpy` is the default backend. It performs deterministic, exact cosine ranking in-process with no service or native vector-search dependency. It keeps the corpus matrix in memory and does `O(corpus_size × embedding_dimensions)` work per query, so it is intended for modest evaluation collections.
265
+
266
+ Weaviate is opt-in for BM25 and hybrid experiments:
267
+
268
+ ```bash
269
+ pip install "retrieval-evaluator[weaviate]"
270
+ retrieval-evaluator eval \
271
+ --collections my-collection \
272
+ --model intfloat/multilingual-e5-base \
273
+ --query-prompt "query: " --passage-prompt "passage: " \
274
+ --index-backend weaviate \
275
+ --alpha 1.0 0.5 0.0
276
+ ```
277
+
278
+ Evaluation starts a temporary embedded Weaviate instance and removes its data after each run. Embedded Weaviate supports Linux and macOS; its first use downloads and caches a platform binary. The `database.weaviate` connection block is for exporting source chunks during dataset generation, not for evaluation indexing.
279
+
280
+ At `alpha=0.0`, evaluation uses Weaviate's BM25 query directly and skips passage
281
+ and query embedding requests. Hybrid runs (`0.0 < alpha < 1.0`) score lexical
282
+ matches only against passage content, never chunk identifiers.
283
+
284
+ ## Embedder configuration
285
+
286
+ For repeatable multi-model comparisons, define embedders in `config/embedders.yml`:
287
+
288
+ ```yaml
289
+ multilingual-e5-base:
290
+ provider: hf
291
+ model: intfloat/multilingual-e5-base
292
+ max_tokens: 512
293
+ query_prompt: "query: "
294
+ passage_prompt: "passage: "
295
+ precision: float32
296
+ ```
297
+
298
+ Then run:
299
+
300
+ ```bash
301
+ retrieval-evaluator eval --collections my-collection
302
+ retrieval-evaluator eval --collections my-collection --embedders multilingual-e5-base
303
+ ```
304
+
305
+ `max_tokens` is enforced against the local model's supported context length. If it exceeds the configured micro-chunk size, adjacent chunks from the same document can be merged while relevance is still scored against their original micro-chunk IDs. Use `--batch-size auto` to probe a safe GPU/MPS batch size.
306
+
307
+ Run IDs include the current dataset fingerprint, effective embedder settings, alpha, K values, backend, qrels split, and chunk-merging setting. An identical logical run is skipped; `--force-rerun` replaces its result row and artifacts.
308
+
309
+ ## Python API
310
+
311
+ ```python
312
+ from retrieval_evaluator import evaluate
313
+
314
+ results = evaluate(
315
+ collections=["EXAMPLE"],
316
+ embedder_configs={
317
+ "minilm": {
318
+ "provider": "hf",
319
+ "model": "sentence-transformers/all-MiniLM-L6-v2",
320
+ "max_tokens": 256,
321
+ },
322
+ "e5": {
323
+ "provider": "hf",
324
+ "model": "intfloat/multilingual-e5-base",
325
+ "max_tokens": 512,
326
+ "query_prompt": "query: ",
327
+ "passage_prompt": "passage: ",
328
+ },
329
+ },
330
+ index_backend="numpy",
331
+ artifacts_dir="run_details/api-example",
332
+ )
333
+
334
+ print(results[["embedder", "collection", "R@1", "R@5", "MRR@10"]])
335
+ results.to_csv("run_details/api-example/results.csv", index=False)
336
+ ```
337
+
338
+ To inspect this saved API run, install `[dashboard]` and launch:
339
+
340
+ ```bash
341
+ retrieval-evaluator dashboard \
342
+ --results-file run_details/api-example/results.csv \
343
+ --artifacts-dir run_details/api-example
344
+ ```
345
+
346
+ For your own datasets, also pass `--dataset-dir` with the dataset root used by `evaluate()`.
347
+ The API returns the results table; saving it explicitly makes it available to the dashboard.
348
+
349
+ `build_dataset()` provides the in-memory counterpart to `build-dataset`. See the runnable [programmatic API example](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/examples/05_programmatic_api.py).
350
+
351
+ ## Optional features
352
+
353
+ The base install contains dataset I/O, metrics, the NumPy backend, CLI scaffolding, and the Python API. Install only the features you use:
354
+
355
+ | Extra | Capability |
356
+ |---|---|
357
+ | `hf` | Local HuggingFace/sentence-transformers embeddings |
358
+ | `openai` | OpenAI embeddings and OpenAI LangChain adapter |
359
+ | `cohere` | Cohere embeddings |
360
+ | `dashboard` | Streamlit results dashboard |
361
+ | `dataset` | K-means document selection and LangChain dataset-generation pipeline |
362
+ | `anthropic` | Anthropic LangChain adapter; combine with `dataset` |
363
+ | `weaviate` | Weaviate source connector and embedded hybrid evaluation backend |
364
+ | `qdrant` | Qdrant source connector |
365
+ | `datasets` | Hugging Face dataset import (`import-dataset --format hf`) |
366
+ | `all` | Every optional feature |
367
+
368
+ Examples: `pip install "retrieval-evaluator[openai,dashboard]"` or `pip install "retrieval-evaluator[dataset,anthropic]"`.
369
+
370
+ ## Runnable examples
371
+
372
+ | Script | Purpose | Requirements |
373
+ |---|---|---|
374
+ | [01_quickstart.py](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/examples/01_quickstart.py) | Bundled benchmark with one local embedder | `[hf]` |
375
+ | [02_eval_local_jsonl.py](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/examples/02_eval_local_jsonl.py) | JSONL chunks → synthetic dataset → evaluation | `[dataset,openai]`, `OPENAI_API_KEY` |
376
+ | [03_custom_source.py](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/examples/03_custom_source.py) | Custom callable source contract | base install |
377
+ | [05_programmatic_api.py](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/examples/05_programmatic_api.py) | Multi-model Python API | `[hf]` |
378
+ | [06_ci_integration.py](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/examples/06_ci_integration.py) | Fail-closed retrieval quality gate | chosen provider extra; `[weaviate]` for that backend |
379
+
380
+ Run examples from the repository root with `uv run python examples/01_quickstart.py`.
381
+
382
+ ## Configuration and outputs
383
+
384
+ The quick start needs no config file. `retrieval-evaluator init` creates two files:
385
+
386
+ - `config/retrieval-evaluator.yaml`: dataset/source settings, output paths, and retrieval defaults.
387
+ - `config/embedders.yml`: named embedding models, used when `eval` is run without `--model`. Its location is set by `settings.embedders_config_path` in the main config.
388
+
389
+ `--config` selects the main config file, not the embedder definitions. For example:
390
+
391
+ ```bash
392
+ retrieval-evaluator eval --config config/retrieval-evaluator.yaml \
393
+ --collections EXAMPLE --embedders all-MiniLM-L6-v2
394
+ ```
395
+
396
+ Use `retrieval-evaluator init --global` for `~/.config/retrieval-evaluator/`. The search order is:
397
+
398
+ 1. `--config PATH` (or `RETRIEVAL_EVALUATOR_CONFIG`);
399
+ 2. `config/retrieval-evaluator.yaml`;
400
+ 3. `~/.config/retrieval-evaluator/retrieval-evaluator.yaml`; and
401
+ 4. `/etc/retrieval-evaluator/retrieval-evaluator.yaml`.
402
+
403
+ The first matching file is merged with built-in defaults. Relative paths in the config and CLI are relative to the directory you run the command from, **not the config file's directory**. Run project commands from the project root, or use absolute paths when invoking them elsewhere; parent directories are not searched. `--config` takes precedence over the environment variable.
404
+
405
+ Before evaluation starts, the CLI prints the selected config and absolute dataset, results, and artifact paths. It labels the bundled example data explicitly when used.
406
+
407
+ Evaluation uses the bundled `EXAMPLE` data when the default `eval_data/` directory does not exist. An explicit `--dataset-dir` must exist. Dataset generation always writes to `settings.evaluation_dataset_dir` (default: `eval_data/`) or `--output-dir`, never into the installed package.
408
+
409
+ CLI evaluation appends one row per logical run to `eval_runs.csv`; that row includes the dataset fingerprint. Rankings, query snapshots, qrels, and each passage's full text and metadata are stored under `run_details/<run-id>/`. The dashboard uses the fingerprint and snapshots to flag runs whose source dataset has changed.
410
+
411
+ Every command supports `--help`. The [architecture guide](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/docs/architecture.md) documents extension points for chunk sources, retrieval backends, and metrics.
412
+
413
+ ## Contributing and security
414
+
415
+ See [CONTRIBUTING.md](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/CONTRIBUTING.md) for development setup. Please report vulnerabilities privately using the process in [SECURITY.md](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/SECURITY.md). User-facing changes are recorded in [CHANGELOG.md](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/CHANGELOG.md).
416
+
417
+ ## License
418
+
419
+ [MIT](https://github.com/MaxBelitsky/retrieval-evaluator/blob/main/LICENSE)