
文本分块(Text Splitting),RAG不可缺失的重要环节
本文介绍了在增强检索生成(RAG)流程中,文本分块的重要性和实现方式。详细解释了为什么要对文本进行切分及代码示例,展示了分块后的效果。通过合理分块,可以有效应对模型的输入限制,提升检索与生成的质量,是构建高效 LLM 应用的关键步骤之一。
1. 文档分块的原因
2. 文档分块的基本思路
2.1 基于长度的分块类型
2.2 代码实现
2.2 拆分结果
3. 图形化显示分块
总结
在快速发展的自然语言处理(NLP)领域,增强检索生成(RAG)已成为提高 AI 生成响应的准确性和相关性的强大技术。
在 RAG 的核心步骤中,有一个至关重要的步骤:“文本分块(Text Splitting)”。
它的主要作用就是把一大段文本切分成更小、更合理的片段,这样模型才能更好地理解、处理或者存储这些内容。
比如说,如果你有一篇几千字的文章,直接丢给模型处理,很可能会超过它的最大上下文长度(就是它一次能“看”的最多字数)。这个时候就得用 文本分块(Text Splitting)来把文章拆成几段,让每一段都不超出模型的处理能力,而且尽量保证语义完整、段落自然,不要断在奇怪的地方。
除了应对长度限制,还有个原因是为了更精准地做 embedding、搜索或者问答。
举个例子,如果你用 RAG 来做知识库问答,先要把整个文档转成 embedding(向量表示),然后做向量检索找出相关内容。
如果一整篇文章不拆开,那 embedding 的颗粒度太粗,问答的时候很容易不准。所以切得好不好,直接影响最后答案的相关性和准确性。
1. 文档分块的原因
拆分文档有几个原因:
- 处理不均匀的文档长度:现实世界的文档集合通常包含不同大小的文本。拆分确保对所有文档进行一致的处理。
- 克服模型限制:许多嵌入模型和语言模型都有最大输入大小限制。拆分允许我们处理那些否则会超出这些限制的文档。
- 提高表示质量:对于较长的文档,嵌入或其他表示形式的质量可能会随着过多信息而降低。拆分可以导致每个部分更加集中和准确的表示。
- 增强检索精度:在信息检索系统中,拆分可以提高搜索结果的粒度,从而允许查询与相关文档部分的更精确匹配。
- 优化计算资源:处理较小的文本块可以更加节省内存,并允许更好的并行处理任务。
2. 文档分块的基本思路
最基本的分块方法是根据文档的长度进行拆分。这种简单而有效的方法确保每个块不会超过指定的大小限制。
基于长度拆分的主要好处:简单明了的实现、一致的块大小、易于适应不同模型的要求。缺点就是: 过于死板,忽视文本结构。
2.1 基于长度的分块类型:
- 基于token的:根据token数量分割文本,这在使用语言模型时非常有用。
- 基于字符的:根据字符数量分割文本,这在不同类型的文本中可能更为一致。
2.2 代码实现
以基于字符的拆分为例来了解分块的基本思路:
需要了解的概念
- 块大小(Chunk Size)- 每个数据块包含的字符数,比如 50、100、100,000 等。
- 块重叠(Chunk Overlap)- 相邻数据块之间重叠的字符数量。这样做是为了避免将一个完整语境拆成几部分,但会导致各块之间出现重复数据。
使用LangChain创建 CharacterTextSplitter 实例,设置三个关键参数:
- chunk_size=15 :每个分割块的最大字符数为15
- chunk_overlap=5 :相邻块之间重叠的字符数为5,这有助于保持上下文连贯性
- separator='' :使用空字符串作为分隔符,意味着将按照纯字符数量进行分割,而不是按照特定分隔符(如句号、空格等)
from langchain.text_splitter import CharacterTextSplitter
text = "青云山连绵百里,峰峦起伏,最高有七峰,高耸入云,平日里只见白云环绕山腰,不识山顶真容。青云山山林密布,飞瀑奇岩,珍禽异兽,在所多有,景色幽险奇峻,天下闻名。"
text_splitter = CharacterTextSplitter(chunk_size=15, chunk_overlap=5, separator='')
docs = text_splitter.create_documents([text])
for doc in docs:
print('-' * 50)
print(doc)
2.2 拆分结果
根据设置的参数(chunk_size=15和chunk_overlap=5),文本被分成了8个片段,每个片段大约包含15个字符(包括标点符号),相邻片段之间有5个字符的重叠,这确保了文本的连贯性。
例如:"起伏,最高"这部分内容在第一段末尾和第二段开头都出现,这就是重叠的效果
分割后的每个片段都保持了基本的可读性,虽然有些句子被切分开了。
最后一个片段"奇峻,天下闻名。"因为是文本末尾,所以长度较短,不足15个字符
--------------------------------------------------
page_cnotallow='青云山连绵百里,峰峦起伏,最高'
--------------------------------------------------
page_cnotallow='起伏,最高有七峰,高耸入云,平'
--------------------------------------------------
page_cnotallow='耸入云,平日里只见白云环绕山腰'
--------------------------------------------------
page_cnotallow='云环绕山腰,不识山顶真容。青云'
--------------------------------------------------
page_cnotallow='真容。青云山山林密布,飞瀑奇岩'
--------------------------------------------------
page_cnotallow=',飞瀑奇岩,珍禽异兽,在所多有'
--------------------------------------------------
page_cnotallow=',在所多有,景色幽险奇峻,天下'
--------------------------------------------------
page_cnotallow='奇峻,天下闻名。'
3. 图形化显示分块
通过www.chunkviz.com可以以图形化的方式看到分块结果。
总结
文本分块虽然看起来只是把文本切成小段,但它在大语言模型的应用中扮演着非常重要的角色。
它不仅解决了模型上下文长度的限制问题,还直接影响了后续任务的效果,比如 embedding 的精度、搜索的相关性、问答的准确性等等。
切分策略得当,不仅能提升模型的理解力,还能让整个系统运行得更高效、更智能。所以在设计 LLM 应用时,文本分块绝对不是一个可以忽略的细节,而是值得精心打磨的核心组件之一。
本文转载自AI取经路,作者:AI取经路
