返回 RAG 工程实战目录

文档预处理与入库流水线

完成解析、OCR、切片、向量化与对账

生命周期 · 阶段四 开发实现(离线侧) | 上游:环境就绪(04)| 下游:查询链路(06)

入库流水线六阶段:接收 → 解析 → OCR → 切片 → 向量化 → 索引。这是 RAG 效果的地基——垃圾进,垃圾出,检索质量上限由入库质量决定。

flowchart TD A["文档上传/接入"] --> B{"格式识别"} B -->|文本型| C["直接解析"] B -->|图片型/扫描件| D["OCR 识别"] C --> E["清洗去噪 去页眉页脚/水印"] D --> E E --> F["切片 Chunking"] F --> G["向量化 Embedding"] G --> H[("写入索引 向量 + 原文 + 元数据")] style H fill:#f0fff4,stroke:#4abf60

一、接收(Ingestion)

职责:接收上游文档,统一登记、去重、分发。

  • 接入方式:API 上传、Web 端拖拽、消息队列(Kafka/RabbitMQ)、定时同步(网盘/SFTP/钉钉文档)
  • 支持格式:PDF、Word、Excel、PPT、HTML、Markdown、TXT、图片、压缩包
  • 登记信息:文档 ID、文件名、来源、上传人、部门、密级、版本、哈希值
  • 去重策略:按文件内容哈希(MD5/SHA256)判重,重复文档不入库或仅更新元数据
  • 版本管理:同一文档更新时,新版本入库、旧版本下线(保留可回溯)

质量检查点

  • [ ] 重复上传同一文件不会产生重复切片
  • [ ] 损坏文件、加密 PDF、0 字节文件有明确报错而非静默失败
  • [ ] 超大文件(如 1000 页 PDF)不阻塞队列

二、解析(Parsing)

职责:把各格式文档提取为结构化文本(正文、标题层级、表格、图注)。

格式推荐工具说明
PDFPyMuPDF / pdfplumber文本型 PDF 直接抽取;表格用 pdfplumber
Wordpython-docx保留标题层级
Excelpandas / openpyxl每个 Sheet 转为 Markdown 表格
HTMLBeautifulSoup去广告、导航等噪声
通用Unstructured / Apache Tika一套 API 解析几十种格式

关键处理

  • 版面分析:区分正文 / 页眉页脚 / 水印 / 目录,剔除噪声
  • 阅读顺序:多栏 PDF 按正确顺序拼接(常见的解析乱序坑)
  • 表格处理:表格转为 Markdown/HTML 结构保留,整表尽量不切断
  • 元数据提取:标题、章节、页码——切片时要随切片携带

质量检查点

  • [ ] 抽取文本与原文抽查比对,无乱码、无漏段、无重复段
  • [ ] 表格行列还原正确(抽查 10 张表)
  • [ ] 页眉页脚、水印文字已被过滤

三、OCR(光学字符识别)

职责:对扫描件、图片型 PDF、照片做文字识别。只对需要的页面做(先判断是否已有文本层)。

  • 触发判断:解析阶段发现页面无文本层或文本量过低 → 转 OCR 分支
  • 引擎选型:PaddleOCR(开源、中文强)/ Tesseract / 商用 API(精度高)
  • 预处理:倾斜校正、去噪、二值化,可显著提升识别率
  • 结构还原:识别结果按版面重排,避免文字顺序错乱
  • 置信度处理:低置信度片段打标记,可用于后续质量评估

已知短板(测试重点关注)

  • 手写字、印章遮挡文字、模糊扫描件识别率骤降
  • 竖排版、繁体、艺术字识别差
  • 表格线还原错乱导致行列错位

质量检查点

  • [ ] 扫描件关键字段识别准确率抽样 ≥ 目标值(如 98%)
  • [ ] 中英混排、数字与日期识别正确(金额、日期是重灾区)
  • [ ] OCR 失败的页面有告警与人工兜底流程

四、切片(Chunking)

职责:把长文本切成适合检索的片段。切片质量直接决定召回精度——切太碎语义不完整,切太大噪声多且耗 token。

