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

760 lines
57 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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,仅保留为历史设计或参考边界。
>
> 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 文件树、编辑器、普通页面搜索仍可正常使用。