适用场景:标准化文档(如普通文本文档、无明显强结构的网页内容)、追求简单快速实现的场景,或作为其他方法的预处理步骤。
原理:严格按照字符数或Token数进行切割。
示例(LangChain):
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(
chunk_size=1000, # 每个片段最大字符数
chunk_overlap=200, # 相邻片段重叠字符数
separator="\n", # 优先在换行符处分割,其次按字符切
length_function=len # 计算长度的方法(此处按字符数)
)
chunks = text_splitter.split_text(your_text)
参数优化建议与考量:
chunk_size
(核心):chunk_overlap
(关键):chunk_size
的10%-25%。信息密度高或结构松散文档可适当增加。separator
(提升语义):["\n\n", "\n", " ", ""]
),优先在段落、句子、单词边界处切割,避免在单词或数字中间切断。length_function
:根据需求选择按字符数 (len
) 或 Token 数(如 tiktoken
库计算)分割。LLM处理基于Token,按Token分割通常更精确匹配其处理能力。优点:实现简单,计算高效。
缺点:容易破坏自然语义结构(切断句子、段落),可能导致检索片段包含不完整信息。
适用场景:具有明显层级结构的文档(如 Markdown, HTML, LaTeX, PDF with Headings, Word with Styles)。
原理:利用文档固有的结构标记(标题、章节、列表等)作为分割点,保持逻辑单元的完整性。
示例(LangChain - Markdown):
from langchain.text_splitter import MarkdownHeaderTextSplitter
headers_to_split_on = [
("#", "Header 1"), # 一级标题
("##", "Header 2"), # 二级标题
("###", "Header 3"),# 三级标题
]
markdown_splitter = MarkdownHeaderTextSplitter(
headers_to_split_on=headers_to_split_on,
strip_headers=False # 可选:是否在输出中保留标题文本
)
chunks = markdown_splitter.split_text(your_markdown_text)
关键点:
Header 1 > Header 2 > Header 3
)作为元数据添加到片段中,极大增强检索和生成时的上下文理解。##
切)可以控制片段的粒度。优点:最大程度保持语义和逻辑单元的完整性,片段自带结构信息,检索和生成质量通常很高。
缺点:依赖文档的结构化程度和质量,对非结构化或结构混乱的文档效果不佳。
适用场景:通用性强,尤其适用于混合内容或结构不清晰但仍有部分分隔符(如段落、句子)的文档。是固定长度分割的智能升级版。
原理:采用分层分割策略。优先使用较大的分隔符(如双换行\n\n
)将文本分割成大块。如果大块仍然超过chunk_size
,则使用下一级分隔符(如单换行\n
)继续分割。依此类推,直到分割成满足chunk_size
要求的片段。这尽可能地在较大语义边界处切割。
示例(LangChain):
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
separators=["\n\n", "\n", ". ", "? ", "! ", " ", ""] # 分割符优先级列表
)
chunks = text_splitter.split_text(your_text)
参数说明:
separators
:最关键参数。定义分割符的优先级列表。分割器会顺序尝试列表中的分隔符。例如,先尝试用"\n\n"
分,分出来的块如果还太大,再用"\n"
分这个块,还不够小再用". "
分,以此类推,直到满足chunk_size
或没有分隔符可用(最后按字符切)。chunk_size
, chunk_overlap
:作用同固定长度分割法。优点:
缺点:对于完全没有明显分隔符(如长段落无换行)的文本,最终还是会退化成按字符/Token切分。
## 方法
、## 结果
等二级标题切分
- 每个片段自动附加"章节标题"元数据separators=["\nUser:", "\nAgent:"]
- 确保每个片段包含完整对话轮次(如用户提问+客服回复)chunk_size=300
固定分割,可能使回复"您的订单号是AB-X"被拆成"您的订单","号是AB-X"chunk_overlap
能有效缓解分割点信息丢失问题,提高上下文连贯性。chunk_size=1200
, chunk_overlap=300
(25%)
- 当分割点出现在"见第3.2条"时,overlap确保下个片段包含3.2条开头chunk_size=800token
(预留足够buffer)chunk_size=1500token
,当需要同时插入2个片段时,总长度超模型限制chunk_size=600
时召回率85%,索引大小120GB
- 优化为chunk_size=800
后召回率82%,索引降至80GB(接受3%召回下降换取40%存储节省)chunk_size
, overlap
, separators
,观察效果变化。A/B测试不同策略非常有效。chunk_size=500, overlap=0
- B组:chunk_size=800, overlap=100
- 评估:B组在"解释技术原理"类问题准确率提升37%
- 迭代:针对"代码示例"问题,额外增加按代码块分割策略{"doc_id": "HR-2024", "section": "休假制度", "effective_date": "2024-01-01"}
- 当用户问"最新病假政策"时,检索器优先返回带effective_date≥2024
片段# 子片段(用于检索)
chunks = split_text(chunk_size=400)
# 父片段(用于生成)
parent_chunks = split_text(chunk_size=2000)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。