RAG中文档分片高级策略

总结摘要
RAG中文档分片高级策略

除了设置**分片覆盖率(Overlap)**来保证上下文的连贯性之外,文档分片(Chunking)还有很多高级策略。不同的分片策略直接决定了 RAG 系统召回的准确率。

1. 语义分片

这是目前最先进的分片方法之一,不是基于固定的字符数,而是基于语义的变化

  • 原理: 将文档切分成句子,计算相邻句子之间的** Embedding 相似度**。如果两个句子的相似度突然急剧下降(语义发生了转折),就在这里进行切分。
  • 优点: 能够确保每个分片内部讨论的是同一个主题,不会把“iPhone 15 的价格”和“特斯拉的刹车”切到同一个块里。
  • 适用场景: 小说、技术文档、演讲稿等语义边界明显的长文本。
  • LangChain4j 实现: 需要结合 EmbeddingModel 自定义实现,或使用 LangChain 中的 SemanticChunker 概念。

2. 递归字符分片

这是目前最通用的“标准做法”,比单纯的固定字符切分更智能。

  • 原理: 按照优先级列表尝试切分。例如:先尝试按段落切分 \n\n;如果段落依然太大,再尝试按句子切分 .;如果句子还大,最后才按字符强制切分。
  • 优点: 它会尽最大努力保持句子的完整性,避免把一句话从中间截断,导致语义丢失。
  • 适用场景: 几乎所有通用文本。
  • LangChain4j 实现: DocumentSplitters.recursive(...)

3. 父文档检索

这是解决“分片太小丢失上下文”与“分片太大匹配不准”这一矛盾的绝佳方案。

  • 原理:
    1. 索引阶段: 将文档切分成小块(例如 200 Token),并记录它们属于哪个父文档(例如 2000 Token)。
    2. 检索阶段: 向量搜索在小块中进行(搜索更精准)。
    3. 生成阶段: 检索到相关的小块后,返回其对应的父文档给 LLM。
  • 优点: 既拥有向量搜索的高精度(小块搜索准),又给 LLM 提供了丰富的上下文(大块内容全)。
  • 面试话术: “为了解决信息碎片化问题,我采用了父文档检索策略,用小块做索引,用大块做生成。”

4. 结构化/元数据分片

利用文档本身的格式信息进行智能切分,而不是把文档当成纯文本流。

  • 原理: 解析 Markdown、HTML 或 PDF 的结构。优先按照 ## 标题- 列表表格 等标签进行切分。同时,保留切分前的标题路径作为元数据。
  • 举例:
    • 原文:一段讲“苹果手机价格”的话。
    • 分片后内容: “…售价 5999 元…”
    • 附带元数据: section: "电子产品/手机/苹果"
  • 优点: 提升了召回的准确度。例如用户搜“手机多少钱”,向量匹配可能不准,但通过元数据过滤 section 包含“手机”的块,就能精准命中。
  • 面试话术: “我在分片时保留了 Markdown 的层级结构作为元数据,这样在检索时可以进行元数据过滤,显著降低了幻觉。”

5. QA 合成 / 假设性问题生成

这是一种“反其道而行之”的分片思路,由微软提出。

  • 原理: 不直接切分文档,而是让 LLM 读取分片内容,并生成 3-5 个该分片能回答的问题
  • 索引:生成的问题进行 Embedding 存入 ES,而不是原文。
  • 检索: 用户提问时,其实是在匹配这些问题,匹配到了再返回对应的原文分片。
  • 优点: 解决了“用户问法”和“文档写法”不一致的问题。
  • 缺点: 成本较高,索引时间变长。
  • 面试话术: “为了解决 Query 和文档语义鸿沟的问题,我尝试了基于假设性问题的索引策略,用 LLM 生成问题来代替原文进行向量化。”

6. 滑动窗口与小结

这种方法常用于处理超长文档(如长篇法律条文、财报)。

  • 原理:
    1. 将长文档切分为较大的重叠块(例如 1000 tokens,重叠 500)。
    2. 让 LLM 对每个块生成一个摘要
    3. 将这些摘要进行索引,或者将摘要再次组合。
  • 或者(滑动窗口索引): 每次切分取 N 个 token,但是只取中间的 M 个 token 做索引(边缘部分丢弃或重叠),避免切片边缘的信息不完整。

总结:面试中如何回答

如果面试官问:“除了设置覆盖率,你还知道哪些分片方法?”

你可以这样回答:

“除了基本的固定大小切分和重叠设置,我在实践中更关注以下几种策略来提升效果:

  1. 首选递归分片: 优先按段落、句子切分,尽量不破坏句子完整性,这是 LangChain4j 中的推荐做法。
  2. 语义分片: 针对逻辑性强的文档,我会计算句向量的余弦相似度,在语义突变处切分,而不是死板地按字符数切。
  3. 父文档检索(重要): 这是我解决上下文不足的关键。我用小块做索引提高召回精度,但在返回给 LLM 时,返回小块所属的大块父文档,保证 LLM 拥有完整的信息。
  4. 元数据保留: 我不会丢弃标题结构,而是把标题路径作为元数据存入 Elasticsearch,这样检索时可以结合 Filter 进行过滤,极大提高精准度。”