Why I Built This
I wanted a chatbot that answers questions from my own documents — without sending data to a cloud API. This RAG setup runs fully offline with Ollama and ChromaDB on my machine.
- Privacy — your data stays on your machine
- No API costs — no usage fees or rate limits
- Speed — no network delay for each query
- Control — you choose what goes into the knowledge base
- Offline use — works without internet after setup
Architecture Overview
My local RAG system consists of four main components:
| Component | Purpose | Technology |
|---|---|---|
| Document Processing | Clean and chunk text documents | Python + Regex |
| Vector Store | Store and search embeddings | ChromaDB |
| Embeddings | Convert text to vectors | sentence-transformers |
| LLM Generation | Generate responses | Ollama + Llama3.1 |
How It Works
Documents → Preprocessing → Embeddings → ChromaDB Storage
↓
User Query → Query Embedding → Vector Search → Context Retrieval
↓
Context + Query → Ollama LLM → Generated Response
Technical Implementation
Prerequisites
Before starting, ensure you have:
- Python 3.8+
- Ollama installed with the
llama3.1model - A virtual environment set up
Install Ollama:
Arch Linux: sudo pacman -S ollama then sudo systemctl enable --now ollama
Ubuntu: curl -fsSL https://ollama.com/install.sh | sh
Pull the model: ollama pull llama3.1
Dependencies
pip install chromadb>=0.4.0
pip install sentence-transformers>=2.0.0
pip install numpy>=1.21.0
pip install torch>=1.9.0
Project Structure
rag/
├── docs/
│ ├── about_me.txt # Personal information
│ ├── education.txt # AI in education knowledge
│ ├── finance.txt # AI in finance knowledge
│ └── healthcare.txt # AI in healthcare knowledge
├── preprocess.py # Document preprocessing
├── rag_local_ollama.py # Main RAG system
└── requirements.txt # Dependencies
Document Preprocessing
The preprocessing pipeline handles document cleaning and chunking:
import os
import re
def clean_text(text):
# Remove HTML tags and normalize whitespace
text = re.sub(r'<[^>]+>', '', text)
text = re.sub(r'\s+', ' ', text).strip()
return text
def chunk_text(text, max_words=100):
# Split into manageable chunks for embeddings
words = text.split()
return [' '.join(words[i:i+max_words])
for i in range(0, len(words), max_words)]
def preprocess_documents(doc_folder):
all_chunks = []
for filename in os.listdir(doc_folder):
if filename.endswith(".txt"):
# Process each document
path = os.path.join(doc_folder, filename)
with open(path, 'r') as f:
raw = f.read()
cleaned = clean_text(raw)
chunks = chunk_text(cleaned)
all_chunks.extend(chunks)
return all_chunks
Vector Database Setup
Using ChromaDB for efficient similarity search:
import chromadb
from chromadb.config import Settings
from sentence_transformers import SentenceTransformer
# Initialize ChromaDB (disable telemetry for privacy)
client = chromadb.Client(Settings(anonymized_telemetry=False))
collection = client.get_or_create_collection(name="my_knowledge")
# Initialize embedding model
model = SentenceTransformer("all-MiniLM-L6-v2")
# Store documents with embeddings
for i, doc in enumerate(documents):
embedding = model.encode(doc).tolist()
collection.add(
documents=[doc],
ids=[str(i)],
embeddings=[embedding]
)
Query Processing & LLM Integration
The main RAG pipeline handles user queries:
import subprocess
# Process user query
query = input("Ask your question: ")
query_embed = model.encode(query).tolist()
# Retrieve relevant context
results = collection.query(
query_embeddings=[query_embed],
n_results=2
)
contexts = results['documents'][0]
context = "\n".join(contexts)
# Build prompt for Ollama
prompt = f"""Answer the following question using only the information in the context. Be concise and factual.
Context:
{context}
Question:
{query}
Answer:"""
# Generate response using Ollama
result = subprocess.run(
["ollama", "run", "llama3.1"],
input=prompt,
capture_output=True,
text=True
)
print("\nLLM Response:")
print(result.stdout.strip())
Knowledge Base Content
My system includes curated information about:
Personal Background
- Name: Saad Ahmad
- Location: Khyber Pakhtunkhwa, Pakistan
- Focus: AI agents and intelligent systems
- Skills: Python, ChromaDB, sentence-transformers, Ollama
AI in Education
- Personalized learning platforms
- Adaptive learning systems
- AI-powered tutoring
- Administrative automation
- Predictive analytics
AI in Finance
- Algorithmic trading
- Fraud detection
- Credit scoring and risk assessment
- Robo-advisors
- RegTech & compliance
AI in Healthcare
- Medical imaging and diagnostics
- Predictive analytics
- Drug discovery
- Virtual health assistants
- Personalized treatment
Testing the System
Example Queries
Personal Information:
Query: "What is Saad Ahmad's location and background?"
Response: "Saad Ahmad's location is DIKhan, Khyber Pakhtunkhwa, Pakistan.
His background includes being a passionate learner focused on building
AI agents and intelligent systems..."
Domain Knowledge:
Query: "How is AI being used in healthcare?"
Response: "AI is revolutionizing healthcare through medical imaging
for diagnostics, predictive analytics for disease onset, drug discovery
acceleration, and personalized treatment plans..."
Performance Insights
What Works Well
- Fast Response Times: Local processing eliminates network latency
- Accurate Retrieval: Semantic search finds relevant context effectively
- Privacy Maintained: No data ever leaves the local system
- Cost Effective: Zero ongoing operational costs
Areas for Improvement
- Chunk Size Optimization: Experiment with different chunk sizes
- Advanced Embeddings: Try domain-specific embedding models
- Query Expansion: Implement query reformulation techniques
- Caching: Add response caching for repeated queries
Future Enhancements
Planned Upgrades
- LangChain Integration: More sophisticated prompt management
- Multi-Modal Support: Add image and document processing
- Real-time Updates: Dynamic knowledge base updates
- Advanced Chunking: Semantic chunking strategies
- Evaluation Metrics: Implement RAG evaluation framework
Integration Possibilities
- Slack Bot: Deploy as a company knowledge assistant
- Web Interface: Build a user-friendly web dashboard
- API Service: Create REST API for external applications
- Voice Interface: Add speech-to-text capabilities
Technical Specifications
System Requirements
- RAM: 8GB+ (for model loading)
- Storage: 5GB+ (for models and embeddings)
- CPU: Multi-core recommended
- GPU: Optional (speeds up embedding generation)
Model Details
- LLM: Llama3.1 (4.9GB)
- Embeddings: all-MiniLM-L6-v2 (80MB)
- Vector DB: ChromaDB (lightweight, embedded)
Conclusion
This local RAG system demonstrates that powerful AI applications don’t require cloud dependencies or expensive APIs. With open-source tools like Ollama, ChromaDB, and sentence-transformers, you can build sophisticated knowledge systems that respect privacy while delivering excellent performance.
The combination of retrieval-augmented generation with local processing opens up new possibilities for personalized AI assistants, company knowledge bases, and privacy-focused applications.
Source Code
The complete implementation is available on GitHub, including all preprocessing scripts, the main RAG pipeline, and sample documents for testing.
Happy building!