Skip to content

aqeeel02/Agentic-RAG-QnA

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ€– Agentic RAG Q&A Chatbot

An intelligent, multi-format document Q&A system powered by a fully agentic Retrieval-Augmented Generation (RAG) pipeline β€” built with FAISS, SentenceTransformers, Groq (LLaMA 3.3-70B), and Streamlit.


πŸ“Œ Overview

Agentic RAG Q&A is an AI-powered chatbot that lets you upload documents in multiple formats and ask natural language questions about them. Unlike a simple RAG pipeline, this system uses a Planner Agent that dynamically decides how to answer each query β€” whether to retrieve from your documents, rewrite the query, answer from general knowledge, or ask for clarification.

Agents communicate through a structured MCP (Message Control Protocol) β€” every handoff between agents is a typed, traceable message with a sender, receiver, payload, and unique trace ID.

All LLM calls go through Groq's API using llama-3.3-70b-versatile for fast, high-quality responses.


✨ Features

  • πŸ“ Multi-format document support β€” PDF, DOCX, PPTX, CSV, TXT, and Markdown
  • πŸ” Semantic search using FAISS + all-MiniLM-L6-v2 SentenceTransformer embeddings
  • πŸ“ Smart chunking β€” 400 token chunks with 80 token overlap, handled by the Retrieval Agent
  • πŸ† Semantic reranking β€” top-8 FAISS candidates reranked by entity match + keyword overlap before returning top-3
  • 🧠 LLM-powered answers via Groq API (LLaMA 3.3-70B) β€” fast and accurate
  • πŸ—‚οΈ Planner Agent β€” dynamically selects the best tool for every query
  • πŸ”„ Query rewriting β€” automatically rewrites failed queries for better retrieval
  • 🌐 General knowledge fallback β€” answers questions even without uploaded documents
  • πŸ“š Source attribution β€” shows exactly which document chunks backed the answer
  • πŸ“¨ MCP message passing β€” all agents communicate via structured, traceable messages
  • πŸ” Session reset β€” clears all uploads, FAISS index, and conversation in one click
  • πŸ–₯️ Clean Streamlit UI β€” easy to use for anyone

πŸ—οΈ Architecture

The system uses a four-agent + tools architecture. The Planner Agent sits at the center, deciding which tool to invoke on each attempt (up to 3 retries). All inter-agent communication uses MCP messages.

User Query
    β”‚
    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚             Ingestion Agent                 β”‚
β”‚  file_parser.py β†’ extracts raw text         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚ MCP Message (raw text + source)
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               Retrieval Agent                    β”‚
β”‚  chunk_text() β†’ 400 token chunks, 80 overlap     β”‚
β”‚  embedding_utils.py (all-MiniLM-L6-v2)           β”‚
β”‚  β†’ FAISS index β†’ top-8 search β†’ rerank β†’ top-3  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚ MCP Message (chunks + score)
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  Planner Agent                      β”‚
β”‚                                                     β”‚
β”‚  attempt 0 β†’ retrieval_tool                         β”‚
β”‚  attempt 1 β†’ rewrite_tool | llm_general_tool        β”‚
β”‚  attempt 2 β†’ llm_general_tool  (final fallback)     β”‚
β”‚                                                     β”‚
β”‚  Tools: retrieval | rewrite | llm_general | clarify β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
                     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           LLM Response Agent                β”‚
β”‚  Groq β†’ LLaMA 3.3-70B β†’ answer + sources   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚ MCP Message
                     β–Ό
              Answer + Source Chunks

πŸ€– Agents

Agent File Responsibility
Ingestion Agent agents/ingestion_agent.py Uses file_parser.py to parse all documents in data/ into text chunks with source metadata, returned as an MCP message
Retrieval Agent agents/retrieval_agent.py Chunks raw text (400 tokens, 80 overlap), embeds with all-MiniLM-L6-v2, indexes in FAISS, fetches top-8 candidates, then reranks by entity match + keyword overlap before returning top-3
Planner Agent agents/planner_agent.py Selects the best tool per attempt using rule-based logic and LLaMA; also rewrites failed queries via a dedicated Groq prompt
LLM Response Agent agents/llm_response_agent.py Scores and deduplicates retrieved chunks, constructs a strict context-grounded prompt, calls Groq (LLaMA 3.3-70B), and returns a structured MCP answer

πŸ› οΈ Tools

Defined in agents/tools.py, these are the callable actions the Planner Agent selects from:

Tool Function What it does
retrieval retrieval_tool() Runs semantic search over the FAISS index and returns matching chunks with their score
llm_general llm_general_tool() Answers directly from LLaMA's general knowledge β€” no documents needed
rewrite rewrite_tool() Prompts LLaMA to rewrite a failed query into a more retrieval-friendly form
clarify clarify_tool() Returns a clarification message when the query is too vague to process

πŸ“¨ MCP Protocol

All agents communicate using structured MCP (Message Control Protocol) messages defined in mcp/protocol.py:

{
    "sender":   "LLMResponseAgent",
    "receiver": "User",
    "type":     "FINAL_RESPONSE",
    "trace_id": "uuid-...",          # unique per request for traceability
    "payload":  { ... }              # agent-specific data
}

