RAG 系统中文本分割(Chunking)的原理与最佳实践
在构建基于大语言模型(LLM)的应用程序,尤其是检索增强生成(RAG)系统时,Chunking(文本分块)是将大量非结构化文本分解为较小、可管理片段的关键过程。这是优化从向量数据库中获得的 LLM 上下文嵌入内容相关性的核心环节。本文将深入探讨 Chunking 如何影响 RAG 应用的效率与准确性,并分析不同策略的权衡。
为什么需要文本分割(Chunking)
在 RAG 架构中,我们在向量数据库(如 Pinecone、Milvus 等)中索引的任何内容都需要先经过 Embedding(嵌入)处理。Chunking 的主要目的是在对上下文片段进行嵌入的过程中,尽可能减少噪声,同时保证内容仍然具有语义相关性。
语义搜索场景
在语义搜索场景中,我们为一个文档集建立索引,每个文档都包含有关特定主题的宝贵信息。通过采用有效的分块策略,可以确保搜索结果准确匹配用户查询的本意。
- 块太小:会导致关键上下文信息丢失,可能错过真正相关的内容,导致检索结果碎片化。
- 块太大:可能导致搜索结果不准确,因为一个过大的块可能包含多个不相关的主题,稀释了核心语义,使得向量表示不够精确。
一般来说,如果一段文字脱离语境的上下文,对于人类来说仍然可以理解其含义,那么这段文字对于语言模型来说也是可以理解的。因此,确定语料库中文档的最佳块大小对提高搜索结果准确性和相关性是非常重要的。
会话智能体场景
在构建会话智能体(Conversational Agents)时,我们需要使用知识库中嵌入的文本段来构建让智能体使用的知识上下文。这种情况下,必须对这些文本段作出正确的选择,原因有二:
- Prompt 相关性:这决定了嵌入的知识是否与我们的 Prompt 相关(Prompt 中会嵌入真正的用户问题)。如果检索到的块与问题无关,生成的回答将产生幻觉或错误。
- Token 限制:检索到文本的大小决定了我们是否能够将嵌入到要发送的上下文中传递给外部模型提供商(例如 OpenAI),因为每个模型支持的发送 Token 的数量是有限的。例如,使用有 32k 上下文窗口的 GPT-4,文本切分的问题可能不大。然而,在使用非常大的文本块时,仍需要谨慎处理,因为这可能对从向量数据库得到的结果的相关性产生负面影响,甚至导致请求因超出 Token 限制而失败。
Embedding 大文本和小文本
当嵌入内容时,可以根据内容是简短(例如句子)还是长(例如文本段或整个文档)来设计不同的 Embedding 行为。理解这种差异对于选择合适的 Chunking 策略至关重要。
句子级嵌入
当一个句子被嵌入时,得到的向量会聚焦于该句子的特定含义。当用其他句子的嵌入进行搜索时,通常在这一层面上进行。这也意味着该嵌入可能会遗漏在文本段或文件中会找到的更宽泛的上下文信息。这种方法适合需要精确匹配具体事实或定义的场景。
段落/文档级嵌入
当一个完整的段落或文档被嵌入时,嵌入过程要关注整体的上下文以及文本内部句子和短语之间的关系。这可能会产生一个更全面的向量表示,向量会表示出文本更广泛的含义和主题。另一方面,较大的输入文本尺寸可能会引入噪声、淡化单个句子或短语的重要性,使得在查询索引时找到精确匹配更困难。
查询长度的影响
查询的长度也影响着嵌入向量之间的关系。像一个单独的句子或短语这类较短的查询,会专注于具体内容,可能更适合与句子级别的嵌入进行匹配。一个跨越多个句子或一个段落的较长查询可能与段落或文档级别的嵌入更匹配,因为它可能在寻找更广泛的上下文或主题。
非均质索引的挑战
索引也可能是非均质的,并包含不同大小块的嵌入。这可能对查询结果的相关性提出挑战,但也可能有一些积极的影响。一方面,由于长短内容的语义表示之间的差异,查询结果的相关性可能会波动。另一方面,非均质索引可能能够更广泛地捕获上下文和信息,因为不同的块大小代表文本中不同级别的粒度。这可能更灵活地适应不同类型的查询,但会增加评估和优化的复杂度。
分块的思路与变量
确定最佳分块策略有几个关键变量,这些变量因使用场景而异。以下是一些需要注意的核心问题:
- 索引内容的特性是什么? 是在处理长篇文档,如文章、书籍或技术手册,还是较短的内容,如推文、即时消息或日志条目?这个答案将决定哪种模型更适合目标,并因此决定应用哪种分块策略。
- 正在使用哪种嵌入模型,它在哪种块大小上表现最佳? 不同的模型有不同的偏好。例如,句子转换模型在单个句子上表现良好,但像
text-embedding-ada-002这样的通用模型在包含 256 或 512 个标记的块上表现更优。了解模型的训练数据分布有助于设定初始参数。


