Files
mnote/design/07-ai/done/7-52-lightrag-image-ocr-search-chain-hardening-v1.md
T

9.2 KiB
Raw Blame History

7-52 LightRAG 图片 OCR 与搜索召回链路加固 v1

创建时间:2026-06-07

当前状态:DONE

2026-06-25 历史口径:本文记录 LightRAG 图片 OCR 与搜索召回链路当时已完成的历史事实,不再代表当前新主线。当前 7-68 OpenHub + WeKnora + MNote Page AI 深度融合 将默认知识库 provider 切到 WeKnora;本文只作为 lightrag_legacy / fallback / 迁移对照边界。

Owner07-ai / knowledge-rag / local-search

上位依据:design/07-ai/done/7-50-lightrag-knowledge-rag-provider-v1.md

1. 问题结论

这不是 Page AI 某次回答措辞错误,而是 LightRAG 集成链路同时暴露了三层缺口:

  • 图片 ingest 缺口:MNote 对图片 source 写入 LightRAG input 时使用 Markdown wrapper,当前 indexed chunk 只有 ![image](...) 占位,没有把 MinerU OCR 文本写入 LightRAG chunk / reference。
  • 工具契约缺口:mnote_knowledge_rag_queryrawMetadata.keywords、实体和关系计数暴露给 agent,但没有明确这些只是查询处理元数据,agent 容易把它误判为“source OCR 成功且已返回原文”。
  • 搜索召回缺口:/api/search/documents 仍是普通 local searchincludeOcr=true 目前不代表会查 LightRAG OCR 文本,因此搜索“线程作用域”不会命中目标图片。

2. 现场证据

目标 source

/mnt/Data1T/Mnote_data/users/mnote-e2e/workspaces/my-space/新页面233155/image copy 6.png

已确认的事实:

  • LightRAG source registry 中该图片为 processedlightRagDocId=doc-781c4b5f39f135886eb6062d8606058elightRagFilePath=mnote-d0985c21239b677d-image copy 6.png.md
  • kv_store_text_chunks.json 中对应 chunk 内容只有 # image copy 6.png 和 Markdown 图片占位。
  • 直接调用 LightRAG 的 MinerU parser CLI 解析原 PNG 可以识别出包含“线程作用域”的文本,并生成 blocks.jsonl 与 bbox。
  • /query/data 能在 metadata 里返回 rawMetadata.keywords.high_level=["线程作用域"],但 references/chunks 没有返回这段 OCR 原文;这只能证明查询分析或图谱元数据命中,不能证明引用文本已暴露。
  • /api/search/documents 查询 线程作用域 返回 0;代码中 include_ocr 只进入 meta,没有参与搜索。

3. 目标边界

本修复继续保持 7-50 的边界:

  • LightRAG 是知识库 OCR / parse / chunk / vector / graph / query provider。
  • MNote 不复制 LightRAG 图谱,不把 LightRAG chunk 当正文真相。
  • MNote 必须负责 source registry、权限、引用打开、普通搜索入口的边界标注,以及 agent 工具契约。
  • 普通搜索可以显示“资料库 OCR 命中”,但不能变成必须依赖 LightRAG 服务才能打开页面或搜索普通 Markdown。

4. 修复方案

P0:工具契约防误判

mnote_knowledge_rag_query 返回给 agent 的 compact result 必须明确:

  • rawMetadata.keywords、entity count、relation count 只是 provider 查询处理 / retrieval bookkeeping。
  • OCR 是否真正暴露,以 references[].quotereferences[].contentDiagnostics.ocrTextExposed 为准。
  • 当 quote 为空或只有 Markdown 图片占位时,agent 必须说明“返回引用未暴露 OCR 原文”,不能声称 OCR 成功。

验收:

  • 图片 wrapper quote # image.png\n\n![image.png](<image.png>) 被标记为 quoteOnlyImagePlaceholder=trueocrTextExposed=false
  • Agent 工具 compact result 不再把 raw metadata 当 OCR 成功证据;真实 Page AI 回答必须以该工具契约为准。

P1:图片 ingest 让 OCR 文本进入 LightRAG 可引用内容

图片 source 不能只靠 Markdown wrapper 占位入库。需要二选一并以真实探针定案:

  1. 优先方案:扩展 LightRAG /documents/scan 支持 .png/.jpg/.jpeg/.webp/.bmp/.tif/.tiff,并让 parser routing 对图片走 MinerU。MNote 对图片直接 symlink 原图入 inputs/registry 记录真实图片 source 和 LightRAG basename。
  2. 兼容方案:如果上游 scan 暂不支持图片,MNote connector 调用 LightRAG parser 能力为图片生成 provider sidecar,并写入包含 OCR 文本的受控 .md ingestion document,同时保留图片 openAction 指向原 source。该 .md 是 LightRAG staging 派生物,不进入 MNote 文件树正文。

无论选哪条,必须保证:

  • LightRAG chunk/reference 中能返回 OCR 文本,不只是图片占位。
  • blocks.jsonl 能通过 registry 反查到原图并生成 EvidenceLocator
  • reindex 会删除旧 wrapper doc,避免同一图片同时存在“占位 doc”和“OCR doc”。

