ragrefine 0.2.1__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.
- ragrefine-0.2.1/LICENSE +21 -0
- ragrefine-0.2.1/PKG-INFO +183 -0
- ragrefine-0.2.1/README.md +151 -0
- ragrefine-0.2.1/pyproject.toml +90 -0
- ragrefine-0.2.1/pyproject.toml.orig +71 -0
- ragrefine-0.2.1/src/ragrefine/__init__.py +14 -0
- ragrefine-0.2.1/src/ragrefine/_channels.py +16 -0
- ragrefine-0.2.1/src/ragrefine/config.py +27 -0
- ragrefine-0.2.1/src/ragrefine/errors.py +21 -0
- ragrefine-0.2.1/src/ragrefine/integrations/__init__.py +1 -0
- ragrefine-0.2.1/src/ragrefine/integrations/haystack/__init__.py +33 -0
- ragrefine-0.2.1/src/ragrefine/integrations/haystack/adapter.py +72 -0
- ragrefine-0.2.1/src/ragrefine/integrations/haystack/component.py +150 -0
- ragrefine-0.2.1/src/ragrefine/integrations/haystack/fixture.py +96 -0
- ragrefine-0.2.1/src/ragrefine/integrations/haystack/pipeline.py +104 -0
- ragrefine-0.2.1/src/ragrefine/integrations/haystack/prompt.py +17 -0
- ragrefine-0.2.1/src/ragrefine/models.py +52 -0
- ragrefine-0.2.1/src/ragrefine/py.typed +0 -0
- ragrefine-0.2.1/src/ragrefine/query/__init__.py +18 -0
- ragrefine-0.2.1/src/ragrefine/query/normalize.py +34 -0
- ragrefine-0.2.1/src/ragrefine/query/patterns.py +132 -0
- ragrefine-0.2.1/src/ragrefine/ranking/__init__.py +24 -0
- ragrefine-0.2.1/src/ragrefine/ranking/lexical.py +97 -0
- ragrefine-0.2.1/src/ragrefine/ranking/patterns.py +153 -0
- ragrefine-0.2.1/src/ragrefine/ranking/rrf.py +87 -0
- ragrefine-0.2.1/src/ragrefine/ranking/types.py +25 -0
- ragrefine-0.2.1/src/ragrefine/refiner.py +516 -0
- ragrefine-0.2.1/src/ragrefine/rerank/__init__.py +6 -0
- ragrefine-0.2.1/src/ragrefine/rerank/base.py +30 -0
- ragrefine-0.2.1/src/ragrefine/rerank/sentence_transformers.py +133 -0
- ragrefine-0.2.1/src/ragrefine/results.py +20 -0
- ragrefine-0.2.1/src/ragrefine/selection/__init__.py +27 -0
- ragrefine-0.2.1/src/ragrefine/selection/deduplicate.py +142 -0
- ragrefine-0.2.1/src/ragrefine/selection/selector.py +126 -0
- ragrefine-0.2.1/src/ragrefine/selection/tokens.py +10 -0
- ragrefine-0.2.1/src/ragrefine/tracing/__init__.py +5 -0
- ragrefine-0.2.1/src/ragrefine/tracing/models.py +22 -0
ragrefine-0.2.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Atharva Dharmadhikari
|
|
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.
|
ragrefine-0.2.1/PKG-INFO
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ragrefine
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Retriever-agnostic post-retrieval refinement for RAG candidates
|
|
5
|
+
Keywords: rag,retrieval,reranking,information-retrieval,llm
|
|
6
|
+
Author: Atharva Dharmadhikari
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
15
|
+
Classifier: Topic :: Text Processing :: Indexing
|
|
16
|
+
Classifier: Typing :: Typed
|
|
17
|
+
Requires-Dist: beir==2.2.0 ; extra == 'beir'
|
|
18
|
+
Requires-Dist: haystack-ai==2.31.0 ; extra == 'haystack'
|
|
19
|
+
Requires-Dist: ragas==0.4.3 ; extra == 'ragas'
|
|
20
|
+
Requires-Dist: langchain-openai>=0.2.0,<1.0 ; extra == 'ragas'
|
|
21
|
+
Requires-Dist: sentence-transformers>=6.0.0,<7 ; extra == 'rerank'
|
|
22
|
+
Requires-Python: >=3.12
|
|
23
|
+
Project-URL: Homepage, https://github.com/Atharva01/ragrefine
|
|
24
|
+
Project-URL: Repository, https://github.com/Atharva01/ragrefine
|
|
25
|
+
Project-URL: Changelog, https://github.com/Atharva01/ragrefine/blob/main/CHANGELOG.md
|
|
26
|
+
Project-URL: Issues, https://github.com/Atharva01/ragrefine/issues
|
|
27
|
+
Provides-Extra: beir
|
|
28
|
+
Provides-Extra: haystack
|
|
29
|
+
Provides-Extra: ragas
|
|
30
|
+
Provides-Extra: rerank
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# ragrefine
|
|
34
|
+
|
|
35
|
+
**Evidence-first post-retrieval refinement for RAG systems.**
|
|
36
|
+
|
|
37
|
+
[](https://github.com/Atharva01/ragrefine/actions/workflows/ci.yml)
|
|
38
|
+
[](https://www.python.org/downloads/)
|
|
39
|
+
[](LICENSE)
|
|
40
|
+
|
|
41
|
+
`ragrefine` improves an existing retriever's candidate set before it reaches an
|
|
42
|
+
LLM. It reranks, fuses, deduplicates, and selects context while preserving the
|
|
43
|
+
original evidence and recording an auditable trace.
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
retriever -> Top-N candidates -> ragrefine -> refined Top-K + trace -> LLM
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The core library is framework- and retriever-agnostic. Haystack support is
|
|
50
|
+
available as an optional integration.
|
|
51
|
+
|
|
52
|
+
## Core deliverables
|
|
53
|
+
|
|
54
|
+
| Capability | Delivered behaviour |
|
|
55
|
+
|---|---|
|
|
56
|
+
| Candidate contract | Immutable candidates retain IDs, text, metadata, retrieval rank, and retrieval score |
|
|
57
|
+
| Ranking channels | Independent original, neural, lexical, and configurable pattern rankings over the same candidate pool |
|
|
58
|
+
| Rank fusion | Deterministic reciprocal-rank fusion without mixing incompatible raw-score scales |
|
|
59
|
+
| Context refinement | Exact/near-duplicate suppression and rank-preserving Top-K/token-budget selection |
|
|
60
|
+
| Traceability | Per-channel evidence, fusion contributions, stage timings, configuration, and explicit failure records |
|
|
61
|
+
| Neural reranking | Optional SentenceTransformers CrossEncoder adapter with batched inference |
|
|
62
|
+
| Haystack integration | Serializable component profiles and a retriever-to-generator pipeline builder |
|
|
63
|
+
| Evaluation | Frozen BEIR candidate pools, checksummed artifacts, reproducibility commands, and a paired Ragas harness |
|
|
64
|
+
|
|
65
|
+
Output candidates always originate from the supplied input pool; `ragrefine`
|
|
66
|
+
does not invent or rewrite evidence.
|
|
67
|
+
|
|
68
|
+
## Quick start
|
|
69
|
+
|
|
70
|
+
Python 3.12+ is required. From this checkout:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
uv sync
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from ragrefine import Candidate, CandidateSet, Refiner
|
|
78
|
+
|
|
79
|
+
candidates = CandidateSet(
|
|
80
|
+
name="my-retriever",
|
|
81
|
+
candidates=(
|
|
82
|
+
Candidate(
|
|
83
|
+
id="doc-1",
|
|
84
|
+
text="Python 3.12 improves f-string parsing.",
|
|
85
|
+
retrieval_rank=1,
|
|
86
|
+
retrieval_score=0.91,
|
|
87
|
+
),
|
|
88
|
+
Candidate(
|
|
89
|
+
id="doc-2",
|
|
90
|
+
text="Python 3.11 introduced exception groups.",
|
|
91
|
+
retrieval_rank=2,
|
|
92
|
+
retrieval_score=0.84,
|
|
93
|
+
),
|
|
94
|
+
),
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
result = Refiner().refine(
|
|
98
|
+
query="Which Python version improves f-string parsing?",
|
|
99
|
+
candidate_set=candidates,
|
|
100
|
+
top_k=1,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
print(result.candidates[0].candidate.id)
|
|
104
|
+
print(result.trace)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`Refiner()` preserves the original ranking. Explicit `RefinerConfig` settings
|
|
108
|
+
enable lexical, pattern, neural, or fused profiles. See the
|
|
109
|
+
[technical design](TECHNICAL_DESIGN.md) for the configuration contract.
|
|
110
|
+
|
|
111
|
+
## Haystack integration
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
uv sync --extra haystack
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The optional integration provides document conversion, a serializable
|
|
118
|
+
`RagRefineComponent`, registered refiner profiles, prompt construction, and a
|
|
119
|
+
complete Haystack pipeline builder. The [RAG pipeline guide](docs/rag-pipeline-guide.md)
|
|
120
|
+
contains the runnable recipe and customization points.
|
|
121
|
+
|
|
122
|
+
## Evaluation summary
|
|
123
|
+
|
|
124
|
+
Post-retrieval comparisons reuse the same frozen first-stage Top-50 candidates.
|
|
125
|
+
Retrieval is not regenerated between profiles, and candidate-pool Recall@50 is
|
|
126
|
+
a fixed ceiling rather than a refinement gain.
|
|
127
|
+
|
|
128
|
+
| Experiment | SciFact result | Decision |
|
|
129
|
+
|---|---:|---|
|
|
130
|
+
| B0 — frozen dense baseline | nDCG@5 0.4592 | Baseline |
|
|
131
|
+
| B1-reference — MiniLM-L6/CUDA | nDCG@5 **0.6262** | Retained neural profile |
|
|
132
|
+
| B1-light — TinyBERT-L2/CPU | nDCG@5 **0.6112** | Retained measured profile |
|
|
133
|
+
| B2-L — lexical/CPU | nDCG@5 **0.5432** | Retained lightweight profile |
|
|
134
|
+
| B2-P — patterns/CPU | nDCG@5 0.4559 | Not retained |
|
|
135
|
+
| B3 — equal-weight fusion | Best profile nDCG@5 0.5715 | Not retained; below B1-reference |
|
|
136
|
+
|
|
137
|
+
The end-to-end Ragas A/B used 13 paired DeepSeek queries. It is statistically
|
|
138
|
+
inconclusive: the positive directional score differences have 95% paired
|
|
139
|
+
bootstrap confidence intervals spanning zero, and both context metrics are
|
|
140
|
+
saturated at 1.0. The run establishes neither an end-to-end benefit nor a
|
|
141
|
+
regression. See the [retained A/B report](benchmarks/results/haystack-ragas-analysis-v1/ragas-report.md).
|
|
142
|
+
|
|
143
|
+
Machine-readable artifacts are the source of truth. No experiment is described
|
|
144
|
+
as improved unless its recorded measurements support that claim.
|
|
145
|
+
|
|
146
|
+
## Documentation
|
|
147
|
+
|
|
148
|
+
Detailed material removed from this README remains in the repository's focused
|
|
149
|
+
documents:
|
|
150
|
+
|
|
151
|
+
- [Product requirements](AI_PRD.md) — supported scope and product boundary
|
|
152
|
+
- [Technical hypotheses](TECHNICAL_HYPOTHESIS.md) — testable claims and current evidence
|
|
153
|
+
- [Technical design](TECHNICAL_DESIGN.md) — architecture, configuration, selection, and tracing contracts
|
|
154
|
+
- [Evaluation contract](docs/evaluation-contract-v0.1.md) — frozen-pool rules, metrics, profiles, and reporting policy
|
|
155
|
+
- [Benchmark guide](docs/benchmark-baseline.md) — execution and reproduction commands
|
|
156
|
+
- [Retained artifact manifest](benchmarks/artifacts/README.md) — checksummed benchmark inputs and verification
|
|
157
|
+
- [Haystack pipeline guide](docs/rag-pipeline-guide.md) — integration and serialization
|
|
158
|
+
- [Ragas evaluation guide](docs/haystack-ragas-evaluation.md) — paired A/B design and analysis
|
|
159
|
+
- [v0.2 release record](docs/v0.2-release.md) — delivered scope, validation, and limitations
|
|
160
|
+
|
|
161
|
+
## Scope
|
|
162
|
+
|
|
163
|
+
`ragrefine` owns post-retrieval candidate refinement, context selection, and
|
|
164
|
+
tracing. It deliberately does not own ingestion, parsing, chunking, embeddings,
|
|
165
|
+
vector databases, first-stage retrieval, LLM generation, agents, or deployment.
|
|
166
|
+
|
|
167
|
+
## Development
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
uv sync --extra haystack --extra ragas
|
|
171
|
+
uv run ruff check .
|
|
172
|
+
uv run ruff format --check .
|
|
173
|
+
uv run mypy src/
|
|
174
|
+
uv run pytest
|
|
175
|
+
uv build
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Heavy model and benchmark dependencies remain optional so the core package has
|
|
179
|
+
no runtime dependencies.
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# ragrefine
|
|
2
|
+
|
|
3
|
+
**Evidence-first post-retrieval refinement for RAG systems.**
|
|
4
|
+
|
|
5
|
+
[](https://github.com/Atharva01/ragrefine/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.python.org/downloads/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
`ragrefine` improves an existing retriever's candidate set before it reaches an
|
|
10
|
+
LLM. It reranks, fuses, deduplicates, and selects context while preserving the
|
|
11
|
+
original evidence and recording an auditable trace.
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
retriever -> Top-N candidates -> ragrefine -> refined Top-K + trace -> LLM
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The core library is framework- and retriever-agnostic. Haystack support is
|
|
18
|
+
available as an optional integration.
|
|
19
|
+
|
|
20
|
+
## Core deliverables
|
|
21
|
+
|
|
22
|
+
| Capability | Delivered behaviour |
|
|
23
|
+
|---|---|
|
|
24
|
+
| Candidate contract | Immutable candidates retain IDs, text, metadata, retrieval rank, and retrieval score |
|
|
25
|
+
| Ranking channels | Independent original, neural, lexical, and configurable pattern rankings over the same candidate pool |
|
|
26
|
+
| Rank fusion | Deterministic reciprocal-rank fusion without mixing incompatible raw-score scales |
|
|
27
|
+
| Context refinement | Exact/near-duplicate suppression and rank-preserving Top-K/token-budget selection |
|
|
28
|
+
| Traceability | Per-channel evidence, fusion contributions, stage timings, configuration, and explicit failure records |
|
|
29
|
+
| Neural reranking | Optional SentenceTransformers CrossEncoder adapter with batched inference |
|
|
30
|
+
| Haystack integration | Serializable component profiles and a retriever-to-generator pipeline builder |
|
|
31
|
+
| Evaluation | Frozen BEIR candidate pools, checksummed artifacts, reproducibility commands, and a paired Ragas harness |
|
|
32
|
+
|
|
33
|
+
Output candidates always originate from the supplied input pool; `ragrefine`
|
|
34
|
+
does not invent or rewrite evidence.
|
|
35
|
+
|
|
36
|
+
## Quick start
|
|
37
|
+
|
|
38
|
+
Python 3.12+ is required. From this checkout:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uv sync
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from ragrefine import Candidate, CandidateSet, Refiner
|
|
46
|
+
|
|
47
|
+
candidates = CandidateSet(
|
|
48
|
+
name="my-retriever",
|
|
49
|
+
candidates=(
|
|
50
|
+
Candidate(
|
|
51
|
+
id="doc-1",
|
|
52
|
+
text="Python 3.12 improves f-string parsing.",
|
|
53
|
+
retrieval_rank=1,
|
|
54
|
+
retrieval_score=0.91,
|
|
55
|
+
),
|
|
56
|
+
Candidate(
|
|
57
|
+
id="doc-2",
|
|
58
|
+
text="Python 3.11 introduced exception groups.",
|
|
59
|
+
retrieval_rank=2,
|
|
60
|
+
retrieval_score=0.84,
|
|
61
|
+
),
|
|
62
|
+
),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
result = Refiner().refine(
|
|
66
|
+
query="Which Python version improves f-string parsing?",
|
|
67
|
+
candidate_set=candidates,
|
|
68
|
+
top_k=1,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
print(result.candidates[0].candidate.id)
|
|
72
|
+
print(result.trace)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`Refiner()` preserves the original ranking. Explicit `RefinerConfig` settings
|
|
76
|
+
enable lexical, pattern, neural, or fused profiles. See the
|
|
77
|
+
[technical design](TECHNICAL_DESIGN.md) for the configuration contract.
|
|
78
|
+
|
|
79
|
+
## Haystack integration
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv sync --extra haystack
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The optional integration provides document conversion, a serializable
|
|
86
|
+
`RagRefineComponent`, registered refiner profiles, prompt construction, and a
|
|
87
|
+
complete Haystack pipeline builder. The [RAG pipeline guide](docs/rag-pipeline-guide.md)
|
|
88
|
+
contains the runnable recipe and customization points.
|
|
89
|
+
|
|
90
|
+
## Evaluation summary
|
|
91
|
+
|
|
92
|
+
Post-retrieval comparisons reuse the same frozen first-stage Top-50 candidates.
|
|
93
|
+
Retrieval is not regenerated between profiles, and candidate-pool Recall@50 is
|
|
94
|
+
a fixed ceiling rather than a refinement gain.
|
|
95
|
+
|
|
96
|
+
| Experiment | SciFact result | Decision |
|
|
97
|
+
|---|---:|---|
|
|
98
|
+
| B0 — frozen dense baseline | nDCG@5 0.4592 | Baseline |
|
|
99
|
+
| B1-reference — MiniLM-L6/CUDA | nDCG@5 **0.6262** | Retained neural profile |
|
|
100
|
+
| B1-light — TinyBERT-L2/CPU | nDCG@5 **0.6112** | Retained measured profile |
|
|
101
|
+
| B2-L — lexical/CPU | nDCG@5 **0.5432** | Retained lightweight profile |
|
|
102
|
+
| B2-P — patterns/CPU | nDCG@5 0.4559 | Not retained |
|
|
103
|
+
| B3 — equal-weight fusion | Best profile nDCG@5 0.5715 | Not retained; below B1-reference |
|
|
104
|
+
|
|
105
|
+
The end-to-end Ragas A/B used 13 paired DeepSeek queries. It is statistically
|
|
106
|
+
inconclusive: the positive directional score differences have 95% paired
|
|
107
|
+
bootstrap confidence intervals spanning zero, and both context metrics are
|
|
108
|
+
saturated at 1.0. The run establishes neither an end-to-end benefit nor a
|
|
109
|
+
regression. See the [retained A/B report](benchmarks/results/haystack-ragas-analysis-v1/ragas-report.md).
|
|
110
|
+
|
|
111
|
+
Machine-readable artifacts are the source of truth. No experiment is described
|
|
112
|
+
as improved unless its recorded measurements support that claim.
|
|
113
|
+
|
|
114
|
+
## Documentation
|
|
115
|
+
|
|
116
|
+
Detailed material removed from this README remains in the repository's focused
|
|
117
|
+
documents:
|
|
118
|
+
|
|
119
|
+
- [Product requirements](AI_PRD.md) — supported scope and product boundary
|
|
120
|
+
- [Technical hypotheses](TECHNICAL_HYPOTHESIS.md) — testable claims and current evidence
|
|
121
|
+
- [Technical design](TECHNICAL_DESIGN.md) — architecture, configuration, selection, and tracing contracts
|
|
122
|
+
- [Evaluation contract](docs/evaluation-contract-v0.1.md) — frozen-pool rules, metrics, profiles, and reporting policy
|
|
123
|
+
- [Benchmark guide](docs/benchmark-baseline.md) — execution and reproduction commands
|
|
124
|
+
- [Retained artifact manifest](benchmarks/artifacts/README.md) — checksummed benchmark inputs and verification
|
|
125
|
+
- [Haystack pipeline guide](docs/rag-pipeline-guide.md) — integration and serialization
|
|
126
|
+
- [Ragas evaluation guide](docs/haystack-ragas-evaluation.md) — paired A/B design and analysis
|
|
127
|
+
- [v0.2 release record](docs/v0.2-release.md) — delivered scope, validation, and limitations
|
|
128
|
+
|
|
129
|
+
## Scope
|
|
130
|
+
|
|
131
|
+
`ragrefine` owns post-retrieval candidate refinement, context selection, and
|
|
132
|
+
tracing. It deliberately does not own ingestion, parsing, chunking, embeddings,
|
|
133
|
+
vector databases, first-stage retrieval, LLM generation, agents, or deployment.
|
|
134
|
+
|
|
135
|
+
## Development
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
uv sync --extra haystack --extra ragas
|
|
139
|
+
uv run ruff check .
|
|
140
|
+
uv run ruff format --check .
|
|
141
|
+
uv run mypy src/
|
|
142
|
+
uv run pytest
|
|
143
|
+
uv build
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Heavy model and benchmark dependencies remain optional so the core package has
|
|
147
|
+
no runtime dependencies.
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ragrefine"
|
|
3
|
+
version = "0.2.1"
|
|
4
|
+
description = "Retriever-agnostic post-retrieval refinement for RAG candidates"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
keywords = [
|
|
10
|
+
"rag",
|
|
11
|
+
"retrieval",
|
|
12
|
+
"reranking",
|
|
13
|
+
"information-retrieval",
|
|
14
|
+
"llm",
|
|
15
|
+
]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
22
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
23
|
+
"Topic :: Text Processing :: Indexing",
|
|
24
|
+
"Typing :: Typed",
|
|
25
|
+
]
|
|
26
|
+
dependencies = []
|
|
27
|
+
|
|
28
|
+
[[project.authors]]
|
|
29
|
+
name = "Atharva Dharmadhikari"
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/Atharva01/ragrefine"
|
|
33
|
+
Repository = "https://github.com/Atharva01/ragrefine"
|
|
34
|
+
Changelog = "https://github.com/Atharva01/ragrefine/blob/main/CHANGELOG.md"
|
|
35
|
+
Issues = "https://github.com/Atharva01/ragrefine/issues"
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
beir = ["beir==2.2.0"]
|
|
39
|
+
rerank = ["sentence-transformers>=6.0.0,<7"]
|
|
40
|
+
haystack = ["haystack-ai==2.31.0"]
|
|
41
|
+
ragas = [
|
|
42
|
+
"ragas==0.4.3",
|
|
43
|
+
"langchain-openai>=0.2.0,<1.0",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[build-system]
|
|
47
|
+
requires = ["uv_build>=0.12.0,<0.13.0"]
|
|
48
|
+
build-backend = "uv_build"
|
|
49
|
+
|
|
50
|
+
[dependency-groups]
|
|
51
|
+
dev = [
|
|
52
|
+
"hypothesis>=6.165.10",
|
|
53
|
+
"mypy>=2.3.1",
|
|
54
|
+
"pytest>=9.1.1",
|
|
55
|
+
"pytest-cov>=7.1.0",
|
|
56
|
+
"ruff>=0.16.3",
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
[tool.ruff]
|
|
60
|
+
extend-exclude = ["docs"]
|
|
61
|
+
line-length = 88
|
|
62
|
+
target-version = "py312"
|
|
63
|
+
|
|
64
|
+
[tool.ruff.lint]
|
|
65
|
+
select = [
|
|
66
|
+
"E",
|
|
67
|
+
"F",
|
|
68
|
+
"I",
|
|
69
|
+
"UP",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[tool.mypy]
|
|
73
|
+
files = ["src"]
|
|
74
|
+
python_version = "3.12"
|
|
75
|
+
strict = true
|
|
76
|
+
|
|
77
|
+
[[tool.mypy.overrides]]
|
|
78
|
+
module = [
|
|
79
|
+
"huggingface_hub",
|
|
80
|
+
"sentence_transformers",
|
|
81
|
+
]
|
|
82
|
+
ignore_missing_imports = true
|
|
83
|
+
|
|
84
|
+
[tool.pytest.ini_options]
|
|
85
|
+
testpaths = ["tests"]
|
|
86
|
+
pythonpath = ["."]
|
|
87
|
+
markers = [
|
|
88
|
+
"integration: tests that require integration infrastructure",
|
|
89
|
+
"model: tests that require model downloads or inference",
|
|
90
|
+
]
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ragrefine"
|
|
3
|
+
version = "0.2.1"
|
|
4
|
+
description = "Retriever-agnostic post-retrieval refinement for RAG candidates"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
authors = [{ name = "Atharva Dharmadhikari" }]
|
|
10
|
+
keywords = ["rag", "retrieval", "reranking", "information-retrieval", "llm"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 4 - Beta",
|
|
13
|
+
"Intended Audience :: Developers",
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3.12",
|
|
16
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
17
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
18
|
+
"Topic :: Text Processing :: Indexing",
|
|
19
|
+
"Typing :: Typed",
|
|
20
|
+
]
|
|
21
|
+
dependencies = []
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://github.com/Atharva01/ragrefine"
|
|
25
|
+
Repository = "https://github.com/Atharva01/ragrefine"
|
|
26
|
+
Changelog = "https://github.com/Atharva01/ragrefine/blob/main/CHANGELOG.md"
|
|
27
|
+
Issues = "https://github.com/Atharva01/ragrefine/issues"
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
beir = ["beir==2.2.0"]
|
|
31
|
+
rerank = ["sentence-transformers>=6.0.0,<7"]
|
|
32
|
+
haystack = ["haystack-ai==2.31.0"]
|
|
33
|
+
ragas = ["ragas==0.4.3", "langchain-openai>=0.2.0,<1.0"]
|
|
34
|
+
|
|
35
|
+
[build-system]
|
|
36
|
+
requires = ["uv_build>=0.12.0,<0.13.0"]
|
|
37
|
+
build-backend = "uv_build"
|
|
38
|
+
|
|
39
|
+
[dependency-groups]
|
|
40
|
+
dev = [
|
|
41
|
+
"hypothesis>=6.165.10",
|
|
42
|
+
"mypy>=2.3.1",
|
|
43
|
+
"pytest>=9.1.1",
|
|
44
|
+
"pytest-cov>=7.1.0",
|
|
45
|
+
"ruff>=0.16.3",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[tool.ruff]
|
|
49
|
+
extend-exclude = ["docs"]
|
|
50
|
+
line-length = 88
|
|
51
|
+
target-version = "py312"
|
|
52
|
+
|
|
53
|
+
[tool.ruff.lint]
|
|
54
|
+
select = ["E", "F", "I", "UP"]
|
|
55
|
+
|
|
56
|
+
[tool.mypy]
|
|
57
|
+
files = ["src"]
|
|
58
|
+
python_version = "3.12"
|
|
59
|
+
strict = true
|
|
60
|
+
|
|
61
|
+
[[tool.mypy.overrides]]
|
|
62
|
+
module = ["huggingface_hub", "sentence_transformers"]
|
|
63
|
+
ignore_missing_imports = true
|
|
64
|
+
|
|
65
|
+
[tool.pytest.ini_options]
|
|
66
|
+
testpaths = ["tests"]
|
|
67
|
+
pythonpath = ["."]
|
|
68
|
+
markers = [
|
|
69
|
+
"integration: tests that require integration infrastructure",
|
|
70
|
+
"model: tests that require model downloads or inference",
|
|
71
|
+
]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Retriever-agnostic post-retrieval refinement for RAG candidate sets."""
|
|
2
|
+
|
|
3
|
+
from ragrefine.config import RefinerConfig
|
|
4
|
+
from ragrefine.models import Candidate, CandidateSet
|
|
5
|
+
from ragrefine.refiner import Refiner
|
|
6
|
+
from ragrefine.results import RefinementResult
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"Candidate",
|
|
10
|
+
"CandidateSet",
|
|
11
|
+
"RefinerConfig",
|
|
12
|
+
"RefinementResult",
|
|
13
|
+
"Refiner",
|
|
14
|
+
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Private channel execution result used only by :mod:`ragrefine.refiner`."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
|
|
6
|
+
from ragrefine.models import Candidate
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True, slots=True)
|
|
10
|
+
class _ChannelResult:
|
|
11
|
+
"""One successful channel execution over the unchanged input candidate pool."""
|
|
12
|
+
|
|
13
|
+
name: str
|
|
14
|
+
ranking: tuple[Candidate, ...]
|
|
15
|
+
evidence: Mapping[str, Mapping[str, object]]
|
|
16
|
+
metadata: Mapping[str, object] = field(default_factory=dict)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Public configuration for deterministic refinement channels."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True, slots=True)
|
|
7
|
+
class ChannelConfig:
|
|
8
|
+
"""Whether to run one channel, require success, and its fusion weight."""
|
|
9
|
+
|
|
10
|
+
enabled: bool = False
|
|
11
|
+
required: bool = True
|
|
12
|
+
weight: float = 1.0
|
|
13
|
+
|
|
14
|
+
def __post_init__(self) -> None:
|
|
15
|
+
if self.weight < 0:
|
|
16
|
+
raise ValueError("channel weight must be non-negative")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass(frozen=True, slots=True)
|
|
20
|
+
class RefinerConfig:
|
|
21
|
+
"""Explicit independent channel configuration for B0 through B3 modes."""
|
|
22
|
+
|
|
23
|
+
original: ChannelConfig = field(default_factory=lambda: ChannelConfig(enabled=True))
|
|
24
|
+
neural: ChannelConfig = field(default_factory=ChannelConfig)
|
|
25
|
+
lexical: ChannelConfig = field(default_factory=ChannelConfig)
|
|
26
|
+
pattern: ChannelConfig = field(default_factory=ChannelConfig)
|
|
27
|
+
fusion_enabled: bool = False
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Typed package exceptions for refinement failures."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class RagRefineError(Exception):
|
|
5
|
+
"""Base exception for explicit ragrefine failures."""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RerankerError(RagRefineError):
|
|
9
|
+
"""Raised when neural reranking cannot complete safely."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PatternError(RagRefineError):
|
|
13
|
+
"""Raised when configured pattern processing is invalid or unsafe."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ChannelExecutionError(RagRefineError):
|
|
17
|
+
"""Raised when a required ranking channel cannot complete."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class MultipleActiveChannelsError(RagRefineError):
|
|
21
|
+
"""Raised when independent rankings need fusion but it is disabled."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Optional framework integrations for ragrefine."""
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Optional Haystack integration for ragrefine.
|
|
2
|
+
|
|
3
|
+
Installed with ``ragrefine[haystack]``. Provides the document adapter,
|
|
4
|
+
``RagRefineComponent`` with serializable refiner profiles, the prompt builder,
|
|
5
|
+
a frozen retrieval fixture, and a ready-made RAG pipeline builder.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from ragrefine.integrations.haystack.adapter import HaystackDocumentAdapter
|
|
9
|
+
from ragrefine.integrations.haystack.component import (
|
|
10
|
+
RagRefineComponent,
|
|
11
|
+
refiner_for_profile,
|
|
12
|
+
register_refiner_factory,
|
|
13
|
+
)
|
|
14
|
+
from ragrefine.integrations.haystack.fixture import FrozenHaystackFixture
|
|
15
|
+
from ragrefine.integrations.haystack.pipeline import (
|
|
16
|
+
ChatPromptAdapter,
|
|
17
|
+
build_rag_pipeline,
|
|
18
|
+
demo_documents,
|
|
19
|
+
)
|
|
20
|
+
from ragrefine.integrations.haystack.prompt import PROMPT_TEMPLATE, prompt_builder
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"ChatPromptAdapter",
|
|
24
|
+
"FrozenHaystackFixture",
|
|
25
|
+
"HaystackDocumentAdapter",
|
|
26
|
+
"PROMPT_TEMPLATE",
|
|
27
|
+
"RagRefineComponent",
|
|
28
|
+
"build_rag_pipeline",
|
|
29
|
+
"demo_documents",
|
|
30
|
+
"prompt_builder",
|
|
31
|
+
"refiner_for_profile",
|
|
32
|
+
"register_refiner_factory",
|
|
33
|
+
]
|