Multi-Rag / README.md
VashuTheGreat2's picture
Upload folder using huggingface_hub
9c90775 verified
|
Raw
History Blame Contribute Delete
10.9 kB
---
title: Multi-Rag
emoji: πŸ€–
colorFrom: blue
colorTo: green
sdk: docker
app_file: main.py
pinned: false
short_description: This is the Multi-Rag Agent
---
# 🧠 Multi-RAG β€” Advanced Multi-Modal Retrieval Augmented Generation
<p align="center">
<img src="https://img.shields.io/badge/Python-3.12-blue?style=for-the-badge&logo=python" />
<img src="https://img.shields.io/badge/FastAPI-0.135-green?style=for-the-badge&logo=fastapi" />
<img src="https://img.shields.io/badge/LangGraph-1.0-orange?style=for-the-badge" />
<img src="https://img.shields.io/badge/LangChain-1.2-yellow?style=for-the-badge" />
<img src="https://img.shields.io/badge/FAISS-CPU-red?style=for-the-badge" />
<img src="https://img.shields.io/badge/Groq-LLM-purple?style=for-the-badge" />
<img src="https://img.shields.io/badge/Docker-Ready-blue?style=for-the-badge&logo=docker" />
</p>
A production-grade, **session-aware multi-modal RAG system** built with LangGraph, FastAPI, and a hybrid retrieval pipeline. Upload PDFs, DOCX, TXT, or images β€” get intelligent, context-grounded answers powered by an adaptive agentic graph that decides when to search your documents, when to fall back to the web, and when to just chat.
---
## πŸ“Έ Agent Graph
The LangGraph pipeline is fully visualized below β€” each node represents a stage in the decision-making workflow:
![Agent Graph Workflow](graph_visualization.png)
| Node | Role |
|---|---|
| `orchastrator` | Routes query: DB search needed or direct chat? |
| `query_generation` | Generates semantically rich retrieval queries |
| `retreiver` | Hybrid FAISS + BM25 + FlashRank reranking |
| `relevance_checker` | Evaluates if retrieved docs are CORRECT / AMBIGUOUS / INCORRECT |
| `document_refiner` | Passes verified docs to context builder |
| `web_search` | Tavily-powered fallback when docs are insufficient |
| `context_builder` | Assembles multimodal context (text + tables + images) |
| `chat` | Generates final Markdown response |
---
## ✨ Features
- πŸ—‚ **Multi-Format Ingestion** β€” PDF, DOCX, TXT, PNG/JPG/HEIF; all converted to a unified PDF pipeline
- πŸ” **Hybrid Retrieval** β€” FAISS (dense) + BM25 (sparse) via `EnsembleRetriever`, re-ranked with FlashRank
- 🧩 **Multimodal Chunks** β€” Extracts text, tables (HTML), and base64-encoded images from documents
- πŸ€– **Agentic LangGraph Workflow** β€” Adaptive routing with conditional edges; not just a static RAG chain
- 🌐 **Web Search Fallback** β€” Tavily search kicks in when retrieved docs are insufficient
- πŸ’Ύ **Session Persistence** β€” Per-user thread IDs with `InMemorySaver` checkpointing; conversation history preserved
- πŸ” **Auth Middleware** β€” Lightweight session-based authentication on every request
- πŸ–₯ **Full Web UI** β€” Jinja2-rendered frontend with upload flow, chat interface, and document explorer
- 🐳 **Docker Ready** β€” Single `Dockerfile` for deployment; also supports Jenkins CI
- πŸ“ **Rotating Logs** β€” Timestamped rotating log files under `logs/`
---
## πŸ— Architecture
```
Multi-Rag/
β”œβ”€β”€ main.py # Entrypoint β€” loads .env, starts FastAPI
β”œβ”€β”€ api/
β”‚ β”œβ”€β”€ main.py # FastAPI app, middleware, router registration
β”‚ β”œβ”€β”€ routes/
β”‚ β”‚ β”œβ”€β”€ upload_router.py # File upload handling
β”‚ β”‚ β”œβ”€β”€ ingest_docs_router.py # Triggers vectorization pipeline
β”‚ β”‚ β”œβ”€β”€ chat_router.py # Chat endpoint β†’ LangGraph invocation
β”‚ β”‚ β”œβ”€β”€ user_router.py # Session/thread management
β”‚ β”‚ β”œβ”€β”€ load_conversation_router.py # Restore chat history
β”‚ β”‚ └── frontend_router.py # Serves HTML pages
β”‚ β”œβ”€β”€ middlewares/
β”‚ β”‚ └── Authenticate_middleware.py
β”‚ β”œβ”€β”€ templates/ # Jinja2 HTML templates
β”‚ └── static/ # CSS / JS assets
β”‚
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ graphs/
β”‚ β”‚ └── builder.py # LangGraph StateGraph definition
β”‚ β”œβ”€β”€ nodes/
β”‚ β”‚ └── main_nodes.py # All 8 node implementations
β”‚ β”œβ”€β”€ states/
β”‚ β”‚ └── Main_State.py # LangGraph State + Pydantic output schemas
β”‚ β”œβ”€β”€ pipeline/
β”‚ β”‚ β”œβ”€β”€ Vectiorizer_pipeline.py # Ingestion + Transformation orchestration
β”‚ β”‚ └── GraphRunner_pipeline.py # Graph execution wrapper
β”‚ β”œβ”€β”€ components/
β”‚ β”‚ β”œβ”€β”€ data_ingestion.py # File-to-PDF conversion dispatch
β”‚ β”‚ β”œβ”€β”€ data_transformation.py # PDF β†’ chunks β†’ FAISS vector store
β”‚ β”‚ └── run_graph.py # graph.ainvoke() wrapper
β”‚ β”œβ”€β”€ retrievers/
β”‚ β”‚ └── create_retreivers.py # Hybrid retriever + FlashRank compression
β”‚ β”œβ”€β”€ prompts/
β”‚ β”‚ └── prompt_templates.py # All LLM prompt templates
β”‚ β”œβ”€β”€ entity/
β”‚ β”‚ β”œβ”€β”€ config_entity.py # Dataclass configs
β”‚ β”‚ └── artifact_entity.py # Dataclass artifacts
β”‚ β”œβ”€β”€ llm/
β”‚ β”‚ └── llm_loader.py # Groq ChatGroq instantiation
β”‚ β”œβ”€β”€ memory/
β”‚ β”‚ └── __init__.py # InMemorySaver checkpointer
β”‚ β”œβ”€β”€ tools/
β”‚ β”‚ └── __init__.py # Tavily web search StructuredTool
β”‚ β”œβ”€β”€ constants/
β”‚ β”‚ └── __init__.py # Global constants
β”‚ └── utils/
β”‚ β”œβ”€β”€ ingestion_utils.py # image_to_pdf, text_to_pdf, docs_to_pdf
β”‚ └── asyncHandler.py # Async decorator for uniform error handling
β”‚
β”œβ”€β”€ exception/
β”‚ └── __init__.py # MyException with structured logging
β”œβ”€β”€ logger/
β”‚ └── __init__.py # RotatingFileHandler setup
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ jenkins
└── pyproject.toml
```
---
## πŸ”„ RAG Pipeline Flow
```
User Uploads Files
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Vectorization Pipeline β”‚
β”‚ β”‚
β”‚ File β†’ docs_to_pdf β†’ partition_pdf (hi_res) β”‚
β”‚ β†’ chunk_by_title β†’ FAISS + Embeddings β”‚
β”‚ β†’ saved per thread_id β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
User Sends Chat Message
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ LangGraph Agent β”‚
β”‚ β”‚
β”‚ Orchestrator ──→ Query Generation β”‚
β”‚ β”‚ β”‚
β”‚ Retriever (Hybrid) β”‚
β”‚ β”‚ β”‚
β”‚ Relevance Checker β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ CORRECT/ INCORRECT β”‚
β”‚ AMBIGUOUS β”‚ β”‚
β”‚ β”‚ Web Search β”‚
β”‚ Document β”‚ β”‚
β”‚ Refiner β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ Context Builder β”‚
β”‚ β”‚ β”‚
β”‚ Chat β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```
---
## βš™οΈ Tech Stack
| Layer | Technology |
|---|---|
| **LLM** | Groq (`llama-3.x` / configurable) |
| **Embeddings** | `sentence-transformers/all-MiniLM-L6-v2` via HuggingFace |
| **Vector Store** | FAISS (CPU) |
| **Sparse Retrieval** | BM25 (`rank-bm25`) |
| **Reranking** | FlashRank |
| **Web Search** | Tavily (`langchain-tavily`) |
| **Agent Framework** | LangGraph 1.x (`StateGraph`) |
| **Orchestration** | LangChain 1.x |
| **Document Parsing** | `unstructured[all-docs]` + `pdfminer-six` + `pdf2image` |
| **OCR** | EasyOCR + Tesseract |
| **API** | FastAPI + Uvicorn |
| **Frontend** | Jinja2 + Vanilla JS |
| **Memory** | LangGraph `InMemorySaver` |
| **Packaging** | `uv` + `pyproject.toml` |
---
## πŸš€ Getting Started
### Prerequisites
```bash
# System dependencies (Ubuntu/Debian)
sudo apt-get install -y \
tesseract-ocr \
libtesseract-dev \
poppler-utils \
libmagic-dev
```
### Installation
```bash
# Clone the repo
git clone https://github.com/VashuTheGreat/Multi-Rag.git
cd Multi-Rag
# Create virtual environment with uv
pip install uv
uv venv
source .venv/bin/activate
# Install all dependencies
uv sync
```
### Environment Variables
Copy `.env.example` to `.env` and fill in your keys:
```bash
cp .env.example .env
```
```env
GROQ_API_KEY=your_groq_api_key
TAVILY_API_KEY=your_tavily_api_key
```
### Run
```bash
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
```
Navigate to `http://localhost:8000`
---
## 🐳 Docker
```bash
docker build -t multi-rag .
docker run -p 7860:7860 --env-file .env multi-rag
```
---
## πŸ“ Supported File Types
| Format | Conversion Path |
|---|---|
| `.pdf` | Used directly by `unstructured` |
| `.docx` | `python-docx` β†’ `fpdf2` β†’ PDF |
| `.txt` | `fpdf2` β†’ PDF |
| `.png / .jpg / .heif` | `Pillow` β†’ PDF |
---
## 🧩 Key Design Decisions
- **Adaptive Routing** β€” The orchestrator decides per-query whether vector search is needed, avoiding unnecessary DB calls for greetings/small talk.
- **Hybrid Retrieval** β€” FAISS (70%) + BM25 (30%) ensemble captures both semantic and keyword relevance; FlashRank re-ranks the top results.
- **Relevance Gating** β€” A dedicated LLM call classifies retrieved docs as `CORRECT`, `AMBIGUOUS`, or `INCORRECT` before deciding whether to use them or fall back to web search.
- **Per-Thread Isolation** β€” Each user session gets its own `thread_id`; vector stores and artifacts are namespaced by thread to prevent cross-user data leakage.
- **Multimodal Context** β€” The `context_builder` node assembles text, HTML tables, and base64 images extracted from document chunks into a rich multimodal prompt.
---
## πŸ“œ License
[MIT](LICENSE)
---
## πŸ‘€ Author
**VashuTheGreat (Vansh Sharma)**
> Built with β˜• and an unhealthy obsession with RAG pipelines.