Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

RAG-Powered Document Q&A System

A retrieval-augmented generation (RAG) pipeline that lets users upload PDF documents and query them in natural language — in Arabic, French, or English — receiving grounded, source-cited answers instead of hallucinated ones.

Overview

Traditional LLMs only know what they were trained on. This system solves that by combining a user's own documents with an LLM at query time:

  1. PDFs are ingested, split into overlapping chunks, and embedded into vectors using a multilingual sentence-transformers model.
  2. Vectors are stored in ChromaDB, isolated per user.
  3. When a user asks a question, the most relevant chunks are retrieved via vector similarity search and injected into the LLM's prompt.
  4. The LLM answers strictly from that retrieved context, citing the source document and page — reducing hallucination and keeping answers auditable.

Features

  • Multilingual retrieval and generation — ask questions in Arabic, French, or English; the system answers in the same language.
  • Sub-second retrieval on corpora of 1000+ pages, thanks to vector search in ChromaDB.
  • JWT-protected user document spaces — each user only sees and queries their own uploaded documents.
  • Source-grounded answers — every response cites the originating document and page number.
  • Async-friendly document status — documents move through pending → processing → ready/failed states, tracked and polled by the frontend.

Architecture

React (Vite) → Django REST Framework → RAG pipeline → ChromaDB ↓ ↓ JWT auth (SimpleJWT) Hugging Face Inference (embeddings + LLM)

Ingestion pipeline: PDF upload → text extraction (pypdf) → chunking (LangChain RecursiveCharacterTextSplitter) → embedding (sentence-transformers, multilingual model) → storage in a per-user ChromaDB collection.

Query pipeline: question → embedded with the same model → top-k similarity search in ChromaDB → relevant chunks injected into a grounded prompt → answer generated via Hugging Face's Inference Providers router → response returned with cited sources.

Tech stack

Layer Technology
Backend Django, Django REST Framework, SimpleJWT
Frontend React (Vite), React Router, Axios
Orchestration LangChain
Embeddings sentence-transformers (paraphrase-multilingual-mpnet-base-v2)
Vector store ChromaDB
LLM Hugging Face Inference Providers
Containerization Docker, docker-compose

Project structure

rag-qa-system/ ├── backend/ │ ├── config/ # Django project settings, URLs │ ├── documents/ # Models, serializers, views, auth, upload API │ └── rag/ # Ingestion, retrieval, and generation pipeline └── frontend/ └── src/ ├── api/ # Axios client, auth, documents/query calls ├── components/ # UploadForm, DocumentList, ChatBox └── pages/ # Login, Register, Dashboard

Getting started

Prerequisites

  • Python 3.10+
  • Node.js 18+
  • A Hugging Face account and API token with Inference Providers access (create one here)

Backend setup

cd backend
python -m venv venv
source venv/bin/activate        # venv\Scripts\activate on Windows
pip install -r requirements.txt

Create a .env file in backend/:

DJANGO_SECRET_KEY=your-generated-secret-key
DJANGO_DEBUG=True
HF_API_TOKEN=hf_your_token_here

Generate a secure secret key:

python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"

Then run migrations and start the server:

python manage.py makemigrations documents
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver

Frontend setup

cd frontend
npm install

Create a .env file in frontend/:

VITE_API_URL=http://localhost:8000/api

Then start the dev server:

npm run dev

Visit http://localhost:5173, create an account, log in, upload a PDF, wait for its status to become ready, and start asking questions.

API endpoints

Method Endpoint Description
POST /api/auth/register/ Create a new user account
POST /api/auth/login/ Obtain JWT access/refresh tokens
POST /api/auth/refresh/ Refresh an expired access token
GET /api/documents/ List the authenticated user's documents
POST /api/documents/ Upload a PDF (triggers ingestion)
DELETE /api/documents/{id}/ Delete a document and its vectors
POST /api/query/ Ask a question against the user's ready documents
GET /api/query/history/ List past questions and answers

Known limitations

  • PDF ingestion runs synchronously in the request cycle — large files (100+ pages) will block the upload request until indexing completes. A production version would offload this to a background worker (Celery + Redis).
  • Scanned/image-only PDFs without embedded text are not supported (no OCR step yet).
  • The embedding model is downloaded and cached in memory on first use per server process, causing a delay on cold start.

License

This project is for educational and portfolio purposes.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages