Skip to content

Commit 47c0d2b

Browse files
committed
docs: add readthedocs mkdocs scaffold
1 parent 32882ca commit 47c0d2b

14 files changed

Lines changed: 506 additions & 117 deletions

.github/workflows/docs-build.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Docs Build
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
workflow_dispatch:
9+
10+
jobs:
11+
mkdocs:
12+
name: MkDocs Strict Build
13+
runs-on: ubuntu-22.04
14+
permissions:
15+
contents: read
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: '3.11'
23+
24+
- name: Install documentation dependencies
25+
run: python -m pip install -r docs/requirements.txt
26+
27+
- name: Build documentation
28+
run: python -m mkdocs build --strict --config-file mkdocs.yml

.readthedocs.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: 2
2+
3+
build:
4+
os: ubuntu-22.04
5+
tools:
6+
python: "3.11"
7+
8+
mkdocs:
9+
configuration: mkdocs.yml
10+
fail_on_warning: true
11+
12+
python:
13+
install:
14+
- requirements: docs/requirements.txt

README.md

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,10 @@ leann ask my-docs "Where are prompts configured?"
11101110
# Detect file changes since last build/watch checkpoint
11111111
leann watch my-docs
11121112
1113-
# List all your indexes
1113+
# Keep an index current as files are saved
1114+
leann watch my-docs --live
1115+
1116+
# List discoverable indexes
11141117
leann list
11151118
11161119
# Remove an index
@@ -1152,23 +1155,27 @@ leann search INDEX_NAME QUERY [OPTIONS]
11521155
Options:
11531156
--top-k N Number of results (default: 5)
11541157
--complexity N Search complexity (default: 64)
1158+
--max-depth N Maximum app-index discovery depth (default: 4)
11551159
--recompute / --no-recompute Enable/disable embedding recomputation (default: enabled). Should not do a `no-recompute` search in a `recompute` build.
11561160
--pruning-strategy {global,local,proportional}
11571161
```
11581162
11591163
**Watch Command:**
11601164
```bash
1161-
leann watch INDEX_NAME
1165+
leann watch INDEX_NAME [OPTIONS]
11621166
11631167
# Compares the current file system state against the last checkpoint (Merkle tree snapshot)
1164-
# and reports which files have been added, removed, or modified, along with their chunk IDs.
1168+
# and updates the index when files have been added, removed, or modified.
11651169
#
1166-
# - Automatically saves a new checkpoint after detecting changes
1170+
# - Use --once --dry-run to report changes without updating the index
1171+
# - Use --live to wake updates from filesystem events instead of the polling interval
1172+
# - --debounce-ms controls live event batching (default: 500)
1173+
# - Automatically saves a new checkpoint after successful index updates
11671174
# - Each subsequent run compares against the most recent checkpoint
11681175
# - File change detection uses SHA-256 content hashing via a Merkle tree
11691176
#
11701177
# Example output:
1171-
# === Changes since last checkpoint ===
1178+
# === Changes detected ===
11721179
# modified (1):
11731180
# - /path/to/file.py
11741181
# chunks: 42, 43, 44
@@ -1187,24 +1194,34 @@ Options:
11871194
11881195
**List Command:**
11891196
```bash
1190-
leann list
1197+
leann list [OPTIONS]
1198+
1199+
Options:
1200+
--max-depth N Maximum app-index discovery depth (default: 4)
11911201
1192-
# Lists all indexes across all projects with status indicators:
1202+
# Lists discoverable indexes from the current project and registered project roots:
11931203
# ✅ - Index is complete and ready to use
11941204
# ❌ - Index is incomplete or corrupted
11951205
# 📁 - CLI-created index (in .leann/indexes/)
11961206
# 📄 - App-created index (*.leann.meta.json files)
1207+
#
1208+
# App-created index discovery is bounded and skips heavyweight directories
1209+
# such as .git, node_modules, virtualenvs, build/cache folders, and directory symlinks.
1210+
#
1211+
# Commands that resolve app-created indexes by name also accept --max-depth,
1212+
# including search, watch, rebuild, migrate-ids, warmup, daemon, and react.
11971213
```
11981214
11991215
**Remove Command:**
12001216
```bash
12011217
leann remove INDEX_NAME [OPTIONS]
12021218
12031219
Options:
1204-
--force, -f Force removal without confirmation
1220+
--force, -f Force removal without confirmation
1221+
--max-depth N Maximum app-index discovery depth (default: 4)
12051222
12061223
# Smart removal: automatically finds and safely removes indexes
1207-
# - Shows all matching indexes across projects
1224+
# - Shows all bounded matching indexes across registered projects
12081225
# - Requires confirmation for cross-project removal
12091226
# - Interactive selection when multiple matches found
12101227
# - Supports both CLI and app-created indexes
@@ -1272,6 +1289,9 @@ results = searcher.search("banana‑crocodile", use_grep=True, top_k=1)
12721289
12731290
## Benchmarks
12741291
1292+
For the current benchmark inventory and reporting template, see the
1293+
[Benchmark Guide](docs/benchmarks.md).
1294+
12751295
**[DiskANN vs HNSW Performance Comparison →](benchmarks/diskann_vs_hnsw_speed_comparison.py)** - Compare search performance between both backends
12761296
12771297
**[Simple Example: Compare LEANN vs FAISS →](benchmarks/compare_faiss_vs_leann.py)** - See storage savings in action

benchmarks/README.md

Lines changed: 98 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,131 @@
1-
# 🧪 LEANN Benchmarks & Testing
1+
# LEANN Benchmarks
22

3-
This directory contains performance benchmarks and comprehensive tests for the LEANN system, including backend comparisons and sanity checks across different configurations.
3+
This directory contains benchmark scripts and data-dependent evaluation suites for LEANN. The
4+
canonical benchmark inventory now lives in [docs/benchmarks.md](../docs/benchmarks.md).
45

5-
## 📁 Test Files
6+
## Quick Starts
67

7-
### `diskann_vs_hnsw_speed_comparison.py`
8-
Performance comparison between DiskANN and HNSW backends:
9-
-**Search latency** comparison with both backends using recompute
10-
-**Index size** and **build time** measurements
11-
-**Score validity** testing (ensures no -inf scores)
12-
-**Configurable dataset sizes** for different scales
8+
Run a small backend comparison:
139

1410
```bash
15-
# Quick comparison with 500 docs, 10 queries
16-
python benchmarks/diskann_vs_hnsw_speed_comparison.py
17-
18-
# Large-scale comparison with 2000 docs, 20 queries
19-
python benchmarks/diskann_vs_hnsw_speed_comparison.py 2000 20
20-
```
21-
22-
### `test_distance_functions.py`
23-
Tests all supported distance functions across DiskANN backend:
24-
-**MIPS** (Maximum Inner Product Search)
25-
-**L2** (Euclidean Distance)
26-
-**Cosine** (Cosine Similarity)
27-
28-
```bash
29-
uv run python tests/sanity_checks/test_distance_functions.py
11+
uv run python benchmarks/diskann_vs_hnsw_speed_comparison.py
3012
```
3113

32-
### `test_l2_verification.py`
33-
Specifically verifies that L2 distance is correctly implemented by:
34-
- Building indices with L2 vs Cosine metrics
35-
- Comparing search results and score ranges
36-
- Validating that different metrics produce expected score patterns
14+
Compare LEANN storage usage against a FAISS baseline:
3715

3816
```bash
39-
uv run python tests/sanity_checks/test_l2_verification.py
17+
uv run python benchmarks/compare_faiss_vs_leann.py
4018
```
4119

42-
### `test_sanity_check.py`
43-
Comprehensive end-to-end verification including:
44-
- Distance function testing
45-
- Embedding model compatibility
46-
- Search result correctness validation
47-
- Backend integration testing
20+
Run the synthetic, model-free code-context expansion benchmark:
4821

4922
```bash
50-
uv run python tests/sanity_checks/test_sanity_check.py
23+
uv run python benchmarks/benchmark_code_context.py \
24+
--modules 1000 \
25+
--warmups 1 \
26+
--repeats 5 \
27+
--data-source synthetic-code-context \
28+
--data-revision 2026-06-03-fixture \
29+
--format markdown \
30+
--json-output benchmark-results/code-context.json \
31+
--markdown-output benchmark-results/code-context.md
5132
```
5233

53-
## 🎯 What These Tests Verify
34+
This benchmark fixture exercises direct related-code matches, direct immediate-base inherited
35+
calls, and bounded one-hop exact-call expansion. Its JSON and Markdown artifacts report data
36+
source/revision, local environment provenance, direct related counts, inherited related counts,
37+
one-hop related counts, expected inherited/one-hop coverage, unique related passages,
38+
cap/truncation accounting, command provenance, and timing summaries.
5439

55-
### ✅ Distance Function Support
56-
- All three distance metrics (MIPS, L2, Cosine) work correctly
57-
- Score ranges are appropriate for each metric type
58-
- Different metrics can produce different rankings (as expected)
40+
The curated documentation report for this benchmark lives in
41+
[docs/code_context_benchmark.md](../docs/code_context_benchmark.md).
5942

60-
### ✅ Backend Integration
61-
- DiskANN backend properly initializes and builds indices
62-
- Graph construction completes without errors
63-
- Search operations return valid results
43+
Run the main retrieval evaluation driver:
6444

65-
### ✅ Embedding Pipeline
66-
- Real-time embedding computation works
67-
- Multiple embedding models are supported
68-
- ZMQ server communication functions correctly
69-
70-
### ✅ End-to-End Functionality
71-
- Index building → searching → result retrieval pipeline
72-
- Metadata preservation through the entire flow
73-
- Error handling and graceful degradation
74-
75-
## 🔍 Expected Output
76-
77-
When all tests pass, you should see:
78-
79-
```
80-
📊 测试结果总结:
81-
mips : ✅ 通过
82-
l2 : ✅ 通过
83-
cosine : ✅ 通过
84-
85-
🎉 测试完成!
45+
```bash
46+
uv run benchmarks/run_evaluation.py
8647
```
8748

