A single-user, local-first knowledge base + RAG chat workbench.
Drop in your notes (Markdown / PDF / DOCX / PPTX / CSV / TXT), chat with an OpenAI assistant that cites the matching snippets, and have every Q&A turn auto-deduped and written back so retrieval gets sharper as you use it.
Local-only by design — the server binds to
127.0.0.1, no login layer.
- Smart Markdown-aware chunker with sentence-level overlap and tiktoken budgeting
- SSE chat streaming with citation pills (KB / chunk position) and an "exclude prior Q&A from RAG" toggle
- Async, fail-safe Q&A write-back (chat UX is never blocked)
- Cross-KB BM25 search with
<mark>highlights, KB filter sidebar, and Flat / Grouped views
React + Vite UI ──► FastAPI (127.0.0.1:8000)
├─ OpenAI (gpt-4o + ada-002)
└─ Elasticsearch 7.13.4 (Docker)
All persistent state lives in deploy/elasticsearch/data/.
# 1. Elasticsearch + Kibana
cd deploy && echo 'ELASTIC_PASSWORD=changeme' > .env && docker compose up -d && cd ..
# 2. Backend
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cat > .env <<EOF
OPENAI_API_KEY=sk-...
ELASTICSEARCH_URL=http://127.0.0.1:9200
ELASTIC_USERNAME=elastic
ELASTIC_PASSWORD=changeme
EOF
python main.py # http://127.0.0.1:8000
# 3. Frontend
cd frontend && npm install && npm run dev # http://127.0.0.1:5173Swagger UI: http://127.0.0.1:8000/swagger-ui.
Reset everything: stop containers and rm -rf deploy/elasticsearch/data.