Production RAG over EU compliance regulations (GDPR + EU AI Act) with hybrid search, contextualized embeddings, cited answers, and abstention — on MongoDB Atlas.
- Package:
rag_knowledge_assistant· Python: 3.12 - LLM: OpenAI-compatible adapter (default: HuggingFace router →
Llama-3.3-70B-Instruct) - Embeddings: Voyage
voyage-context-4(contextualized, 1024-dim) - Vector store + search: MongoDB Atlas (
$vectorSearch+ Atlas Search BM25, fused with$rankFusion)
corpus.jsonl ─▶ chunker ─▶ Voyage context-4 ─▶ Atlas (chunks + vector & text indexes)
(structure-aware) │
▼
question ─▶ HybridRetriever ($rankFusion / RRF) ─▶ grounded prompt ─▶ LLM ─▶ cited answer | abstain
Pipeline stages (each behind an interface so strategies are swappable):
| Stage | Module | Notes |
|---|---|---|
| Chunking | ingestion/chunker.py |
structure-aware (legal numbering) + sentence-pack to a token cap, clause-path metadata |
| Embedding | embeddings/voyage.py |
contextualized: chunks grouped per article |
| Ingestion | ingestion/pipeline.py |
chunk → embed → upsert chunk docs |
| Indexes | db/indexes.py |
creates vector + text Atlas Search indexes (idempotent) |
| Retrieval | retrieval/ |
VectorRetriever (dense) and HybridRetriever ($rankFusion, falls back to client-side RRF) |
| Answering | rag/answer.py |
grounded prompt, inline [n] citations, abstention |
| Evaluation | evaluation/harness.py + evals/ |
retrieval (recall/precision/MRR) + generation (mention recall, abstention/citation accuracy) |
cp .env.example .env # fill in MONGODB_URI, VOYAGE_API_KEY, HF_TOKEN (or OPENAI_API_KEY)
make installuv run python scripts/download_corpus.py # -> data/processed/corpus.jsonl (212 articles)
uv run python scripts/build_index.py # chunk -> embed -> store -> create Atlas indexes
uv run python scripts/build_index.py --limit 12 # quick subset for a smoke testmake run # uvicorn; POST /askcurl -s localhost:8000/ask -H 'content-type: application/json' \
-d '{"question":"How quickly must a personal data breach be reported?","source":"GDPR"}'Returns a grounded answer with citations (source, article, clause) and an
abstained flag (true when the corpus does not contain the answer).
uv run python evals/run_eval.py # hybrid retriever
uv run python evals/run_eval.py --retriever vectorRuns the golden set (evals/golden.jsonl), prints a metrics table, and saves
the run under evals/results/ for comparison across configurations.
make check # ruff lint + format check, mypy --strict, pytestGenerated from
ai-portfolio-template.