My Studio

This is my studio page where I share all of my projects , experiments , learnings , blogs/articles , and also I share daily or frequent logs of my learnings or what currently I am working on.

Advanced RAG BackendSeptember 10, 2026

#Generative AI#RAG#Backend#AI

A backend-only Advanced Retrieval-Augmented Generation (RAG) system built with Node.js, OpenAI, Qdrant, Redis, and BullMQ.

The project goes beyond basic vector search by combining multiple retrieval and ranking techniques to improve the quality and relevance of the context given to the LLM.

View source code on GitHub

Why I Built This

I built this project to understand how modern RAG systems work beyond the basic:

Query → Vector Search → LLM

Instead of only following a single retrieval path, this project explores techniques such as query rewriting, step-back prompting, sub-query decomposition, HyDE, Reciprocal Rank Fusion (RRF), and LLM-based reranking.

The main goal was to learn how these techniques work together in a real backend system rather than implementing them as isolated examples.


How It Works

Document Indexing

PDF
 ↓
PDF parsing
 ↓
Chunking
 ↓
OpenAI embeddings
 ↓
Qdrant

Uploaded documents are processed asynchronously using BullMQ + Redis. The text is split into chunks, converted into embeddings using text-embedding-3-small, and stored in Qdrant along with the original chunk data.

Query Pipeline

User Query
    ↓
Query Rewriting
    ├── Rewritten Query
    ├── Step-back Query
    └── 3 Sub-queries
    ↓
Vector Retrieval
    +
HyDE Retrieval
    ↓
Reciprocal Rank Fusion
    ↓
Candidate Chunks
    ↓
LLM Reranking
    ↓
Top 5 Chunks
    ↓
GPT-4o-mini
    ↓
Final Answer

RAG Techniques Used

  • Query Rewriting — improves and clarifies the original query.
  • Step-back Prompting — creates a broader query to retrieve useful background context.
  • Sub-query Decomposition — breaks complex queries into focused searches.
  • HyDE (Hypothetical Document Embeddings) — generates a hypothetical answer and uses its embedding for retrieval.
  • RRF (Reciprocal Rank Fusion) — combines results from multiple retrieval paths.
  • LLM Reranking — uses gpt-4o-mini to score and reorder the retrieved candidates.
  • Context Selection — passes the highest-ranked chunks to the final generation step.

Tech Stack

  • Node.js + Express — backend and API
  • OpenAI — embeddings and LLM generation
  • Qdrant — vector database
  • Redis — queue backing store
  • BullMQ — asynchronous document indexing and query processing
  • pdf-parse — PDF text extraction
  • Docker / Docker Compose — local infrastructure

Models

  • Embeddings: text-embedding-3-small
  • Chat / generation / reranking: gpt-4o-mini

Project Structure

src/
├── config/
│   └── env.js
├── routes/
│   ├── document.routes.js
│   └── query.routes.js
├── controllers/
│   ├── document.controller.js
│   └── query.controller.js
├── middleware/
│   └── upload.middleware.js
├── queues/
│   └── queues.js
├── workers/
│   ├── indexing.worker.js
│   └── query.worker.js
├── ingestion/
│   ├── pdf.parser.js
│   ├── chunker.js
│   └── indexer.js
├── embeddings/
│   └── openai.embeddings.js
├── databases/
│   └── qdrant.js
├── query/
│   ├── query.rewriter.js
│   ├── hyde.js
│   └── test-hyde.js
├── retrieval/
│   ├── retriever.js
│   ├── rrf.js
│   ├── reranker.js
│   └── test-reranker.js
├── generation/
│   └── answer.generator.js
├── pipeline/
│   └── rag.pipeline.js
└── server.js

Run Locally

1. Clone the repository

git clone https://github.com/Sulochan36/Advanced-RAG-Patterns
cd advanced-rag

2. Install dependencies

npm install

3. Configure environment variables

Create a .env file based on .env.example:

cp .env.example .env

Add your OpenAI API key and configure the other variables if required.

4. Start Redis and Qdrant

