当前位置: 首页 > news >正文

70%的RAG性能与分块有关

RAG(检索增强生成)管道在很大程度上依赖于你如何分割文档(分块)。在这篇文章中,我将介绍RAG工作流程,突出分块在其中的作用,然后深入探讨固定、递归、语义、基于结构和后期分块技术,包括定义、权衡和伪代码,以便你能采用适合自己用例的方法。

检索增强生成(RAG)工作流程(高级)

以下是标准流程:

按回车键或点击以查看全尺寸图像

  1. 文档摄取与分块 处理大型文档(PDF、HTML、原始文本)→ 分割(“分块”)→ 计算嵌入向量 → 在向量DB中建立索引。

  2. 查询 / 检索 用户查询 → 嵌入查询 → 检索最接近的前 k 个块(通过余弦相似度)

  3. 增强 / 提示构建将检索到的文本块(加上元数据)注入到大语言模型提示中,通常会使用模板和过滤器。

  4. 生成 大语言模型(LLM)基于检索到的上下文和模型先验生成答案。

由于生成器只能看到你提供给它的内容,因此你的检索质量起着主导作用。如果文本块格式错误或不相关,即使是最好的大语言模型也无法挽救。这就是为什么很多人说检索增强生成(RAG)大约70%在于检索,30%在于生成。

在我们深入探讨技巧之前,先来了解一下为什么良好的组块化是必不可少的:

  • 嵌入和大语言模型(LLM)有上下文窗口限制;你不能直接处理大型文档。

  • 文本块需要语义连贯。如果在句子中间或想法中间进行分割,嵌入结果将产生噪声或具有误导性。

  • 如果你的数据块太大,系统可能会遗漏细粒度的相关信息。

  • 相反,如果数据块太小或重叠过多,就会存储冗余内容,浪费计算/存储资源。

让我们来探索五种突出的组块技术,从最简单到最先进。

1. 固定分块

将文本分割成大小相等的块(按标记、单词或字符),块之间通常有重叠。

它是您的RAG项目的良好起点,在文档结构未知时是不错的基线,或者适用于统一/枯燥的文本(日志、纯文本)。

实现代码示例:

 
def fixed_chunk(text, max_tokens=512, overlap=50):
tokens = tokenize(text)
chunks = []
i = 0
while i < len(tokens):chunk = tokens[i : i + max_tokens]chunks.append(detokenize(chunk))i += (max_tokens - overlap)
return chunks


2. 递归分块

首先在高层次边界(例如段落或章节)处进行分割。如果分割后的块仍然太大(超过限制),则递归地进一步分割(例如按句子),直到所有块都在限制范围内。

适用于半结构化文档(包含章节、段落),在这类文档中,你既希望保留语义边界,又要限制篇幅。

它尽可能保留逻辑单元(段落),避免跨越不自然的界限,并且你会得到一组适合内容变化的混合尺寸

递归分块示例(LangChain)

 
from langchain.text_splitter import RecursiveCharacterTextSplitter# Sample text
text = """
Input text Placeholder...
"""# Define a RecursiveCharacterTextSplittertext_splitter = RecursiveCharacterTextSplitter(chunk_size=200,           # target size of each chunkchunk_overlap=50,         # overlap between chunks for context continuityseparators=["\n\n", "\n", " ", ""]  # order of recursive splitting
)# Split the text
chunks = text_splitter.split_text(text)# Display results
for i, chunk in enumerate(chunks, 1):print(f"Chunk {i}:\n{chunk}\n{'-'*40}")

这样可以确保在你嵌入和稍后检索文本块时,不会在边界处丢失重要的上下文信息。

3.语义分块

按语义转换对文本进行分段。使用嵌入(例如句子嵌入)来确定一个段落的结束位置和下一个段落的起始位置。如果相邻的段落非常相似,则将它们合并;当相似度降低时,则进行分割。

当检索精度至关重要时(法律文本、科学文章、支持文档)效果最佳,但你需要留意嵌入和相似度计算成本,同时定义阈值(相似度下降)需要仔细调整

实现代码示例

 
from sentence_transformers import SentenceTransformer, utilmodel = SentenceTransformer("all-MiniLM-L6-v2")def semantic_chunk(text, sentence_list, sim_threshold=0.7):embeddings = model.encode(sentence_list)chunks = []current = [sentence_list[0]]for i in range(1, len(sentence_list)):sim = util.cos_sim(embeddings[i-1], embeddings[i]).item()if sim < sim_threshold:chunks.append(" ".join(current))current = [sentence_list[i]]else:current.append(sentence_list[i])chunks.append(" ".join(current))return chunks


