? ? ? ?在RAG系统中,包括检索和生成两大组件,而检索的关键是对数据的分块策略,本文将根据Greg Kamradt的视频(https://www.youtube.com/watch?v=8OJC21T2SL4)整理如下五个分块级别策略,代码实现在参考文献[2]:
? ? ? ?这是最粗糙和最简单的文本分割方法。它将文本分解为指定数量的字符块,而不考虑其内容或结构。
? ?Langchain和llamaindex框架为这种分块技术提供了CharacterTextSplitter和SentenceSplitter(默认为对句子进行拆分)类。需要记住的几个概念:
? ? ? ?虽然固定大小的分块更容易实现,但它不考虑文本的结构。递归分块使用一组分隔符,以分层和迭代的方式将文本划分为更小的块。如果最初分割文本的尝试没有产生所需大小的块,则该方法会使用不同的分隔符递归地调用结果块,直到达到所需的块大小。
? ? ? ?Langchain框架提供了RecursiveCharacterTextSplitter类,该类使用默认分隔符(“\n\n”, “\n”, “ “,””)分割文本
? ? ? ?在这种分块方法中,我们根据文档的固有结构对其进行拆分。这种方法考虑了内容的流动和结构,但可能不是缺乏明确结构的文件。
? ? ? ?以上三个级别都处理文档的内容和结构,并且需要保持块大小的恒定值。这种分块方法旨在从嵌入中提取语义,然后评估这些分块之间的语义关系。核心思想是将语义相似的块放在一起。
? ? ??LlamaIndex具有SemanticSplitterNodeParser类,该类允许使用块之间的上下文关系将文档拆分为块,使用嵌入相似性自适应地选择句子之间的断点。
SemanticSplitterNodeParser超参数介绍:
? ? ? ?这种分块策略探索了使用LLM来根据上下文确定块中应包含多少文本以及哪些文本的可能性。
? ? ? ?为了生成初始块,参考论文《Dense X Retrieval: What Retrieval Granularity Should We Use?》,从原始文本中提取独立语句。Langchain提供了propositional-retrieval模板(https://templates.langchain.com/new?integration_name=propositional-retrieval)来实现这一点。
? ? ? ?在生成命题之后,这些命题输入到基于LLM的代理。该代理确定命题是否应包括在现有块中,或者是否应创建新块。
[1]?https://medium.com/@anuragmishra_27746/five-levels-of-chunking-strategies-in-rag-notes-from-gregs-video-7b735895694d
[2]?https://github.com/FullStackRetrieval-com/RetrievalTutorials/blob/main/5_Levels_Of_Text_Splitting.ipynb
[3]?https://docs.llamaindex.ai/en/stable/examples/node_parsers/semantic_chunking.html