A local-first AI assistant that helps you explore and learn from your personal markdown notes using natural language queries.
🎨 Beautiful Chat Interface - Just open http://localhost:8000 and start chatting with your notes! No complicated APIs or command lines needed.
✅ Semantic Search - Find information across all your notes using natural language ✅ Q&A with Citations - Ask questions and get answers with source references ✅ Summarization - Generate summaries of multiple notes by topic ✅ Analytics - Analyze your learning patterns and identify knowledge gaps ✅ Privacy-First - All data stays on your machine (optional cloud LLMs with your API keys) ✅ Multi-LLM Support - Choose between OpenAI, Anthropic Claude, or local Ollama ✅ Auto-Sync - Automatically syncs your vault on startup
- Python 3.11+
- pip or uv (recommended)
- (Optional) Ollama - For free local LLM (install here)
# Navigate to backend directory
cd knowledge-assistant/backend
# Install dependencies
pip install -r requirements.txt
# Or with uv (faster)
uv pip install -r requirements.txtCreate a .env file in the project root:
# Copy example
cp .env.example .env
# Edit .env with your settings
nano .envMinimum Required Configuration:
# Point to your markdown notes folder
VAULT_PATH=/Users/yourname/Documents/YourNotes
# Choose LLM provider (ollama is free and local)
LLM_PROVIDER=ollama
LLM_MODEL=llama3.2
# Embedding settings (local is free)
EMBEDDING_PROVIDER=local
EMBEDDING_MODEL=all-MiniLM-L6-v2For Cloud LLMs (Optional):
# OpenAI
LLM_PROVIDER=openai
LLM_MODEL=gpt-4o-mini
OPENAI_API_KEY=sk-your-key-here
# OR Anthropic
LLM_PROVIDER=anthropic
LLM_MODEL=claude-sonnet-4-20250514
ANTHROPIC_API_KEY=sk-ant-your-key-here# macOS
brew install ollama
# Linux
curl https://ollama.ai/install.sh | sh
# Pull a model
ollama pull llama3.2cd backend
python main.pyThe API will start at http://localhost:8000
On first run, it will:
- Create SQLite database
- Initialize ChromaDB
- Load the embedding model
- Sync your vault (if
VAULT_PATHis set)
Open the interactive API docs:
http://localhost:8000/docs
Or use curl:
# Health check
curl http://localhost:8000/api/v1/health
# Trigger sync
curl -X POST http://localhost:8000/api/v1/sync
# Ask a question
curl -X POST http://localhost:8000/api/v1/query \
-H "Content-Type: application/json" \
-d '{
"query": "What do my notes say about Python testing?",
"query_type": "qa",
"stream": false
}'| Endpoint | Method | Description |
|---|---|---|
/api/v1/sync |
POST | Sync markdown files from vault |
/api/v1/query |
POST | Query your notes (Q&A, search, summarize, analytics) |
/api/v1/health |
GET | Health check |
/api/v1/stats |
GET | Database statistics |
/docs |
GET | Interactive API documentation |
{
"query": "Your question here",
"query_type": "auto", // or "qa", "search", "summarize", "analytics"
"max_results": 5,
"stream": true // Enable streaming response
}Query Types:
auto- Automatically detect type based on keywordsqa- Question answering with citationssearch- Just find relevant chunks (no LLM)summarize- Generate thematic summaryanalytics- Analyze learning distribution and gaps
knowledge-assistant/
├── backend/
│ ├── main.py # FastAPI app
│ ├── config.py # Settings management
│ ├── models/
│ │ ├── sqlite_models.py # Database models
│ │ └── request_response.py # API models
│ ├── repositories/
│ │ ├── chroma_repository.py # Vector DB operations
│ │ └── sqlite_repository.py # Metadata operations
│ ├── services/
│ │ ├── sync_service.py # File ingestion
│ │ └── query_service.py # RAG pipeline
│ ├── providers/
│ │ ├── openai_provider.py # OpenAI integration
│ │ ├── anthropic_provider.py # Claude integration
│ │ └── ollama_provider.py # Local LLM
│ ├── prompts/
│ │ └── templates.py # Prompt templates
│ └── utils/
│ ├── markdown_parser.py # Chunking logic
│ ├── embedding_generator.py # Embeddings
│ └── context_builder.py # RAG context
└── README.md
Markdown Files → Parse → Chunk by Headers → Generate Embeddings → Store in ChromaDB + SQLite
User Query → Embed Query → Search ChromaDB → Build Context → LLM Generate → Return with Citations
- ChromaDB: Vector embeddings for semantic search (~50MB for 500 files)
- SQLite: File metadata, config, query history (~5MB)
Q&A:
"What do my notes say about RAG systems?"
"How does FastAPI handle async requests?"
"Explain the difference between REST and GraphQL based on my notes"
Summarization:
"Summarize all my Python testing notes"
"Give me an overview of my machine learning notes"
"What are the main themes in my backend development notes?"
Analytics:
"What percentage of my notes are about tech vs business?"
"Where should I focus more learning based on my notes?"
"Show me the distribution of topics in my notes"
Search:
"Find all mentions of 'authentication'"
"Search for notes about Docker"
Ollama (Free, Local)
LLM_PROVIDER=ollama
LLM_MODEL=llama3.2 # or llama3.1, mistral, etc.OpenAI (Paid, Cloud)
LLM_PROVIDER=openai
LLM_MODEL=gpt-4o-mini # Cheapest: ~$0.001 per query
OPENAI_API_KEY=sk-...Anthropic Claude (Paid, Cloud)
LLM_PROVIDER=anthropic
LLM_MODEL=claude-sonnet-4-20250514
ANTHROPIC_API_KEY=sk-ant-...Local (Free, Recommended)
EMBEDDING_PROVIDER=local
EMBEDDING_MODEL=all-MiniLM-L6-v2 # 384 dimensions, fastOpenAI (Paid, Higher Quality)
EMBEDDING_PROVIDER=openai
EMBEDDING_MODEL=text-embedding-3-small
OPENAI_API_KEY=sk-...- Check that
VAULT_PATHin.envpoints to a valid directory - Use absolute paths:
/Users/yourname/Documents/Notes
- Set
OPENAI_API_KEYin.envif using OpenAI - Or switch to
LLM_PROVIDER=ollamafor free local LLM
- Delete
./chroma_datadirectory and restart - Check disk space (needs ~50MB for embeddings)
- First run downloads the model (~80MB for MiniLM)
- Subsequent runs are instant (model is cached)
- Make sure Ollama is running:
ollama serve - Pull the model first:
ollama pull llama3.2
Initial Sync (500 files):
- ~60 seconds (one-time)
- Generates embeddings and indexes all files
Query Latency:
- Vector search: ~10-50ms
- LLM response (streaming): 1-3 seconds to first token
- Total perceived latency: <100ms
Storage:
- 500 markdown files (~5MB) = ~60MB total (embeddings + metadata)
The backend is complete and ready to use! You can:
- Use the API directly via
/docsor curl - Build a simple web UI with React/Vue/Svelte
- Create a CLI tool for terminal-based queries
- Integrate with Obsidian via a plugin
// Simple fetch example
async function query(question) {
const response = await fetch('http://localhost:8000/api/v1/query', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
query: question,
query_type: 'qa',
stream: false
})
});
const result = await response.json();
console.log(result.answer);
console.log('Sources:', result.sources);
}
query("What do my notes say about Python?");// Server-Sent Events for streaming
const eventSource = new EventSource('http://localhost:8000/api/v1/query');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'sources') {
console.log('Sources:', data.sources);
} else if (data.type === 'token') {
process.stdout.write(data.content); // Stream tokens
} else if (data.type === 'done') {
console.log('\nDone!');
eventSource.close();
}
};This is your personal knowledge assistant! Feel free to:
- Modify prompts in
prompts/templates.py - Adjust chunking strategy in
utils/markdown_parser.py - Add new query types
- Customize the RAG pipeline
MIT License - Use however you like!
- API Docs: http://localhost:8000/docs
- Health Check: http://localhost:8000/api/v1/health
- Logs: Structured JSON logs to stdout
Built with: FastAPI, ChromaDB, SQLite, sentence-transformers, OpenAI/Anthropic/Ollama