Every handoff β€” ingestion β†’ retrieval β†’ planner β†’ LLM β€” passes through this format, making the pipeline easy to debug, extend, and trace.


πŸ” How the Planner Decides

The Planner Agent runs up to 3 attempts per query:

  • Attempt 0 β€” always tries retrieval first
  • Attempt 1 β€” if retrieval score is low (< 0.3), tries rewrite; otherwise asks LLaMA to pick the best tool based on the query and score
  • Attempt 2 β€” falls back to llm_general unconditionally

If the LLM answers "not found in the document" even after a successful retrieval, the planner automatically escalates to general knowledge. If the LLM confidence is below 0.35, it selects clarify instead. This loop ensures the user always gets an answer.


πŸ“ Project Structure

Agentic-RAG-QnA/
β”‚
β”œβ”€β”€ agents/
β”‚   β”œβ”€β”€ ingestion_agent.py        # Document parsing agent
β”‚   β”œβ”€β”€ retrieval_agent.py        # FAISS embedding & retrieval agent
β”‚   β”œβ”€β”€ planner_agent.py          # Tool selection & query rewriting agent
β”‚   β”œβ”€β”€ llm_response_agent.py     # Groq LLaMA answer generation agent
β”‚   └── tools.py                  # retrieval, llm_general, rewrite, clarify tools
β”‚
β”œβ”€β”€ mcp/
β”‚   └── protocol.py               # create_mcp_message() β€” structured agent messaging
β”‚
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ file_parser.py            # File type dispatcher (PDF, DOCX, PPTX, CSV, TXT, MD)
β”‚   └── embedding_utils.py        # EmbeddingModel wrapper (all-MiniLM-L6-v2)
β”‚
β”œβ”€β”€ vector_store/                 # FAISS index + metadata persistence
β”‚
β”œβ”€β”€ app.py                        # Streamlit web application
β”œβ”€β”€ main.py                       # CLI entry point
β”œβ”€β”€ requirements.txt              # Python dependencies
└── README.md

πŸš€ Getting Started

Prerequisites

1. Clone the Repository

git clone https://github.com/aqeeel02/Agentic-RAG-QnA.git
cd Agentic-RAG-QnA

2. Set Up Environment Variables

Create a .env file in the root directory:

GROQ_API_KEY=your_groq_api_key_here

3. Install Dependencies

pip install -r requirements.txt

4. Run the App

streamlit run app.py

The app will open in your browser at http://localhost:8501.


πŸ› οΈ Tech Stack

Technology Purpose
Streamlit Web UI
Groq API Fast LLM inference
LLaMA 3.3-70B Answer generation & planning
FAISS Vector similarity search
SentenceTransformers (all-MiniLM-L6-v2) Text embeddings
PyMuPDF PDF parsing
python-docx DOCX parsing
python-pptx PPTX parsing
Pandas CSV parsing

πŸ“¦ Dependencies

streamlit
python-docx
python-pptx
PyMuPDF
pandas
markdown
faiss-cpu
sentence-transformers
transformers
groq
python-dotenv

Install all with:

pip install -r requirements.txt

πŸ—ΊοΈ Pipeline Deep Dive

utils/file_parser.py

A file-type dispatcher that routes each uploaded file to the correct parser β€” fitz for PDFs, python-docx for Word files, python-pptx for PowerPoint, pandas for CSV, and plain file reading for TXT and Markdown. Returns raw extracted text.

utils/embedding_utils.py

A thin wrapper around SentenceTransformers that loads all-MiniLM-L6-v2 and exposes an embed_texts() method. Used by the Retrieval Agent to encode both document chunks and incoming queries into the same vector space.

Ingestion Agent

Scans the data/ directory, calls file_parser.py for each file, and wraps the resulting raw text in an MCP message with source metadata. It does not chunk β€” it hands off the full text to the Retrieval Agent.

Retrieval Agent

The most complex agent in the pipeline. It first chunks the raw text into 400-token windows with 80-token overlap using chunk_text(). Each chunk is embedded using EmbeddingModel.embed_texts() and indexed in FAISS with metadata (source, chunk_id, entities). On a query, it fetches the top-8 candidates from FAISS, then reranks them using a scoring formula that boosts named entity matches (+2.5 per entity) and keyword overlap (+0.2 per word hit) on top of the base similarity score. The top-3 reranked chunks and their average score are returned via MCP message.

Planner Agent

The brain of the system. On each attempt it evaluates the query and retrieval score to pick the most appropriate tool. Uses LLaMA itself to reason about tool selection when the decision isn't purely rule-based. Also rewrites failed queries by prompting LLaMA for a more retrieval-friendly version.

LLM Response Agent

Receives retrieved chunks, scores and deduplicates them by relevance, builds a strict context-grounded prompt (max 2000 characters of context), and calls LLaMA 3.3-70B via Groq. Returns a final MCP message with the answer and the top 2 most relevant source snippets with their chunk IDs.


πŸ“„ License

This project is open source. Feel free to use, modify, and distribute it.


⭐ If you found this project useful, consider giving it a star!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages