# 7-75 [process] Knowledge RAG UI 面板优化 v1 > 创建时间:2026-07-13 > > 状态:`PROCESS` > > Owner:`07-ai` > > 范围:3000 主壳中的知识库 / RAG / OCR 状态面板、FileTree 知识库状态灯、当前页面附件索引入口、Page AI 对知识库状态的可见性。 > > 上位依据: > - `/mnt/Data1T/mnote/ARCHITECTURE.md`(`CURRENT_ARCHITECTURE.md` 为兼容指针) > - `/mnt/Data1T/mnote/design/07-ai/done/7-50-lightrag-knowledge-rag-provider-v1.md` > - `/mnt/Data1T/mnote/design/07-ai/done/7-51-lightrag-post-commit-hardening-v1.md` > - `/mnt/Data1T/mnote/design/07-ai/done/7-52-lightrag-image-ocr-search-chain-hardening-v1.md` > - `/mnt/Data1T/mnote/design/10-review/done/20-post-lightrag-runtime-hardening-checklist-v1.md` ## 1. 第一结论 当前更高优先级不是先恢复旧本地 OCR sidecar,而是把 **Knowledge RAG UI 面板** 做成用户能理解和操作的资料库控制面。 原因: - 旧 `/api/local-folder/ocr/*` 已退役,当前图片 / PDF / Office OCR 与资料库问答主线统一走 Knowledge RAG provider。 - LightRAG 本地服务已具备图片 VLM / MinerU 路由能力,但用户在 MNote 里看不到“这张图是否已索引 / 是否已有 OCR 文本 / 是否失败 / 是否过期”。 - FileTree 目前只有 `indexed / indexing / failed` 三态,缺少 `not_indexed / stale / ocr_text_exposed / provider_unavailable` 等用户可行动状态。 - Page AI 能直接看本地图片,但长期知识库和非多模态模型仍需要 OCR / sidecar / index;UI 必须先让用户知道当前资源处于哪种状态。 因此,本设计把“图片插入后 OCR 能力增强”拆成 Knowledge RAG 面板的一部分,而不是重开旧 OCR 入口。 ## 2. 当前证据 ### 2.1 已存在能力 - Knowledge RAG source 支持 `md / pdf / docx / pptx / xlsx / csv / png / jpg / jpeg / webp / gif / bmp / tif / tiff` 等文件。 - `/api/knowledge-rag/ingest` 已能接收 `rootUri + sources[]`,注册 source,创建 LightRAG input symlink,并触发 provider scan。 - FileTree 行模型已带 `indexStatus`,前端可渲染 `indexed / indexing / failed`。 - 旧 OCR sidecar frontmatter 读取 helper 仍在,可作为历史兼容读取,不作为新任务入口。 - LightRAG health 能返回 provider 配置、pipeline 状态、VLM 是否启用、MinerU / parser routing 等诊断信息。 ### 2.2 已确认缺口 - 新插入图片只写为 Markdown 图片引用和本地文件,不会自动登记为 Knowledge RAG source。 - 未索引图片没有明确 UI 状态,用户只能看到文件存在,无法知道是否可被文本模型/RAG 检索。 - Knowledge RAG registry 中存在大量 stale / provider_missing / failed 历史记录,但 UI 缺少 doctor 视图解释和引导。 - 当前“索引到默认知识库”入口藏在 FileTree 右键菜单,缺少当前页面级的“索引本页附件”入口。 - 失败原因没有被产品化展示,例如 provider API key 不一致、provider missing、chunk 超时、parser 失败。 - OCR 结果没有在图片资源 tab 或页面侧栏中形成可读 preview;用户不知道 OCR 文本是否真正暴露给 AI。 - Page AI target package 不应恢复旧 `ocrContext`,但需要一个轻量 `resourceOcrStatus` 告诉 agent 当前资源是否已有可查 OCR / 是否应调用 Knowledge RAG / 是否需要多模态兜底。 ## 3. 目标体验 Knowledge RAG 面板应回答用户四个问题: 1. **资料库是否可用**:provider 是否在线、当前默认 provider 是谁、队列是否忙。 2. **哪些资源已进入知识库**:当前 workspace / 当前页面 / 当前文件夹下的 source 状态。 3. **图片/PDF/Office 是否已 OCR/解析**:是否已索引、是否有真实 OCR 文本、是否只是图片占位符。 4. **下一步能做什么**:索引、重试、强制重建、打开引用、查看 OCR 摘要、查看失败原因。 目标 UI 不是 debug 面板,而是资料库操作面板。Raw provider payload 只放到折叠诊断区。 ## 4. 非目标 - 不恢复 `/api/local-folder/ocr/*` 作为主动 OCR API。 - 不把旧 `.ocr` sidecar 重新变成页面正文真相。 - 不让 MNote 复制 LightRAG 的 chunk / vector / graph 真相。 - 不在普通页面打开、FileTree 渲染、Markdown 编辑保存中硬依赖 LightRAG 可用性。 - 不自动清理 registry / 删除 provider 索引;任何清理、删除、强制重建都必须用户确认。 ## 5. 信息架构 ### 5.1 面板入口 保留当前知识库入口,但改成四区布局: ```text 知识库 Provider 状态 当前页面资源 Workspace Sources 诊断与修复 ``` 入口位置: - Sidebar 顶部资料库 / 搜索附近保留主入口。 - FileTree 右键保留“索引到知识库”,但成功后跳转或高亮 Knowledge RAG 面板对应 source。 - 文档页资源 tab 对图片/PDF/Office 显示“资料库状态”轻量按钮。 ### 5.2 Provider 状态区 显示: - provider 名称:`LightRAG / WeKnora / RAGFlow / legacy fallback`。 - health:在线、不可达、API key 错误、pipeline busy。 - dashboard 链接。 - VLM/OCR 能力:图片解析是否启用、MinerU/Docling/native 路由摘要。 - 队列状态:queued/running/failed/retry required。 对用户文案: - 在线:`知识库服务可用` - 不可达:`知识库服务不可用,页面仍可编辑;AI 将只能读取本地文件或多模态图片` - API key 错误:`MNote 与 provider 的 API key 不一致,请检查配置` - 队列忙:`正在解析资料,稍后会自动刷新状态` ### 5.3 当前页面资源区 针对当前 Markdown 页面解析图片、PDF、Office、mindmap、附件引用,展示: | 列 | 含义 | |----|------| | 资源 | 文件名、类型、路径 | | 状态 | 未索引 / 排队中 / 索引中 / 已索引 / 失败 / 已过期 | | OCR | 不适用 / 待解析 / 已有文本 / 只有占位 / 失败 | | 操作 | 索引、重试、强制重建、打开资源、查看 OCR | 当前页面区必须提供批量动作: - `索引本页附件` - `重试失败项` - `重建已过期项` ### 5.4 Workspace Sources 区 展示 registry 中当前 actor 可见的 sources: | 列 | 含义 | |----|------| | Source | root-relative path | | 类型 | markdown / image / pdf / office | | Provider | LightRAG / WeKnora / RAGFlow | | 状态 | registry + provider status 合并结果 | | 更新时间 | registry updatedAt / provider updatedAt | | 引用 | open_reference 可否定位 | 默认过滤: - 隐藏已删除完成项。 - stale / failed 单独汇总到顶部。 - 测试 fixture 或历史 provider_missing 只在诊断区展开显示。 ### 5.5 OCR / 解析预览区 点击图片 source 后,右侧或下方展示: - 原图预览。 - OCR / parsed text preview。 - `ocrTextExposed`:是否返回了真实文本,而不是 Markdown 图片占位符。 - sidecar / blocks 路径只在诊断展开时显示。 - `复制 OCR 文本`、`用 OCR 问 AI`、`打开引用位置`。 如果没有 OCR 文本: ```text 这张图片尚未解析成文本。多模态模型可以临时读图,但文本模型和知识库检索需要先索引。 ``` 如果只有图片占位: ```text provider 只返回了图片占位符,未暴露 OCR 正文。建议重试解析或改用 MinerU/VLM parser。 ``` ## 6. 状态模型 ### 6.1 Source index status 后端和前端统一使用以下状态: - `not_indexed`:本地资源存在,但 registry 无有效 entry。 - `queued`:已提交,但 provider 尚未开始。 - `indexing`:provider processing / parsing / submitted。 - `indexed`:provider doc id 存在且 indexedAt 有效。 - `failed`:provider failed / provider_missing / delete_retry_required。 - `stale`:source hash/mtime 变化,已有索引过期。 - `deleting`:delete submitted。 - `deleted`:delete completed。 FileTree 可以继续只显示少量灯号,但 tooltip / 面板必须展示完整状态。 ### 6.2 OCR status 图片、扫描 PDF、Office 附件需要额外 OCR/解析状态: - `not_applicable`:纯文本 Markdown 等无需 OCR。 - `not_started`:未提交解析。 - `processing`:解析中。 - `text_exposed`:引用/sidecar 中已有真实文本。 - `placeholder_only`:只返回图片占位符,没有 OCR 正文。 - `failed`:解析失败。 - `stale`:源文件变化后 OCR 过期。 `text_exposed` 的判断不得只看 provider “成功”,必须看 `contentDiagnostics.ocrTextExposed` 或 sidecar meaningful block 数。 ## 7. 后端合同调整 ### 7.1 Status API 扩展 `/api/knowledge-rag/status?rootUri=...` 返回: ```json { "sourceSummary": { "total": 0, "notIndexed": 0, "indexing": 0, "indexed": 0, "failed": 0, "stale": 0, "ocrTextExposed": 0, "placeholderOnly": 0 }, "sources": [ { "sourceRootRelativePath": "docs/photo.jpg", "resourceType": "image", "indexStatus": "indexed", "ocrStatus": "text_exposed", "ocrTextPreview": "前 300 字...", "failureMessage": null, "actions": ["open", "reindex", "view_ocr"] } ] } ``` ### 7.2 Current page assets API 新增或复用 Page Aggregate 输出当前页资源引用,面板拿到: ```json { "pageId": "local-md:...", "sourceRootRelativePath": "docs/Page.md", "assets": [ { "href": "photo.jpg", "sourceRootRelativePath": "docs/photo.jpg", "resourceType": "image", "exists": true, "indexStatus": "not_indexed" } ] } ``` 这一步不要让前端重复解析 Markdown 真相;优先从 Page Aggregate / kernel projection 输出。 ### 7.3 Ingest response `/api/knowledge-rag/ingest` 当前返回 configured / scan 等信息,面板需要稳定字段: - `submittedSources[]` - `skippedSources[]` - `retryRequired` - `providerErrorCode` - `userMessage` - `nextPollAfterMs` ### 7.4 Registry doctor 增加只读 doctor endpoint 或 status 子对象: ```json { "doctor": { "staleEntries": 58, "providerMissingEntries": 58, "failedEntries": 1, "apiKeyMismatchSuspected": true, "suggestedActions": ["check_provider_config", "retry_failed", "archive_stale_test_entries"] } } ``` 清理动作必须单独确认,不在 status 读取时自动执行。 ## 8. 前端交互 ### 8.1 FileTree 灯号 灯号含义: - 无灯:不支持索引或用户未开启显示。 - 空心灰点:支持索引但未索引。 - 黄点:排队/索引中。 - 绿点:已索引且 OCR 文本暴露。 - 蓝点:已索引但该资源不需要 OCR。 - 红点:失败。 - 橙点:过期。 FileTree 行已有 `data-index-status`,需要扩展为 `data-index-status` + `data-ocr-status`,tooltip 显示完整原因。 ### 8.2 图片插入后 图片插入完成后: 1. 保存图片文件。 2. Markdown 写入图片引用。 3. UI 立刻把该资源标记为 `not_indexed`。 4. 如果用户开启“自动索引新图片”,后台提交 `/api/knowledge-rag/ingest`。 5. 默认不开启自动索引时,显示轻量提示:`图片已插入,可索引后用于文本检索和非多模态 AI`。 自动索引应是 workspace/user preference,不是硬编码默认。 ### 8.3 Page AI 协同 Page AI 不恢复旧 `ocrContext`,改用轻量状态: ```json { "resourceOcrStatus": { "currentPageAssets": [ { "sourceRootRelativePath": "docs/photo.jpg", "resourceType": "image", "indexStatus": "not_indexed", "ocrStatus": "not_started", "recommendedReadMode": "multimodal_fallback" } ] } } ``` AI 行为: - 多模态模型:可以临时读图,但应提示“未索引,无法长期检索”。 - 文本模型:如果未 OCR,应建议用户索引图片;不要假装已读图。 - 已 OCR:优先调用 `mnote.knowledge_rag.query` / `section_context`,必要时再多模态核验。 ## 9. 实施步骤 ### Phase 1:只读状态面板 - [ ] 统一 Knowledge RAG provider 文案,避免 LightRAG / WeKnora / RAGFlow legacy fallback 在用户界面混乱。 - [ ] 扩展 `/api/knowledge-rag/status` 的 source summary 与 registry doctor。 - [ ] 新建 Knowledge RAG 面板基础 UI,显示 provider health、source summary、失败/stale 汇总。 - [ ] FileTree tooltip 展示当前 `indexStatus`,不改变索引行为。 ### Phase 2:当前页面资源闭环 - [ ] 从 Page Aggregate / projection 输出当前页附件清单。 - [ ] 面板展示“当前页面资源”列表。 - [ ] 支持“索引本页附件”“重试失败项”。 - [ ] 图片插入后刷新当前页面资源区并标记 `not_indexed`。 ### Phase 3:OCR 预览与诊断 - [ ] 后端为 image/PDF/Office source 暴露 `ocrStatus` 与 `ocrTextPreview`。 - [ ] 图片资源 tab 增加 OCR/资料库状态按钮。 - [ ] 面板支持 OCR preview、placeholder-only 诊断、失败原因展示。 - [ ] Page AI target package 增加轻量 `resourceOcrStatus`。 ### Phase 4:Doctor 与配置修复 - [ ] 增加 registry doctor UI。 - [ ] 检测 MNote 读取的 LightRAG API key 与 provider 实际认证失败时的差异,给出明确配置建议。 - [ ] 对 stale/provider_missing 历史记录提供“归档测试记录”建议,但执行前必须确认。 - [ ] 增加失败重试与强制重建的确认流程。 ## 10. 验收标准 - 插入一张图片后,当前页面资源区能立即显示该图片为 `未索引`。 - 对该图片点击“索引”后,UI 进入 `索引中`,并能在 provider 完成后转成 `已索引` 或 `失败`。 - 图片如果 provider 只返回 Markdown 图片占位,UI 必须显示 `未暴露 OCR 正文`,不能显示成 OCR 成功。 - 图片 OCR 成功后,用户能在面板看到 OCR 预览,并能让 Page AI 基于 Knowledge RAG 查询引用。 - provider 不可达或 API key 错误时,页面编辑不受影响,面板显示明确诊断。 - 旧 `.ocr` sidecar 不作为普通页面进入 PageTree;历史 sidecar 只作为兼容资源打开。 - 非多模态模型面对未 OCR 图片时,不声称已读取图片内容。 ## 11. 测试计划 ### Rust - `cargo test -p mnote-web knowledge_rag -- --test-threads=1` - 增加 `knowledge_rag_status_reports_not_indexed_page_assets` - 增加 `knowledge_rag_status_reports_ocr_text_exposed_only_for_meaningful_sidecar` - 增加 `knowledge_rag_registry_doctor_reports_provider_missing_without_cleanup` - 增加 `page_ai_target_package_includes_resource_ocr_status_without_ocr_context` ### Browser smoke - 新增 `scripts/task8xx-knowledge-rag-panel-status-smoke.js` - 登录 `mnote-e2e` - 打开含图片页面 - 验证面板显示 provider health、当前页面图片、未索引状态 - 新增 `scripts/task8xx-knowledge-rag-image-index-flow-smoke.js` - 用测试图片触发索引 - 验证 FileTree 状态灯从未索引到索引中 - provider 可用时验证 OCR preview;provider 不可用时验证失败诊断 - 更新 Page AI smoke: - 文本模型未 OCR 图片:提示需要索引 - 多模态模型可临时读图,但回答标记未长期索引 ## 12. 风险 - LightRAG provider 解析大文件可能慢或超时;UI 必须将失败原因产品化,不能只显示“索引失败”。 - 自动索引新图片可能消耗 VLM / MinerU 成本;默认建议关闭,由 workspace preference 控制。 - registry 历史测试数据较多,doctor 只能提示,不应自动删除。 - provider 名称当前存在历史口径漂移;面板第一阶段必须先统一用户可见命名。 ## 13. Definition of Done - 用户在 MNote 内不用打开终端,就能判断当前图片/PDF/Office 是否已进入知识库、是否有 OCR 文本、是否失败、是否过期。 - 用户可以从当前页面一键索引本页附件,并看到可追踪状态。 - Page AI 能基于状态选择:直接读本地文件、多模态临时读图、或调用 Knowledge RAG。 - 旧 OCR sidecar 仍可兼容打开,但不会重新成为主路径。