Skip to main content

Novelty-Aware RAG scoring — Filter chunks by information gain, not just relevance

Project description

pymrsf — Novelty-Aware RAG Chunk Scoring

Python 3.9+ License: MIT Tests

Stop wasting context window on information your LLM already knows.

pymrsf scores RAG chunks by measuring information gain — not just relevance. It uses the model's own predictive surprise to detect which chunks contain genuinely new information.

The Problem

Standard RAG retrieves chunks by relevance (cosine similarity). But a chunk can be highly relevant while containing only facts the model already memorized during training. You waste precious context window on redundant information.

Also, if the LLM already knows the answer to the query, even novel chunks are less useful. And if two chunks say the same thing, you don't need both.

The Solution

pymrsf introduces multi-factor novelty-aware scoring:

Factor What It Measures Weight
Novelty How much new information does this chunk contain? 40%
Relevance How related is this chunk to the query? 40%
Query Ignorance Does the model not know the answer to your question? 20%
Diversity Does a better chunk already cover this content? Dedup

Quick Start

from pymrsf.rag import filter_chunks

# Your retrieved chunks
chunks = [
    "Backpropagation computes gradients using the chain rule.",
    "Neural networks are inspired by the human brain.",
    "The sky is blue because of Rayleigh scattering.",
]

# Filter to only useful chunks
query = "How does backpropagation work?"
useful = filter_chunks(chunks, query, min_rag_score=50, verbose=True)

# → Pass only useful chunks to your LLM
answer = llm.complete(query, context=useful)

Installation

pip install llama-cpp-python faiss-cpu msgpack tiktoken
git clone https://github.com/riiseup08/mrsf.git
cd mrsf
pip install -e .

Features

🎯 RAG Chunk Scoring (Core Feature)

from pymrsf.rag import score_chunk, score_chunks, score_chunks_batch

# Single chunk scoring
result = score_chunk(
    "Backpropagation computes gradients using the chain rule.",
    query="How does backpropagation work?",
    verbose=True
)
print(result["rag_score"])    # 72/100
print(result["verdict"])      # "good"
print(result["query_knowledge"])  # how much model knows the query

# Batch scoring (3-5x faster for many chunks)
results = score_chunks_batch(chunks, query)

# Custom weights (adjust the formula)
weights = {"novelty": 0.5, "relevance": 0.3, "query_ignorance": 0.2}
result = score_chunk(chunk, query, weights=weights)

🔍 Knowledge Probing

from pymrsf import probe

result = probe("To be or not to be, that is the question.")
print(f"Knowledge: {result['knowledge_score']}/100 ({result['label']})")
# → Knowledge: 92/100 (memorized) — Shakespeare is well-known

result = probe("My proprietary algorithm uses a novel attention mechanism.")
print(f"Knowledge: {result['knowledge_score']}/100 ({result['label']})")
# → Knowledge: 15/100 (unknown) — novel content!

🔧 RAG Pipeline Filter

from pymrsf.rag import filter_chunks

chunks = retriever.get(query, top_k=20)   # your retriever

# Only keep chunks worth sending to the LLM
good = filter_chunks(
    chunks,
    query,
    min_rag_score=50,      # skip low-value chunks
    top_k=5,                # limit context window usage
    diversity_threshold=0.85,  # dedup similar chunks
    verbose=True,
)

answer = llm.complete(query, context=good)

📦 Delta Compression (Experimental)

Store text efficiently using LLM surprises:

from pymrsf import mrsf_write, mrsf_read, save_index

# Write (stores only surprise tokens = ~40% compression)
mrsf_write("The Eiffel Tower is in Paris.")
save_index()

# Read (reconstructs from delta + model)
results = mrsf_read("famous landmark in France")

Configuration

Create a .env file:

PYMRSF_PROVIDER=local
PYMRSF_MODEL_PATH=./models/mistral-7b-v0.1.Q4_K_M.gguf

Scoring Concepts

RAG Score Formula

rag_score = novelty × 0.40 + relevance × 0.40 + query_ignorance × 0.20

What the Scores Mean

Score Verdict Action
80-100 Excellent Prioritize this chunk
60-79 Good Include in context
40-59 Moderate Include if space allows
20-39 Weak Skip if better chunks exist
0-19 Skip Model already knows this

Project Structure

pymrsf/
├── __init__.py     # Public API exports
├── core.py         # Provider routing (local + openai), lazy model loading
├── embeddings.py   # Ollama embedding API client
├── probe.py        # Knowledge probing (how well does model know a text?)
├── rag.py          # RAG chunk scoring with novelty + relevance + diversity
├── storage.py      # Delta compression storage (experimental)
├── inspect.py      # Token-level visualization tools
└── benchmark.py    # Compression/latency benchmarks

Project Status

Alpha — The RAG novelty scoring works and solves a real problem. The delta compression/storage system is experimental.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pymrsf-0.4.0.tar.gz (26.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pymrsf-0.4.0-py3-none-any.whl (21.6 kB view details)

Uploaded Python 3

File details

Details for the file pymrsf-0.4.0.tar.gz.

File metadata

  • Download URL: pymrsf-0.4.0.tar.gz
  • Upload date:
  • Size: 26.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for pymrsf-0.4.0.tar.gz
Algorithm Hash digest
SHA256 f090b4a01416434d7083fa3dffe2006d1f41eab8f3b47a8399dc8b46087c9076
MD5 fca3365e729f0450734fe31f0f945edb
BLAKE2b-256 c5a85653addbf08b00d919f31bf6b4193c63456aa4cb1f6bb12700326e3c3378

See more details on using hashes here.

File details

Details for the file pymrsf-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: pymrsf-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 21.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for pymrsf-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bbb16ba4eb235af7d9a8911c51b72731488cde294fbb2e72e3de689d7f114994
MD5 0c94b35a3da73e12d79dfdae54713d0e
BLAKE2b-256 de0870a2c6cd75a58e3d4f06e7804fe5048316262b078ad85f285a3c5ebdf67b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page