Skip to content

内容入库流程

入库是检索与语义加工的上游:内容只有先过了这条管线,才谈得上被搜到、被答到、被织进图谱。Molore的四类内容——笔记(note)、剪藏(clip)、知识单元(knowledge)、文档(document)——共用同一条入库管线:统一的全文/向量索引、统一的打标范围、统一的图谱语料口径。文档类多一段抽取前置。本页按数据流向讲这条管线。

管线总览

写入内容表
  →(仅文档)文本抽取:pymupdf / RapidOCR / XLSX·DOCX 表格管道化 / 图片后台 OCR
  → 向量前拦门:active + extraction_status=success + 正文 ≥200 字(图片 ≥20 字)
  → FTS5 全文索引(虚拟表 + 触发器)
  → sqlite-vec 向量索引(bge-m3,1024 维,分块)
  → 自动打标(本地 0.8b,零成本)
  → 图谱语料 / wiki 素材(语义加工层)
阶段模块关键机制代码位置
写入各域端点四类内容分表,统一内容 id 体系app/api/v1/endpoints/notes.py
文档抽取文档服务文字层优先,扫描件 OCR 降级,表格结构化app/services/document_service.pyapp/services/document_ocr.py
前拦门嵌入服务长度 + 状态门,不过门不进向量app/services/note_embedding_service.py
全文索引FTSFTS5 虚拟表 + 触发器,BM25app/services/fts_index.py
向量索引vecsqlite-vec 影子索引,分块嵌入app/services/vec_index.py
自动打标打标服务本地模型零成本,事件监听 + 定时兜底app/services/autotag_service.py
语义加工图谱/wiki语料口径 = 前拦门 + index_only 过滤app/services/graphify_service.pyapp/services/wiki_service/

文档抽取(仅 document 类)

抽取把上传文件转成 content_text 文本层,原始文件不动;extraction_status 记录 pending / success / errorapp/models/content.py)。

  • PDF:pymupdf 抽文字层;文字层里的线框表格用 find_tables() 结构化成 Markdown 表(单页失败只丢结构不丢文字,回落纯文本)。扫描件无文字层时走 RapidOCR,信号量 _ocr_semaphore = threading.Semaphore(1) 限 1 并发,OCR 不可用时优雅降级不阻塞入库。
  • XLSX:每个工作表输出 ## 工作表:{名} 章节前缀 + Markdown 管道表(首个 ≥2 非空行的行作表头,无够格表头不硬造);单元格批注内联为「值(批注:…)」。
  • DOCX:按 body 顺序遍历段落与表格,表格同样转管道表——此前实现只取段落、整表丢弃,属已修复的实捕缺陷。
  • 图片:后台 OCR,产物进同一文本层。
  • 表格结构化的价值在检索侧兑现:表格行会生成 row:: 带章节前缀 + 列名的结构化行条目(500 行限帽),供枚举/整表补全通道直取(见检索问答)。

向量前拦门

不是一切内容都进向量。过门条件(note_embedding_service.py):

  • 正文 ≥ MIN_EMBED_TEXT_LEN = 200 字;图片文档放宽到 MIN_EMBED_TEXT_LEN_IMAGE = 20 字(OCR 文本常不足 200 字,200 字门会把绝大多数图片文档永远拦在向量通道外);
  • 内容处于 active 状态;
  • 文档类要求 extraction_status = success

个人与团队内容同口径过门,空间隔离不在此处分流,而在检索侧内容行收口。不过门的内容仍可被 FTS 与 SQL 直查命中。

全文与向量索引

  • FTS5app/services/fts_index.py):虚拟表 + 触发器随内容事务同步,BM25 排序,启动钩子负责探测与回填。
  • sqlite-vecapp/services/vec_index.py):影子向量索引,嵌入统一 bge-m3 1024 维;长文按块嵌入(chunk 行带父内容引用),/health 端点回报 vec_index 可用性。

两路索引是检索问答的双通道底座,召回侧如何融合见检索问答

自动打标

过门内容进自动打标范围(note/clip/knowledge/document 四类):

  • 全程本地模型 qwen3.5:0.8b,零成本,绝不自动扣费;本地模型不可用就跳过,不回落计费通道。
  • 长文抽样取「头 1200 + 中 400 + 尾 400」送模型,避免纯头部样本代表不了全文。
  • 触发链 = 内容变更事件监听 + 启动 120s 首扫 + 每小时兜底扫描autotag_service.py);事件驱动必须配定时兜底,这是云端打标曾静默死过三周换来的纪律。
  • 标签关联带 source(auto/manual),手动重打只清 auto;模型失败文本([Error: ...])不会被当成标签挂上。

存量回填机制

管线升级(如 XLSX/DOCX 表格管道化上线)后,存量内容靠一次性回填追平,机制统一:

  • 启动后延迟约 120s 后台执行,让启动主链路先就绪;
  • 完成标记落 system_configs(如表格抽取回填的 marker extract_md_tables_v1),全成才落 marker,重跑幂等;
  • 有差异才更新:比对抽取结果,变了才写回文本层并重走 FTS 重同步 + 向量重嵌,零差异零写入。

仓库模式门禁(index_only)

notes/browser_clips/documents 三表有 index_only 列(迁移 DEFAULT 0)。置位表示「仅入库检索」:

  • 只进检索层——FTS/向量/SQL 直查照常,RAG 照常可答;
  • 不进语义加工层——图谱语料、自动打标、复盘素材、wiki 代表标题、成本估算统一经 app/core/tenant_scope.pysemantic_visible() 过滤(NULL 兼容老库);
  • 站内统计与存储计费不滤
  • 取消标记即回归全加工,由打标兜底扫描、下次建图、wiki 编译等周期机制自然接管,无专门入口。

下一步

基于 AGPL-3.0 协议发布。