本案例展示了如何使用LlamaIndex中的语义分块器(SemanticSplitterNodeParser)来智能地分割文本确保每个块包含语义相关的句子而不是简单地按照固定大小分割文本。1. 案例目标本案例的主要目标是演示语义分块的工作原理展示如何使用嵌入相似度来识别文本中的语义边界而不是使用固定大小的块。对比传统分块方法比较语义分块与传统的固定大小分块(SentenceSplitter)的效果差异。评估查询效果通过创建向量索引和查询引擎测试不同分块方法对查询结果的影响。2. 技术栈与核心依赖LlamaIndex用于构建索引和查询的核心框架OpenAI嵌入模型用于生成文本嵌入向量计算语义相似度SemanticSplitterNodeParserLlamaIndex中的语义分块器SentenceSplitter传统的基于句子和大小的分块器用作对比VectorStoreIndex用于创建向量索引3. 环境配置在运行本案例前需要安装以下依赖%pip install llama-index-embeddings-openai此外需要设置OpenAI API密钥import os os.environ[OPENAI_API_KEY] sk-...4. 案例实现4.1 数据准备案例使用Paul Graham的一篇散文作为示例数据from llama_index.core import SimpleDirectoryReader # 加载文档 documents SimpleDirectoryReader(input_files[pg_essay.txt]).load_data()4.2 创建语义分块器创建语义分块器设置缓冲区大小和断点百分位阈值from llama_index.core.node_parser import ( SentenceSplitter, SemanticSplitterNodeParser, ) from llama_index.embeddings.openai import OpenAIEmbedding embed_model OpenAIEmbedding() splitter SemanticSplitterNodeParser( buffer_size1, breakpoint_percentile_threshold95, embed_modelembed_model ) # 同时创建基准分块器用于对比 base_splitter SentenceSplitter(chunk_size512)4.3 分块处理使用两种分块器处理文档# 语义分块 nodes splitter.get_nodes_from_documents(documents) # 传统分块 base_nodes base_splitter.get_nodes_from_documents(documents)4.4 创建查询引擎为两种分块结果创建向量索引和查询引擎from llama_index.core import VectorStoreIndex # 语义分块的查询引擎 vector_index VectorStoreIndex(nodes) query_engine vector_index.as_query_engine() # 传统分块的查询引擎 base_vector_index VectorStoreIndex(base_nodes) base_query_engine base_vector_index.as_query_engine()5. 案例效果5.1 分块效果对比语义分块生成的块包含语义相关的句子例如一个块可能包含作者童年使用IBM 1401计算机的经历另一个块包含个人计算机和大学经历。传统分块按照固定大小(512字符)分割可能会在不相关的句子中间切断导致语义连贯性较差。5.2 查询结果对比当查询告诉我作者从童年到大学的编程历程时语义分块的查询结果提供了更连贯、更全面的回答包含了从IBM 1401到微计算机再到大学学习AI的完整历程。传统分块的查询结果回答相对简略可能遗漏了一些关键细节因为相关信息可能分散在不同的块中。6. 案例实现思路6.1 语义分块原理语义分块的核心思想是句子级别分割首先将文本分割成句子嵌入计算为每个句子生成嵌入向量相似度计算计算相邻句子之间的相似度断点识别在相似度低于阈值的位置设置断点块形成将断点之间的句子组合成一个块6.2 参数调优语义分块器有两个关键参数buffer_size控制断点前后的句子数量默认为1breakpoint_percentile_threshold控制断点设置的相似度阈值默认为95这些参数需要根据具体文本类型和需求进行调整以获得最佳的分块效果。7. 扩展建议7.1 多语言支持当前实现主要针对英语句子可以扩展支持其他语言的句子分割和语义分析。7.2 自定义嵌入模型除了OpenAI嵌入模型可以尝试使用其他嵌入模型如开源的Sentence-BERT模型以降低成本和提高隐私保护。7.3 动态阈值调整可以根据文本类型和内容自动调整断点阈值而不是使用固定的百分位阈值。7.4 层次化分块结合语义分块和传统分块先进行语义分块再对过大的块进行大小限制实现更灵活的分块策略。7.5 领域特定优化针对特定领域(如法律、医学、技术文档)训练专门的嵌入模型提高领域内语义相似度的准确性。8. 总结语义分块是一种创新的文本分割方法它通过分析句子之间的语义相似度来确定分块边界而不是简单地按照固定大小分割。这种方法能够更好地保持文本的语义连贯性提高检索和问答系统的性能。本案例展示了如何使用LlamaIndex中的SemanticSplitterNodeParser实现语义分块并通过与传统分块方法的对比证明了语义分块在保持语义连贯性和提高查询质量方面的优势。语义分块特别适用于处理长文档、构建知识库和开发RAG(检索增强生成)系统能够显著提升用户体验和系统性能。
【RAG】【Data-Processor】【node_parsers02】语义分块(Semantic Chunking)案例分析
本案例展示了如何使用LlamaIndex中的语义分块器(SemanticSplitterNodeParser)来智能地分割文本确保每个块包含语义相关的句子而不是简单地按照固定大小分割文本。1. 案例目标本案例的主要目标是演示语义分块的工作原理展示如何使用嵌入相似度来识别文本中的语义边界而不是使用固定大小的块。对比传统分块方法比较语义分块与传统的固定大小分块(SentenceSplitter)的效果差异。评估查询效果通过创建向量索引和查询引擎测试不同分块方法对查询结果的影响。2. 技术栈与核心依赖LlamaIndex用于构建索引和查询的核心框架OpenAI嵌入模型用于生成文本嵌入向量计算语义相似度SemanticSplitterNodeParserLlamaIndex中的语义分块器SentenceSplitter传统的基于句子和大小的分块器用作对比VectorStoreIndex用于创建向量索引3. 环境配置在运行本案例前需要安装以下依赖%pip install llama-index-embeddings-openai此外需要设置OpenAI API密钥import os os.environ[OPENAI_API_KEY] sk-...4. 案例实现4.1 数据准备案例使用Paul Graham的一篇散文作为示例数据from llama_index.core import SimpleDirectoryReader # 加载文档 documents SimpleDirectoryReader(input_files[pg_essay.txt]).load_data()4.2 创建语义分块器创建语义分块器设置缓冲区大小和断点百分位阈值from llama_index.core.node_parser import ( SentenceSplitter, SemanticSplitterNodeParser, ) from llama_index.embeddings.openai import OpenAIEmbedding embed_model OpenAIEmbedding() splitter SemanticSplitterNodeParser( buffer_size1, breakpoint_percentile_threshold95, embed_modelembed_model ) # 同时创建基准分块器用于对比 base_splitter SentenceSplitter(chunk_size512)4.3 分块处理使用两种分块器处理文档# 语义分块 nodes splitter.get_nodes_from_documents(documents) # 传统分块 base_nodes base_splitter.get_nodes_from_documents(documents)4.4 创建查询引擎为两种分块结果创建向量索引和查询引擎from llama_index.core import VectorStoreIndex # 语义分块的查询引擎 vector_index VectorStoreIndex(nodes) query_engine vector_index.as_query_engine() # 传统分块的查询引擎 base_vector_index VectorStoreIndex(base_nodes) base_query_engine base_vector_index.as_query_engine()5. 案例效果5.1 分块效果对比语义分块生成的块包含语义相关的句子例如一个块可能包含作者童年使用IBM 1401计算机的经历另一个块包含个人计算机和大学经历。传统分块按照固定大小(512字符)分割可能会在不相关的句子中间切断导致语义连贯性较差。5.2 查询结果对比当查询告诉我作者从童年到大学的编程历程时语义分块的查询结果提供了更连贯、更全面的回答包含了从IBM 1401到微计算机再到大学学习AI的完整历程。传统分块的查询结果回答相对简略可能遗漏了一些关键细节因为相关信息可能分散在不同的块中。6. 案例实现思路6.1 语义分块原理语义分块的核心思想是句子级别分割首先将文本分割成句子嵌入计算为每个句子生成嵌入向量相似度计算计算相邻句子之间的相似度断点识别在相似度低于阈值的位置设置断点块形成将断点之间的句子组合成一个块6.2 参数调优语义分块器有两个关键参数buffer_size控制断点前后的句子数量默认为1breakpoint_percentile_threshold控制断点设置的相似度阈值默认为95这些参数需要根据具体文本类型和需求进行调整以获得最佳的分块效果。7. 扩展建议7.1 多语言支持当前实现主要针对英语句子可以扩展支持其他语言的句子分割和语义分析。7.2 自定义嵌入模型除了OpenAI嵌入模型可以尝试使用其他嵌入模型如开源的Sentence-BERT模型以降低成本和提高隐私保护。7.3 动态阈值调整可以根据文本类型和内容自动调整断点阈值而不是使用固定的百分位阈值。7.4 层次化分块结合语义分块和传统分块先进行语义分块再对过大的块进行大小限制实现更灵活的分块策略。7.5 领域特定优化针对特定领域(如法律、医学、技术文档)训练专门的嵌入模型提高领域内语义相似度的准确性。8. 总结语义分块是一种创新的文本分割方法它通过分析句子之间的语义相似度来确定分块边界而不是简单地按照固定大小分割。这种方法能够更好地保持文本的语义连贯性提高检索和问答系统的性能。本案例展示了如何使用LlamaIndex中的SemanticSplitterNodeParser实现语义分块并通过与传统分块方法的对比证明了语义分块在保持语义连贯性和提高查询质量方面的优势。语义分块特别适用于处理长文档、构建知识库和开发RAG(检索增强生成)系统能够显著提升用户体验和系统性能。