Agentic RAG pipeline failure diagnosis โ no database, no LLM API, no cloud
Project description
๐ฉบ rag-doctor
Diagnose why your RAG pipeline returned the wrong answer โ in under 2 seconds.
No database. No API keys. No cloud calls. Just pass your documents and get a root cause.
Quick Start ยท How It Works ยท Examples ยท CLI ยท Docs
The Problem
RAG pipelines fail silently. You get a wrong answer and have no idea if it's a chunking problem, a retrieval miss, a position bias, or a hallucination. Existing evaluation tools give you a score โ they don't tell you why.
rag-doctor tells you why.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
RAG-DOCTOR โ ISSUES FOUND
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Root Cause : context_position_bias (RC-2)
Severity : HIGH
Finding : Best document at position 1/2 โ in danger zone (risk: 1.00)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Fix: Enable a reranker to push the most relevant document to position 0.
Config Patch: {"retrieval.reranker": true}
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Quick Start
pip install rag-doctor
from rag_doctor import Doctor
from rag_doctor.connectors.mock import MockConnector
connector = MockConnector(corpus=[
{"id": "doc1", "content": "For liver disease patients maximum acetaminophen dose is 2000mg per day."},
{"id": "doc2", "content": "Standard adult dose: up to 4000mg per day."},
])
docs = connector.retrieve("acetaminophen dose liver disease", top_k=3)
answer = "The maximum daily dose is 4000mg."
report = Doctor.default().diagnose(
query = "What is the max acetaminophen dose for liver disease?",
answer = answer,
docs = docs,
expected = "For liver disease patients max dose is 2000mg per day.",
)
print(report.to_text())
How It Works
rag-doctor runs a deterministic six-tool agent loop. Each tool targets a specific failure mode:
| Tool | Root Cause | What It Catches |
|---|---|---|
RetrievalAuditor |
RC-1 retrieval_miss |
Correct document not in top-k results |
PositionTester |
RC-2 context_position_bias |
Correct doc retrieved but ignored in middle position |
ChunkAnalyzer |
RC-3 chunk_fragmentation |
Mid-sentence truncation, incoherent chunks |
HallucinationTracer |
RC-4 hallucination |
Answer claims not grounded in retrieved documents |
QueryRewriter |
RC-5 query_mismatch |
Query vocabulary doesn't match document vocabulary |
ChunkOptimizer |
RC-3 sub-tool | Grid-searches best chunk_size and strategy |
No Database. No LLM. No API Keys.
rag-doctor builds an ephemeral VectorStore in memory from whatever documents you pass. Your production database is never touched.
Embedding backends (auto-selected, no config needed):
| Priority | Backend | Install |
|---|---|---|
| 1 | sentence-transformers |
pip install sentence-transformers |
| 2 | Ollama nomic-embed-text |
ollama pull nomic-embed-text |
| 3 | TF-IDF (stdlib + numpy) | nothing โ built in |
| 4 | Char n-gram fallback | nothing โ always available |
Three Ways to Use It
Mode A โ Debug from Logs (no re-query needed)
from rag_doctor import Doctor
from rag_doctor.connectors.base import Document
docs = [
Document(content=row["text"], score=row["score"], position=i)
for i, row in enumerate(db_rows)
]
report = Doctor.default().diagnose(
query="What is the refund policy?",
answer="30 days for all customers.",
docs=docs,
expected="Enterprise customers get 90-day refunds.",
)
print(report.root_cause) # retrieval_miss
print(report.fix_suggestion) # Increase top_k or check corpus coverage.
Mode B โ Corpus-Level Evaluation (CI / pytest)
connector = MockConnector(corpus=YOUR_CORPUS)
docs = connector.retrieve(query, top_k=5)
report = Doctor.default(connector).diagnose(query=query, answer=answer, docs=docs, expected=expected)
assert report.severity in ("low", "medium"), report.to_text()
Mode C โ Connect Your Production Stack
class ChromaConnector(PipelineConnector):
def retrieve(self, query, top_k=5):
results = self.collection.query(query_texts=[query], n_results=top_k)
return [Document(content=d, score=s, position=i) for i,(d,s) in enumerate(...)]
report = Doctor.default(ChromaConnector(my_collection)).diagnose(...)
CLI Reference
# Single query
rag-doctor diagnose \
--query "What is the termination notice?" \
--answer "30 days." \
--expected "Enterprise requires 90 days written notice."
# Batch from JSONL
rag-doctor batch --input examples/batch_example.jsonl --fail-on-severity high
# JSON output for CI
rag-doctor diagnose --query "..." --answer "..." --output json | jq .root_cause
Local Setup (Mac)
git clone https://github.com/your-org/rag-doctor
cd rag-doctor
chmod +x scripts/test_local_mac.sh
./scripts/test_local_mac.sh
Documentation
| Doc | Description |
|---|---|
| docs/user-guide.md | Complete user guide โ all 5 journeys, all 6 root causes |
| docs/architecture.md | Internal design: embedding chain, VectorStore, agent loop |
| docs/tools-reference.md | API reference for all 6 tools |
| docs/connectors.md | Building custom connectors |
| docs/configuration.md | Thresholds and config options |
| docs/publishing.md | How to release to PyPI |
License
MIT โ free for personal and commercial use.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rag_doctor-1.0.0.tar.gz.
File metadata
- Download URL: rag_doctor-1.0.0.tar.gz
- Upload date:
- Size: 66.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cbbcf0e88d8926af66930d71a86ed85893407bfc5264f980f9459b65011c36d4
|
|
| MD5 |
c24ad2819432fe6459ff097048495ea9
|
|
| BLAKE2b-256 |
8674958598c8b4a681e4070180e0db363f9f772ef812f9ce8c69d5c54c8ad3d9
|
File details
Details for the file rag_doctor-1.0.0-py3-none-any.whl.
File metadata
- Download URL: rag_doctor-1.0.0-py3-none-any.whl
- Upload date:
- Size: 39.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2751bdf9b216a3f35e2d5fe4af9f598a849b78d4a4a487e4ef6ed25d89f3a58a
|
|
| MD5 |
25d31408b23849d54d8e18ce027b53a7
|
|
| BLAKE2b-256 |
ec163c7fdacc992169c02b0ee82f7e418586271f70ba35b9ec46170d16dc1ddb
|