A full-stack Retrieval-Augmented Generation (RAG) system that allows authenticated users to ingest documents, perform semantic search, and generate grounded responses with evaluation metrics for retrieval quality and faithfulness.
Backend: backend/ (FastAPI)
Frontend: frontend/ (React + Vite)
- Backend health:
GET /health(defaulthttp://localhost:8000/health) - Frontend shows backend health status (default
http://localhost:5173)
If the frontend shows Backend health: error, start the backend without --reload first (some environments block file watching).
Copy env.example to .env and set OPENAI_API_KEY when you get to chat generation.
- Put real secrets in
.envonly (it is gitignored). - Do not commit real keys into
env.example.
Add a strong JWT secret for auth:
JWT_SECRET=your-long-random-secret
Recommended model:
OPENAI_MODEL=gpt-4o-mini
- Auth: register/login/refresh with JWT.
- Ingest:
- PDF upload:
POST /ingest/pdf - URL ingest:
POST /ingest/url - Jobs (poll):
GET /ingest/jobs/{job_id}
- PDF upload:
- Documents:
- List:
GET /documents - Delete (async):
DELETE /documents/{document_id}(deletes chunks + associated chats, then rebuilds the per-user index) - PDF file streaming:
GET /documents/{document_id}/file(PDFs only)
- List:
- Chat:
- Per-document chat tabs (persisted):
POST /chat/sessions,GET /chat/sessions - Load history:
GET /chat/sessions/{session_id}/messages - Ask:
POST /chatwith{ question, session_id }(saves Q/A + citations)
- Per-document chat tabs (persisted):
- Citations: stored with assistant messages and shown in the UI with page jump links.
docker compose up --build- Frontend:
http://localhost:8080 - Backend:
http://localhost:8000
Backend:
uv run uvicorn backend.app.main:app --host 127.0.0.1 --port 8000Frontend:
cd frontend
npm install
npm run devAfter ingesting documents (1,000+ chunks), run (per-user index):
uv run python -m backend.scripts.benchmark_retrieval --user-id <USER_ID>Tip: get your USER_ID from GET /auth/me after logging in.
Create a dataset (copy eval/dataset.example.jsonl) and run:
python eval/run_eval.py --api http://localhost:8000 --email you@example.com --password "yourpassword" --dataset eval/dataset.jsonl --k 6It reports:
recall@k(retrieval hit rate against your gold citations)faithfulness_pass_rate(OpenAI judge; requiresOPENAI_API_KEY)