Skip to main content

ragrefine

Evidence-first post-retrieval refinement for RAG systems.

CI PyPI Python 3.12 License: MIT

ragrefine improves an existing retriever's candidate set before it reaches an LLM. It reranks, fuses, deduplicates, and selects context while preserving the original evidence and recording an auditable trace.

retriever -> Top-N candidates -> ragrefine -> refined Top-K + trace -> LLM

The core library is framework- and retriever-agnostic. Haystack and LangChain support are available as optional integrations.

Core deliverables

Capability Delivered behaviour
Candidate contract Immutable candidates retain IDs, text, metadata, retrieval rank, and retrieval score
Ranking channels Independent original, neural, lexical, and configurable pattern rankings over the same candidate pool
Rank fusion Deterministic reciprocal-rank fusion without mixing incompatible raw-score scales
Context refinement Exact/near-duplicate suppression and rank-preserving Top-K/token-budget selection
Traceability Per-channel evidence, fusion contributions, stage timings, configuration, and explicit failure records
Neural reranking Optional SentenceTransformers CrossEncoder adapter with batched inference
Haystack integration Serializable component profiles and a retriever-to-generator pipeline builder
LangChain integration RagRefineCompressor, a LangChain BaseDocumentCompressor that refines retrieved documents and exposes the trace
Evaluation Frozen BEIR candidate pools, checksummed artifacts, reproducibility commands, and a paired Ragas harness

Output candidates always originate from the supplied input pool; ragrefine does not invent or rewrite evidence.

Quick start

Python 3.12+ is required.

pip install ragrefine

Or, from this checkout:

uv sync
from ragrefine import Candidate, CandidateSet, Refiner

candidates = CandidateSet(
    name="my-retriever",
    candidates=(
        Candidate(
            id="doc-1",
            text="Python 3.12 improves f-string parsing.",
            retrieval_rank=1,
            retrieval_score=0.91,
        ),
        Candidate(
            id="doc-2",
            text="Python 3.11 introduced exception groups.",
            retrieval_rank=2,
            retrieval_score=0.84,
        ),
    ),
)

result = Refiner().refine(
    query="Which Python version improves f-string parsing?",
    candidate_set=candidates,
    top_k=1,
)

print(result.candidates[0].candidate.id)
print(result.trace)

Refiner() preserves the original ranking. Explicit RefinerConfig settings enable lexical, pattern, neural, or fused profiles. See the technical design for the configuration contract.

Haystack integration

uv sync --extra haystack

The optional integration provides document conversion, a serializable RagRefineComponent, registered refiner profiles, prompt construction, and a complete Haystack pipeline builder. The RAG pipeline guide contains the runnable recipe and customization points.

LangChain integration

pip install "ragrefine[langchain]"

This requires LangChain 1.x (langchain-core>=1.6.9). With the repository's current pins it cannot be installed in the same environment as the ragas extra (the ragas extra pins langchain-openai<1.0).

from ragrefine import Refiner, RefinerConfig
from ragrefine.config import ChannelConfig
from ragrefine.integrations.langchain import RagRefineCompressor
from ragrefine.ranking.lexical import LexicalRanker

refiner = Refiner(
    lexical_ranker=LexicalRanker(),
    config=RefinerConfig(
        original=ChannelConfig(enabled=False), lexical=ChannelConfig(enabled=True)
    ),
)
compressor = RagRefineCompressor(refiner=refiner, top_k=5)
# documents only
docs = compressor.compress_documents(retrieved_docs, "my query")

# documents + RefinementTrace
docs, trace = compressor.refine("my query", retrieved_docs)
  • Returned documents are the original objects. They are never copied or edited, and the output is always a subset of the input.
  • Documents without an id get a positional id lc:<n>. Duplicate ids raise ValueError.
  • Original retrieval scores are not read from LangChain metadata, so they are not carried into the trace.
  • To plug into a retriever, use ContextualCompressionRetriever(base_compressor=compressor, base_retriever=retriever) (that class now ships in the langchain-classic package), or wrap the compressor in a runnable: RunnableLambda(lambda x: compressor.compress_documents(x["documents"], x["query"])).

This integration is plumbing only; it makes no retrieval-quality claim. See the evaluation section for what has been measured.

Evaluation summary

Post-retrieval comparisons reuse the same frozen first-stage Top-50 candidates. Retrieval is not regenerated between profiles, and candidate-pool Recall@50 is a fixed ceiling rather than a refinement gain.

Experiment SciFact result Decision
B0 — frozen dense baseline nDCG@5 0.4592 Baseline
B1-reference — MiniLM-L6/CUDA nDCG@5 0.6262 Retained neural profile
B1-light — TinyBERT-L2/CPU nDCG@5 0.6112 Retained measured profile
B2-L — lexical/CPU nDCG@5 0.5432 Retained lightweight profile
B2-P — patterns/CPU nDCG@5 0.4559 Not retained
B3 — equal-weight fusion Best profile nDCG@5 0.5715 Not retained; below B1-reference

The end-to-end Ragas A/B used 13 paired DeepSeek queries. It is statistically inconclusive: the positive directional score differences have 95% paired bootstrap confidence intervals spanning zero, and both context metrics are saturated at 1.0. The run establishes neither an end-to-end benefit nor a regression. See the retained A/B report.

Machine-readable artifacts are the source of truth. No experiment is described as improved unless its recorded measurements support that claim.

Documentation

Detailed material removed from this README remains in the repository's focused documents:

Scope

ragrefine owns post-retrieval candidate refinement, context selection, and tracing. It deliberately does not own ingestion, parsing, chunking, embeddings, vector databases, first-stage retrieval, LLM generation, agents, or deployment.

Development

uv sync --extra haystack --extra ragas
uv run ruff check .
uv run ruff format --check .
uv run mypy src/
uv run pytest
uv build

Heavy model and benchmark dependencies remain optional so the core package has no runtime dependencies.

License

MIT

Metadata

Release files for ragrefine 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ragrefine 0.3.0
File Size Uploaded Provenance Actions
ragrefine-0.3.0.tar.gz 25.6 kB With provenance Details for ragrefine-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for ragrefine 0.3.0
File Interpreter ABI Platform Actions
ragrefine-0.3.0-py3-none-any.whl Python 3 none any Details for ragrefine-0.3.0-py3-none-any.whl

Total release size: 64.4 kB

Release files / ragrefine-0.3.0.tar.gz

Download URL ragrefine-0.3.0.tar.gz
Size 25.6 kB
Tags Source
SHA-256 checksum
How to use checksums
727a636fcb815476ddab2889b90ac938f743d2fe0cf4c1cc17251ecf15deec72
BLAKE2b-256 checksum
How to use checksums
715c90e1e55e2a8d00af4a32c119c089b591b2552e5d8a54a0d6c4fa75e54e4c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Release files / ragrefine-0.3.0-py3-none-any.whl

Download URL ragrefine-0.3.0-py3-none-any.whl
Size 38.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5f2a9771d8093da0539382b10c0b4141046ba81ffc4cb3fc93a588067de4dc90
BLAKE2b-256 checksum
How to use checksums
1463611cd00974d562b7fe3c09fe747e2548f1f6c1f0c30a554f6cea4e18f854
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

Security for ragrefine 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for ragrefine-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page