验收:

  • 重新索引目标图片后,/query/data 查询 线程作用域 的 references/chunks 至少一项包含 OCR 文本。
  • sourceRootRelativePath 仍映射到 新页面233155/image copy 6.png
  • citation/openAction 打开原图资源,而不是打开派生 wrapper。

P1reference enrichment 与诊断

当 LightRAG 返回的 reference quote 为空、缺失或仅为图片占位时,MNote connector 应做有界补全:

  • 先按 chunk_idkv_store_text_chunks.json
  • 再按 registry 的 lightRagFilePathinputs/__parsed__/<file>.parsed/*.blocks.jsonl
  • 对图片占位类 quote,不能直接拿占位去匹配 sidecar;应允许按 query terms / block text 补最相关 OCR block。
  • 返回 contentDiagnostics,标明 quoteSource=chunk|sidecar|missing|placeholderocrTextExposedlocatorSource

验收:

  • OCR sidecar 已存在但 chunk 未带内容时,工具仍能返回一段真实 OCR quote,并标记来源为 sidecar
  • 若 sidecar 不存在,工具返回明确诊断,不把 metadata 当证据。

P1:普通搜索 includeOcr=true 语义落地

includeOcr=true 不能继续是 no-op。推荐先做“普通搜索 + 资料库 OCR 有界补充”:

  • 普通 Markdown / title / resource metadata 仍走本地轻索引。
  • includeOcr=true 且普通结果不足 limit 时,追加查询 LightRAG source registry + sidecar/chunk 的 OCR 文本结果。
  • 搜索结果必须标注 boundary.kind=ordinary_local_search_with_knowledge_ocr,单条结果标注 matchSource=knowledge_rag_ocr
  • LightRAG 不可用时普通搜索不失败,只设置 degraded=truedegradedReason=knowledge_rag_unavailable

验收:

  • /api/search/documents 查询 线程作用域includeOcr=true 能返回目标图片或 owner page。
  • includeOcr=false 保持原普通搜索语义。
  • 返回结果包含可打开的 resource locator/citation,不只是一条不可点击文本。

P2:健康检查与 UI 暴露

资料库状态面板需要区分:

  • source 是否 registered。
  • LightRAG doc 是否 processed。
  • OCR text 是否进入 chunk/reference。
  • sidecar 是否存在且可用于 locator。
  • 普通搜索是否能通过 includeOcr 召回。

验收:

  • 对目标图片能显示“processed but OCR text not exposed in reference/chunk”这类可操作状态,而不是只有绿灯。

5. 执行 Checklist

  • P0 工具契约:compact reference 增加 contentDiagnostics 并补单测。
  • P0 agent 工具契约 smoke:确认 compact result 不再把 raw metadata 当 OCR 成功证据。
  • P1 ingest spike:验证 LightRAG 直接 scan 图片扩展 vs MNote 调 parser 生成 OCR ingestion doc,选择一条实现。
  • P1 reindex migration:删除旧图片 wrapper doc 后重新索引目标图片。
  • P1 reference enrichmentsidecar/chunk/query term 补 quote,返回明确 quoteSource
  • P1 搜索:includeOcr=true 追加 knowledge OCR 命中,并保持 LightRAG 不可用时普通搜索降级。
  • P1 browser/API smoke线程作用域 在 knowledge-rag 和 /api/search/documents 两条入口都可召回并可打开来源。
  • P2 状态 UI:把 OCR 文本是否真正进入 reference/chunk 暴露成诊断项。

7. 验收证据

2026-06-07 已完成目标图片重建索引:

  • registry新页面233155/image copy 6.png -> lightRagDocId=doc-ac03e578a6c6af7eb0a3224276e4b954lightRagFilePath=mnote-d0985c21239b677d-image copy 6.[mineru].pnglightRagStatus=processed
  • LightRAG status diagnosticsdirectImageScan=truesidecarExists=trueocrTextExposed=truesidecarMeaningfulBlocks=2
  • /api/knowledge-rag/query 查询 线程作用域:首条 reference 映射到 新页面233155/image copy 6.pngquoteSource=sidecarcontentDiagnostics.ocrTextExposed=truelocatorDegraded=falsequote 含 线程作用域
  • /api/search/documents 查询 线程作用域includeOcr=true:返回 1 条 knowledge_rag_ocr 命中,path 为 新页面233155/image copy 6.pngsnippet 含 线程作用域boundary 为 ordinary_local_search_with_knowledge_ocr
  • /api/search/documents 查询 线程作用域includeOcr=false:返回 0 条,boundary 保持 ordinary_local_search,证明普通搜索未被强依赖 LightRAG。

8. 当前禁止事项

  • 不把 rawMetadata.keywords 当 source OCR 证据。
  • 不恢复 LiteParse 为默认 fallback。
  • 不把 OCR 文本写回用户 Markdown 正文。
  • 不让普通搜索强依赖 LightRAG 才能返回 Markdown 页面结果。
  • 不保留同一图片的旧占位 wrapper doc 与新 OCR doc 双索引状态。