Chat with your documents. DocMind is a small, readable Retrieval-Augmented Generation (RAG) engine: point it at PDFs, Markdown or text, ask questions, and get answers that are grounded in the source and cite their passages.
It runs fully offline out of the box (a dependency-free hashing embedder and an "echo" LLM), then upgrades to real semantic embeddings and hosted or local LLMs by changing a single environment variable.
┌─────────┐ ┌────────┐ ┌─────────┐ ┌──────────────┐ ┌──────────┐ ┌──────────┐
│ Ingest │ → │ Chunk │ → │ Embed │ → │ Vector store │ → │ Retrieve │ → │ Generate │
│ pdf/md │ │ overlap│ │ vectors │ │ cosine scan │ │ top-k │ │ + cite │
└─────────┘ └────────┘ └─────────┘ └──────────────┘ └──────────┘ └──────────┘
Most RAG demos are a single 400-line notebook. DocMind breaks the loop into small modules you can actually read and reason about — one per stage — so it works as both a usable tool and a clear reference implementation.
pip install -r requirements.txt
# Index the bundled sample, then ask a question — no API key needed:
python -m docmind.cli ingest samples
python -m docmind.cli ask "What are the steps in the RAG pipeline?"
# Or run the web app and drag a PDF in:
python -m docmind.cli serve # http://127.0.0.1:8000Everything is configured by environment variables (see .env.example):
| Variable | Default | Options |
|---|---|---|
DOCMIND_EMBEDDER |
hashing |
sentence-transformers, openai |
DOCMIND_LLM |
echo |
openai, anthropic, ollama |
DOCMIND_TOP_K |
4 |
any int |
DOCMIND_CHUNK_SIZE / _OVERLAP |
800 / 120 |
any int |
# Real semantic search + a local model via Ollama, still no cloud:
pip install sentence-transformers
export DOCMIND_EMBEDDER=sentence-transformers
export DOCMIND_LLM=ollama DOCMIND_LLM_MODEL=llama3| Method | Path | Body | Returns |
|---|---|---|---|
GET |
/health |
– | index size + provider |
POST |
/ingest |
{"path": "./docs"} |
chunks indexed |
POST |
/upload |
multipart file | chunks indexed |
POST |
/query |
{"question": "…"} |
{text, sources[]} |
Every answer returns the passages it used, with a similarity score, so a human can verify each claim.
docmind/
config.py env-driven settings
ingest.py pdf / md / txt loaders
chunk.py paragraph- and sentence-aware chunking with overlap
embed.py pluggable embedders (hashing | sentence-transformers | openai)
store.py NumPy cosine vector store with persistence
llm.py provider abstraction (echo | openai | anthropic | ollama)
rag.py the engine that wires the stages together
api.py FastAPI app
cli.py ingest / ask / serve
web/ minimal chat UI
tests/ offline, deterministic test suite
- Grounded by construction. The system prompt tells the model to answer only from the retrieved context and to admit when the answer isn't there — the discipline that makes RAG trustworthy.
- Swap-friendly. The vector store is exact cosine over NumPy; scaling up is
a localised change to one
search()method (e.g. FAISS), nothing else. - Honest defaults. The hashing embedder is a lexical baseline, not magic — labelled as such — so the project is clone-and-run without pretending a keyword match is semantic understanding.
pip install -e ".[dev]"
pytest -q # runs fully offline- Streaming responses in the API and UI
- FAISS backend for large corpora
- Reranking retrieved passages before generation
- Per-document namespaces and metadata filters
MIT © OpusDevs