docker compose up -d

5. Start the indexing worker

node src/workers/indexing.worker.js

6. Start the query worker

node src/workers/query.worker.js

7. Start the API server

npm run dev

The backend will run on:

http://localhost:8000

Upload a PDF through the document endpoint, wait for indexing to complete, and then send a query through the query endpoint.


Concepts & RAG Pipeline

This project was built as a learning project to understand how an Advanced RAG system works internally and how different retrieval techniques can be combined into one pipeline.

1. Document Ingestion

When a PDF is uploaded, the indexing worker processes it asynchronously:

PDF
 ↓
Text Extraction
 ↓
Chunking
 ↓
Embeddings
 ↓
Qdrant

The document is divided into smaller chunks because embedding and retrieving an entire document at once would make it difficult to find precise information.

Each chunk is converted into a vector using OpenAI text-embedding-3-small and stored in Qdrant along with its text and metadata.

2. Query Rewriting

Instead of searching only with the user's original question, the system generates different versions of the query:

  • Rewritten query — makes the question clearer and self-contained.
  • Step-back query — asks a broader question to retrieve useful background information.
  • Sub-queries — breaks the original question into three focused questions.

This creates multiple retrieval paths for the same user query.

3. HyDE

HyDE (Hypothetical Document Embeddings) generates a hypothetical passage that could answer the user's question.

The hypothetical passage is then embedded and searched against the document vectors.

User Query
 ↓
Hypothetical Document
 ↓
Embedding
 ↓
Vector Search

The goal is to make the retrieval query more similar in meaning and structure to the actual document content.

4. Multiple Retrieval

The rewritten query, step-back query, sub-queries, and HyDE each perform vector searches against Qdrant.

This gives the system multiple ranked lists of potentially relevant chunks.

5. Reciprocal Rank Fusion

RRF (Reciprocal Rank Fusion) combines the ranked results from these different retrieval paths.

A chunk that appears near the top of multiple lists receives a higher combined score.

Query Results
Step-back Results
Sub-query Results
HyDE Results
       ↓
      RRF
       ↓
Unified Candidate Ranking

This helps combine the strengths of different retrieval strategies.

6. LLM Reranking

The top candidates from RRF are passed to gpt-4o-mini.

The model scores each chunk based on how relevant it is to the original user query.

RRF Candidates
 ↓
LLM Reranker
 ↓
Relevance Scores
 ↓
Top 5 Chunks

RRF is mainly used to build a strong candidate pool, while reranking focuses on selecting the most relevant context.

7. Final Generation

The final selected chunks are provided to gpt-4o-mini along with the original question.

The model uses this retrieved context to generate the final answer.

Original Query
     +
Top 5 Retrieved Chunks
     ↓
   GPT-4o-mini
     ↓
 Final Answer

Complete Pipeline

                    DOCUMENT SIDE
                         │
                       PDF
                         ↓
                    PDF Parser
                         ↓
                      Chunking
                         ↓
                    Embeddings
                         ↓
                      Qdrant
                         │
                         │
─────────────────────────┼──────────────────────────
                         │
                      QUERY SIDE
                         │
                    User Query
                         ↓
                 Query Rewriting
                    /    |    \
             Rewritten Step-back Sub-queries
                    \    |    /
                         ↓
                  Vector Retrieval
                         +
                       HyDE
                         ↓
                       RRF
                         ↓
                Candidate Chunks
                         ↓
                  LLM Reranking
                         ↓
                    Top 5 Chunks
                         ↓
                  GPT-4o-mini
                         ↓
                    Final Answer

What I Learned

This project helped me understand that RAG is not simply:

Query → Vector Search → LLM

A more advanced system can improve retrieval by combining query understanding, multiple retrieval strategies, result fusion, reranking, and controlled context selection before the final generation step.

The project was built primarily to understand these concepts by implementing them in a working Node.js backend.


Project Goal

This project is primarily a learning-focused implementation of an Advanced RAG architecture, with an emphasis on understanding how retrieval, ranking, and generation work together in a production-style backend.