architecture · Personal project
DocuMind — A Production RAG Platform
A multi-tenant RAG platform with streamed, cited answers — hybrid BM25 + embedding retrieval with reranking, a Redis semantic cache, and RAGAS scoring on every change.
- Role
- Sole designer and builder — ingestion, retrieval, caching, evaluation, and the app
- Team
- Solo
- Scope
- Multi-tenant question answering over PDFs and wiki pages, with streamed answers that cite their sources
- Level
- Personal project
Retrieval
Method: BM25 and embedding retrieval merged and reranked with a cross-encoder, compared with a vector-only baseline on the evaluation set.
Window: by design
Quality tracking
Method: Faithfulness and context recall are scored with RAGAS on an evaluation set for every change.
Window: every change
Repeated questions
Method: Redis semantic cache returns answers for semantically repeated questions, cutting latency and token cost.
Window: by design
Context
"Chat with your documents" is easy to demo and hard to make good. DocuMind is a personal project to build it the way a production system needs to be built: multi-tenant, answers streamed and cited, retrieval quality measured, and costs kept under control. It answers questions over PDFs and wiki pages.
Code: repository link coming soon.
Retrieval is the product
Vector search is good at meaning and bad at exact terms — error codes, product names, section titles. Keyword search is the opposite. DocuMind uses hybrid retrieval: BM25 and embeddings run together, and a cross-encoder reranker scores each candidate against the actual question before anything reaches the model. That improves relevance over vector-only search.
One store for vectors and tenants
Embeddings live in PostgreSQL with pgvector, next to tenant and document metadata. Every query must only ever see the asking tenant's documents, and keeping both in one store means tenant scoping is part of the same query that does the search.
Cheaper repeats
People ask the same question in different words. A Redis semantic cache catches those rephrasings, so repeats come back faster and cost no generation tokens.
Measured, not guessed
Every change — chunking, retrieval, reranking, prompts — is scored with RAGAS on an evaluation set: faithfulness (does the answer stick to the sources?) and context recall (did retrieval find what was needed?). Separating the two tells you whether to fix retrieval or generation.
What broke
The first cache matched only on question similarity, which meant a similar question from one tenant could in principle get another tenant's cached answer. I caught it in testing, and cache keys are now scoped by tenant and document-set version, with a test that tries to read across tenants. Separately, fixed-size chunking split tables and headings from their content, and context recall made that visible — so chunking now follows document structure.
Outcomes
Streamed, cited answers over PDFs and wiki pages; hybrid retrieval with reranking; a tenant-safe semantic cache cutting latency and token cost; and answer quality tracked with RAGAS on every change.
Decision Records
Where I Got It Wrong
Failure 1
The first version of the semantic cache matched only on question similarity, so in principle a similar question from one tenant could be served another tenant's cached answer — caught in testing before it shipped
Cost: A redesign of the cache keys, and a reminder that in a multi-tenant system every shortcut is a potential data leak
Lesson: In a multi-tenant system, scope every cache key by tenant and by the version of the document set — and write a test that tries to read across tenants
Failure 2
Fixed-size chunking split tables and section headings away from their content, which showed up as low context recall on questions about structured parts of documents
Cost: Answers that missed information sitting just across a chunk boundary
Lesson: Chunk along document structure — headings, sections, tables — and let the context-recall metric tell you when chunking is the problem rather than the prompt
Long-Term Impact
A reference implementation for production RAG: hybrid retrieval, tenant-safe caching, cited answers, and quality measured on every change.