An end-to-end retrieval-augmented generation application with:
- PDF ingestion pipeline with chunking and embedding
- Chroma vector database for semantic retrieval
- LLM-powered answer generation grounded in retrieved context
- React frontend for document upload and Q&A
- Latency benchmarking and basic accuracy evaluation scripts
- Backend: FastAPI, LangChain, OpenAI API, ChromaDB
- Frontend: React, Vite
rag-doc-qa/
backend/
app/
main.py
rag.py
config.py
schemas.py
scripts/
benchmark.py
evaluate.py
sample_qa.json
data/
uploads/
chroma/
requirements.txt
.env.example
frontend/
src/
components/
App.jsx
styles.css
- Go to backend directory.
- Create and activate a virtual environment.
- Install dependencies.
- Copy
.env.exampleto.envand setOPENAI_API_KEY. - Start API server.
cd backend
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
copy .env.example .env
uvicorn app.main:app --reloadAPI default: http://127.0.0.1:8000
You can run this project fully local using Ollama.
- Install Ollama and start it.
- Pull required local models:
ollama pull llama3.2:3b
ollama pull nomic-embed-text- In
backend/.env, set:
LLM_PROVIDER=ollama
EMBEDDING_PROVIDER=ollama
OLLAMA_BASE_URL=http://127.0.0.1:11434
OLLAMA_CHAT_MODEL=llama3.2:3b
OLLAMA_EMBEDDING_MODEL=nomic-embed-text
OPENAI_API_KEY=
- Restart backend server.
cd frontend
npm install
npm run devUI default: http://127.0.0.1:5173
GET /healthPOST /documents/uploadwith multipartfile(PDF only)POST /qa/askwith JSON body:
{
"question": "What does the report conclude?",
"top_k": 4
}Run after indexing at least one document.
cd backend
python scripts/benchmark.py- Fill
scripts/sample_qa.jsonwith expected snippets. - Run:
cd backend
python scripts/evaluate.py- Returned answers include citations with filename, page, and chunk ID.
- If retrieval does not contain enough context, the model is instructed to say it lacks enough information.