4. 基于结构的分块

使用文档的固有结构,如标题、副标题、HTML标签、表格、列表项等,作为自然的分块边界。 例如,每个章节或标题成为一个分块(或进一步递归分块)。 最适合HTML页面、技术文档、类似维基百科的内容或任何带有语义标记的内容。

根据我的个人经验,这种策略能取得最佳效果,尤其是与递归分块结合使用时。 然而,它需要解析和理解文档格式,对于大篇幅内容可能会超出令牌限制,因此可能需要采用递归拆分的混合方法。

实施提示

  • 使用 HTML / Markdown / PDF 结构库进行解析

  • 使用章节 / <h1>、<h2>等作为块根

  • 如果一个部分太大,则回退到递归拆分

  • 对于表格/图像,要么将它们视为单独的部分,要么对其进行总结

5. 延迟分块(又称动态/查询时分块)

定义

延迟分块意味着将文档的分割方式推迟到查询时。不是预先将所有内容分割,而是存储较大的片段或整个文档。当查询到来时,只有相关的片段才会被动态分割(或过滤)。这样做的目的是在嵌入过程中保留完整的上下文,只在必要时进行分解。

Weaviate将延迟分块描述为“颠倒嵌入和分块的传统顺序”。

  1. 首先使用长上下文模型嵌入整个文档(或大段内容)。

  2. 然后进行合并并创建分块嵌入(基于标记跨度或边界线索)。

概念流程

  1. 在索引中存储大段内容或整个文档。

  2. 查询时,检索1 - 2个顶级片段。

  3. 在这些内容中,围绕与查询匹配的部分动态分割(例如语义分割或重叠分割)成细粒度的片段。

  4. 过滤或排序块以提供给生成器。

按回车键或点击以查看全尺寸图像

这种方法类似于编程中的延迟绑定,直到有更多上下文时再进行处理。

用例

  • 大文档集(技术报告、长篇内容),其中段落间的上下文关系很重要。

  • 文档内容经常变化的系统中,避免完全重新分块可以节省时间。

  • 高风险或对精度敏感的检索增强生成(RAG)应用(法律、医疗、监管领域),在这些应用中,对代词或指代的误解可能代价高昂。

这听起来很高级,但也有代价。嵌入整个文档(或大篇幅内容)的计算成本很高,可能需要具有长标记限制的模型。 它还会增加查询时的成本,包括计算成本和潜在的延迟。

http://www.dtcms.com/a/520417.html

相关文章:

  • 足球网站开发外贸网站优化推广
  • Uncertainty-Aware Null Space Networks for Data-Consistent Image Reconstruction
  • 孝感网站seodw做网站的导航栏怎么做
  • LeetCode 每日一题 166. 分数到小数
  • 封面论文丨薄膜铌酸锂平台实现强耦合电光调制,《Light Sci. Appl. 》报道机器学习优化新范式
  • 做外贸找产品上哪个网站好flash素材网站有哪些
  • Rust内存安全:所有权与生命周期的精妙设计
  • 2510rs,稳定裸函数
  • 西安住房建设局网站首页企业网站 设计需求
  • LangChain:让大模型具备思考与行动能力的框架
  • MySQL 及 SQL 注入详细说明
  • 医院移动护理系统源码,JAVA移动护理系统源码,医院移动护士站源码
  • 网站建设营销型新型塑料建筑模板图片
  • Linux 有哪些功能相似的命令
  • 外贸推广网站冲压加工瑞安有做网站吗
  • 【开题答辩实录分享】以《租房小程序的设计和实现》为例进行答辩实录分享
  • vscode debug Transformer源码说明
  • 仓颉语言核心特性深度解析:类型系统与内存安全实践
  • IP 地址 (Internet Protocol Address) 详细介绍
  • PHP网站开发常用函数房城乡建设部网站
  • 开源的SSR框架都是怎么实现的?
  • RLVR训练多模态文档解析模型-olmOCR 2技术方案(模型、数据和代码均开源)
  • AI 领域热门方向或代表性技术/模型
  • MySQL 体系结构、SQL 执行与设计范式
  • 个人网站如何搭建国家企业信用信息网官网
  • MySQL学习之SQL语法与操作
  • “麻烦您了”英语怎么说?
  • 临时上线没有回滚方案会怎样
  • 哪个网站做高仿衣服中小学网站建设建议
  • Linux 中的 DNS 工作原理(二):各级 DNS 缓存