loci 🧠
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
> Two thousand years ago, orators stored their speeches in the rooms of a
> palace and walked through them to remember. **loci does the same for your
> files.**
>
> *Loci* is the method behind every memory palace: place knowledge in
> locations, recall it by walking the path.
**A queryable "second brain" for the project docs, notes, and chat logs scattered
across a dozen directories — and an MCP server so your AI agents can use it too.**
Local files → heading-aware chunking → embeddings → hybrid retrieval (vector +
BM25) → LLM answer with section-level citations. The index lives entirely on
your machine; only embedding/chat calls go out, to any OpenAI-compatible API
(Zhipu / DeepSeek / Kimi / OpenAI / …).
> **The thesis** (from studying the 90k-star platforms and the graveyard of
> dead lightweight tools — see
> our competitive landscape study):
> don't build another chat app. Build the **memory layer that every chat app
> can mount**. Claude Desktop, Cursor, Cline, or any MCP host becomes this
> project's UI, for free.
Demo
Real session, indexed against the docs of
minimax-h3-turing
(paths shortened for display):
Hybrid retrieval means a Chinese query still finds the English doc (and vice
versa) — keyword evidence (BM25) catches what embeddings miss, and every
citation points at a **section**, not just a file.
Does hybrid actually help? (mini-eval, 10 bilingual queries)
Hybrid also fixed the #1 ranking on keyword-ish queries (e.g. "T8 block cache
threshold speedup": vector put an FAQ first, hybrid puts the actual T8
writeup first). Run it against your own corpus with your own cases file.
Reranking: two providers
--rerank reorders the fused candidates for precision:
| Provider | How | Cost |
|---|---|---|
| llm (default) | pointwise 0–3 relevance scoring by your chat model | one extra LLM call |
| local | cross-encoder, via pip install 'loci[rerank]' | ~30–70 ms for 5 pairs on GPU — offline, free |
The local model downloads on first use (~1.1 GB; set HF_ENDPOINT=https://hf-mirror.com
if HuggingFace is slow in your region). Measured on a 2080 Ti, bilingual query.
Office documents, PDF tables, web pages, org files, chat logs
- **PDFs**: with the [pdf] extra, PyMuPDF4LLM extracts pages as markdown —
**tables come through as pipe rows** (plain pypdf text is the fallback)
- **Word**: with the [docx] extra, .docx paragraphs and table rows are indexed
- **HTML**: .html / .htm pages become text with headings preserved (stdlib
html.parser, zero dependencies — honored, script/style skipped)
- **org-mode**: .org notes convert faithfully — #+TITLE becomes the h1 with
*-sections nested under it, #+FILETAGS become searchable tags
- **Chat exports**: drop a ChatGPT or Claude conversations.json into any
source directory — it becomes one searchable document per conversation,
tagged chatlog (search --tag chatlog scopes to chat history)
How it relates to Obsidian / your note app
It doesn't compete — the two layer up. Obsidian (or any editor) is the
note-taking frontend; this is the **cross-vault search engine**: point
sources at any directories (Obsidian vaults, project docs, chat exports)
and query all of them at once — from your terminal, your scripts, or your AI
agent via MCP. Obsidian-native details are understood: frontmatter tags:
(filter with search --tag), [[wikilinks]] (walk the graph with links),
code blocks are never cut mid-block, and one-line notes stay searchable.
How it works
The write path in one line: loaders → chunker (heading-aware split) → embedder → store (ChromaDB, persistent) — incremental, deduplicated by content hash.
Install & quick start
Requires Python 3.11+ (uses the stdlib tomllib).
Providers
[llm] and [embed] can point at different providers (chat via DeepSeek,
embeddings via OpenAI — mixing is fine). The only rule: the [embed] endpoint
must offer an OpenAI-style /embeddings API.