Files
wehub-resource-sync 15dadb5432
CI / build (push) Waiting to run
Link Check / link-check (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:38:09 +08:00

9.8 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

LEANN is a lightweight vector database and RAG (Retrieval-Augmented Generation) system that achieves 97% storage reduction compared to traditional vector databases through graph-based selective recomputation. It enables semantic search across various data sources (emails, browser history, chat history, code, documents) on a single laptop without cloud dependencies.

Build & Development Commands

Quick install (pip)

pip install leann

Development setup (from source)

# Install uv first (required package manager)
curl -LsSf https://astral.sh/uv/install.sh | sh

git submodule update --init --recursive

# macOS
brew install libomp boost protobuf zeromq pkgconf
uv sync

# Ubuntu/Debian
sudo apt-get install libomp-dev libboost-all-dev protobuf-compiler \
    libabsl-dev libmkl-full-dev libaio-dev libzmq3-dev
uv sync

# Windows (requires VS 2022 Build Tools with C++ workload, vcpkg, chocolatey)
choco install cmake swig pkgconfiglite nuget.commandline -y
vcpkg install zeromq:x64-windows openblas:x64-windows lapack:x64-windows boost-program-options:x64-windows protobuf:x64-windows
# Set CMAKE_PREFIX_PATH, PKG_CONFIG_PATH, OPENBLAS_LIB to vcpkg paths (see README)
uv sync --extra diskann

# Install lint tools
uv sync --group lint

# Install test tools
uv sync --group test

Code Quality

# Format code
ruff format

# Lint with auto-fix
ruff check --fix

# Pre-commit hooks (install once)
pre-commit install

# Run pre-commit manually
uv run pre-commit run --all-files

Architecture

Core API Layer (packages/leann-core/src/leann/)

  • api.py: Main APIs - LeannBuilder, LeannSearcher, LeannChat
  • react_agent.py: ReActAgent for multi-turn reasoning
  • cli.py: CLI implementation (leann build, leann search, leann ask)
  • chat.py: LLM provider integrations (OpenAI, Ollama, HuggingFace, Anthropic)
  • embedding_compute.py: Embedding computation (sentence-transformers, MLX, OpenAI)
  • metadata_filter.py: Search result filtering by metadata

Backend Layer (packages/)

  • leann-backend-hnsw/: Default backend using FAISS HNSW for fast in-memory search
  • leann-backend-ivf/: IVF backend (FAISS IndexIVFFlat + DirectMap.Hashtable) supporting in-place add/remove without rebuild
  • leann-backend-diskann/: DiskANN backend for larger-than-memory datasets
  • leann-mcp/: MCP server for Claude Code integration

Backends are auto-discovered via leann-backend-* naming convention and registered in registry.py.

RAG Applications (apps/)

Example applications demonstrating RAG on various data sources:

  • document_rag.py: PDF/TXT/MD documents
  • email_rag.py: Apple Mail
  • browser_rag.py: Chrome browser history
  • wechat_rag.py, imessage_rag.py: Chat history
  • code_rag.py: Codebase search with AST-aware chunking
  • slack_rag.py, twitter_rag.py: MCP-based live data

Key Design Patterns

Incremental Update (IVF backend)

The IVF backend supports in-place updates and deletes without rebuilding the entire index:

  • add_vectors(index_path, embeddings, passage_ids): Append new vectors to an existing index.
  • remove_ids(index_path, passage_ids): Remove vectors by passage ID using FAISS DirectMap.Hashtable.
  • LeannBuilder.update_index(): High-level API that orchestrates remove-then-add for changed files, compacts passages.jsonl, and updates the offset map.

leann build is idempotent — re-running it on an existing index automatically performs an incremental update instead of a full rebuild. It detects new, modified, and removed files and applies the minimal set of changes:

  • IVF: Supports add, remove, and modify incrementally (remove old chunks then re-insert).
  • HNSW (non-compact): Supports add-only incremental updates; modified/removed files trigger a full rebuild.
  • Use --force / -f to force a full rebuild regardless.

Index Structure

A LEANN index consists of:

  • <name>.meta.json: Metadata (backend, embedding model, dimensions)
  • <name>.passages.jsonl: Raw text chunks with metadata
  • <name>.passages.idx: Offset map for fast passage lookup
  • <name>.index: Backend-specific vector index

Embedding Recomputation

The core storage optimization: instead of storing embeddings, LEANN stores a pruned graph and recomputes embeddings on-demand during search via ZMQ server communication.

CLI Usage

# Build index
leann build my-docs --docs ./documents/

# Search
leann search my-docs "query"

# Interactive chat
leann ask my-docs --interactive

# List indexes
leann list

# Remove index
leann remove my-docs

Common Development Tasks

Running example RAG applications:

# Document RAG (easiest to test)
python -m apps.document_rag --query "What is LEANN?"

# Code RAG
python -m apps.code_rag --repo-dir ./src --query "How does search work?"

Python Version

Requires Python 3.10+ (uses PEP 604 union syntax X | Y).

Agent Coding Guidelines

General

  • Voice input may contain typos — interpret intent, not literal text.
  • When you encounter a problem, fix it immediately and keep going until there are no more problems.
  • Do not ask about ordering or sequencing — figure it out. If something is unclear, note it and skip it; only escalate when all paths are blocked.
  • Obvious bugs: fix silently without reporting.
  • No fallbacks or compatibility shims. One correct implementation per feature — no redundancy.

Roadmap

  • Public roadmap: docs/roadmap.md — tracks P0/P1 priorities, completed milestones, and timeline.
  • Long-term vision: docs/ultimate_goal.md — the north star for where LEANN is headed.
  • Keep in sync with GitHub issue #237.
  • Welcome everyone to add more, and the craziest feature you want to put here! If people want some feature, all put there.

Changelog (for contributors)

  • Maintain docs/CHANGELOG.md — append-only log of major changes (new features, breaking changes, important fixes).
  • Format: ## YYYY-MM-DD: <short summary> followed by bullet points.
  • Update the changelog when merging significant PRs or completing notable work.
  • See docs/CONTRIBUTING.md for full contributor workflow (conventional commits, PR process, CI).

Personal Dev Notes (gitignored)

  • docs/dev/ is gitignored for personal development notes (TODO, progress, experiments).
  • Use docs/dev/TODO.md for in-progress tasks, docs/dev/PROGRESS.md for completed work.
  • These are private scratch space — but must follow the Self-Contained Principle below.

Documentation — Self-Contained Principle

All dev docs (PROGRESS.md, STATES.md, EXPERIMENTS.md, TODO.md) must be fully understandable from the document alone, with no reliance on conversation context or implied knowledge.

Requirements:

  1. Every technique/approach must be explained on first use. Not "switched to IVF backend" — write "switched to IVF backend (FAISS IndexIVFFlat + DirectMap.Hashtable, supports in-place add/remove without full index rebuild)."
  2. Never assume the reader knows any abbreviation. On first use: full name + one-sentence explanation. E.g., "HNSW (Hierarchical Navigable Small World — a graph-based ANN index used as LEANN's default backend)."
  3. Benchmark results must include full context. Not "recall improved to 0.95" — write "recall@10 improved from 0.91 to 0.95 after switching from flat chunking (512 tokens, no overlap) to AST-aware chunking (function-level splits with 64-token overlap)."
  4. Numbers must have reference points. Not "build time: 12s" — write "build time: 12s (vs. 45s before incremental update support, on 10k-document corpus)."
  5. Include the causal chain — not just conclusions. Not "duplicate chunks appeared after incremental build" — write "Duplicate chunks appeared after incremental build because passages.jsonl was appended without first removing stale entries for modified files. The IVF index had correct vectors (remove-then-add), but the passage store was append-only, causing the same text to appear at multiple offsets."
  6. docs/dev/STATES.md top section maintains a glossary of all key terms (backends, index files, chunking strategies, embedding models). Other docs reference it at the top.

Bad examples (forbidden):

  • "Fixed the chunking bug" → Which bug? What was the symptom? What was the root cause?
  • "Improved search quality" → By what metric? From what baseline? What change caused it?
  • "Used nprobe=32" → What is nprobe? Why 32? What was it before and what effect did the change have?

Doc Maintenance

  • Maintain docs/dev/PROGRESS.md — completed work only (with key script/log/config paths). No plans.
  • Maintain docs/dev/TODO.md — incomplete/in-progress/next-steps only (aim for one-command reproducibility). When done: remove from TODO, write result to PROGRESS, update STATES/EXPERIMENTS if needed.
  • Both files: append-only, chronological order (oldest first). Use tail -n 80 docs/dev/PROGRESS.md to read recent entries; increase range or grep by date/keyword if needed.
  • Keep TODO clean — either do items or remove them. Ask the user when unsure how to handle a TODO item.
  • Maintain docs/dev/STATES.md — tracks all currently useful state (index configs, backend choices, known limitations); does NOT grow indefinitely (delete stale entries).
  • Maintain docs/dev/EXPERIMENTS.md — benchmarks, A/B comparisons, parameter sweeps (recall@k, latency, storage size). Experimental content goes here, not in STATES.md.

Commits

Commit when: (1) a complete feature is finished and tested, or (2) a destructive change is unavoidable.

git add <specific files>
git commit -m “feat: ...” # follow conventional commits
  • When correcting errors: fix directly with no trace of the error.
  • If you write a correct new version of a file, delete the wrong version. No duplicate implementations.