88-
## 🐛 Troubleshooting
49+
This command treats an incomplete `benchmarks/data/` tree, including a README-only checkout or an
50+
`indices/` tree without any `.index` artifact, as missing benchmark data and downloads the public
51+
data pack. The repository-provided prebuilt indexes are large; check local disk capacity before
52+
relying on the automatic download path.
8953

90-
### Common Issues
54+
For larger retrieval runs after data has been downloaded:
9155

92-
**Import Errors**: Ensure you're running from the project root:
9356
```bash
94-
cd /path/to/leann
95-
uv run python tests/sanity_checks/test_distance_functions.py
57+
uv run benchmarks/run_evaluation.py benchmarks/data/indices/rpj_wiki/rpj_wiki \
58+
--dataset rpj_wiki \
59+
--data-source LEANN-RAG/leann-rag-evaluation-data \
60+
--data-revision 2026-06-02-download \
61+
--num-queries 2000 \
62+
--top-k 3 \
63+
--complexity 120 \
64+
--format markdown \
65+
--json-output benchmark-results/retrieval-rpj-wiki.json \
66+
--markdown-output benchmark-results/retrieval-rpj-wiki.md
9667
```
9768

98-
**Memory Issues**: Reduce graph complexity for resource-constrained systems:
99-
```python
100-
builder = LeannBuilder(
101-
backend_name="diskann",
102-
graph_degree=8, # Reduced from 16
103-
complexity=16 # Reduced from 32
104-
)
105-
```
69+
Retrieval evaluation is search-only by default. Use `--run-llm` only when generation should be
70+
included as opt-in metadata outside retrieval latency. Retrieval artifacts include per-query result
71+
IDs, golden IDs, and duplicate-text counters so reviewers can audit text-overlap recall when passage
72+
ID schemes differ across indexes. CLI-generated artifacts also record SHA256 hashes for the query
73+
and ground-truth files plus shell-quoted script command arguments.
10674