常见切片策略

策略原理适用
固定长度每 500 字一段简单场景,基线方案
递归分割先按段落→句子→字符逐级切,尽量保完整语义(LangChain 默认)通用推荐
按结构切按标题/章节边界切有清晰目录的文档(手册、制度)
语义切片用 Embedding 计算相邻句相似度,在语义突变处断开质量要求高,成本略高
父子切片检索用小切片(准),生成用其父切片(上下文全)精度与上下文兼得,推荐进阶

关键参数经验值

  • chunk_size:中文 300~800 字起步,问答类偏小,叙述类偏大
  • overlap(重叠):10%~20%(如 500 字 + 50~100 重叠),防止关键句被切断
  • 表格:整表一个切片;超长表按行组切并保留表头
  • 每个切片至少携带可追溯元数据:文档 ID、版本、来源位置和更新时间;章节、页码、权限标签等字段按文档类型与业务要求配置

质量检查点

  • [ ] 抽查切片可独立读懂,无"断了半句话"
  • [ ] 切片长度分布合理(无大量超短/超长切片)
  • [ ] 表格未被腰斩,表头随行携带

五、向量化(Embedding)

职责:把每个切片转成语义向量。

  • 模型:BGE / M3E / text-embedding-3 等(见 02 篇选型)
  • 预处理:部分模型需加指令前缀(如 BGE 查询侧加 "为这个句子生成表示…")
  • 批量编码:批量推理提升吞吐,注意限流
  • 归一化:向量 L2 归一化后用内积即余弦相似度
  • 维度:bge-large 1024 维、text-embedding-3-small 1536 维——建库时确定,不可中途更换模型(换模型 = 全量重建)

质量检查点

  • [ ] 用项目语料建立相似、易混和无关文本对,记录分数分布并建立自己的冒烟基线;不同模型的分数不可直接套用统一阈值
  • [ ] 批量编码无静默丢片(入向量数 = 切片数)
  • [ ] 空切片、超长切片有拦截或拆分

六、索引(Indexing)

职责:向量 + 原文 + 元数据写入向量数据库,建立可检索索引。

向量库核心设计

// Collection Schema 示例
{
  "collection": "kb_docs",
  "fields": {
    "id":          "主键(自动生成)",
    "vector":      "FLOAT_VECTOR(1024)",
    "text":        "切片原文",
    "doc_id":      "所属文档ID",
    "doc_name":    "文档名",
    "page":        "页码",
    "section":     "章节",
    "department":  "所属部门(权限过滤用)",
    "security":    "密级",
    "version":     "版本号",
    "created_at":  "入库时间"
  },
  "index": "HNSW(m=16, efConstruction=200)",
  "metric": "COSINE"
}

索引类型对比

索引特点适用
HNSW查询快、召回高,内存占用大默认推荐
IVF_FLAT可控折中,需训练大规模
FLAT暴力精确检索小数据量、评测基准

混合检索(Hybrid Search)

  • 向量检索(语义)+ BM25 关键词检索(精确词、编号、人名)→ RRF 融合
  • 金融/法律等专有名词多的场景强烈建议开混合检索

质量检查点

  • [ ] 入库条数 = 切片条数,无丢失
  • [ ] 元数据完整(随机抽 10 条核对)
  • [ ] 相似度检索 top1 命中预期切片(冒烟)
  • [ ] 文档删除后,其切片同步物理删除
  • [ ] 权限字段(部门/密级)随切片正确写入

七、流水线整体测试要点(详见 08 篇)

  • 端到端正确性:上传 → 可检索 → 可回答
  • 幂等性:重复上传不产生重复数据
  • 删除一致性:删文档/换版本后检索不到旧数据
  • 异常容错:坏文件、大文件、并发上传
  • 性能:单文档入库耗时、1000 文档批量入库吞吐

本篇交付与下一步

本阶段应留下源文件清单、解析产物、切片配置、嵌入版本、导入批次和文档/切片/向量对账结果。接口返回成功不代表入库完成;还要验证可检索、无重复、无缺失向量且失败队列已处理。下一步进入 06-检索与生成链路设计