ESC
输入关键词搜索文章
目录

把个人笔记文件夹变成 Agent 可查询的 RAG:本地优先方案

把个人笔记变成 Agent 可查询的知识库

这份方案回答一个具体问题:如何把本地笔记文件夹变成 RAG,让 Hanako/OpenHanako agent 能可靠查询信息。

核心结论:不要只接一个向量数据库。推荐做 Hanako Plugin + Local RAG Core + Optional MCP Bridge。检索层默认使用全文检索/BM25 + 向量语义检索 + rerank + 相邻 chunk 扩展,并且所有结果必须带来源引用。

为什么不是“直接上向量库”?

个人笔记不是普通网页语料。它里面有大量精确信号:文件名、课程名、项目名、人名、日期、标签、org heading、roam links。纯向量检索擅长语义相似,但对专名、缩写、路径和精确关键词并不稳定。

Haystack 的 hybrid retrieval 教程明确说明:BM25 这类 keyword-based retrieval 在特定领域常常优于 dense retrieval,而混合检索能同时利用关键词和语义表示的优势。Qdrant 的 hybrid search 教程也采用 dense embeddings、sparse BM25 和 late interaction reranking 的组合。

所以个人笔记 RAG 的默认检索流应该是:

query
  → FTS/BM25 recall
  → vector semantic recall
  → Reciprocal Rank Fusion
  → reranker
  → neighbor chunk expansion
  → cited context pack

推荐总体架构

用户笔记目录,例如 ~/Org/roam、Obsidian vault、课程笔记
  ↓ parser + watcher
RAG Core Service / Library
  ├─ parser: org / md / txt / pdf / docx
  ├─ metadata: path / title / tags / heading / links / mtime / hash
  ├─ index: SQLite FTS5 + sqlite-vec 或 Qdrant/Chroma
  ├─ retrieval: FTS + vector + RRF + rerank + neighbor expansion
  ├─ policy: roots whitelist / deny globs / rag_exclude
  └─ API: local tool interface
       ├─ Hanako Plugin Tools
       └─ optional MCP Bridge

Hanako plugin 应该是主入口,因为它能承载设置页、目录授权、索引状态、PathGuard、工具权限和桌面 UI。MCP Bridge 适合做跨客户端兼容层,让 Claude、Cursor 或其他 MCP host 查询同一个本地知识库。

笔记应该如何解析

不要把所有文件粗暴切成固定长度。笔记的结构本身就是重要信号。

格式应提取的信息作用
Org-modetitle、ID、tags、properties、heading path、links、aliases保留 org-roam 语义和反链关系
Markdownfrontmatter、heading、wikilinks、tags、代码块适配 Obsidian/普通文档库
PDF/DOCX转 Markdown、标题、段落、表格、页码统一进入文本 chunk 管线
附件图片OCR 或 vision caption二期支持,不建议 MVP 先做

理想 chunk 是 heading/段落级,而不是固定字符窗口。每个 chunk 应保留前后邻居,避免 agent 拿到断裂上下文。

Agent 工具设计

Agent 不应该知道数据库细节,只调用稳定工具。

工具作用权限说明
kb_search_notesHybrid 搜索笔记 chunk只读返回 score、path、heading、摘要、chunk_id
kb_read_note读取完整笔记或 heading只读path 必须在白名单内
kb_get_neighbors读取 chunk 前后文只读解决 chunk 截断问题
kb_build_context构造带引用上下文包只读搜索、邻居、反链、去重后组合
kb_index_status查看索引状态只读返回 last_indexed、pending、errors
kb_request_reindex请求刷新索引需确认非只读,必须用户确认

MVP 不开放 write/delete/move。写笔记属于另一类高风险能力,必须有 diff 预览、备份和撤销。

技术路线对比

方案优势劣势适用条件
纯向量 RAG语义召回好,教程多专名和路径弱,调试难非结构化长文本语义问答
FTS/BM25 only轻量、可解释、精确词强抽象语义弱MVP、文件名/标题/术语查询
Hybrid + rerank质量上限高工程复杂,需要调参正式个人知识库 RAG
LlamaIndex文件夹读取和增量 API 成熟长期产品化可控性一般快速原型
HaystackPipeline 和 hybrid retrieval 清晰对小型本地库偏重实验和工程 pipeline
SQLite FTS5 + sqlite-vec单文件、本地、易嵌入需要自建 chunk/rerank/中文分词Hanako 内置 RAG Core
QdrantHybrid、多向量、过滤强需要独立服务或部署大规模和复杂检索
现成 MCP RAG最快接入 MCP host权限/UI/工具面不一定适合 HanakoPoC 或参考实现