107-
**ZMQ Port Conflicts**: The tests use different ports to avoid conflicts, but you may need to kill existing processes:
108-
```bash
109-
pkill -f "embedding_server"
110-
```
75+
Retrieval, query-log, and code-context artifacts share the same timing-statistics helper. p95 is the
76+
lower nearest-rank observed sample from sorted timings, so it is deterministic and comparable across
77+
reviewable benchmark reports. The standalone BM25 and DiskANN baseline scripts use the same
78+
observed-sample percentile helpers for their latency report fields.
11179

112-
## 📊 Performance Expectations
80+
Run one retrieval manifest across multiple prebuilt backend indexes:
11381

114-
### Typical Timing (3 documents, consumer hardware):
115-
- **Index Building**: 2-5 seconds per distance function
116-
- **Search Query**: 50-200ms
117-
- **Recompute Mode**: 5-15 seconds (higher accuracy)
118-
119-
### Memory Usage:
120-
- **Index Storage**: ~1-2 MB per distance function
121-
- **Runtime Memory**: ~500MB (including model loading)
82+
```bash
83+
uv run python benchmarks/compare_retrieval_backends.py benchmark-results/retrieval-comparison.json \
84+
--format markdown \
85+
--json-output benchmark-results/retrieval-comparison-summary.json \
86+
--markdown-output benchmark-results/retrieval-comparison-summary.md
87+
```
12288

