A production-ready Retrieval-Augmented Generation (RAG) chatbot engineered to deliver precise, context-aware AI responses grounded in local document data.
Unlike basic "hello world" wrappers, this project implements a 3-stage advanced retrieval pipeline and features a microservices architecture fully containerized with Docker.
I built this project to demonstrate a deep understanding of modern backend development and advanced LLM integration. Here is what sets it apart:
- Advanced Retrieval Pipeline: Moves beyond basic cosine similarity. It uses Hybrid Search (FAISS Vector + BM25 Keyword), Multi-Query Expansion (generating semantic variations of user queries), and FlashRank Re-ranking to achieve ~90% retrieval accuracy.
- Microservices Architecture: Clean separation of concerns. The FastAPI backend handles the heavy lifting, vector processing, and state management, while the Streamlit frontend acts purely as a stateless UI client.
- Production-Ready Containerization: Fully dockerized with
docker-compose. Utilizes optimized multi-stage builds and the blazing-fastuvpackage manager to keep build times under 2 minutes. CPU-optimized PyTorch keeps the image sizes lean. - Asynchronous & Typed: Written in Python 3.12 utilizing strict Pydantic typing and fully asynchronous endpoints (
async/await) for high concurrency. - Persistent Storage: Configured Docker volumes ensure that local vector stores and conversation memory survive container restarts.
The absolute fastest way to run this application is via Docker. No virtual environments required.
- Docker & Docker Compose installed.
- A free Groq API Key.
- (Optional) A Hugging Face Token to speed up embedding model downloads.
Clone the repository and create a .env file in the root directory:
# Required
GROQ_API_KEY="your_groq_api_key_here"
GROQ_MODEL="llama-3.3-70b-versatile"
# Optional (Prevents HuggingFace rate-limit warnings)
HF_TOKEN="your_huggingface_token_here"
# Vector Store
VECTOR_STORE_PATH="./data/vectorstore"
EMBEDDING_MODEL="sentence-transformers/all-MiniLM-L6-v2"Start the application using Docker Compose. We use uv inside the container, so the build is incredibly fast.
docker compose up --build -d- Web UI (Streamlit): http://localhost:8501
- API Documentation (Swagger): http://localhost:8000/docs
To stop the application, run:
docker compose down┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ User Query │────▶│ Multi-Query │────▶│ Hybrid Search │
│ │ │ Expansion │ │ (Vector+BM25) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Response to │◀────│ LLM │◀────│ FlashRank │
│ User │ │ (Groq/LLaMA 3) │ │ Re-ranking │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Conversation │
│ Memory │
└─────────────────┘
- Backend Framework: FastAPI, Uvicorn
- Frontend UI: Streamlit
- AI / LLM Orchestration: LangChain
- Inference API: Groq (Llama 3.3 70B)
- Embeddings & Re-ranking: Hugging Face (
all-MiniLM-L6-v2), FlashRank - Vector Database & Search: FAISS, Rank-BM25
- Environment Management & Building:
uv, Docker, Docker Compose
If you prefer to run the application directly on your host machine for debugging or development:
# 1. Create a virtual environment using uv
uv venv
# 2. Activate it
# On Windows:
.venv\Scripts\activate
# On macOS/Linux:
source .venv/bin/activate
# 3. Install dependencies
uv pip install -e ".[dev]"
# 4. Run the backend (Terminal 1)
python run_api.py
# 5. Run the frontend (Terminal 2)
streamlit run ui/streamlit_app.pyThe project uses pytest for unit and integration testing.
# Run all tests
pytest
# Run tests with coverage report
pytest --cov=src --cov-report=term-missingThis project is licensed under the MIT License - see the LICENSE file for details.
