文档分块策略:按结构、语义和检索目标切分,而不是固定字数硬切
分块决定 RAG 的召回上限:块太小会丢上下文,块太大会稀释语义、浪费 token;切在表格、代码块或句子中间,会让检索和生成都变差。分块不是“按 500 字切一刀”,而是结合文档结构(标题、段落、列表、表格、代码)、语义边界和检索粒度做取舍。
常见策略:固定 token/字符窗口(简单基线)、递归字符切分(按段落/句子优先级)、结构感知切分(Markdown 标题、PDF 版面)、语义切分(相邻句子相似度)、父子块/小到大检索(子块召回、父块生成)。中文还要考虑 tokenizer 和标点。
# LangChain:递归字符切分,优先按段落/句子断开
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=600,
chunk_overlap=80,
separators=["\n\n", "\n", "。", "!", "?", ";", " ", ""],
)
chunks = splitter.split_text(text)
# LlamaIndex:按句子/ token 切分,并保留元数据
from llama_index.core.node_parser import SentenceSplitter
parser = SentenceSplitter(chunk_size=512, chunk_overlap=64)
nodes = parser.get_nodes_from_documents(documents)
# 结构感知:按 Markdown 标题切分,保留标题路径
from langchain_text_splitters import MarkdownHeaderTextSplitter
splitter = MarkdownHeaderTextSplitter(
headers_to_split_on=[("#", "h1"), ("##", "h2"), ("###", "h3")]
)
sections = splitter.split_text(markdown)
实用起点:
- 块大小:300–800 tokens,按文档类型调整
- 重叠:10%–20%,避免边界信息丢失
- 元数据:标题路径、页码、来源、租户、权限
- 表格/代码:单独成块,保留表头/语言标识
合上页面,先回答,再展开对照。
小程序版
微信扫码,随时查命令