What if you could have a personal AI assistant that:
- ✅ Reads your documents
- ✅ Answers questions about them
- ✅ Never sends your data to the cloud
- ✅ Costs nothing after setup
- ✅ Works offline
This tutorial shows you how to build exactly that. We'll create a complete RAG (Retrieval-Augmented Generation) pipeline using:
- ChromaDB — Vector database for storing document embeddings
- Ollama — Local LLM runtime
- Llama 3.1 — Open-weight language model
- nomic-embed-text — Embedding model
- Docker — Containerized deployment
Architecture Overview
How It Works
- Document Loading — Read text/markdown files from your documents folder
- Chunking — Split documents into manageable pieces (1000 chars with 200 overlap)
- Embedding — Convert text chunks to vector embeddings using nomic-embed-text
- Storage — Store embeddings in ChromaDB for fast similarity search
- Retrieval — When you ask a question, find the most relevant chunks
- Generation — Use Llama 3.1 to generate answers based on retrieved context
- Response — Return the answer with source citations
Prerequisites
| Requirement | Minimum | Recommended |
|---|---|---|
| RAM | 8GB | 16GB+ |
| Disk Space | 10GB | 20GB+ |
| Docker | 20.10+ | Latest |
| Internet | For setup only | Not required after |
Quick Start (Docker)
The fastest way to get started is with Docker:
# Clone or download the project
git clone https://github.com/yourusername/local-ai-assistant.git
cd local-ai-assistant
# Run the start script
chmod +x start.sh
./start.sh
The script will:
- Build the Docker containers
- Start Ollama server
- Pull required models (nomic-embed-text, llama3.1:8b)
- Launch the interactive assistant
Manual Setup (Without Docker)
Step 1: Install Ollama
# macOS / Linux
curl -fsSL https://ollama.com/install.sh | sh
# Windows
# Download from https://ollama.com/download
Step 2: Pull Models
# Embedding model
ollama pull nomic-embed-text
# Language model (8B parameter)
ollama pull llama3.1:8b
Step 3: Install Python Dependencies
# Create virtual environment
python -m venv venv
source venv/bin/activate # macOS/Linux
# venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt
Step 4: Add Your Documents
Place your text or markdown files in the docs/ folder:
docs/
├── python_guide.txt
├── ai_concepts.txt
└── my_notes.md
Step 5: Run the Assistant
python src/simple_assistant.py
Code Walkthrough
Core Components
The assistant has three main components:
class SimpleLocalAssistant:
def __init__(self):
# ChromaDB for vector storage
self.client = chromadb.PersistentClient(path="./chroma_db")
self.collection = self.client.get_or_create_collection("local_docs")
def add_document(self, file_path: str):
# Load, chunk, and embed documents
text = self.load_text_file(file_path)
chunks = self.chunk_text(text)
self.collection.add(documents=chunks, ids=ids)
def ask(self, question: str):
# Search, retrieve, and generate
results = self.collection.query(query_texts=[question])
context = "\n".join(results['documents'][0])
answer = self.ask_ollama(question, context)
return answer
Document Chunking
Documents are split into overlapping chunks to preserve context:
def chunk_text(self, text, chunk_size=1000, overlap=200):
chunks = []
start = 0
while start < len(text):
end = start + chunk_size
chunks.append(text[start:end])
start = end - overlap # Overlap preserves context
return chunks
Query Processing
When you ask a question:
def ask(self, question):
# 1. Search for relevant chunks
results = self.collection.query(
query_texts=[question],
n_results=4 # Top 4 most relevant chunks
)
# 2. Combine context
context = "\n\n".join(results['documents'][0])
# 3. Generate answer with LLM
prompt = f"""Context: {context}
Question: {question}
Answer:"""
response = ollama.chat(model="llama3.1:8b", ...)
return response
Docker Configuration
docker-compose.yml
The Docker setup includes two services:
version: '3.8'
services:
# Ollama LLM Server
ollama:
image: ollama/ollama:latest
ports:
- "11434:11434"
volumes:
- ollama_data:/root/.ollama
# Local AI Assistant
assistant:
build: .
depends_on:
- ollama
environment:
- OLLAMA_BASE_URL=http://ollama:11434
volumes:
- ./docs:/app/docs
- assistant_data:/app/chroma_db
stdin_open: true
tty: true
volumes:
ollama_data:
assistant_data:
Dockerfile
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application
COPY src/ ./src/
COPY docs/ ./docs/
# Create data directories
RUN mkdir -p /app/chroma_db
CMD ["python", "src/simple_assistant.py"]
Docker Commands
# Start everything
docker compose up -d
# View logs
docker compose logs -f
# Stop services
docker compose down
# Access the assistant
docker compose exec assistant python src/simple_assistant.py
Using the Assistant
Interactive Mode
$ python src/simple_assistant.py
🤖 Simple Local AI Assistant
==================================================
📦 Initializing ChromaDB...
✓ ChromaDB ready
📄 Loading: docs/python_guide.txt
✓ Added 12 chunks from docs/python_guide.txt
📄 Loading: docs/ai_concepts.txt
✓ Added 15 chunks from docs/ai_concepts.txt
❓ Question: What are Python data types?
📝 ANSWER:
==================================================
Python has several built-in data types:
- int: Integer numbers (e.g., 42, -7, 0)
- float: Decimal numbers (e.g., 3.14, -0.5)
- str: Text strings (e.g., "hello", 'world')
- bool: Boolean values (True, False)
- list: Ordered collections [1, 2, 3]
- dict: Key-value pairs {"key": "value"}
📚 SOURCES:
1. python_guide.txt
2. python_guide.txt
Available Commands
| Command | Description |
|---|---|
any question |
Ask the assistant |
stats |
Show knowledge base statistics |
help |
Show available commands |
quit |
Exit the assistant |
Project Structure
local-ai-assistant/
├── src/
│ ├── assistant.py # Full-featured version
│ └── simple_assistant.py # Minimal version
├── docs/ # Your documents go here
├── tests/
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── start.sh
├── README.md
└── architecture.svg
| File | Purpose |
|---|---|
simple_assistant.py |
Minimal version with just chromadb and ollama |
assistant.py |
Full-featured version with LangChain |
Dockerfile |
Container build instructions |
docker-compose.yml |
Multi-container orchestration |
start.sh |
Quick start script |
Customization
Changing Models
Edit the configuration to use different models:
# For faster responses (smaller model)
ollama pull llama3.2:3b
# Change in code: llm_model="llama3.2:3b"
# For better quality (larger model, needs more RAM)
ollama pull llama3.1:13b
# Change in code: llm_model="llama3.1:13b"
# For coding tasks
ollama pull deepseek-coder-v2:16b
# Change in code: llm_model="deepseek-coder-v2:16b"
Adjusting Chunk Size
Chunk size affects retrieval quality:
| Chunk Size | Pros | Cons |
|---|---|---|
| 500 | More precise retrieval | Less context per chunk |
| 1000 (default) | Good balance | Balanced |
| 2000 | More context | Less precise retrieval |
Troubleshooting
| Problem | Solution |
|---|---|
| Ollama won't start | Check if port 11434 is in use: lsof -i :11434 |
| Model not found | Pull the model: ollama pull llama3.1:8b |
| Out of memory | Use a smaller model: llama3.2:3b |
| Slow responses | Use GPU if available, or smaller model |
| No documents loaded | Check docs/ folder has .txt or .md files |
Try It Yourself
Build your own local AI assistant with these BestWordz resources:
Conclusion
You now have a complete, private AI assistant that runs entirely on your computer:
- ✅ 100% Private — Your data never leaves your machine
- ✅ No API Costs — Unlimited queries for free
- ✅ Offline Capable — Works without internet
- ✅ Easy to Extend — Just add documents to the
docs/folder - ✅ Docker Ready — One-command deployment
The architecture is simple but powerful:
Documents → Chunking → Embeddings → ChromaDB → Retrieval → LLM → Answer
Start with the sample documents, then add your own knowledge base. The assistant will answer questions grounded in your actual data—not generic training data.
For larger deployments, consider:
- Web interface (Streamlit, Gradio)
- API endpoint for integration
- Multiple document types (PDF, Word)
- Advanced retrieval (hybrid search)
- Model fine-tuning for your domain