Semantic search engine for the llm-code-docs repository, built with LanceDB and sentence-transformers.
- Dual search mode: Returns both specific markdown documents AND general documentation folders
- Semantic search: Uses sentence-transformers embeddings for intelligent matching
- Hybrid ranking: Combines semantic similarity, keyword matching, and recency
- Incremental updates: Fast updates when documentation changes
- CLI interface: Easy-to-use command-line tool
# Build Docker image
docker build -t llm-docs-search .
# Or use docker-compose
docker-compose build# Install dependencies
pip install -r requirements-search.txtNote: On macOS, there may be PyTorch/PyArrow mutex lock issues. Docker is recommended for reliable operation.
# Set up alias for convenience
alias llmdocs='docker run --rm -v ~/github/llm-code-docs:/llm-code-docs:ro -v $(pwd)/lancedb:/app/lancedb llm-docs-search'
# Full rebuild (initial indexing, ~30-60 minutes)
llmdocs python search.py index --rebuild
# Incremental update (after doc changes)
llmdocs python search.py index --update
# Index single framework for testing
llmdocs python search.py index --framework click
# Search documentation
llmdocs python search.py search "gitea repo limit 50 change config"
# Limit results
llmdocs python search.py search "fastapi async database" --limit 5
# Show statistics
llmdocs python search.py stats
# List all frameworks
llmdocs python search.py list-frameworks
# Show framework details
llmdocs python search.py framework gitea# Full rebuild (initial indexing)
python search.py index --rebuild
# Incremental update (after doc changes)
python search.py index --update
# Index single framework for testing
python search.py index --framework click
# Search documentation
python search.py search "gitea repo limit 50 change config"
# Limit results
python search.py search "fastapi async database" --limit 5
# Show statistics
python search.py stats
# List all frameworks
python search.py list-frameworks
# Show framework details
python search.py framework gitea- config.py - Configuration (paths, model settings)
- db/ - LanceDB connection and schema management
schema.py- Table definitions (documents, folders)connection.py- Database connection handling
- embeddings/ - Embedding generation
generator.py- sentence-transformers wrapper
- indexer/ - Indexing pipeline
scanner.py- File tree walkerextractor.py- Metadata extractionchunker.py- Smart document chunkingbuilder.py- Main orchestrator
- searcher/ - Search functionality
query.py- Dual search (documents + folders)ranker.py- Hybrid ranking algorithmformatter.py- Result display
- utils/ - Utilities
yaml_parser.py- index.yaml parserhashing.py- Content hashing for incremental updates
- cli.py - Click CLI interface
- search.py - Entry point
Documents Table (~21K+ rows):
- Document metadata (path, title, headings, keywords)
- Content chunks with embeddings (384-dim vectors)
- Categorization (framework, category)
- Timestamps for incremental updates
Folders Table (~290 rows):
- Framework/tool metadata from index.yaml
- Aggregated content embeddings
- File counts, sizes, descriptions
sentence-transformers/all-MiniLM-L6-v2:
- 384-dimensional embeddings
- Fast local inference (~0.1ms per sentence)
- No API costs, works offline
- Good semantic understanding for technical docs
- Full index: ~30-60 minutes for 21,846 files
- Incremental update: 1-5 minutes (only changed files)
- Search latency: <100ms per query
- Storage: ~500MB (embeddings + content)
# Configuration documentation
python search.py search "gitea repository limit configuration"
# Returns: config-cheat-sheet.md + gitea folder
# Framework features
python search.py search "fastapi async database connection"
# Returns: FastAPI DB docs + fastapi folder
# Testing guidance
python search.py search "pytest fixtures"
# Returns: pytest documentation + pytest folder
# General topics
python search.py search "git hosting"
# Returns: gitea, gitlab folders + relevant docsmacOS PyTorch/PyArrow mutex lock issue:
If indexing hangs with "[mutex.cc : 452] RAW: Lock blocking" error:
- Try on Linux (works reliably)
- Use Docker container
- Or try these workarounds:
# Force CPU-only mode
export PYTORCH_ENABLE_MPS_FALLBACK=1
export OMP_NUM_THREADS=1
export MKL_NUM_THREADS=1
python search.py index --rebuild- Initial indexing: Run overnight, model download takes time on first run
- Batch size: Adjust
config.EMBEDDING_BATCH_SIZEbased on RAM - GPU: CUDA/MPS acceleration automatic if available
- Incremental updates: Much faster than full rebuild
llm-code-docs-meta/
├── search/ # Search engine package
│ ├── config.py
│ ├── db/
│ ├── embeddings/
│ ├── indexer/
│ ├── searcher/
│ └── utils/
├── search.py # CLI entry point
├── requirements-search.txt
├── lancedb/ # Database (gitignored)
└── SEARCH_README.md # This file
- Custom ranking: Modify
search/searcher/ranker.py - Different embeddings: Change model in
search/config.py - Additional metadata: Update schemas in
search/db/schema.py - New commands: Add to
search/cli.py
The search engine is designed for Claude Code agent integration:
from search.searcher.query import get_searcher
searcher = get_searcher()
results = searcher.search("gitea config")
for doc in results.documents:
print(f"- {doc.title} ({doc.path})")
for folder in results.folders:
print(f"- {folder.framework_name}: {folder.description}")Complements existing llm-code-docs discovery tools:
extract_local.py- Discovers awesome listscrawler.py- Crawls for new projects- search engine - Finds specific documentation quickly
- Web UI (FastAPI + React)
- Advanced filters (by category, date range)
- Query expansion and synonyms
- "Find similar" functionality
- Search analytics
- GPU optimization for large-scale indexing
Built with:
- LanceDB - Vector database
- sentence-transformers - Embeddings
- Click - CLI framework
- tqdm - Progress bars