在 RAG 系统中,检索的基本单元是“块”(chunk)。如何将原始文档切成一个个大小合适的块,直接影响检索精度和最终回答质量。固定大小分块是最直观、最常用的切分策略之一:设定一个固定的长度阈值,当文本累计达到该阈值时就进行一次切割。这个阈值可以用字符数或 Token数来衡量。
1. 按字符数分块
怎么做
直接将文本按字符数量切分,例如每 500 个字符切成一块。通常会叠加一个“重叠窗口”(overlap),让相邻块之间共享一部分内容,以避免关键信息恰好被切在两块的边界上。
# 伪代码示例
text = "完整的长文档内容..."
chunk_size = 500 # 每块最多500字符
overlap = 50 # 相邻块重叠50字符
chunks = []
start = 0
while start < len(text):
end = min(start + chunk_size, len(text))
chunks.append(text[start:end])
start += (chunk_size - overlap)
特点
- 实现极简:几乎所有编程语言都可以直接按字符串长度切割,无需任何外部工具或模型。
- 速度快:不涉及分词,对计算资源零依赖。
- 可控性强:块的大小直接对应人眼看到的文本长度,调整参数时非常直观。
局限性
字符数并不能精确反映语义承载量。对于中文,一个汉字通常就代表一个语义单位;而英文一个单词可能由多个字符组成。如果中英文混排,同样 500 字符,中文块的信息密度远高于英文块。此外,按字符切分容易在词语或句子中间截断,破坏语义连贯性。
适用场景
适合文档语言单一、对切分粒度要求不高的初期原型搭建,或者纯中文/纯英文的简短文段处理。
2. 按 Token 数分块
怎么做
Token 是语言模型理解和计费的基本单位。一个英文单词大约等于 1~2 个 Token,一个中文字大约等于 1~2 个 Token(具体取决于分词器)。使用与后续生成模型相同的分词器(tokenizer)对文本进行编码,然后按固定 Token 数切分,再解码回文本。
# 伪代码示例(使用tiktoken库)
import tiktoken
encoder = tiktoken.get_encoding("cl100k_base")
tokens = encoder.encode(text)
chunk_size = 256 # 每块最多256 Token
overlap = 20 # 重叠20 Token
chunks = []
for i in range(0, len(tokens), chunk_size - overlap):
chunk_tokens = tokens[i:i + chunk_size]
chunks.append(encoder.decode(chunk_tokens))
特点
- 与模型对齐:块的大小直接对应生成模型处理时的实际长度,便于控制上下文窗口(如“检索 top-5 块,总 Token 不超过 2000”)。
- 跨语言一致:Token 数在不同语言间有更一致的语义密度。中英文混排时,按 Token 切分比字符数切分更均衡。
- 避免截断问题:配合合理的分词器,通常不会在字符中间截断(但依然可能在词语或短语中间切断,所以重叠仍然重要)。
局限性
需要额外引入分词库或调用模型 API,增加少量复杂度。对于不涉及微调 Token 长度的场景,这个精度提升未必必要。
适用场景
正式生产环境的首选方案。尤其是在调用 OpenAI、Llama 等主流模型时,使用与模型匹配的 Token 切分方式能精确控制每次生成的上下文长度,避免超 Token 限制,也方便成本估算。
3. 关键参数:块大小与重叠量
无论按字符数还是 Token 数切割,两个核心参数都需要根据实际数据和业务目标调整:
- 块大小(chunk_size)
块太小:语义碎片化,可能检索到一个句子却缺少上下文,回答不完整。
块太大:包含过多无关信息,干扰模型聚焦,增加处理延迟和成本。
实践中,256~512 Token(或对应约 300~600 中文字符)是常见起点,再根据具体文档类型(如 FAQ 可以更短,技术手册可稍长)进行微调。
- 重叠量(overlap)
保留相邻块间的部分重复内容,能有效避免“边界切断”造成的语义断裂。典型值设为块大小的 10%~20%。例如 500 字符的块,重叠 50~100 字符。
4. 一个真实配置示例
某公司用 RAG 建设内部技术知识库,文档主要为中文技术手册,偶尔包含英文代码片段。最终选择:按 Token 切分,每块 400 Token,重叠 80 Token。理由如下:
- 400 Token 约能承载一个完整的技术操作步骤加简要说明,不会频繁被截断。
- 重叠 80 Token 保证即使关键步骤落在边界,也会被相邻块完整保留。
- 使用与调用模型(GPT-4)一致的 cl100k_base 编码,块大小直接对应上下文窗口,检索 5 块即 2000 Token,留足容余。
5. 固定大小分块的通用局限性
无论采用字符还是 Token 计数,固定大小分块都有一个共同弱点:不感知文档的自然结构。它可能在段落中间强硬切断,导致一句话的前后文分散在不同块中。对于结构严密的文档(如合同条款、分节的规范),有时需要结合“按段落”“按标题”等语义切分方式,或采用递归分块策略(优先按大分隔符切,不够再按小分隔符切),以保留更好的逻辑完整性。
总结: 固定大小分块是最容易落地、性能最好的起步方案。按 Token 数切分更贴近模型真实行为,推荐用于正式环境;按字符数切分则适合快速验证和纯单一语言场景。无论选择哪种,块大小和重叠量都需要基于实际问答效果反复调试,这是 RAG 系统中性价比最高的优化环节之一。