“我们的离线数据摄取 Pipeline 主要分为五个阶段:解析、切分、增强、向量化和存储。整个流程的核心目的是将非结构化的原始文档,转化为具有高检索价值、且能被大模型准确理解的向量数据


1. Loader (文档解析)

这一步是数据清洗的源头,负责将各种复杂的文档格式统一化。

  • 输入:原始的非结构化文档(例如包含复杂排版的 PDF、Word、HTML 图片等)。

  • 处理机制:我们使用 MarkItDown 这样的工具将 PDF 转换为 Markdown 格式。之所以选择 Markdown,是因为它可以很好地保留文档的结构语义(比如标题层级、表格、列表)。同时,我们会提取文档的元数据(Metadata),比如作者、上传时间、来源文件名等。

  • 输出结构化的 Markdown 纯文本,以及附带的元数据字典(Metadata Dictionary)。

  • 💡 面试加分项:你可以强调,“保留结构语义”对于后续大模型理解文档上下文至关重要,直接提取纯文本往往会丢失章节关系。

2. Splitter (切分器)

大模型和向量模型都有上下文窗口限制,所以我们需要将长文本切分成短文本块。

  • 输入:上一步输出的完整 Markdown 长文本

  • 处理机制:使用 RecursiveCharacterTextSplitter递归字符文本切分器)。它会按照特定的分隔符顺序(如 \n\n -> \n -> 空格 -> 字符)递归地切分文本,尽量保证段落和句子的完整性。通常我们还会设置一定的 chunk_overlap(块重叠),防止关键信息在切分处被截断。

  • 输出:一系列带有上下文重叠的文本块(Chunks),通常每个块在 500-1000 个 Token 左右。

  • 💡 面试加分项:提到“语义连贯性”。说明采用递归切分而不是生硬的按字数切分,是为了防止把一个完整的句子或逻辑生生劈开。

3. Transform (增强处理)

这是体现架构深度的关键步骤。原始切分出来的文本块往往缺乏全局上下文,直接检索效果不好。

  • 输入纯文本块(Chunks)以及可能包含在内的图片

  • 处理机制

    • LLM 重写:利用大模型对文本块进行改写(例如代词替换、上下文补全)让每一个 Chunk 在独立存在时也能表达完整的意思

    • Image Captioning (图片摘要):针对文档中的图片,使用视觉模型生成描述性文本,将图像信息转化为可检索的文本信息。

  • 输出:经过语义丰富、能够独立表达完整含义的高质量 Chunk,以及图片的文本描述

  • 💡 面试加分项:这是解决 RAG 中“指代不明”(如“这个方法具有优势”,但不知道“这个”指什么)问题的最佳实践,能大幅提升最终的检索命中率。

4. Embedding (向量化)

将人类能看懂的文本转换为机器能进行相似度计算的数学表示。

  • 输入:上一步输出的高质量、富语义的 Chunk 及其元数据

  • 处理机制:我们采用了**混合检索(Hybrid Search)**的准备策略。

    • Dense (稠密向量):使用 OpenAI 或 BGE 模型提取语义向量,捕捉上下文和潜在含义。

    • Sparse (稀疏向量):使用 BM25 算法生成词频向量,用于精准的关键词匹配。

  • 输出为每一个 Chunk 绑定两组数学表达:一组稠密向量(浮点数数组)和一组稀疏向量,连同原始文本一起打包。

  • 💡 面试加分项:强调“混合检索”的必要性。稠密向量擅长理解“意思相近”,但在匹配专有名词、序列号、缩写时容易产生幻觉或遗漏,BM25 刚好可以弥补这个精准匹配的短板。

5. Upsert (存储)

最后一步是数据入库,要求做到安全、高效且可重复执行。

  • 输入:包含原始文本、元数据、稠密向量和稀疏向量的完整数据包

  • 处理机制:将数据写入 Chroma 向量数据库。这里我们特别采用了 Upsert (Update or Insert) 的方式进行“幂等写入”。这意味着系统会根据文档 ID 进行校验,如果文档不存在则插入,如果已存在则更新。

  • 输出:成功建立索引的数据库条目,随时准备好接受在线(Online)的检索请求。

  • 💡 面试加分项:一定要突出“幂等写入(Idempotent Writing)”这个词。这向面试官证明了你具备工程化思维——你考虑到了流水线可能会重复运行、或者文档会发生更新,幂等设计可以防止数据库里出现大量重复的脏数据。


Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