📂 595 个栏目 · 20019 篇文章
RAG的Chunking策略:字符切分、句子切分、语义切分,80%的团队选错了
你花3个月调模型,但Chunking是随便设的。这就是为什么你的RAG不行。 绝大多数RAG教程都告诉你:chunk_size=500, chunk_overlap=50。然后你就照做了。但你的文档是法律合同、技术文档、还是小说?不同的文档类型,最优Chunking策略完全不同。 我花了2周时间,实测了5种Chunking策略在中文场景下的表现。以下是完整数据,以及一个Chunking决策框架。 五种Chunking策略实测 策略一:固定字符切分(RecursiveCharacterTextSplitter) 最常用的策略。按固定字符数切分,用分隔符优先级(段落>句子>词)来避免在中间切分。 实测(chunk_size=800, chunk_overlap=200): 法律文档 Recall@10:78.3% 技术文档 Recall@10:82.1% 对话记录 Recall@10:71.5% 问题:完全不考虑语义边界。一个条款可能被切成两半,一段代码可能被拦腰截断。 金句:固定字符切分是"最懒但最常用"的策略。它不差,但远不是最优。 策略二:句子级切分(SentenceSplitter) 按句子边界切分,每个chunk包含N个完整句子。 实测(chunks_per_chunk=5): 法律文档 Recall@10:82.5% 技术文档 Recall@10:84.3% 对话记录 Recall@10:76.2% 优点:保证每个chunk是完整的句子,不会在半句话中间切分。 缺点:句子长度不一,chunk大小不均匀。 策略三:语义切分(SemanticChunker) 用Embedding相似度检测语义边界,在"语义发生变化"的地方切分。 实测(相似度阈值=0.7): 法律文档 Recall@10:88.7% 技术文档 Recall@10:90.2% 对话记录 Recall@10:82.1% 优点:切分质量最高,每个chunk是语义完整的单元。 缺点:计算开销大(需要对每个句子做Embedding),处理速度慢。 金句:语义切分是"质量最高但成本最高"的策略。如果你追求极致召回率,这是唯一选择。 策略四:文档结构切分(HierarchicalChunker) 按文档的层级结构(标题H1→H2→H3→段落)切分,保留层级关系。 实测: 法律文档 Recall@10:90.1% 技术文档 Recall@10:91.5% 对话记录 Recall@10:N/A(对话无层级结构) 优点:保留文档结构,对结构化文档(合同、手册、规范)效果极好。 缺点:只适用于有层级结构的文档,对话和非结构化文本无效。 策略五:小到大窗口(SentenceWindowNodeParser) 每个chunk只包含一个句子,但检索时返回该句子及其前后N个句子。 实测(window_size=3): 法律文档 Recall@10:85.2% 技术文档 Recall@10:86.8% 对话记录 Recall@10:83.5% 优点:检索粒度最细,上下文窗口灵活。 缺点:检索到的句子可能缺乏上下文,LLM需要更多推理。 金句:小到大窗口是"最灵活但最依赖LLM"的策略。LLM越强,这个策略效果越好。 Chunking决策框架 你的文档类型是什么? ├── 结构化文档(合同、手册、规范) │ └── 文档结构切分(HierarchicalChunker) ├── 技术文档(Markdown、代码、Wiki) │ ├── 有层级结构 → 文档结构切分 │ └── 无层级结构 → 语义切分(SemanticChunker) ├── 对话记录(客服、聊天) │ └── 小到大窗口(SentenceWindowNodeParser) ├── 新闻/文章(长文、博客) │ └── 语义切分(SemanticChunker) └── 混合文档(多种类型) └── 按文档类型分别处理,不要一刀切 Chunking的黄金法则 chunk_size根据文档类型设:法律文档800-1200,技术文档500-800,对话记录200-400 chunk_overlap=chunk_size的15-25%:太少了容易丢失边界信息,太多了浪费存储 不要一刀切:不同文档类型用不同的Chunking策略 保留元数据:每个chunk标注来源文档、页码、章节、标题 测试驱动的Chunking:用你的真实查询跑Recall测试,数据说话 金句:Chunking不是"一个参数搞定一切",而是"根据文档类型和查询模式,选最合适的策略"。 ...