Local retrieval over your own notes - 2026本地笔记检索 · 桌面 + MCP · 2026

Personal RAG个人知识库 RAG

Ask your own notes a question and get the paragraph back - entirely on your machine, with a refusal when the answer is not there.对自己的笔记提问,拿回原文段落——全程在本机,找不到证据时会明确说找不到。

Status状态
Personal use自己在用
Year年份
20262026
Role角色
Solo: architecture, engine, eval, desktop shell, MCP独立完成:架构、引擎、评测、桌面壳、MCP
Form形态
Tauri desktop app + MCP serverTauri 桌面应用 + MCP 服务
Stack技术
Rust, Tauri 2, SQLite, LanceDB, Tantivy, fastembedRust · Tauri 2 · SQLite · LanceDB · Tantivy · fastembed
Ask your own notes a question and get the paragraph back - entirely on your machine, with a refusal when the answer is not there.
Cover封面Personal RAG - Local retrieval over your own notes个人知识库 RAG - 本地笔记检索 · 桌面 + MCP
  • Hybrid retrieval: vector Top 40 + BM25 Top 40, fused by RRF, then six paragraphs to the model混合检索:向量 Top 40 + BM25 Top 40,RRF 融合后只给模型六段原文
  • 37 labelled questions: the known source was retrieved for 18 of 19 answerable ones; all 14 unanswerable ones were refused37 道标注题:19 道有答案的里 18 道召回到已知原文;14 道没有答案的全部拒答
  • 20,000 chunks at 512 dims: P95 81 ms per query including the query embedding, 60 runs2 万切片 × 512 维:含查询向量化,P95 81 ms(60 次实测)
  • SQLite is the truth; the vector and keyword indexes are derived and can be deleted and rebuiltSQLite 是唯一真相,向量与关键词索引是派生的,可以删掉重建
  • MCP over stdio: eight tools in three permission tiers, content writes off by default and auditedMCP 走 stdio:八个工具分三档权限,内容写默认关闭并留审计

My notes are where I think. Searching them is keyword matching: either you remember the word, or you do not find it. But the question I actually have is not a keyword - it is what did I conclude about this three months ago, and why.我的思考都写在笔记里。可检索它们的方式是关键词匹配:要么你记得那个词,要么就找不到。而我真正想问的不是一个词,是「三个月前我对这件事的结论是什么,为什么」。

Local is the constraint, not a feature本地不是卖点,是前提

The vault is the source of truth and it never leaves the machine. Extraction, chunking and the query embedding all run in-process through fastembed and a 91 MB ONNX model; retrieval needs no API key at all. A language model is optional - without one the app answers with the retrieved paragraphs and says so.仓库是唯一真相,而且不离开这台机器。抽取、切片、查询向量化全部走进程内的 fastembed 与一个 91 MB 的 ONNX 模型;检索根本不需要 API Key。大模型是可选项——不接,它就直接把召回的原文摆出来,并且明确告诉你现在是纯检索。

Retrieval that is allowed to say no允许说「没有」的检索

The interesting number is not how many answers it finds, it is how often it refuses. Recall-K and Final-K are separate settings, and a relevance floor decides whether enough evidence survived to answer at all - no_evidence is a formal state, not an empty list. The evaluation set reflects that: of 37 labelled questions, 14 have no answer in the vault, and all 14 were refused. Of the 19 answerable ones, 18 retrieved the note that was known to contain the answer.有意思的数字不是它答对了多少,而是它拒绝了多少。Recall-K 与 Final-K 是两个独立参数,相关性地板决定「留下来的证据够不够答」——no_evidence 是一个正式状态,不是一个空列表。评测集就是按这个设计的:37 道标注题里有 14 道在笔记里根本没有答案,这 14 道全部拒答;19 道有答案的题里,18 道召回到了已知包含答案的那一篇。

First run - the vault path is the only required input
Fig. 01First run - the vault path is the only required input首次启动——唯一必填的是仓库路径

The index is disposable索引是可丢弃的

SQLite holds the index truth; LanceDB and Tantivy are derived and are expected to be deleted and rebuilt. That decision made the indexing pipeline boring, which is what it should be - the same vault rebuilt twice produces the same result. On a 20,000-chunk test set, a full delete-and-rebuild took 26 seconds in a debug build and 863 ms in release, which is why every number above is measured in release.SQLite 存索引真相,LanceDB 与 Tantivy 都是派生物,删掉重建是预期行为。这个决定让索引流程变得无聊——而这正是它该有的样子:同一个仓库重建两次,结果必须一样。在 2 万切片的测试集上,全删重建 debug 构建要 26 秒,release 只要 863 毫秒,所以上面所有数字都按 release 口径测。

An agent can read the vault让 agent 读这座仓库

personal-rag mcp speaks JSON-RPC over stdio - no port, no password, nothing exposed to the network. There are eight tools in three tiers: four read-only, two that update the index, two that write content. The write tier is off by default, writes only into an _inbox_mcp folder, never overwrites an existing note, and appends every write to an audit log with the path, byte count and sha256. A disabled tier does not appear in the agent's tool list at all - the agent does not see a door it cannot open.personal-rag mcp 走 stdio 的 JSON-RPC——不开端口、不要密码,什么都不暴露到网络上。八个工具分三档:四个只读、两个只更新索引、两个写内容。写这一档默认关闭,只写进 _inbox_mcp 目录,绝不覆盖已有笔记,而且每次写入都追加一条审计日志,记下路径、字节数与 sha256。关闭的档位根本不会出现在 agent 的工具清单里——它看不到一扇打不开的门。

  • Read-only: search_kb, ask_kb, read_doc, list_scope只读:search_kb、ask_kb、read_doc、list_scope
  • Index writes: ingest_now, index_status索引写:ingest_now、index_status
  • Content writes (off by default): remember, append_note内容写(默认关):remember、append_note
  • The engine locks the index directory, so the desktop app and the MCP server never run together引擎对索引目录加排他锁,所以桌面程序与 MCP 服务不会同时运行
  • 37 notes / 432 chunks took 45 s for a first full index; after that it is incremental37 篇 / 432 个切片首次全量索引 45 秒,之后都是增量
A retrieval system that cannot refuse is just a confident liar.不会拒绝的检索系统,只是一个自信的骗子。Design note设计笔记