简介:本文详细解析RAG系统中文本分块的七种主流策略,帮助开发者、架构师及企业技术团队理解分块原理、选择适用场景,并掌握部署要点与优化方法。通过合理分块,可显著提升检索效率与模型推理质量,为RAG系统的高效运行奠定基础。
在RAG(Retrieval-Augmented Generation)系统中,检索模块负责从海量文档中定位与用户查询最相关的信息,而文本分块(Text Chunking)则是检索模块的基础。分块质量直接影响检索结果的相关性、上下文完整性及大语言模型(LLM)的推理准确性。行业实践表明,分块策略的合理性可决定RAG系统整体效果的70%以上。
本文旨在帮助读者:
langchain、nltk)。文本分块策略的选择需结合业务场景与数据特性。以下场景需重点关注分块质量:
在RAG系统中,文本分块位于文档摄取与Embedding生成之间,是检索模块的起点。其核心组件包括:
langchain、nltk、transformers等库;
pip install langchain nltk transformers
按预设的字符数或Token数直接切分文档,忽略句子与段落边界。例如每500个Token切分一次。
from langchain.text_splitter import RecursiveCharacterTextSplittersplitter = RecursiveCharacterTextSplitter(chunk_size=500, # 分块大小(Token数)chunk_overlap=50 # 分块重叠区域(Token数))chunks = splitter.split_text(long_text) # long_text为待分块文本
chunk_size:分块大小,需根据文档特性调整(如代码文件可设为200-300 Token,长文本可设为500-1000 Token);chunk_overlap:重叠区域,通常为分块大小的10%-20%,用于缓解语义断裂。按完整句子划分文本,每个分块包含一个或多个完整句子,保留语法与语义完整性。
from langchain.text_splitter import SentenceSplittersplitter = SentenceSplitter(separator="\n\n", # 段落分隔符(可根据文档特性调整)max_tokens=200 # 最大Token数(可选,用于限制分块大小))chunks = splitter.split_text(long_text)
separator:句子或段落分隔符(如\n、。、\n\n);max_tokens:可选参数,限制分块最大Token数,防止单个分块过长。按段落划分文本,每个分块包含一个完整段落,保留上下文关联性。
from langchain.text_splitter import RegexTextSplittersplitter = RegexTextSplitter(pattern=r"\n\s*\n", # 匹配段落间的空行chunk_size=1000, # 可选,限制分块大小chunk_overlap=100)chunks = splitter.split_text(long_text)
pattern:正则表达式,用于匹配段落分隔符(如\n\s*\n匹配两个空行);chunk_size与chunk_overlap:同固定大小分块。利用NLP模型(如BERT、Sentence-BERT)识别文本中的语义边界,按语义单元划分分块。
from sentence_transformers import SentenceTransformerfrom sklearn.cluster import KMeansimport numpy as npmodel = SentenceTransformer("all-MiniLM-L6-v2")embeddings = model.encode([sentence for sentence in sentences]) # sentences为句子列表kmeans = KMeans(n_clusters=5).fit(embeddings) # 假设分为5个语义簇labels = kmeans.labels_# 按语义簇合并句子semantic_chunks = []current_chunk = []for i, label in enumerate(labels):if not current_chunk or label == labels[i-1]:current_chunk.append(sentences[i])else:semantic_chunks.append(" ".join(current_chunk))current_chunk = [sentences[i]]if current_chunk:semantic_chunks.append(" ".join(current_chunk))
all-MiniLM-L6-v2、paraphrase-mpnet-base-v2);n_clusters)。利用文档中的标题(如H1、H2)划分分块,每个分块包含一个标题及其下属内容。
from bs4 import BeautifulSouphtml_text = "<h1>Title 1</h1><p>Content 1</p><h2>Subtitle 1</h2><p>Content 2</p>"soup = BeautifulSoup(html_text, "html.parser")headings = soup.find_all(["h1", "h2", "h3"]) # 匹配所有标题heading_chunks = []current_chunk = []for element in soup.children:if element.name in ["h1", "h2", "h3"]:if current_chunk:heading_chunks.append(" ".join(current_chunk))current_chunk = [str(element)]else:current_chunk.append(str(element))if current_chunk:heading_chunks.append(" ".join(current_chunk))
#、##,HTML用<h1>、<h2>);通过正则表达式或关键词匹配定义分块规则(如匹配“摘要”“结论”“参考文献”等关键词)。
import retext = "摘要:本文提出了一种新方法……方法:步骤1……结果:实验表明……"rules = [(r"摘要:.*?方法:", "摘要"), # 匹配“摘要:”到“方法:”之间的内容(r"方法:.*?结果:", "方法"), # 匹配“方法:”到“结果:”之间的内容(r"结果:.*?", "结果") # 匹配“结果:”到文本末尾的内容]rule_chunks = []for pattern, label in rules:match = re.search(pattern, text, re.DOTALL)if match:rule_chunks.append((label, match.group(0)))
r"摘要:.*?方法:");结合多种分块策略(如先按段落分块,再对过长段落按句子分块),平衡语义完整性与计算效率。
from langchain.text_splitter import RecursiveCharacterTextSplitter, SentenceSplitter# 先按段落分块paragraph_splitter = RegexTextSplitter(pattern=r"\n\s*\n", chunk_size=1000)paragraphs = paragraph_splitter.split_text(long_text)# 对过长段落按句子分块sentence_splitter = SentenceSplitter(max_tokens=200)hybrid_chunks = []for paragraph in paragraphs:if len(paragraph.split()) > 200: # 若段落过长hybrid_chunks.extend(sentence_splitter.split_text(paragraph))else:hybrid_chunks.append(paragraph)
文本分块是RAG系统检索质量的核心影响因素。本文详细解析了七种主流分块策略的原理、适用场景与配置方法,并提供了部署流程、验证方法与运维优化建议。开发者应根据业务需求选择最优策略,并通过持续监控与调优提升分块质量,最终实现RAG系统的高效检索与精准推理。