安全与权限

个人知识库是高隐私资产,权限设计必须前置。

  • 用户必须显式选择 roots。
  • 所有 path 入参 canonicalize,解析 symlink 后仍必须在 roots 内。
  • 默认 deny:.gitnode_modules.envprivate财务diary 等。
  • 支持 org property 或 frontmatter 排除:RAG_EXCLUDE: t / rag: false
  • 搜索结果不能泄露被排除笔记的标题。
  • 日志不记录完整 query 和正文,调试日志可一键清除。
  • 云 embedding 必须明确提示笔记内容会发送给第三方,默认使用本地 embedding。

MCP roots 规范明确 roots 是服务器可访问的文件系统边界,并要求防 path traversal 和访问控制。MCP 安全文档也强调 scope minimization。

MVP 路线

第 0 周:离线分析

扫描目标笔记目录,统计格式、数量、总字数、最大文件、org/markdown 比例。做 parser spike:org heading、tags、links、property drawers。

第 1 阶段:只读本地搜索

建立 SQLite documents/chunks/FTS5,实现 kb_search_noteskb_read_note。先不用向量,验证 agent 查询体验。

第 2 阶段:语义检索

加入 sqlite-vec 或 Chroma/Qdrant,增加 embedding cache、RRF hybrid fusion 和 kb_get_neighbors

第 3 阶段:上下文构建

加入 reranker 和 kb_build_context,返回文件路径、标题、heading、chunk_id、修改时间等引用。

第 4 阶段:Hanako 插件化

设置页选择知识库目录和 deny globs,注册 agent tools,展示索引状态 widget,最后增加 MCP bridge。

补充:Hanako 插件落地接口

进一步读取 OpenHanako PLUGINS.md 后,可以把落地方案从“架构建议”推进到“插件开发入口”。OpenHanako 插件可以贡献 tools/skills/commands/routes/、生命周期 index.js、配置 schema、page/widget,并分为 restricted 与 full-access 两级权限。

推荐插件形态

  1. 第一阶段:Tool-only restricted 插件,只暴露只读工具,降低权限面。
  2. 第二阶段:Full-access runtime 插件,加入后台 watcher、HTTP route、状态 widget 和动态工具注册。
notes-rag-plugin/
├── manifest.json
├── tools/
│   ├── search_notes.js
│   ├── read_note.js
│   ├── get_neighbors.js
│   ├── build_context.js
│   └── index_status.js
├── routes/          # 二期 full-access
│   └── status.js
├── index.js         # 二期 full-access: watcher / background indexer
└── skills/
    └── notes-rag/
        └── SKILL.md

工具接口草案

最核心的工具是 search_notes。它应该接收自然语言 query、top_k 和 metadata filters,返回结构化结果,而不是只返回一段文本。

{
  "query": "...",
  "results": [
    {
      "chunk_id": "...",
      "doc_id": "...",
      "title": "...",
      "path": "...",
      "heading": "...",
      "score": 0.87,
      "snippet": "...",
      "mtime": "2026-05-18T00:00:00+08:00"
    }
  ]
}

配置 schema

插件配置应至少包含 rootsdenyGlobsembeddingProvider。roots 决定授权目录,denyGlobs 负责敏感路径排除,embeddingProvider 默认 local,避免默认把笔记发给第三方。

开发循环

OpenHanako 文档建议 Agent 开发插件时走 dev loop:源码放在工作区或 ${HANA_HOME}/plugin-dev-sources/,再通过 plugin_dev_installplugin_dev_reloadplugin_dev_invoke_toolplugin_dev_diagnostics 做安装、热重载、smoke test 和诊断。这让 Notes RAG 插件可以先从只读 search_notes 做起,再逐步加入 indexer、status 和 widget。

最终建议

推荐方案:先做 Hanako 原生只读 RAG 插件,底层使用 SQLite FTS5 + sqlite-vec 的轻量本地 RAG Core;后续再加 Qdrant 选项和 MCP Bridge。

  1. 先选一个目标目录,例如 ~/Org/roam
  2. 写只读 scanner,输出文件统计和解析成功率。
  3. 先用 SQLite FTS5 做可查版本。
  4. 再加 embedding 和 reranker。
  5. 所有答案必须带引用:文件路径、heading、chunk_id、mtime。