An end-to-end Retrieval-Augmented Generation (RAG) system that allows users to ask questions about political party election plans and receive grounded, source-backed answers.
This project uses:
- Qdrant Cloud as the vector database
- Local embeddings (HuggingFace / Sentence Transformers)
- Local LLM via Ollama (no paid APIs)
- FastAPI backend
- Zero paid APIs
Designed as a realistic, minimal, and well-structured RAG system, suitable for educational use, civic transparency, and as a reference architecture.
- 📄 Ingests multiple PDF documents (party programs, manifestos, plans)
- 🔍 Semantic search using vector embeddings
- 🧠 Grounded answers using RAG (no fine-tuning)
- 🔗 Source citations for every answer
- ☁️ Uses Qdrant Cloud (free tier supported)
- 🧠 Fully local inference (zero OpenAI / paid LLM APIs)
- 🚀 FastAPI service
- 🧱 Clean, modular Python architecture
PDFs
↓
Text Extraction
↓
Chunking (512 tokens)
↓
Local Embeddings (Sentence Transformers)
↓
Qdrant Cloud (Vector Storage)
↓
Retriever (Top-K similarity search)
↓
Local LLM (Ollama)
↓
FastAPI (/query endpoint)
| Component | Technology |
|---|---|
| Vector DB | Qdrant Cloud |
| Embeddings | HuggingFace (bge-small-en-v1.5) |
| LLM | Ollama (llama3) |
| RAG Framework | LlamaIndex |
| API | FastAPI |
| PDF Parsing | PyPDF |
| Language | Python 3.10+ |
election-rag/
├── api/ # FastAPI app
├── ingest/ # PDF ingestion & indexing
├── rag/ # Query & LLM logic
├── config/ # Environment-based settings
├── data/
│ └── raw/pdfs/ # Input PDFs
├── scripts/ # Dev & testing scripts
└── README.md
- Python 3.10+
- Ollama (for local LLM)
- A Qdrant Cloud account (free tier)
brew install ollama
ollama serve
ollama pull llama3Verify:
ollama run llama3 "Hello"git clone https://github.com/your-username/election-rag.git
cd election-ragpython3 -m venv .venv
source .venv/bin/activatepip install --upgrade pip
pip install -r requirements.txtOr manually:
pip install \
fastapi uvicorn \
llama-index \
llama-index-llms-ollama \
llama-index-embeddings-huggingface \
llama-index-vector-stores-qdrant \
qdrant-client \
sentence-transformers \
pypdf \
python-dotenv- Create a free Qdrant Cloud cluster
- Copy:
- Cluster URL
- API key
Create a .env file:
QDRANT_URL=https://your-cluster.qdrant.io
QDRANT_API_KEY=your_api_key_herePlace election plans here:
data/raw/pdfs/
This: • Loads PDFs • Chunks text • Generates embeddings • Stores vectors in Qdrant Cloud
python -m ingest.run_ingestpython -m scripts.dev_queryuvicorn api.app:app --reloadServer runs at: http://127.0.0.1:8000
POST /query
Content-Type: application/json
{
"question": "What does Party A propose about healthcare?"
}{
"answer": "Party A proposes increasing healthcare funding...",
"sources": "party_a_2025.pdf (page 12)"
}- Answers are grounded in retrieved documents
- Local LLMs may hallucinate — always verify sources
- Intended for educational and informational use