123-
## 🔗 Integration with CI/CD
89+
The comparison manifest keeps dataset, query file, ground truth, `top_k`, complexity, and batch
90+
size identical across runs. The combined JSON/Markdown artifacts report per-run backend,
91+
passage-ID scheme, embedding model/mode, recall@k, hit rate@k, latency, storage bytes, query file
92+
hash, ground-truth file hash, shell-quoted script command arguments, missing result-ID counts, and
93+
duplicate result/golden text counters.
94+
See [docs/benchmarks.md](../docs/benchmarks.md) for the manifest fields and a complete example.
12495

125-
These tests are designed to be run in automated environments:
96+
Summarize query logs with optional ground truth and storage accounting:
12697

127-
```yaml
128-
# GitHub Actions example
129-
- name: Run Sanity Checks
130-
run: |
131-
uv run python tests/sanity_checks/test_distance_functions.py
132-
uv run python tests/sanity_checks/test_l2_verification.py
98+
```bash
99+
uv run python benchmarks/summarize_query_log.py queries.jsonl \
100+
--ground-truth ground_truth.json \
101+
--index-path .leann/indexes/my-index/documents.leann \
102+
--data-source my-dataset \
103+
--data-revision 2026-06-02-download \
104+
--format markdown \
105+
--json-output benchmark-results/my-index-summary.json \
106+
--markdown-output benchmark-results/my-index-summary.md
133107
```
134108

135-
The tests are deterministic and should produce consistent results across different platforms.
109+
`--format` controls stdout. Use `--json-output` and `--markdown-output` to write durable review
110+
artifacts in the same run. Query-log summaries include latency mean/median/p95/min/max when
111+
available plus counters for records with missing result IDs, total missing result IDs, missing
112+
latency, missing search mode, missing backend metadata, and shell-quoted script command arguments.
113+
114+
The `benchmark-results/` directory is ignored by git and is the default scratch location for local
115+
summary artifacts. Commit only curated reports with full dataset, hardware, and command context.
116+
117+
## Suites
118+
119+
- `bm25_diskann_baselines/`: Natural Questions BM25 and DiskANN search-only baselines that require
120+
externally synced artifacts, report latency with the shared observed-sample percentile helpers,
121+
and can write JSON reports with query hashes, timing scope, recursive storage bytes, settings,
122+
command arguments, and environment provenance.
123+
- `contextbench/`: trace-driven code-assistant benchmark tooling.
124+
- `enron_emails/`: retrieval and generation evaluation on the Enron email corpus.
125+
- `financebench/`: financial document question-answering benchmark.
126+
- `laion/`: multimodal image/text retrieval benchmark.
127+
- `update/`: update-latency and sequential-vs-offline update strategy benchmarks.
128+
129+
Benchmark result files committed under subdirectories are reference outputs from their documented
130+
settings and hardware. Do not treat them as automatically refreshed results for the current branch
131+
unless the relevant command has been rerun.

0 commit comments

Comments
 (0)