Files
mnote/design/07-ai/done/7-50-lightrag-knowledge-rag-provider-v1.md
T

760 lines
57 KiB
Markdown
Raw Normal View History

# 7-50 [done] LightRAG Knowledge RAG Provider v1
> 创建时间:2026-06-06
>
> 当前状态:`DONE`
>
> 2026-07-03 口径回正:当前 runtime 已回到 OpenHub / native agent + LightRAG + Turso/libSQL。本文重新作为当前默认知识库 provider 的完成基线;历史非 LightRAG 默认 provider 口径已标记 stale,仅保留为历史设计或参考边界。
2026-06-26 20:01:02 +08:00
>
> Owner07-ai / knowledge-rag / plugin-ui / external-provider
>
> 取代:`design/old/07-ai/process/7-49-local-understanding-graphrag-kernel-v1.md`
>
> 参考代码:
> - `reference-code/LightRAG`
>
> 本机源码部署:
> - source`/mnt/Data1T/Mnote_data/lightrag/LightRAG`
> - storage`/mnt/Data1T/Mnote_data/lightrag/rag_storage`
> - input spike`/mnt/Data1T/Mnote_data/lightrag/inputs`
> - systemd user service`mnote-lightrag.service`
> - WebUI`http://127.0.0.1:9621`
> - current model`aigc/qwen-3.5`
>
> 上位依据:
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`
> - `/mnt/Data1T/mnote/CURRENT_ARCHITECTURE.md`
> - `design/07-ai/process/7-46-document-evidence-retrieval-kernel-v1.md`
> - `design/07-ai/process/7-48-paperless-ngx-reference-resource-ingestion-job-index-v1.md`
> - `design/03-rust-web/done/3-25-local-folder-mineru-ocr-sidecar-v1.md`
## 1. 第一结论
MNote 后续知识库问答主线改为 **LightRAG 单外挂 Provider**,不继续推进 7-49 的自研 Understanding GraphRAG Kernel / mindmap projection 路线。
目标是减少冗余项目和冲突:
- LightRAG 负责知识库问答相关的 OCR、文档解析调度、MinerU / Docling 接入、sidecar、chunk、向量、图谱、rerank 和跨文档问答。
- MNote 负责 workspace 权限、source truth、resource ownership、引用 UI、agent 授权、任务入口和 LightRAG 结果打开方式。
- LiteParse / MNote 旧解析定位链路退役;旧 OCR / evidence / 本地资料索引入口不再作为默认 fallbackPDF / Office / 图片 OCR 与资料库索引统一交给 LightRAG。
- PageIndex 暂停,不作为当前默认双引擎;未来只在少量书籍确实需要章节树精读时再做定向树索引。
- 插件系统暂不开发完整市场式框架;第一版只做一个薄的 `KnowledgeRagProvider` / `LightRAGAdapter`,让 LightRAG 像插件一样不干扰 MNote 正常功能。
## 2. 为什么放弃 7-49
7-49 的核心假设是 MNote 自己构建本地 Understanding GraphRAG Kernel。这个方向问题不在能力,而在冗余:
- LightRAG 已经覆盖 graph + vector + rerank + parser pipeline 的主体能力。
- 自研 understanding graph 会和 LightRAG 图谱、evidence SQLite、mindmap projection 形成三套相似真相。
- mindmap projection 不能覆盖 NotebookLM 式多书问答的核心体验,反而会牵引 UI 和数据模型提前复杂化。
- 用户当前需求是“很多本书 / 很多篇文献作为资源,agent 能查阅、问答、溯源”,优先级高于自研图谱可视化。
因此 7-49 退役,只保留为历史参考,不再作为 process 设计稿。
## 3. LightRAG 能覆盖的边界
本轮已按最新 LightRAG 代码重新建索引确认:
- LightRAG v1.5 已合并 RagAnything 路线,支持 MinerU / Docling 多模态解析。
- 支持 `legacy` / `native` / `mineru` / `docling` 解析引擎。
- 支持 Fix / Recursive / Vector / Paragraph 四种切分。
- MinerU 支持 `official` / `local` 两种模式;MNote 已有 MinerU token,可先走 official spike。
- sidecar 包含 `blocks.jsonl``drawings.json``tables.json``equations.json`、assets。
- block positions 支持 `bbox`,可表达 page + rectangle。
- chunk 可以通过 `sidecar.refs` 追溯到 block/table/drawing/equation。
关键限制:
- LightRAG 没有集成 LiteParse 本身。
- LightRAG OCR 能力来自 MinerU / Docling 服务,不是内置 OCR 模型。
- LightRAG `/query` 默认引用粒度偏粗,通常是 `reference_id + file_path + chunk content`MNote 需要额外 adapter 反查 sidecar,生成现有 EvidenceLocator。
结论:LightRAG 可以成为主解析/RAG provider,但不能直接替代 MNote 的权限、locator 和引用 UI。
## 4. 新架构边界
本设计的核心边界是:**LightRAG 是独立本地知识库底座服务,MNote 是 UI + source manager + permission layer**。
这不是把 LightRAG 深度嵌入 MNote,也不是让 MNote 复制 LightRAG 内部索引。LightRAG 可以直接对 MNote 暴露的本地文件夹做 RAG / OCR;MNote 只提供允许访问的目录、用户操作入口、任务控制、结果展示和引用打开。
```text
用户资料库
PDF / EPUB / DOCX / PPTX / Markdown / 图片
|
v
MNote LightRAG Connector
- allowed roots
- workspaceId / rootUri
- source file identity
- task control UI
- reference open action
|
v
LightRAG Service / Dashboard
- MinerU / Docling parser
- sidecar
- chunk / vector / graph / rerank
- query / query_data
- task state
|
v
MNote Answer Renderer
- answer
- citations
- LightRAG reference
- MNote open action
- locator fallback
```
MNote 不复制 LightRAG 的图谱,不把 LightRAG 的 chunk 当正文真相。LightRAG 是派生知识库;原始文件仍属于 MNote local-folder / resource tree。
### 4.1 OCR / 索引归属
知识库问答相关的 OCR、parse、chunk、vector、graph、rerank、query index 全部归 LightRAG。
MNote 不再为“问一堆书 / 问一堆论文”维护第二套 OCR / parse / chunk / vector / graph。此前 MNote 为 OCR、索引、source-map、evidence graph 维护过多套派生链路,已经制造了过多 bug 和职责冲突;7-50 的目标就是把这部分降为一个外部 provider。
MNote 可以保留轻量 UI 索引,但它只服务 MNote 正常功能:
- 页面标题、Markdown 正文快速搜索。
- tag / backlink / 最近页面。
- 文件树和资源元数据。
- 当前编辑器内搜索。
区分标准:
| 场景 | Owner |
| --- | --- |
| 搜我的笔记页面、标签、最近编辑、backlink | MNote 轻索引 |
| 问多本书 / 多篇论文 / PDF / 扫描件 / Office 附件 | LightRAG |
| 解析 PDF / OCR 图片 / 建向量 / 建图谱 / rerank | LightRAG |
| 点击来源、打开 MNote resource tab、显示降级来源 | MNote connector |
### 4.2 插件式不干扰原则
LightRAG 第一阶段必须像无害插件:
- 不修改用户 Markdown 正文。
- 不写 MNote 文件树中的业务文件。
- 不接管 MNote 普通搜索。
- 不让 MNote UI 依赖 LightRAG 才能打开页面。
- 不在 MNote active code 中复制 LightRAG pipeline。
- 不把 LightRAG parser/cache/index 失败扩散为 MNote 文件树或编辑器故障。
MNote 和 LightRAG 的连接面应尽量小:
- 配置 LightRAG endpoint / working dir / token 注入方式。
- 给 LightRAG 一组 allowed roots 或 source list。
- 触发 ingest / reindex / delete source。
- 查询 LightRAG result。
- 把 LightRAG reference 映射为 MNote open action。
- 在 MNote 中嵌入或打开 LightRAG dashboard,用于任务控制和 graph 查看。
### 4.3 Source Truth / 删除语义
7-50 的基线不采用“上传一份副本到 LightRAG staging 目录再索引”的默认模式。这个模式会制造两个问题:
- 反复真相:MNote 本地文件是一份,LightRAG input/staging 又是一份,用户编辑、移动、删除后两边容易不一致。
- 删除源后仍可检索:LightRAG 索引是派生缓存,如果没有收到 source delete / stale 标记,旧 chunk / vector / graph 仍可能继续回答。
因此 7-50 的 source truth 规则是:
- 原始资料真相永远是 MNote local-folder / resource tree 中的 host absolute path。
- LightRAG 的 storage、sidecar、chunk、vector、graph 都是派生缓存。
- MNote 默认不把用户资料复制到 LightRAG input 目录;除非 LightRAG API 当前阶段只能 upload,才允许使用临时受控 staging,并且必须记录为 spike 降级方案。
- LightRAG connector 必须维护 source registry
- `workspaceId`
- `rootUri`
- `sourcePath`
- `sourceHash`
- `lightRagDocId`
- `indexedAt`
- `deletedAt`
- `stale`
- source 文件删除、移动、重命名或 hash 变化后,MNote watcher 必须把 registry 标记为 stale,并触发 LightRAG delete / reindex。
- 删除 source 后,query scope 必须过滤 stale / deleted source;如果 LightRAG 侧删除尚未完成,MNote 层不得把该 source 的 citation 当成有效来源展示。
- LightRAG 官方 `DELETE /documents/delete_document` 能删除文档状态、chunks、vector、graph`delete_file=true` 还会删除 input 目录文件。MNote 集成默认只删除 LightRAG 派生索引,不删除用户原始文件。
- 改 parser、embedding dim、storage backend、source parser hint 等影响索引一致性的配置时,必须走“delete old doc -> reindex source”,不能隐式覆盖旧索引。
这个边界决定部署方式:Docker 可以用于隔离 demo,但不作为 7-50 与 MNote connector 的基线。7-50 基线采用源码 / host 部署,保证 LightRAG 能看到 MNote 的真实本地路径、watcher 能做删除同步,MNote adapter 也能以同一套路径身份做引用打开。
### 4.4 Source Truth Spike 结果
2026-06-06 已完成一个受控 source-truth spike
- MNote source 文件:`/mnt/Data1T/Mnote_data/lightrag/source-spike/mnote-source-truth-spike.txt`
- LightRAG input 入口:`/mnt/Data1T/Mnote_data/lightrag/inputs/mnote-source-truth-spike.txt`,以 symlink 指向 source 文件。
- 触发方式:`POST /documents/scan`
- LightRAG doc id`doc-0092d6976b80946591c9d129e92d989a`
- 处理结果:`processed``chunks_count=1``parse_engine=legacy``file_path=mnote-source-truth-spike.txt`
- `query` 能回答 `CARBOXY_PROTECTOR_ALPHA_7349`,并返回 reference。
- `query/data` 能返回 entities / relationships / chunks / references,其中 chunk 带 `chunk_id``file_path`
- `DELETE /documents/delete_document` + `delete_file=false` 删除后,documents 为空,`query/data` 返回 `no_results``query` 返回 no-context 且 references 为空。
- 删除 LightRAG 派生索引没有删除 MNote source 文件;symlink 被 LightRAG scan 移入 `inputs/__parsed__/`
结论:
- symlink scan 可以避免复制 source 内容,但 LightRAG 内部 `file_path` 只保留 basename,不保留 host absolute path。
- 因此 MNote connector 仍必须维护 source registry,把 `workspaceId/rootUri/sourcePath/sourceHash/lightRagDocId/indexedAt/deletedAt/stale` 映射到 LightRAG doc id 和 basename。
- `delete_file=false` 是 MNote 删除 LightRAG 派生索引的默认语义;不能让 LightRAG 删除用户 source。
- source delete / move / rename 的自动触发仍需要 MNote watcher + registry,不能仅依赖 LightRAG scan。
### 4.5 Ingestion Path Spike 结果
2026-06-06 继续补测 SDK / REST upload / input scan / symlink scan 四种入口:
| 入口 | 测试方式 | 结果 | 对 MNote connector 的判断 |
| --- | --- | --- | --- |
| SDK `ainsert` | 独立临时 storage 调用 `LightRAG.ainsert(..., file_paths=/mnt/.../source.txt)` | `processed`chunk token 命中;source 文件未被删除;`file_path` 仍被规整成 basename | 可作为 adapter 内部能力,但不能依赖 LightRAG 保存 host absolute path;仍要 registry |
| REST `/documents/text` | 调用 text API`file_source` 传 host absolute path | `processed``process_options=F``file_path` 被规整成 basename | 适合纯文本 / Markdown 内容直入,但无法表达真实附件生命周期 |
| REST `/documents/upload` | multipart 上传一个文本文件 | `processed`,文件被放入 `inputs/__parsed__/``file_path` 为上传文件名 | 只适合作 fallback / UI 手动上传,不适合作 MNote 默认 source truth |
| `input_dir` real file + `/documents/scan` | 写入真实 input 文件后触发 scan | `processed`scan 会把 input 文件移入 `__parsed__` | 可用于受控 staging,但会制造第二份 source,不作为默认 |
| symlink + `/documents/scan` | `inputs/*.txt` symlink 指向 MNote source 文件 | `processed`symlink 被移入 `inputs/__parsed__/`,原始 source 保留;`file_path` 为 symlink basename | 当前最接近 MNote source-truth 基线;必须由 registry 管理 symlink basename 到 host source |
额外观察:
- `/documents/scan` 在 pipeline busy 时会返回 `scanning_skipped_pipeline_busy`,不会排队;MNote connector 必须做 job ledger / retry,而不能把一次 scan 失败视作 ingestion 完成。
- SDK、text API、upload、scan 都不会保留 host absolute path 到 LightRAG `file_path`LightRAG 引用只能作为 provider-local referenceMNote 侧必须用 `source registry` 反查。
- 本轮临时 server storage 中产生的四个测试 doc 已用 `DELETE /documents/delete_document` + `delete_file=false` 删除;独立 SDK storage 留在 `/tmp/mnote-lightrag-sdk-*` 作为一次性验证产物。
### 4.6 MNote Connector First Cut
2026-06-06 已落第一版 MNote connector,不引入完整插件市场:
- 新增 `rust/crates/mnote-web/src/routes/knowledge_rag.rs`
- 新增 routes
- `GET /api/knowledge-rag/status`
- `POST /api/knowledge-rag/ingest`
- `POST /api/knowledge-rag/query`
- `POST /api/knowledge-rag/open-reference`
- `POST /api/knowledge-rag/delete-source`
- 新增 source registry`.mnote/index/lightrag-source-registry.json`
- `ingest` 默认创建 `input_dir` symlink 后触发 `/documents/scan`,不复制用户 source 内容。
- `delete-source` 调用 LightRAG `DELETE /documents/delete_document` 时固定 `delete_file=false`,只删除派生索引,不删除用户 source。
- `query` 只把 LightRAG raw result 作为 provider 结果返回;MNote 额外生成 `references`,用 registry 把 LightRAG `file_path` 映射回 MNote source。
- `open-reference` 未命中 registry 或 source 已 stale/deleted 时返回 `locatorDegraded=true`,不伪造 page / bbox。
- Hermes/Page AI manifest 新增:
- `mnote.knowledge_rag.status`
- `mnote.knowledge_rag.query`
- `mnote.knowledge_rag.open_reference`
- 新增 skill`skills/mnote-knowledge-rag/SKILL.md`
- Reasonix ACP wrapper 新增对应工具:`mnote_knowledge_rag_status` / `mnote_knowledge_rag_query` / `mnote_knowledge_rag_open_reference`
- Route smoke 已通过:
- `GET /api/knowledge-rag/status` 返回 LightRAG `healthy` / `webui_available=true`
- `POST /api/knowledge-rag/ingest``knowledge-rag-route-probe.md` 创建 symlink 并触发 `scanning_started`
- registry 同步到 `lightRagDocId=doc-0b7eabd99e33100ed94fc929143bb632``indexedAtMs` 有值。
- `POST /api/knowledge-rag/query` 返回 1 条 registry 命中的 reference`locatorDegraded=false`
- `POST /api/knowledge-rag/delete-source` 返回 `deletion_started`registry 标记 `stale=true/deletedAtMs`,原始 source 文件仍存在。
- Hermes manifest 带 `mnote-knowledge-rag` capability pack 和三项 `mnote.knowledge_rag.*` tool。
2026-06-06 运行态复核发现:3000 dev runtime 继承了历史 `LIGHTRAG_API_KEY` 环境变量,导致 MNote connector 优先使用旧 key,请求当前 `mnote-lightrag.service` 返回 `403 Invalid API Key`。已修正 `lightrag_api_key()` 优先级为 `MNOTE_LIGHTRAG_API_KEY` -> LightRAG source `.env` -> 通用 `LIGHTRAG_API_KEY` 兜底,避免旧 LightRAG 环境污染 MNote connector。临时 3027 server 带 `LIGHTRAG_API_KEY=bad-legacy-key` 复测,status / query 均可通过 source `.env` 正确访问当前 LightRAG。
### 4.7 PDF / MinerU Sidecar 验证结果
2026-06-06 已用 `mnote-e2e` local workspace 通过 MNote connector 跑 1 本书籍 PDF、2 篇论文 PDF、1 个扫描 PDF:
| 样本 | MNote source | LightRAG doc | 结果 | 观察 |
| --- | --- | --- | --- | --- |
| 书籍 PDF | `knowledge-rag-fixtures-7-50/book-q1-fy25-earnings.pdf` | `doc-32765c52c02777e6c8f8bc452ac0157e` | `processed` | MinerU`chunks_count=38``mm_chunks=25` |
| 论文 PDF | `knowledge-rag-fixtures-7-50/paper-brotli-comparison.pdf` | `doc-06f4c43d18a0398beeb0f31e91b81466` | `processed` | MinerU`chunks_count=6``mm_chunks=3` |
| 论文 PDF | `knowledge-rag-fixtures-7-50/paper-masterformat-partial.pdf` | `doc-633d81d17d26727bf600f54a7591657b` | `processed` | MinerU`chunks_count=1` |
| 扫描 / 图片 PDF | `knowledge-rag-fixtures-7-50/scan-image-start.pdf` | `doc-14a5926e5c673f446d2be735259c622f` | `processed` | MinerU`chunks_count=1` |
补充观察:
- PDF 不应强制 `parserHint=native`LightRAG 当前 native hint 不支持 PDF,之前强制 native 的 PDF 已验证会失败。
- 对同内容扫描 PDF 再入库时,LightRAG 会标记 duplicate,并通过 `metadata.original_doc_id` 指向原始 docMNote registry 当前只把 processed doc 当成可索引完成,duplicate failed 不应作为有效 citation。
- Sidecar 样本实际落在 `/mnt/Data1T/Mnote_data/lightrag/inputs/__parsed__/*.{pdf}.parsed/*.blocks.jsonl` 与对应 `*.mineru_raw/`,不提交原文 fixture。
- `blocks.jsonl` 的 content block 已包含 `positions: [{ type: "bbox", anchor: "1", range: [...] }]`,其中 `anchor` 可作为页码来源,`range` 可转为 bbox。
- LightRAG `kv_store_text_chunks.json``/query/data` chunks 当前没有 `refs` 字段;chunk 只能拿到 `chunk_id``file_path``reference_id``content`。因此 MNote 先把 query reference enrich 出 `chunkId` / `quote`,再用 `file_path -> parsed sidecar -> blocks.jsonl -> positions` 反查 page/bbox。
- 已新增第一版 `LightRAGSidecarLocator`:用 chunk content / chunk id fallback 匹配 sidecar block,生成 MNote `EvidenceLocator`;匹配失败时继续显示 locator degraded,不伪造页码。
当前已能把一部分 LightRAG PDF 引用升级成真正的 PDF page/bbox EvidenceLocator,但仍不是无损映射:因为 LightRAG chunk 缺少 `refs`MNote 当前依赖 chunk quote 与 sidecar block 文本近似匹配。后续如果 LightRAG 暴露 chunk refs,应改为 refs 优先、文本匹配 fallback。
### 4.8 运行态复核结果
2026-06-06 运行态复核:
- `mnote-lightrag.service` 为 systemd user service,当前 active running;入口为 `/mnt/Data1T/Mnote_data/lightrag/LightRAG/.venv/bin/lightrag-server`,配置来自 `/mnt/Data1T/Mnote_data/lightrag/LightRAG/.env`
- `GET /api/knowledge-rag/status` 返回 LightRAG `healthy``webui_available=true``dashboardUrl=http://127.0.0.1:9621`
- `GET http://127.0.0.1:9621/` 跳转 `/webui/``GET /webui/` 返回 200;但尚未做完整浏览器交互验证 dashboard 的 documents / graph / task 面板。
- `scripts/task529-knowledge-rag-citation-resource-tab-smoke.js` 已通过:`POST /api/knowledge-rag/query` 能召回 `knowledge-rag-fixtures-7-50/scan-image-start.pdf`citationUrl 打开本地 PDF resource tab,带 `page=1` / `bbox=171,126,648,152`,页面内 evidence 高亮渲染。
- `POST /api/hermes/tools/mnote/call` 调用 `mnote.knowledge_rag.query` 已通过,工具层能返回 references 与 `citationMarkdown`;这验证的是 agent tool 检索通道,不等于 Page AI 真实最终回答质量已验收。
- 召回已经可用,但排序还未验收:`scan image start` 查询能召回目标扫描 PDF,不过 top-1 可能是其他 PDF,后续需要专门评估 query mode / rerank / source scope。
- MNote topbar 已新增独立“资料库问答”设置入口,不混入本地索引设置;该面板能读取 `/api/knowledge-rag/status`,展示 LightRAG healthy 状态、dashboard/input/storage、source registry,并提供相对路径 source 输入、ingest、刷新、打开 dashboard 动作。浏览器 smoke 已验证面板在 3000 打开后显示 `LightRAG healthy,已登记 5 个来源`
- `/api/knowledge-rag/ingest` 已支持 sourcePath 指向文件或目录;目录会在授权 root 内递归展开受支持文件,跳过 `.mnote` / `.git` / `node_modules` / `target` / `__parsed__` / `.venv`,并限制单次最多 200 个文件,避免误把整个工作区无限制灌入 LightRAG。对应单元测试已覆盖目录展开、内部目录跳过和不支持扩展名拒绝。
- 资料库问答设置面板已支持从当前 filetree 选中项填入 sourcePath,并在 ingest 输入行展示 `待索引` / `索引中` / `已提交` / `需重试` / `失败` 状态。浏览器 smoke 已验证选中 `knowledge-rag-fixtures-7-50` 后点击“使用选中文件树项”能把该目录写入 source 输入框。
- 运行态继续发现 `3000` dev runtime 继承了旧 Windows `INPUT_DIR=F:/SOFT/MNOTE/LightRAG/inputs` / `WORKING_DIR=F:/SOFT/MNOTE/LightRAG/data`,导致 sidecar locator 在当前 Linux LightRAG storage 中查不到 `blocks.jsonl``task529` 一度降级。已修正 connector 路径优先级为 `MNOTE_LIGHTRAG_*` -> LightRAG source `.env` -> 通用 legacy env -> 默认值,并补 `lightrag_paths_prefer_source_env_over_legacy_process_env` 单测。
- `task529-knowledge-rag-citation-resource-tab-smoke.js` 复跑通过:`scan image start` 当前 top reference 为 `knowledge-rag-fixtures-7-50/scan-image-start.pdf``citationMarkdown=[scan-image-start.pdf · p.1](...)``citationUrl``resourceTab/page=1/bbox=171,126,648,152/blockId=f69c1af99063b608b4031a3c51864265`,浏览器资源标签页能渲染 PDF 和 evidence 高亮。
- Agent 工具输出已改为 `mnote.knowledge_rag.agent_query_result.v1` 紧凑结构,优先给 `references/citations/citationMarkdown/locator`,不再把 LightRAG raw chunks 放在工具输出前面,避免 Page AI 最终回答看不到 citation 或把 raw retrieval 当回答。
- `hybrid` mode 已在 MNote connector 中别名到 `mix`,避免 agent 复用本地 evidence search 的 `hybrid` 习惯时召回偏离;同时对 mapped references 做 query lexical rerank,让明确文件名 / 关键词的命中优先出现在 references 前列。`query_ranking_prefers_exact_source_and_quote_match``query_mode_aliases_hybrid_to_mix_for_lightrag` 已覆盖。
- 新增 `scripts/task530-knowledge-rag-page-ai-final-answer-smoke.js`,真实浏览器打开 Page AI drawer,切到 Reasonix,发送资料库问题并验证最终可见回答包含 `scan-image-start.pdf · p.1` 的可点击 resourceTab citation,且不泄漏 raw JSON / 工具名 / 检索过程叙述。该 smoke 已通过。
- 新增 `scripts/task531-lightrag-dashboard-ui-smoke.js`,从 MNote `/api/knowledge-rag/status` 读取 `dashboardUrl` 后打开 LightRAG WebUI,真实浏览器验证 Documents / Knowledge Graph / Retrieval 三个入口可见:Documents 显示 `Completed (5)` / `Fail (4)` / 扫描 PDF doc id 与 summaryGraph 显示 `Connected`Retrieval 显示 `Query Mode` / `KG Top K` / `Connected`。截图落在 `tmp/task531-lightrag-dashboard-ui-smoke/`
### 4.9 旧搜索 / Evidence 退役结果
LightRAG 引入后,旧搜索链路先完成回归确认,随后按最新产品决策退役 LiteParse / evidence fallback。当前分工是:
- `/api/evidence/search` 已返回 `410 Gone` / `mnote_evidence_search_retired`,不再作为 agent fallback。
- `mnote.evidence.search/read/open``mnote.index.status/refresh/update_settings` 不再暴露在 Hermes / Reasonix manifest 与 capability pack 中。
- `/api/local-folder/ocr/jobs/status/read/insert/delete` 已返回 `410 Gone` / `mnote_local_ocr_retired`,旧 OCR sidecar API 不再作为 UI 或 agent 通道。
- `mnote-local-index` skill 退役;兼容 alias `mnote-document-evidence` / `mnote-local-index` 映射到 `mnote-knowledge-rag`
- `/api/search/documents` 继续保留 MNote 页面 / Markdown resource 普通搜索,但 `includeOcr` 不再读取 `.mnote/ocr-index.json`PDF / Office / 图片 OCR 与资料库问答走 LightRAG。
- `/api/knowledge-rag/query` / `mnote.knowledge_rag.query` 是资料库问答和跨资料 citation 的默认路径。
- FileTree `data-index-status` 已改为读取 LightRAG source registry,而不是 LiteParse sidecar / evidence.sqlite / local OCR index。
2026-06-06 已补跑旧链路 smoke,作为退役前基线;随后相关 active smoke 已软归档到 `recycle/20260606-liteparse-retirement/`
- `scripts/task528-document-evidence-liteparse-agent-smoke.js` 通过:直接 `/api/evidence/search` 命中 `Printer test page``mnote.evidence.search` 返回同一 PDF evidence 的 `quote/page/bbox/sourceMapPath`Reasonix ACP 实际调用 `mnote_evidence_search`LiteParse sidecar 与 `.mnote/index/evidence.sqlite` 均存在。
- `scripts/task529-local-search-result-open-locator-smoke.js` 通过:`/api/search/documents` 搜索 `三甲基硅酯` 后,点击结果仍停留在当前文档页并打开 Markdown resource tab,定位到 `docs/Silicon.md` 命中段落,截图落在 `tmp/task529-local-search-result-open-locator-smoke/`
- `scripts/task452-local-search-index-browser-smoke.js` 已按当前独立索引设置 surface 更新并通过:显式保存 `includePaths=["."]` 后刷新索引,初次搜索能找到新建 Markdown;导航页和文档页都能打开独立索引面板,不回落到页面设置页签;`/api/search/local-index/backlinks``/api/search/local-index/tags` 仍返回 200;重命名后刷新索引,搜索结果更新到新路径且不再返回旧路径。
- `scripts/task526-local-folder-ocr-api-smoke.js` 已从 active scripts 移到 recyclePage AI raw resource target smoke 已改为确认不再携带 `ocrContext` / `ocrRootRelativePath`
结论:旧 evidence 能力曾验证可用,但当前默认产品路径已切到 LightRAG;历史 sidecar 只作为归档数据解释材料,不再驱动新的 OCR / 索引 / agent 检索。
### 4.10 DOCX / Office Ingestion 验证结果
2026-06-06 新增 `scripts/task532-knowledge-rag-docx-ingestion-smoke.js`,用现有 OnlyOffice smoke DOCX 生成带唯一 marker 的 DOCX fixture,走 MNote `/api/knowledge-rag/ingest` 入库并真实查询:
- DOCX source`knowledge-rag-fixtures-7-50/docx-rag-smoke-1780745370830.docx`
- LightRAG doc id`doc-2f561f74048372a3f66b7bbe8a6e713a`
- LightRAG file path`mnote-4e26c0dd3d2bf575-docx-rag-smoke-1780745370830.docx`
- 查询 marker`DOCX RAG SMOKE 1780745370830`
- 结果:LightRAG 能解析 DOCX 正文并召回包含 marker 的 chunkMNote registry 能把 LightRAG file_path 映射回 workspace source path。
- citationDOCX 当前没有 PDF page/bbox sidecar locator,因此 `locatorDegraded=true`;但 connector 已补 fallback citation URL,把引用打开到同工作区 Markdown host 页并恢复 DOCX resource tab,浏览器验证 `panelKind=office``panelResourcePath=knowledge-rag-fixtures-7-50/docx-rag-smoke-1780745370830.docx`
结论:DOCX ingestion、召回、source registry 映射和资源 tab 回跳已跑通;DOCX 仍没有页码/bbox 级定位。PPTX/XLSX 还未作为 7-50 验收样本补测。
### 4.11 Source Watcher / Stale Sync 验证结果
2026-06-06 已把 LightRAG source registry 同步接入 MNote 现有 local-folder watcher,而不是新增第二套 watcher
- `rust/crates/mnote-web/src/routes/local_folder_events.rs` 的 tree live watcher 收到 `watch_batch` 前,会调用 `knowledge_rag::sync_registry_for_root(...)`
- `knowledge_rag::sync_registry_with_documents(...)` 会同步 LightRAG `/documents` 状态,并额外检查 registry 中 source 的当前文件状态。
- source 文件不存在时:registry 标记 `stale=true``deletedAtMs`、清空 `lightRagDocId/indexedAtMs`,并 best-effort 调用 LightRAG `DELETE /documents/delete_document`,固定 `delete_file=false`
- source hash 变化时:registry 标记 `stale=true`、清空旧 `lightRagDocId/indexedAtMs`、更新 `sourceHash`,并 best-effort 删除旧 LightRAG doc,避免旧 chunk 继续作为有效引用。
- `mapped_references(...)` 过滤 stale / deleted registry 命中的 references;即使 LightRAG 删除尚未完成,MNote query 结果也不把该 source 当成有效 citation 返回。
新增验证:
- `cargo test -p mnote-web knowledge_rag -- --nocapture` 通过 14 项;其中 `source_state_marks_deleted_and_changed_entries_stale` 覆盖删除 / hash 变化 registry 状态。
- `scripts/task533-knowledge-rag-source-watcher-sync-smoke.js` 通过:真实 ingest `knowledge-rag-fixtures-7-50/watcher-stale-1780745838741.md`,打开 `/api/local-folder/events?treeLive=true`,删除 source 后收到 `Remove(File)` watch_batch;不调用 status 的情况下直接读 registry,确认 `stale=true``deletedAtMs``lightRagDocId=null``indexedAtMs=null`;随后 query marker 不再返回该 source 的有效 reference。
当前边界:delete / missing source 的 watcher 闭环已浏览器验证;hash 变化由单元测试覆盖;rename / move 本质上会让旧 source path missing,走同一 stale/delete 逻辑,但尚未单独补浏览器 smoke。hash 变化后的自动“重建新 doc”仍保守为 stale + 需要重新 ingest,避免在任意文件保存事件上自动把大文件重新灌入 LightRAG。
### 4.12 Source 管理 UI / Query Scope 验证结果
2026-06-06 继续补齐 source 管理和查询范围:
- 资料库问答设置面板的 registry 行新增 `重索引` / `删除索引` 操作。
- `重索引` 对单个 source 调用 `/api/knowledge-rag/ingest`,用于 stale / retry source 的行级重试。
- `删除索引` 对单个 source 调用 `/api/knowledge-rag/delete-source`,仍固定 `delete_file=false`,只删除 LightRAG 派生索引,不删除用户 source。
- `mnote.knowledge_rag.query` / `/api/knowledge-rag/query` 新增 `sourcePaths` 参数,接受 workspace 相对文件或目录;MNote 对 mapped references 做 source scope 过滤。
- LightRAG `/query/data` 在部分情况下只返回 `data.chunks`,不返回可直接消费的 top-level referencesMNote connector 已补 chunks fallback,把 chunk 的 `file_path/reference_id` 生成 reference candidate,再走 registry 映射和 source scope。
- 修复了一个 stale registry 匹配 bug:没有 `doc_id` 的 reference 不得错误命中 `lightRagDocId=None` 的已删除 entry。
新增验证:
- `cargo test -p mnote-web knowledge_rag -- --nocapture` 通过 17 项;新增覆盖 source scope、chunks fallback reference、已删除 entry 不误匹配。
- `scripts/task534-knowledge-rag-source-management-scope-smoke.js` 通过:创建 alpha/beta 两个 Markdown sources`sourcePaths=[alpha]` 时 scoped query 只返回 alpha;浏览器打开资料库问答面板,确认 source row 有行级 `重索引` / `删除索引`;点击 `删除索引` 后 UI 显示已删除,原始 alpha 文件仍存在;删除后 scoped query 不再返回 alpha reference。
结论:source 管理 UI 已从“只能批量输入路径”推进到 registry 行级 reindex/deletequery scope 已可按 source 文件或目录过滤 MNote references。排序层已有 query lexical rerank 和 `hybrid -> mix` alias;真实 rerank 模型仍保持关闭,后续仅在样本证明需要时评估。
## 5. Provider 合同
第一版只需要一个内部 provider 合同,不做完整插件系统。
```rust
KnowledgeRagProvider {
status(workspace_id, root_uri) -> ProviderStatus
configure_sources(source_refs, options) -> ConfigureResult
ingest_or_reindex(source_refs, options) -> IngestJob
query(question, scope, options) -> RagAnswer
query_data(question, scope, options) -> RagRetrievalData
open_reference(reference_id, chunk_id?) -> OpenReferencePlan
delete_source(source_ref) -> DeleteResult
}
```
LightRAGAdapter 实现该合同。
MNote 侧保留:
- `workspaceId`
- `rootUri`
- `allowedRoots`
- resource source path
- owner document / resource tab mapping
- open action / locator fallback
- citationMarkdown / citationUrl 生成
- LightRAG dashboard embedding
LightRAG 侧保留:
- parser routing
- OCR / MinerU / Docling
- sidecar artifacts
- vector / graph storage
- query modes
- reranker
- parse cache
- task state / graph view / dashboard
## 6. 初始配置
第一阶段优先把 LightRAG 以源码 / host 方式独立跑起来,再让 MNote 通过 connector 访问。不要先改 MNote 主链。
部署原则:
- 7-50 基线:源码编译 / host service。
- Docker:只用于隔离 demo 或确认官方 dashboard,不作为 MNote connector 默认路径。
- LightRAG 服务绑定 `127.0.0.1`,不暴露公网。
- LightRAG storage 放到 MNote 控制范围外的派生缓存目录,例如 `/mnt/Data1T/Mnote_data/lightrag/rag_storage`
- LightRAG source 读取 MNote allowed roots 中的真实文件路径;如果官方 scan 只能扫描单一 input dir,先用最小 source spike 确认是否支持 host path / symlink / SDK 直入,再决定是否需要 adapter。
- 任何 staging / upload 降级都必须带 registry 映射和删除同步,不得成为长期主线。
LightRAG 初始配置优先使用官方 MinerU API,减少本地服务数量:
```bash
HOST=127.0.0.1
PORT=9621
CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
WORKING_DIR=/mnt/Data1T/Mnote_data/lightrag/rag_storage
INPUT_DIR=/mnt/Data1T/Mnote_data/lightrag/inputs
LIGHTRAG_KV_STORAGE=JsonKVStorage
LIGHTRAG_VECTOR_STORAGE=NanoVectorDBStorage
LIGHTRAG_GRAPH_STORAGE=NetworkXStorage
LIGHTRAG_DOC_STATUS_STORAGE=JsonDocStatusStorage
LLM_BINDING=openai
LLM_BINDING_HOST=http://127.0.0.1:20128/v1
LLM_MODEL=aigc/qwen-3.5
LLM_TIMEOUT=180
MAX_ASYNC_LLM=4
KEYWORD_MAX_ASYNC_LLM=4
QUERY_MAX_ASYNC_LLM=4
VLM_LLM_BINDING=openai
VLM_LLM_BINDING_HOST=http://127.0.0.1:20128/v1
VLM_LLM_MODEL=aigc/qwen-3.5
VLM_MAX_ASYNC_LLM=1
EMBEDDING_BINDING=openai
EMBEDDING_BINDING_HOST=http://127.0.0.1:20128/v1
EMBEDDING_MODEL=nvidia/baai/bge-m3
EMBEDDING_DIM=1024
EMBEDDING_TOKEN_LIMIT=8192
EMBEDDING_SEND_DIM=false
EMBEDDING_FUNC_MAX_ASYNC=8
EMBEDDING_BATCH_NUM=32
EMBEDDING_TIMEOUT=60
ENABLE_LLM_CACHE=false
ENABLE_LLM_CACHE_FOR_EXTRACT=true
CHUNK_SIZE=1200
CHUNK_OVERLAP_SIZE=100
TOP_K=40
CHUNK_TOP_K=20
MAX_ENTITY_TOKENS=6000
MAX_RELATION_TOKENS=8000
MAX_TOTAL_TOKENS=30000
KG_CHUNK_PICK_METHOD=VECTOR
RELATED_CHUNK_NUMBER=5
COSINE_THRESHOLD=0.2
MAX_PARALLEL_INSERT=3
MAX_PARALLEL_PARSE_NATIVE=5
MAX_PARALLEL_PARSE_MINERU=2
MAX_PARALLEL_ANALYZE=3
MAX_UPLOAD_SIZE=0
LIGHTRAG_PARSER=*:native-iteP,*:mineru-iteP,*:legacy-R
MINERU_API_MODE=official
MINERU_API_TOKEN=<from MNote secret store>
MINERU_OFFICIAL_ENDPOINT=https://mineru.net
MINERU_MODEL_VERSION=vlm
MINERU_IS_OCR=false
MINERU_LANGUAGE=ch
MINERU_ENABLE_TABLE=true
MINERU_ENABLE_FORMULA=true
MINERU_POLL_INTERVAL_SECONDS=2
MINERU_MAX_POLLS=300
VLM_PROCESS_ENABLE=true
SUMMARY_LANGUAGE=Chinese
ENTITY_EXTRACTION_USE_JSON=true
```
当前默认文本 LLM、extract/query 与 VLM 已统一为 `aigc/qwen-3.5`,服务入口为 `http://127.0.0.1:20128/v1`。此前 `deepseek-v4-flash` / Nemotron VLM 结论只保留为历史模型筛选记录,不再作为当前默认配置。embedding 继续使用 OmniRoute / NVIDIA 的 `nvidia/baai/bge-m3`,维度固定为 `1024`,必须在首次 ingest 前确定,后续不能随意改。
VLM 候选实测结论:
- `nvidia/nemotron-nano-12b-v2-vl:free`OpenRouter 直连可用;红色矩形识别正确约 2.7s,真实杯子图片约 6.1s;曾作为免费 VLM canary 对照,当前默认已切到 `aigc/qwen-3.5`
- `nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free`OpenRouter 直连返回空内容,不采用。
- `nvidia/nemotron-3.5-content-safety:free`:主要返回安全分类,不适合作通用 VLM。
- OmniRoute / NVIDIA 的 Nemotron VLM 路线:当前多返回图片 unavailable / 无法查看图片,暂不采用。
- `agnes-2.0-flash`:文本问答可用;图像输入可识别简单图片,但 VLM 延迟不稳定,真实图片可到 80s+,降为备选。
- `geminipay/gemini-3.1-flash-lite-preview`:通过简单图像输入测试,响应约 1s,但属于收费账号,不作为默认。
- `cx/gpt-5.4-mini` / `codex/gpt-5.4-mini` / `xx/gpt-5.4-mini`:可调用,但对图像回答“无法判断”,不适合作为 VLM 默认。
- `agnes-image-2.0-flash` / `agnes-image-2.1-flash` 属于图像生成 / 编辑方向,不是 LightRAG 所需的 image-to-text VLM;按 chat completions 测试返回 404,暂不纳入 LightRAG VLM。
复杂截图补测:
- 测试图:MNote Page AI 复杂网页截图,压缩到 `888x650`、约 `41KB`
- `nvidia/nemotron-nano-12b-v2-vl:free`:约 `5.9s`,能提取中心标题和关键 token,但把右侧标题误读为“页面截面视图”。
- `agnes-2.0-flash`:约 `9.6s`,中心标题、右侧“页面 AI”和 token 提取更准确。
- 历史结论:Nemotron 免费 VLM 速度和可用性较好,曾适合作 canary;当前默认已切到 `aigc/qwen-3.5`,高精度 UI/OCR 场景仍需继续用样本评估。
本地 embedding 平台补测:
- 本机 Ollama 已有 `bge-m3:latest`embedding 维度 `1024`,模型 F16,约 `1.1GB`,当前通过 Ollama 100% CPU 执行。
- 64 段中文文本 embeddingOllama 本地 `bge-m3``33.7s`OmniRoute / NVIDIA `nvidia/baai/bge-m3``1.6s`
- Ollama 运行 `bge-m3` 后新增 runner RSS 约 `1.3GB`GPU 显存基本不变。
- 当前不建议切本地 embedding 默认;若要本地化,应优先评估 llama.cpp / CUDA 或 quantized GGUF server,而不是直接用 Ollama F16 CPU 路线。
Embedding / rerank 当前建议:
- 默认 embedding 继续使用 `nvidia/baai/bge-m3`,不要在正式样本 ingestion 前频繁切换;embedding 模型或维度变化会要求重建索引。
- 本地 embedding 只保留为后续优化方向,优先路线是 `llama.cpp + bge-m3 GGUF + CUDA`Ollama F16 CPU 路线不适合作默认批量建库。
- 备选 embedding 中,`nvidia/nv-embedqa-e5-v5` 实测可用且维度 `1024`,但需要 `input_type=query/passage` 这类 asymmetric 参数;LightRAG 接入复杂度高于当前 `bge-m3`,暂不切换。
- `openrouter/openai/text-embedding-3-small` 可用但维度 `1536`,切换会改变索引维度;当前不采用。
- rerank 先保持 `RERANK_BINDING=null`。OmniRoute 中可见 `nvidia/nv-rerankqa-mistral-4b-v3`,但当前 `/v1/rerank``/rerank``/v2/rerank``/v1/ranking` 等常见端点实测 404,暂不能直接按 LightRAG rerank binding 配。
- 若真实样本出现“召回足够但排序差”,优先本地评估 `bge-reranker-v2-m3``Qwen3-Reranker-0.6B`,通过 Cohere-compatible / vLLM-compatible 服务接入 LightRAG。
不要直接套用泛化配置里的旧变量名:
- `LLM_API_KEY` / `LLM_API_BASE` 应改为 LightRAG v1.5 的 `LLM_BINDING_API_KEY` / `LLM_BINDING_HOST`
- `EMBEDDING_API_KEY` / `EMBEDDING_API_BASE` 应改为 `EMBEDDING_BINDING_API_KEY` / `EMBEDDING_BINDING_HOST`
- `SERVER_HOST` / `SERVER_PORT` 应改为 `HOST` / `PORT`
- `CHUNK_OVERLAP` 应改为 `CHUNK_OVERLAP_SIZE`
- `KV_STORAGE` / `VECTOR_STORAGE` / `GRAPH_STORAGE` / `DOC_STATUS_STORAGE` 应改为 `LIGHTRAG_*_STORAGE`
- `TEXTRACT_USE_OCR` / `OCR_ENGINE` / `OCR_WORKERS` 不是当前 LightRAG v1.5 API server 的 MinerU 路线变量;当前应使用 `LIGHTRAG_PARSER` + `MINERU_API_MODE` + `MINERU_*`
`ENABLE_LLM_CACHE=false` 是有意设置:source delete / stale 语义验证前,不缓存最终问答,避免删除源后自然语言回答仍从 cache 命中。`ENABLE_LLM_CACHE_FOR_EXTRACT=true` 保留,只缓存抽取过程,降低重复建库成本。
后续大量书籍批处理时再评估本地 MinerU:
```bash
MINERU_API_MODE=local
MINERU_LOCAL_ENDPOINT=http://localhost:8000
```
默认 query 策略:
- 宽泛跨书总结:`mode=mix``mode=global`,开启 rerank。
- 指定文档细节:先在 MNote scope 限制到 source,再用 LightRAG query。
- 只要需要可点击来源,必须走 `query_data` 或补充读取 chunk/sidecar,不能只消费自然语言 answer。
第一阶段可接受 MNote 只打开 LightRAG 自身 UI / dashboard,先验证 ingestion、OCR、query、graph view 和引用质量;MNote 内嵌 UI 延后。
## 7. LiteParse 退役结果
LiteParse 已从默认路径退役:
- [x] LightRAG 能处理当前样本 PDF / DOCX / 图片 PDF。(PDF / 图片 PDF 已跑通;DOCX 已通过 `task532` 验证 ingestion / query / resource tab fallback citation
- [x] MinerU official token 路线在 MNote secret 注入后可跑通。
- [x] LightRAG sidecar `blockid -> positions -> page/bbox` 能映射到 MNote EvidenceLocator。(已通过扫描 PDF smoke;当前为 quote/block 文本匹配 fallback,不是 refs 无损映射)
- [x] 查询结果能返回可点击 citation,打开到 resource tab / page / bbox。(`task529-knowledge-rag-citation-resource-tab-smoke` 已通过)
- [x] 旧 evidence search 已完成退役前回归,随后 `/api/evidence/search` / agent evidence tools 从默认路径移除。
- [x] 删除或重建知识库不会删除用户原始文件。
- [x] 旧 LiteParseProvider 的测试覆盖有替代路径或明确归档说明。(见 7.1LightRAG PDF/DOCX/扫描 PDF 路线作为新资料默认)
### 7.1 LiteParse -> LightRAG Cutover
当前切换策略是“active 退役 + recycle 软归档 + 新资料默认 LightRAG”:
| 代码 / 能力 | 当前状态 | Cutover 决策 |
| --- | --- | --- |
| `evidence_parse.rs` / `LiteParseProvider` | active provider 返回 `liteparse_retired`;历史实现软归档到 `recycle/20260606-liteparse-retirement/` | 不再调用 `lit` / `liteparse` CLI |
| `local_search_index.rs` 的资源 parse sidecar 入库 | 不再为 PDF / Office 调用 LiteParse parse sidecar | PDF / Office / 图片 OCR 走 LightRAG source registry + query |
| `/api/evidence/search``mnote.evidence.search/read/open` | `/api/evidence/search` 返回 retiredagent manifest 不再暴露 evidence tools | 使用 `mnote.knowledge_rag.query/open_reference` |
| `/api/local-folder/ocr/*``.mnote/ocr-index.json` 检索 | HTTP API 返回 retiredactive UI 不再调用旧 OCR sidecar`includeOcr` 不再追加 OCR sidecar 搜索结果 | 图片 / PDF / Office 统一通过 `mnote.knowledge_rag.status/ingest/query/delete-source` |
| `skills/mnote-local-index/SKILL.md` | 软归档到 recycleactive capability pack 删除 | 兼容 alias 映射到 `mnote-knowledge-rag` |
| FileTree `data-index-status` | 从 LightRAG registry 读取 indexed / indexing / failed | 旧 evidence.sqlite / OCR index 不再决定文件树勾选状态 |
| `skills/mnote-knowledge-rag/SKILL.md` | 新资料库问答优先走 LightRAG | 作为多书 / 多论文 / PDF / DOCX 的默认入口 |
| 7-46 / 7-48 evidence 设计稿 | 仍解释旧 sidecar / evidence index 生命周期 | 保留为历史解释 / migration note |
执行顺序:
1. 退役 LiteParse active provider 和 agent evidence / local-index capability。
2. 顶栏 OCR / 本地索引入口并入 LightRAG 资料库问答入口。
3. FileTree 勾选 / 失败状态从 LightRAG registry 读取。
4. FileTree 右键“生成 OCR”替换成“加入资料库索引”。
5. 资源页 / Page AI target / Reasonix ACP 不再调用旧 OCR/evidence/index 工具。
6. 历史 LiteParse / local OCR 代码、skill、smoke 软归档到 recycle。
退役顺序:
1. 新导入资料默认走 LightRAG。
2. Agent 工具默认只暴露 LightRAG knowledge RAG。
3. FileTree 状态绑定 LightRAG source registry。
4. 历史 LiteParse sidecar 只保留 migration note,不再作为 UI / agent fallback。
### 7.2 MNote / LightRAG Coupling Review Fix
2026-06-06 人工复核后继续收口 MNote 与 LightRAG 的耦合状态:
- 顶栏只保留 1 个 `资料库问答` 入口;历史 OCR task toggle 不再由 resource tab runtime 动态创建。
- 删除 source 后,`/api/knowledge-rag/delete-source` 会把 registry 标为 `delete_submitted``delete_completed`;后续 `/api/knowledge-rag/status` 会对照 LightRAG `/documents` 自动把已消失的 doc 标为 `delete_completed`
- FileTree 状态语义调整为:`indexed` 绿灯、`indexing` 黄灯、`failed` 红灯、未索引或 `delete_completed` 无灯;`delete_submitted` 作为黄灯,不再被误显示成失败。
- 新增 `/api/knowledge-rag/prune-registry` 与 UI `清除失效记录`,用于一键清理已删除 / 过期 / 失败的 registry 记录;仍在 `delete_submitted` 的记录不会被清掉,避免隐藏 LightRAG 后台删除尚未确认的状态。
- 新增索引输入去重,同一批重复 source 不会重复提交;相同 `sourcePath + sourceHash` 已登记且未过期时,非 `force` ingest 会返回 `already_registered`
- 新增索引 / 删除 / prune 成功后会触发 `mnote:knowledge-rag-source-updated`,设置面板和 FileTree 会立即刷新;LightRAG busy 时也会刷新 registry 并把 source 保持为等待 / 处理中状态。
- 设置面板不再默认显示空输入行的 `待索引` 标签,避免与上方 source registry 状态重复。
- Dashboard URL 在 LAN 访问 MNote 时会把 `127.0.0.1` / `localhost` 改写为当前 MNote host;如果 LightRAG 服务自身仍只绑定 loopback,下一步应改 LightRAG bind host 或做 MNote 反向代理。
- 2026-06-06 追加复核:LightRAG 已切到 `aigc/qwen-3.5`MNote status 面板会显示当前 LLM model`/api/knowledge-rag/status` 额外返回 LightRAG `/documents` 摘要和状态分组,UI 同时显示 `MNote 登记来源数``LightRAG 文档数`,并把未映射到 MNote registry 的 LightRAG 文档列为 `LightRAG 未映射` 分类。
- 资料库设置 UI 调整为“操作在上、列表在下”,来源列表新增分类过滤:`需处理``索引中``失败/过期``已索引``已移除``LightRAG 未映射``全部`;默认优先显示需处理项,减少成功项噪音。
- 补齐 `travel_explore` 本地 SVG mask,避免资料库入口在 Material Symbols 字体不可用时显示成黑色方块。
本轮验证:
- `node --check` 覆盖 `sidebar-page-settings-runtime.js``sidebar-tree-runtime.js``document-resource-tab-runtime.js``sidebar-tree-live-apply-runtime.js`
- `cargo check -p mnote-web` 通过。
- `cargo test -p mnote-web knowledge_rag -- --nocapture` 通过 21 项。
- `cargo test -p mnote-web local_file_tree_marks_lightrag_indexed_indexing_and_failed_source_files -- --nocapture` 通过,覆盖 indexed / indexing / failed / delete_submitted / delete_completed。
- `cargo test -p mnote-web sidebar_settings_runtime_routes_index_and_ocr_to_lightrag_settings -- --nocapture``page_layout_exposes_lightrag_knowledge_rag_settings_only` 通过。
- 浏览器复核 `http://127.0.0.1:3000/`topbar `资料库问答` 入口数量为 1,旧 OCR / 本地索引入口数量为 0;面板显示 `LightRAG healthy`、有 `清除失效记录`,空输入行不显示 `待索引`;旧 deleted registry 已同步为 `LightRAG 已移除` 且 FileTree 无灯。
### 7.3 Status Bridge / Image Wrapper Follow-up
2026-06-07 复核确认:LightRAG 切到 `aigc/qwen-3.5` 后索引速度恢复,但 MNote 仍必须主动同步后台完成状态,不能假设 LightRAG 会向 MNote 推送事件。
当前补充口径:
- LightRAG 当前文本 LLM、extract/query 与 VLM 统一使用 `aigc/qwen-3.5`VLM host 为 `http://127.0.0.1:20128/v1`status 为 healthy。此前 `deepseek-v4-flash` 只作为历史调试背景,不再作为当前默认模型口径。
- MNote ingest / reindex 后启动有界 status bridge/backoff,对照 LightRAG `/documents` 同步 `processing/submitted -> processed/failed`,再刷新 source registry、资料库设置面板和 FileTree 灯号;这不是长期无界轮询。
- LightRAG Documents 页面看不到原始图片文件是预期边界:当前 `/documents/scan` 不直接索引 `png/jpg`MNote 为图片 source 生成 Markdown wrapper,再由 LightRAG 索引 wrapper 文档,同时 registry 仍映射回原始图片路径。
- `MNote 登记来源数``LightRAG 文档数` 应优先看是否一一映射;未映射文档只作为 LightRAG 残留 / 外部手动导入提示,不作为 MNote source truth。
- 清空历史时只清 LightRAG 派生 documents / input wrapper / parsed cache 与 MNote registry,不删除 workspace 原始资料。
## 8. 不做事项
- 不继续开发 7-49 的 `mnote.understanding.*` 工具。
- 不继续开发自研 understanding.sqlite。
- 不做 mindmap projection 作为知识库默认视图。
- 不默认接入 PageIndex。
- 不把 Understand Anything dashboard 作为 MNote 主 dashboard。
- 不同时默认维护 LiteParse + LightRAG + PageIndex 多套 provider。
- 不让 LightRAG 写用户 Markdown 正文。
- 不把 LightRAG sidecar 当用户可编辑真相。
- 不让 MNote 为 LightRAG 结果再建一套 RAG 索引。
- 不为了 LightRAG 改动 MNote 文件树、编辑器、普通搜索的主路径。
## 9. 插件系统判断
当前不开发完整插件系统,但按插件边界实施。
原因:
- 近期真实需要的知识库 provider 只有 LightRAG 一个。
- 过早插件化会引入 manifest、生命周期、权限、版本、升级、隔离和 UI 管理成本。
- MNote 现在更需要稳定 provider boundary,而不是多 provider marketplace。
- LightRAG 已经有自己的任务、图谱、解析和 dashboard 能力,MNote 不应复制一套控制面。
第一版只做“无害集成”:
- 配置项:LightRAG endpoint / working dir / MinerU token secret key / parser mode。
- 状态页:provider status、job status、storage path、最近错误、dashboard URL。
- 工具层:query / ingest / reindex / delete source / open reference。
- UI 层:先外链或 iframe 嵌入 LightRAG dashboard,用于任务控制、graph 查看和 ingestion 状态。
当出现第二个稳定 provider,且必须和 LightRAG 并存时,再抽正式插件系统。
## 10. 实施 Checklist
### A. 退役 7-49
- [x] 7-49 从 active `design/07-ai/process` 移出。
- [x] 7-49 标记为 `[recycle]`
- [x] 撤回 `mnote.understanding.*` route / tool / skill 接线。
- [x] 删除未落地主线的 `understanding.rs` untracked 代码。
- [x] 7-50 明确不再沿 Docker staging 作为 MNote connector 基线。
### B. LightRAG Spike
- [x] 固定 LightRAG 参考版本和源码 / host 运行方式。
- [x] 建立最小 LightRAG server / SDK 本地运行脚本。
- [x] 验证 LightRAG 源码运行依赖版本;如 Python 3.14 不兼容,改用专用 Python 3.12/3.13 venv。
- [x] 验证 OmniRoute OpenAI-compatible 模型在 LightRAG client 下可用;当前默认已从历史 `deepseek-v4-flash` 切到 `aigc/qwen-3.5`
- [x] 挑选快速 / 便宜的 OmniRoute 视觉模型,`geminipay/gemini-3.1-flash-lite-preview` 可用但因收费不作为默认。
- [x] 筛选 OpenRouter 免费 VLM 与 Agnes 免费模型;当前默认已统一为 `aigc/qwen-3.5`,历史 VLM canary 仅保留为对照记录。
- [x] 验证 `nvidia/baai/bge-m3` embedding 维度和 LightRAG 配置一致。
- [x] 测试本地 Ollama `bge-m3` embedding 代价,并与 OmniRoute / NVIDIA embedding 对照。
- [x] 筛选 embedding / rerank 候选并冻结当前默认:embedding 继续 `nvidia/baai/bge-m3`rerank 暂不开。
- [x] 使用复杂 MNote UI 截图补测 VLM OCR / UI 理解能力。
- [x] 接入 MinerU official token,不把 token 暴露给前端。
- [x] 对照外部 env 建议,补齐 LightRAG v1.5 实际识别的 storage / chunk / query / concurrency / MinerU 参数。
- [x] 用 symlink scan 跑通受控 source 文件 ingestion,避免默认复制 source 内容。
- [x] 明确 source registry 字段和 stale / deleted 过滤规则。
- [x] 验证 `query_data` 返回 chunk/reference。
- [x] 验证 `DELETE /documents/delete_document` 删除后旧 source 不再可检索。
- [x] 验证 SDK / upload / symlink / scan 四种路径中哪一种最适合 MNote connector 长期使用。
- [x] 验证 MNote source 删除后能触发 LightRAG delete,不删除用户原始文件。(显式 `delete-source` route 与 watcher stale sync 均已覆盖;watcher smoke 见 `task533`
- [x] 用 1 本书籍 PDF、1 个扫描 PDF、2 篇论文跑 ingestion。
- [x] 保存 sidecar 样本到 `tmp/` 或测试 fixture,不提交敏感原文。(样本保留在 LightRAG `inputs/__parsed__` 派生缓存,不提交)
- [x] 验证 LightRAG dashboard 能查看任务、graph、文档状态。(`task531-lightrag-dashboard-ui-smoke.js` 已通过:Documents 显示 completed/fail/doc summaryKnowledge Graph / Retrieval 均显示 connected
- [x] 验证 chunk 能反查 sidecar 并生成 locator。(当前不是 refs 无损映射,而是 `file_path + quote/chunk content` 匹配 sidecar block
- [x] 验证 sidecar position 能生成 MNote EvidenceLocator。(`task529` 已验证 PDF resource tab / page / bbox / 高亮)
### C. MNote Adapter
- [x] 新增内部 `KnowledgeRagProvider` 合同。
- [x] 新增 `LightRAGAdapter`,只封装 HTTP / SDK 调用,不复制 LightRAG 逻辑。(当前落为 `knowledge_rag` route adapter,未额外抽 trait
- [x] 新增 provider status route。
- [x] 新增 dashboard URL / open route。
- [x] 新增 ingestion / reindex job 控制 route。
- [x] 新增 query route。
- [x] 新增 open reference resolver。
- [x] Hermes / Page AI 只看到 MNote tool,不直接看到 LightRAG 内部路径。
- [x] MNote 普通页面搜索、文件树、编辑器不依赖 LightRAG 可用性。
- [x] Connector 避免被历史 `LIGHTRAG_API_KEY` 污染,优先使用 MNote 专用 key 或 LightRAG source `.env`
### D. UI / Agent 闭环
- [x] Page AI 能选择“资料库问答”模式。(通过 `mnote-knowledge-rag` capability pack 暴露)
- [x] Agent skill 只暴露少量知识库工具:status、query、open_reference。(reindex/ingest 暂只保留 HTTP route,不暴露给只读 agent
- [x] 回答必须带 citations。(skill 要求引用 `references` / `citationMarkdown`
- [x] citation 能打开到原文 resource tab。(`task529` 已通过)
- [x] citation 能展示 page / bbox / quote 降级状态。(已返回 `chunkId` / `quote`,并能在扫描 PDF 样本生成 page/bbox;未命中时继续降级,不伪造)
- [x] 没有 locator 时明确显示“来源定位降级”,不伪造页码。
- [x] Page AI 真实回答能使用 RAG citation,而不是只验证 tool 层。(`task530-knowledge-rag-page-ai-final-answer-smoke.js` 已通过:Reasonix 最终可见回答引用 `scan-image-start.pdf · p.1` 可点击 resourceTab 链接)
- [x] MNote 中可以进入 LightRAG UI 进行任务控制和 graph 查看。(通过 MNote `/api/knowledge-rag/status``dashboardUrl` 打开 WebUI`task531` 已浏览器验证 Documents / Knowledge Graph / Retrieval
### E. LiteParse 退役
- [x] 对照 LiteParse 当前能力和 LightRAG sidecar 能力。(见 7.1
- [x] 列出仍依赖 LiteParse 的代码路径。(见 7.1
- [x] 把 LiteParse 默认 provider 切到 LightRAG,不再 fallback 到 evidence。
- [x] 删除 active UI 中的 LiteParse / 本地索引 / OCR 专属入口。
- [x] FileTree 勾选 / 失败状态改为读取 LightRAG source registry。
- [x] 软归档 LiteParse / local OCR 历史代码与 smoke 到 `recycle/20260606-liteparse-retirement/`
### F. 当前剩余闭环
当前 7-50 v1 已可归档;下面是本轮收口项与非阻塞后续:
- [x] LightRAG 资料库设置 UI:不能混入现有 MNote 本地索引设置;需要独立 surface,显示 provider status、dashboard URL、working dir、input dir、source registry、最近错误。(已落独立 topbar 入口与状态面板)
- [x] LightRAG source 管理 UI:支持从当前 local-folder 中选择要索引的文件 / 目录,调用 `/api/knowledge-rag/ingest`,展示 indexing / processed / stale / deleted / retryRequired 状态。(已支持手填、从 filetree 选中项填入路径、输入行状态、registry 行级 reindex/delete`task534` 已浏览器验证)
- [x] LightRAG dashboard 接入:第一步可以外链打开 `dashboardUrl`,第二步再评估 iframe;必须浏览器验证 documents / graph / task 状态可见。(`task531` 已完成外链 dashboard 的 documents / graph / retrieval 验证;iframe 仍作为后续体验评估,不阻塞 v1)
- [x] source watcher 自动同步:source 删除 / 移动 / 重命名 / hash 变化后,自动标记 registry stale,并触发 delete / reindex;不能只依赖显式 `delete-source` route。(`task533` 验证删除事件;hash 变化有单测;重命名 / 移动复用旧 path missing 逻辑;自动重建新 doc 当前保守为 stale + 重新 ingest
- [x] 查询 scope 与排序:支持按选中 source / 目录限制 RAG 查询;`hybrid -> mix` alias 和 MNote lexical rerank 已先落地,仍需评估 `mix/global/local``topK/chunkTopK` 与 rerank。(`sourcePaths` 已落 route / Hermes / Reasonix schema`task534` 验证按 source 文件过滤;rerank 仍按 7-50 结论默认关闭)
- [x] Page AI 真实回答 smoke:不仅验证 Hermes tool 能返回 references,还要验证 Page AI 最终回答使用 `citationMarkdown`,不会把 retrieval raw 当最终答案,也不会伪造页码。(`task530` 已通过)
- [x] DOCX / Office 样本 ingestion:补测 LightRAG 对 DOCX / Office 附件的解析与 citation 回跳能力。(`task532` 已验证 DOCX 解析、marker 召回、registry 映射和 DOCX resource tab fallback citationPPTX/XLSX 未纳入本轮)
- [x] 旧 evidence search 退役:保留历史回归证据,但 active route / agent tool 不再作为 fallback;新检索与 OCR / 索引统一走 LightRAG。
- [x] LiteParse 退役设计:见 7.1;结论已从冻结 fallback 更新为 active 退役 + recycle 软归档。
## 11. 验收标准
- 用户能把多本书 / 多篇论文纳入同一个资料库。
- LightRAG 可以在不改动 MNote 普通功能的情况下完成 OCR、parse、index、query。
- LightRAG 读取的是 MNote 允许的真实 source,或有明确 registry 映射的临时 staging;不能存在无人管理的第二份资料真相。
- agent 能回答跨资料问题。
- 回答不能只给“看起来合理”的总结,必须有来源。
- 至少 PDF 页码和 chunk quote 可追溯。
- 对支持 bbox 的 sidecar,能打开到页面区域或保留 bbox metadata。
- 删除知识库索引不会删除用户原始文件。
- 删除 / 移动 / 重命名 source 后,旧索引不会继续作为有效来源参与回答;删除同步失败时必须显示 stale 状态。
- MNote active 代码中不再出现未完成的 `mnote.understanding.*` 主线接线。
- LightRAG 不可用时,MNote 文件树、编辑器、普通页面搜索仍可正常使用。