Local-first PDF/EPUB library explorer with grounded RAG Q&A and semantic chunk indexing.
- Scans a source folder of
.pdfand.epubfiles and categorizes books. - Builds semantic artifacts for search and RAG:
output/semantic_source.jsonloutput/semantic_chunks.jsonloutput/semantic_index/output/semantic_index_chunks/
- Runs a Streamlit dashboard (
dashboard.py) for:- semantic search,
- Ask Books grounded Q&A with citations,
- recommendation and graph views.
- macOS/Linux
- Python 3.10+ (project currently runs with
.venv) - Optional:
- Ollama (for text generation backend)
cd ~/Projects/EBooksSorter
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtUse this if you want downloaded models (embedders/rerankers) saved under
output/hf_cache instead of ~/.cache/huggingface.
cp .env.example .env
# ensure these are present in .env
# HF_HOME=/Users/longtran/Projects/EBooksSorter/output/hf_cache
# HF_HUB_CACHE=/Users/longtran/Projects/EBooksSorter/output/hf_cache/hub
set -a
source .env
set +a.venv/bin/python index_books.py \
--config "./categories.yaml" \
--source "/Users/longtran/Documents/E-Books" \
--output-dir "./output".venv/bin/python build_semantic_index.py \
--semantic-source "./output/semantic_source.jsonl" \
--output-dir "./output/semantic_index" \
--model "sentence-transformers/all-MiniLM-L6-v2".venv/bin/python build_semantic_index.py \
--semantic-source "./output/semantic_chunks.jsonl" \
--output-dir "./output/semantic_index_chunks" \
--model "sentence-transformers/all-MiniLM-L6-v2"# MiniLM (faster, lighter)
.venv/bin/python build_semantic_index.py \
--semantic-source "./output/semantic_chunks.jsonl" \
--output-dir "./output/semantic_index_chunks_minilm" \
--model "sentence-transformers/all-MiniLM-L6-v2"
# BGE base (usually better retrieval quality)
.venv/bin/python build_semantic_index.py \
--semantic-source "./output/semantic_chunks.jsonl" \
--output-dir "./output/semantic_index_chunks_bge_base" \
--model "BAAI/bge-base-en-v1.5"
# BGE large (higher quality, slower/heavier)
.venv/bin/python build_semantic_index.py \
--semantic-source "./output/semantic_chunks.jsonl" \
--output-dir "./output/semantic_index_chunks_bge_large" \
--model "BAAI/bge-large-en-v1.5"
# MXBAI large (strong retrieval quality)
.venv/bin/python build_semantic_index.py \
--semantic-source "./output/semantic_chunks.jsonl" \
--output-dir "./output/semantic_index_chunks_mxbai_large" \
--model "mixedbread-ai/mxbai-embed-large-v1"
# GTE large (quality-focused alternative)
.venv/bin/python build_semantic_index.py \
--semantic-source "./output/semantic_chunks.jsonl" \
--output-dir "./output/semantic_index_chunks_gte_large" \
--model "thenlper/gte-large"export RAG_API_KEY="change-this-internal-key"
.venv/bin/python manage.py runserver 0.0.0.0:8000 --noreload.venv/bin/streamlit run dashboard.pyollama pull granite3.3:8b
ollama run granite3.3:8b "hello"Use in Ask Books:
- generation mode:
ollama - base URL:
http://127.0.0.1:11434 - model:
granite3.3:8b
- reranker: enabled
- fallback: enabled
In Ask Books (RAG) sidebar:
- turn on
Enable reranker - pick model from
Reranker model preset - keep
Reranker top-Nbetween24and40for quality-focused tests
Recommended models to test:
cross-encoder/ms-marco-MiniLM-L-12-v2(better quality, moderate latency)BAAI/bge-reranker-base(strong on technical content)BAAI/bge-reranker-large(highest quality, slowest/heaviest)
Optional warm-download command (avoids first-query model download delay):
set -a
source .env
set +a
.venv/bin/python - <<'PY'
from sentence_transformers import CrossEncoder
for name in [
"cross-encoder/ms-marco-MiniLM-L-12-v2",
"BAAI/bge-reranker-base",
"BAAI/bge-reranker-large",
]:
print(f"Downloading/loading {name} ...")
CrossEncoder(name)
print("Done.")
PYcurl -X POST "http://127.0.0.1:8000/rag/answer" \
-H "Content-Type: application/json" \
-H "X-API-Key: ${RAG_API_KEY}" \
-d '{
"query": "Explain a neural network using grounded citations",
"top_k": 4,
"max_citations": 3,
"ollama": {
"enabled": true,
"base_url": "http://127.0.0.1:11434",
"model": "granite3.3:8b"
}
}'output/semantic_index/*.npy|*.jsonoutput/semantic_index_chunks/*.npy|*.json
/rag/*returns 401/503: setRAG_API_KEYon server and sendX-API-Keyheader.- Slow first run: embedding models download on first use.
- No chunk index: rebuild with
--semantic-source output/semantic_chunks.jsonl.
RUNBOOK.mdandDEPLOYMENT.mdare aligned with this README:- index refresh remains
index_books.py+build_semantic_index.py.
- index refresh remains