LangChain实战(六):Document Transformers - 文本分割与处理
本文是《LangChain实战课》系列的第六篇,将深入探讨LangChain中的Document Transformers,特别是文本分割技术。你将学习为什么需要文本分割、各种分割器的原理与使用,以及如何优化分割策略来提升AI应用的效果。
前言
在上一篇文章中,我们学习了如何从各种数据源加载文档。然而,加载的原始文档往往过长或不适合直接用于大语言模型。今天,我们将深入探讨Document Transformers,特别是文本分割技术,这是构建高效AI应用的关键步骤。
为什么需要文本分割?
1. 模型上下文长度限制
大语言模型(LLM)有固定的上下文窗口限制,例如:
-
GPT-3.5-turbo: 4096 tokens
-
GPT-4: 8192 tokens(某些版本可达32768 tokens)
-
Claude 2: 100000 tokens
过长的文档需要被分割成适合模型处理的块。
2. 提高检索效果
在检索增强生成(RAG)系统中,较小的、语义集中的文本块能提高检索的准确性和相关性。
3. 保持语义完整性
合理的分割可以确保每个文本块包含完整的语义单元,如段落、章节或完整的思想。
4. 处理效率优化
较小的文本块可以提高处理速度,减少内存使用,并允许并行处理。
核心文本分割器详解
1. RecursiveCharacterTextSplitter
这是最常用且功能强大的文本分割器,它递归地尝试不同的分隔符来分割文本。
工作原理
RecursiveCharacterTextSplitter
按照以下优先级顺序尝试分隔符:
"\n\n"
(双换行符)- 段落分隔"\n"
(单换行符)- 行分隔" "
(空格)- 单词分隔""
(空字符)- 字符分隔
这种递归方法确保即使某些分隔符不存在,也能找到合适的分割点。
基本使用
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.docstore.document import Document# 创建示例文档
sample_text = """
机器学习是人工智能的一个分支,它使计算机系统能够从数据中学习并改进,而无需明确编程。深度学习是机器学习的一个子领域,使用多层神经网络来处理复杂模式和大规模数据。自然语言处理(NLP)是人工智能的另一个重要领域,专注于让计算机理解和生成人类语言。
"""document = Document(page_content=sample_text, metadata={"source": "sample"})# 初始化分割器
text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, # 每个块的最大字符数chunk_overlap=20, # 块之间的重叠字符数length_function=len, # 计算长度的方法separators=["\n\n", "\n", " ", ""] # 分隔符优先级
)# 分割文档
docs = text_splitter.split_documents([document])print(f"原始文本长度: {len(sample_text)}")
print(f"分割后的文档数: {len(docs)}")
for i, doc in enumerate(docs):print(f"文档 {i+1} (长度: {len(doc.page_content)}): {doc.page_content}")print(f"元数据: {doc.metadata}")print("---")
2. CharacterTextSplitter
基于字符的分割器,使用固定的分隔符进行分割。
from langchain.text_splitter import CharacterTextSplitter# 使用特定分隔符进行分割
text_splitter = CharacterTextSplitter(separator="\n", # 使用换行符作为分隔符chunk_size=150,chunk_overlap=30,length_function=len
)docs = text_splitter.split_documents([document])
3. TokenTextSplitter
基于token数量的分割器,更适合LLM的token限制。
from langchain.text_splitter import TokenTextSplitter
import tiktoken# 基于token的分割
text_splitter = TokenTextSplitter(chunk_size=100, # 每个块的token数chunk_overlap=20, # 重叠的token数encoding_name="cl100k_base" # OpenAI的编码方式
)docs = text_splitter.split_documents([document])
控制块大小和重叠
1. 块大小(Chunk Size)的选择策略
选择合适的块大小需要考虑多个因素:
def optimize_chunk_size(document_type, model_context_size=4096):"""根据文档类型和模型上下文大小优化块大小"""recommendations = {"technical_documentation": 512,"legal_document": 1024,"news_article": 256,"academic_paper": 768,"code_file": 384}# 保留20%的空间用于提示和响应effective_context_size = model_context_size * 0.8chunk_size