An AI assistant that answers questions using your Obsidian Vault as the knowledge base, powered by RAG (Retrieval-Augmented Generation) with hybrid search.
- Hybrid Search: Combines vector similarity (ChromaDB) and BM25 keyword search for accurate retrieval
- AI-Generated Answers: GPT-4o-mini synthesizes answers grounded in your vault content, with source citations
- Incremental Indexing: Detects modified notes via file modification time and indexes only the changes
- Full Re-indexing: Reset and rebuild the entire vector index on demand
- Auto Indexing: Background scheduler keeps the index up to date automatically
- Search History: Saves past queries for quick re-access
- Note Tagger: Standalone UI for bulk-labeling notes with
content_originfrontmatter
| Component | Technology |
|---|---|
| UI | Streamlit |
| Vector Store | ChromaDB |
| Embedding | OpenAI text-embedding-3-small |
| Generation | OpenAI gpt-4o-mini |
| Keyword Search | BM25 (rank-bm25) |
| Scheduler | APScheduler |
- Python 3.9+
- OpenAI API key
- Obsidian vault
git clone <repo-url>
cd knowledge-reuse-platform
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtCreate a .env file in the project root:
OPENAI_API_KEY=sk-...
VAULT_PATH=/path/to/your/vault
VAULT_NAME=MyVault
# Optional — defaults shown
TOP_K=10
VECTOR_WEIGHT=0.7
BM25_WEIGHT=0.3
AUTO_INDEX_ENABLED=true
AUTO_INDEX_INTERVAL_MINUTES=5
GENERATION_MODEL=gpt-4o-mini
MAX_CONTEXT_CHUNKS=5Alternatively, configure everything from the Settings page in the app.
streamlit run app/main.py| Page | Description |
|---|---|
| Search | Enter a query; get an AI-generated answer with source citations and Obsidian deep links |
| Indexing | Run incremental or full re-indexing with live log output and index statistics |
| Settings | Manage API key, vault path, search parameters, and auto-indexing schedule |
A separate Streamlit tool for bulk-labeling notes with content_origin frontmatter (scraps / original).
streamlit run scripts/tagger.py- Filter notes by filename or path (e.g.
clippings/2025) - Select individual notes or use Select All
- Apply
scrapsororiginallabel in bulk via the sidebar - Automatically excludes Excalidraw, Templater, and Kanban files
knowledge-reuse-platform/
├── app/
│ └── main.py # Streamlit UI (Search / Indexing / Settings)
├── pipeline/
│ ├── indexing.py # Indexing pipeline
│ └── search.py # Search pipeline
├── components/ # Core processing components
│ ├── loader.py
│ ├── parser.py
│ ├── normalizer.py
│ ├── chunker.py
│ ├── retriever.py
│ ├── response_generator.py
│ └── bm25_index.py
├── infra/
│ ├── embedding/ # EmbeddingModel interface + OpenAI impl
│ └── vectorstore/ # VectorStore interface + ChromaDB impl
├── scheduler/
│ └── incremental_indexer.py
├── domain/
│ ├── models.py
│ └── id_utils.py
├── scripts/
│ └── tagger.py # Standalone note tagging tool
├── config.py
└── requirements.txt
MIT