Skip to content

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Harry Potter RAG Project

A Retrieval-Augmented Generation (RAG) system for answering questions about the Harry Potter books using semantic retrieval, vector search, query routing, and grounded answer generation.

Live Frontend

The deployed frontend is available at:

(https://harry-potter-rag.vercel.app/)

The frontend communicates with the FastAPI backend through the /query endpoint.


Project Architecture

The overall workflow is:

                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚   Harry Potter PDF   β”‚
                         β”‚    harrypotter.pdf   β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                                    β–Ό
                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚   Text Extraction    β”‚
                         β”‚      + Cleaning      β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                                    β–Ό
                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚  Semantic Chunking   β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                                    β–Ό
                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚  Chunk JSON Payloads β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                                    β–Ό
                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚   E5 Embeddings     β”‚
                         β”‚ multilingual-e5-largeβ”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                                    β–Ό
                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚     Qdrant Cloud     β”‚
                         β”‚    Vector Database   β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                                    β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚                                           β”‚
              β–Ό                                           β–Ό
      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
      β”‚ Vercel Frontendβ”‚                         β”‚  FastAPI API   β”‚
      β”‚                β”‚                         β”‚    /query      β”‚
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                         β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                         β”‚
                                                         β–Ό
                                                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                                β”‚   Groq Router   β”‚
                                                β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                         β”‚
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚                          β”‚                         β”‚
                              β–Ό                          β–Ό                         β–Ό
                         retrieve                   chitchat                  off-topic
                              β”‚                          β”‚                         β”‚
                              β–Ό                          β–Ό                         β–Ό
                       E5 Embedding                Groq Response          Fixed Response
                              β”‚
                              β–Ό
                         Qdrant Search
                              β”‚
                              β–Ό
                         Top-K Chunks
                              β”‚
                              β–Ό
                       Gemini Generation
                              β”‚
                              β–Ό
                      Grounded Answer
                              β”‚
                              β–Ό
                       Source Metadata

RAG Workflow

For each user question, the backend follows these steps:

1. Query Routing

The user's question is first sent to a Groq-powered router.

The router classifies the message into exactly one of:

retrieve
chitchat
off-topic

retrieve

Used for questions about the Harry Potter books, including:

chitchat

Used for casual interaction such as:

Hello
How are you?

These requests receive a short conversational response.

off-topic

Used for questions unrelated to the Harry Potter books.

These requests are rejected without performing retrieval.


2. Query Embedding

For retrieve queries, the backend generates an embedding using Sentence Transformers.

Current model:

intfloat/multilingual-e5-large

Embeddings are normalized before retrieval.


3. Vector Search

  • The generated query vector is sent to Qdrant Cloud.

  • The system retrieves the top-K most relevant semantic chunks.

  • Each retrieved chunk contains metadata such as:

  • Chunk ID
  • Book name
  • Page start
  • Page end
  • Chunk text
  • Similarity score

4. Context Construction

The retrieved chunks are formatted into a context passed to the generation model.

The context includes the relevant book text and metadata, for example:

[Source 1]

Chunk ID: ...
Book: ...
Pages: ...

Text:
...

5. Answer Generation

The retrieved context and the user's question are sent to Gemini.


Dataset

The Harry Potter books were processed from the source PDF:

The processed dataset contains approximately:

Total pages:       3,623
Total characters:  6,273,981
Total words:       1,121,939
Empty pages:       19
Low-text pages:    17

The processing pipeline is:

PDF
 ↓
Text Extraction (markdown file)
 ↓
Cleaning
 ↓
Semantic Chunking
 ↓
Chunk JSON
 ↓
Embeddings
 ↓
Qdrant

Project Structure

Harry_Potter_RAG/
β”‚
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ rag_api.py
β”‚   └── requirements.txt
β”‚
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ script.js
β”‚   └── style.css
β”‚
β”œβ”€β”€ notebooks/
β”‚   └── RAG_Final_Project.ipynb
β”‚
β”œβ”€β”€ Testing_Screens/
β”‚   β”œβ”€β”€ Chitchat example.png
β”‚   β”œβ”€β”€ Off-topic example.png
β”‚   └── Retrieve example.png
β”‚
β”œβ”€β”€ .env.example
β”‚
β”œβ”€β”€ .gitignore
β”‚
└── README.md

Required Environment Variables

Create a .env file for local development.

Follow the structure of .env.example

Installation

Create and activate a virtual environment:

Windows PowerShell

python -m venv .venv
.\.venv\Scripts\Activate.ps1

Install the required dependencies:

pip install -r requirements.txt

Running the API Locally

Start the FastAPI application with Uvicorn:

uvicorn rag_api:app --reload --host 0.0.0.0 --port 8000

The API exposes:

GET  /
GET  /health
POST /query

Interactive API documentation (Swagger UI):

http://localhost:8000/docs

API Endpoints

GET /

Returns basic API information and status.

Example:

{
  "name": "Harry Potter RAG API",
  "version": "1.0.0",
  "status": "running",
  "docs": "/docs"
}

GET /health

Checks API health and Qdrant connectivity.

POST /query

Main RAG endpoint.

Request:

{
  "query": "Who gave Harry the Marauder's Map?"
}

The endpoint returns:

{
  "query": "Who gave Harry the Marauder's Map?",
  "route": "retrieve",
  "answer": "...",
  "sources": [
    {
      "chunk_id": "...",
      "book_name": "...",
      "page_start": 0,
      "page_end": 0,
      "score": 0.0
    }
  ]
}

Example Using cURL

curl -X POST "http://localhost:8000/query" \
  -H "Content-Type: application/json" \
  -d "{\"query\":\"Who gave Harry the Marauder's Map?\"}"

Development / Notebook Workflow

The development notebook is:

notebooks/RAG_Final_Project.ipynb

The main workflow is:

  1. Load and inspect the Harry Potter PDF.
  2. Extract and clean the text.
  3. Perform semantic chunking.
  4. Create chunk payloads.
  5. Generate embeddings.
  6. Upload vectors and metadata to Qdrant.
  7. Test retrieval.
  8. Test answer generation.
  9. Evaluate sample questions.
  10. Persist and reuse the vector database.

The API then uses the already-created Qdrant collection for real-time retrieval.


Frontend Workflow

The frontend is deployed separately using Vercel.

Live application:

https://harry-potter-rag.vercel.app/

The frontend sends user questions to the FastAPI backend through:

POST /query

The backend performs:

User Question
     ↓
Groq Router
     ↓
Route
     β”‚
     β”œβ”€β”€ chitchat β†’ Groq
     β”‚
     β”œβ”€β”€ off-topic β†’ Fixed response
     β”‚
     └── retrieve
            ↓
         E5 Embedding
            ↓
          Qdrant
            ↓
        Top-K Chunks
            ↓
          Gemini
            ↓
         Answer

Security

Do not commit .env files or API keys.

Add .env to .gitignore:

.env
.venv/
__pycache__/

API keys should be configured through environment variables or the deployment platform's secret/environment-variable system.

The original Harry Potter PDF contains copyrighted material. Avoid committing or distributing the complete copyrighted book text unnecessarily.


Troubleshooting

Embedding Model Fails to Load

Check:

EMBEDDING_MODEL

and make sure the deployment environment can download the model.

The current model is:

intfloat/multilingual-e5-large

For deployment environments with limited RAM, a smaller E5 model may be considered.

Qdrant Connection Fails

Verify:

QDRANT_URL
QDRANT_API_KEY
QDRANT_COLLECTION

Also make sure that the configured collection exists.

Gemini Generation Fails

Check:

GEMINI_MODEL
GEMINI_API_KEY

If the selected Gemini model is unavailable or temporarily unavailable, configure another supported model.

Groq Routing Fails

Check:

GROQ_MODEL
GROQ_API_KEY

The Groq model is responsible for routing queries and handling chitchat.


Current Technology Stack

Component Technology
Language Python
API FastAPI
API Server Uvicorn
Query Router Groq
Generation Google Gemini
Embeddings Sentence Transformers
Embedding Model intfloat/multilingual-e5-large
Vector Database Qdrant Cloud
Frontend HTML / CSS / JavaScript
Frontend Deployment Vercel
Development VS Code / Jupyter Notebook

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages