A full-stack, agentic RAG platform: upload documents, ask questions, get grounded answers with citations — with a tool-calling agent that can also search the web and do math when your documents alone aren't enough.
Live demo: https://docmind-client-bdfn.onrender.com/
docmind-client/ React + Vite frontend
docmind-server/ Node/Express — auth, conversation persistence, proxies to the RAG service
docmind-service/ Python/FastAPI/LangChain — ingestion, retrieval, re-ranking, generation, agent loop
┌─────────────┐ ┌──────────────┐ ┌────────────────────┐ ┌──────────────────┐
│ React │─────▶│ Node/Express │─────▶│ Python/FastAPI │─────▶│ Groq (LLM) │
│ (client) │ │ (auth, chat │ │ (RAG + agent) │ │ Cohere (embed) │
│ │◀─────│ history) │◀─────│ │◀─────│ Tavily (search) │
└─────────────┘ └──────┬───────┘ └─────────┬──────────┘ └──────────────────┘
│ │
▼ ▼
MongoDB Atlas MongoDB Atlas Vector Search
(users, conversations) (chunks + embeddings)
- RAG pipeline: PDF ingestion → chunking → Cohere API embeddings → MongoDB Atlas Vector Search → cross-encoder re-ranking → Groq (Llama) generation with inline citations
- Agentic layer: a planning loop that decides whether to search the user's documents, search the web (Tavily), or run a calculation. Document search always runs first, deterministically — the planner can't skip it in favor of the web, so answers stay grounded in the user's own sources by default. Arithmetic is never done by the LLM directly; it's delegated to a sandboxed calculator tool for reliability. Every response includes a step-by-step trace of what the agent did.
- Measured, not assumed: a 13-question eval harness
(
docmind-service/eval/) tracks retrieval accuracy and answer correctness. Adding cross-encoder re-ranking improved the pass rate from 85% to 92% — seedocmind-service/eval/FINDINGS.mdfor the full before/after breakdown, including an honestly-documented known limitation (a chunk-boundary retrieval gap re-ranking can't fix, since it can only rank what vector search already surfaced). - Built to survive free-tier constraints: Groq and Tavily free tiers,
MongoDB Atlas free tier, Cohere free-tier embeddings with batching and
backoff to respect rate limits. The deployed instance runs with the
re-ranker disabled (
RERANKER_ENABLED=false) to fit Render's 512MB free-tier memory limit — a deliberate, documented trade-off, not an oversight. Locally and in eval, re-ranking stays on and the improvement above is fully reproducible.
Each service has its own README with detailed setup steps:
Quick start (3 terminals):
# 1. Python RAG service (port 8000)
cd docmind-service && source venv/bin/activate && uvicorn app.main:app --reload --port 8000
# 2. Node server (port 5000)
cd docmind-server && npm run dev
# 3. React frontend (port 5173)
cd docmind-client && npm run devAll three services are deployed on Render (free tier):
docmind-service— Web Service, deployed from Dockerfiledocmind-server— Web Service, Node runtimedocmind-client— Static Site
See each service's README for environment variables required at deploy time.
Frontend: React, Vite, Axios Backend: Node.js, Express, MongoDB (Mongoose), express-rate-limit AI service: Python, FastAPI, LangChain, sentence-transformers (re-ranking) Infra: MongoDB Atlas (Vector Search), Groq (Llama 3.1), Cohere (embeddings), Tavily (web search), Docker, Render
- Table-aware PDF extraction (
pdfplumber/camelot) — financial tables in complex filings currently extract as flattened, hard-to-retrieve text - Multi-query retrieval for multi-entity comparison questions (e.g. "compare X and Y" currently benefits from naming both entities and the metric explicitly; splitting into per-entity sub-queries automatically would remove that dependency on phrasing)
- Re-ranker-aware low-confidence detection (skip generation and say "not found" when the best re-rank score is below a threshold, instead of always generating an answer from weak candidates)