433 lines
20 KiB
Markdown
433 lines
20 KiB
Markdown
## 前言
|
||
|
||
RAG 就像我们做开卷考试,在回答考题之前,先翻我们准备的资料(通过检索相关文档来增强自己的能力),这样一来,答题不仅更准确,还能带上更多上下文信息,显得更有深度和针对性。
|
||
|
||
在 RAG 中,我们需要提前预备知识资料,然后向量化后存到向量数据库中,在回答问题的时候,并对问题进行向量化,然后去检索我们数据库是否有相似的内容,如果相似则召回,并把召回的内容一并给到大模型(如:Deepseek),然后通过大模型的推理归纳给出相应的答案。
|
||
|
||
**类似下面步骤:**
|
||
|
||
**第一步:预备数据** 首先,把我们准备的资料知识文档,“切”成一个个小文档块,然后存到数据库里。如果这些小文档块还生成了对应的“嵌入”(可以理解成一种数学表示),那这个数据库就可以升级成向量存储,方便后续的快速查找。
|
||
|
||
**第二步:检索** 当用提问时,系统先把问题向量化,并通过向量搜索、全文搜索,或者多模态的方式,去数据库里检索最相关的小文档块。当定位到那些和用户问题最匹配的信息片段后,以上下文的方式喂给大模型,这样大模型不仅能更快找到答案,还能确保回答得更精准、更有针对性,同时也减少了幻觉。
|
||
|
||
## 面临的挑战
|
||
|
||
对于企业或者个人来说,有很多政策条文,或者文献,通常都是很长篇幅的内容。如果把这些很长的篇幅给到大模型,基于现有大模型的计算能力则无法一次性处理,那就需要对文本进行切块,然而切块不是越大越好,在向量化时,长文本面临以下核心挑战:
|
||
|
||
### 一、语义信息稀释
|
||
|
||
* **1. 多主题覆盖 **:长文本常包含多个主题或观点,整体向量难以准确捕捉细节语义,导致核心内容被淡化
|
||
* **2. 上下文连续性丢失 **:直接平均词向量或使用\[CLS]标记的方式无法有效处理长文本的连贯语义关系,可能割裂上下文逻辑
|
||
|
||
### 二、计算复杂度与资源消耗
|
||
|
||
* **1. 注意力机制瓶颈 **:Transformer 架构的自注意力层具有 O(n²)复杂度,当处理千字以上的长文本时,计算资源呈指数级增长
|
||
* **2. 内存压力 **:生成的高维向量需要大量存储空间,检索时可能降低匹配效率
|
||
|
||
### 三、文本分块技术限制
|
||
|
||
* **1. 最优分块尺寸选择 **:过大的分块导致语义混杂,过小的分块破坏上下文连贯性,50%重叠分块虽可缓解但增加存储冗余
|
||
* **2. 特殊内容处理**:表格、代码段等非连续文本的分割可能破坏结构化信息,影响后续 QA 效果
|
||
|
||
### 四、模型架构制约
|
||
|
||
* **1. 输入长度限制 **:多数预训练模型的最大输入长度在 512-2048 tokens 之间,超出部分需截断或分段处理
|
||
* **2. 位置编码失真 **:分块处理会重置位置编码,影响模型对长程依赖关系的捕捉
|
||
|
||
### 五、质量与效率平衡
|
||
|
||
* **1. 维度优化困境 **:高维向量提升精度但增加计算成本,低维简化计算却损失语义信息
|
||
* **2. 噪声敏感性 **:长文本中拼写错误、口语化表达等噪声对向量质量的影响被放大
|
||
|
||
## 切块方法论
|
||
|
||
在上面我们看到“分块”在 RAG 中起到关键角色和面临的挑战,它直接决定了我们召回知识的准确性,因此选择合适的分块方法尤为重要;有效切割文件的关键在于平衡信息的完整性和管理的便捷性, 可以采用**固定大小分块、语义分块、递归分块、基于文档结构的分块以及基于 LLM 的分块**等多种策略 。
|
||
|
||
* **1. 固定大小分块 **:按预定义的字符数、单词数或 Token 数量对文本进行切分,同时保留一定的重叠部分。这种方法实现简单,但可能会将句子截断,导致信息分散在不同的块中 1。
|
||
* **2.语义分块 **:根据有意义的单元对文档进行分段,持续将单元添加到现有块中,直到余弦相似度显著下降。这种方法能够保持语言的自然流畅性。
|
||
* **3. 递归分块 **:基于内在分隔符(如段落或章节)进行分块。如果某个块的大小超过限制,则将其进一步分割为更小的块。这种方法同样能够保持语言的自然流畅性。
|
||
* **4. 基于文档结构的分块 **:利用文档的内在结构(如标题、章节或段落)进行分块。这种方法能够保持文档的自然结构,但前提是文档具有清晰的结构。
|
||
* **基于 LLM 的分块 **:使用提示工程引导 LLM 生成有意义的分块。这种方法结合了大模型的智能,但可能需要更多的计算资源和时间。
|
||
|
||
<p
|
||
style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;margin: 0;line-height: 26px;color: black;"
|
||
>
|
||
<strong style="font-weight: bold;color: black;">
|
||
<span>总结表格如下:</span>
|
||
</strong>
|
||
</p>
|
||
<table style="display: table;text-align: left;">
|
||
<thead>
|
||
<tr
|
||
class="firstRow"
|
||
style="border: 0;border-top: 1px solid #ccc;background-color: white;"
|
||
>
|
||
<th
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;font-weight: bold;background-color: #f0f0f0;"
|
||
>
|
||
<section><span>分块策略 </span></section>
|
||
</th>
|
||
<th
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;font-weight: bold;background-color: #f0f0f0;"
|
||
>
|
||
<section><span>优点 </span></section>
|
||
</th>
|
||
<th
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;font-weight: bold;background-color: #f0f0f0;"
|
||
>
|
||
<section><span>缺点 </span></section>
|
||
</th>
|
||
<th
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;font-weight: bold;background-color: #f0f0f0;"
|
||
>
|
||
<section><span>典型适用场景 </span></section>
|
||
</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr style="border: 0;border-top: 1px solid #ccc;background-color: white;">
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<strong style="font-weight: bold;color: black;">
|
||
<span>1. 固定大小分块 </span>
|
||
</strong>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>✅ 实现简单快速</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>✅ 计算成本极低</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>✅ 内存占用稳定</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>❌ 可能切断语义关联</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>❌ 需反复调试块大小</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>❌ 对长文本不友好</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>基础问答系统</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>处理格式统一文档</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr style="border: 0;border-top: 1px solid #ccc;background-color: #F8F8F8;">
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<strong style="font-weight: bold;color: black;">
|
||
<span>2.语义分块</span>
|
||
</strong>
|
||
<section><span></span></section>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>✅ 保留完整语义单元</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>✅ 提升上下文相关性</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>✅ 动态适应内容</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>❌ 依赖 NLP 模型质量</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>❌ 计算资源消耗较高</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>❌ 处理速度较慢</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>专业领域分析</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>逻辑推理任务</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr style="border: 0;border-top: 1px solid #ccc;background-color: white;">
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<strong style="font-weight: bold;color: black;">
|
||
<span>3. 递归分块</span>
|
||
</strong>
|
||
<section><span></span></section>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>✅ 多粒度内容覆盖</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>✅ 冗余信息捕获能力强</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>✅ 灵活调整层级深度</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>❌ 实现复杂度高</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>❌ 可能产生信息重复</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>❌ 需要多层索引管理</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>学术文献处理</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>法律合同解析</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr style="border: 0;border-top: 1px solid #ccc;background-color: #F8F8F8;">
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<strong style="font-weight: bold;color: black;">
|
||
<span>4. 文档结构分块</span>
|
||
</strong>
|
||
<section><span></span></section>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>✅ 精准定位章节信息</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>✅ 保持原始逻辑结构</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>✅ 支持跨块引用</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>❌ 依赖文档格式规范</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>❌ 处理非结构化数据困难</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>❌ 需要预解析规则</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>技术手册处理</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>论文解析系统</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
<tr style="border: 0;border-top: 1px solid #ccc;background-color: white;">
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<strong style="font-weight: bold;color: black;">
|
||
<span>5. 基于 LLM 的分块</span>
|
||
</strong>
|
||
<section><span></span></section>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>✅ 理解深层语义意图</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>✅ 动态生成最优块结构</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>✅ 适配复杂任务</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>❌ 推理延迟显著</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>❌ API 调用成本高</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>❌ 存在模型幻觉风险</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
<td
|
||
style="font-size: 16px;border: 1px solid #ccc;padding: 5px 10px;text-align: left;"
|
||
>
|
||
<ul
|
||
class="list-paddingleft-1"
|
||
style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: disc;"
|
||
>
|
||
<li>
|
||
<section><span>高精度问答系统</span></section>
|
||
</li>
|
||
<li>
|
||
<section><span>跨文</span></section>
|
||
</li>
|
||
</ul>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
|
||
|
||
|
||
## RAGFlow 支持的切块方法
|
||
|
||
结合业务场景与文本特点选择合适分块策略是相对较好的方式,在 RAGFlow 中就支持多种分块的方法,下面表格展示了不同分块方法说明及其支持的文档格式
|
||
|
||
**分块方法:**
|
||
|
||
| Template | Description | File format |
|
||
| ---------------------- | --------------------------------------------------- | ----------------------------------------------------------------------- |
|
||
| **General(通用)** | 支持的文件格式比较多,需要自己设置对应的分割方式,比较难以控制,需要配合自然语言处理模型才会有好的效果 | DOCX、EXCEL、PPT、IMAGE、PDF、TXT、MD、JSON、EML、HTML, JPEG, JPG, PNG, TIF, GIF |
|
||
| **Resume(简历)** | | DOCX、PDF、TXT |
|
||
| **Q\&A (问答)** | 问题描述及问题答案,比较适合做客服问答相关 | EXCEL, CSV/TXT |
|
||
| **Manual(手册)** | 会使用 OCR 分割文档 | PDF |
|
||
| **Table(表格形式文件** | | EXCEL, CSV/TXT |
|
||
| **Paper(论文)** | | PDF |
|
||
| **Book(书籍类型)** | | DOCX, PDF, TXT |
|
||
| **Laws(律法相关)** | | DOCX, PDF, TXT |
|
||
| **Presentation(演示文稿)** | | PDF, PPTX |
|
||
| **Picture(图片)** | | JPEG, JPG, PNG, TIF, GIF |
|
||
| **One(完整文件)** | 文件不会被切割,直接一个文件给到大模型,有很好的上下文,但是文件长度取决于配置的大模型支持的长度 | DOCX, EXCEL, PDF, TXT |
|
||
| **Tag(标签)** | 需要提前设置标签描述与标签,类似 Q\&A,在上面的解析中,设置标库用,会自动匹配命中的块并增加标签 | EXCEL, CSV/TXT |
|
||
|
||
## 召回方式也很关键
|
||
|
||
虽然我们掌握了如何对文档进行分块,但对分块的数据召回也是很关键的步骤,怎么提升数据的召回准确率也是一项亟待解决的问题。
|
||
|
||
影响数据召回准确率的原因有很多,从单一方面很难甚至可以说根本无法解决这个问题,因此提升数据的准确性就需要从多个方面入手。
|
||
|
||
**以下是目前主流的一些方式:**
|
||
|
||
**1. 混合检索方法** 同时执行向量检索(语义匹配)和全文检索(关键词匹配),通过线性加权或倒序融合(RRF)合并结果。 引入重排序模型(如BGE-Reranker),对多路召回结果二次排序,优先保留高相关片段。
|
||
|
||
**2. 多路召回策略** 采用多模型并行检索(如BM25、DPR、Embedding模型),覆盖不同粒度的匹配需求。 对于复杂查询,将问题拆解为多个子查询,分别检索后合并结果。
|
||
|
||
**3. 动态参数调整** 设置相似度阈值(如0.5-0.7),过滤低相关片段;根据业务反馈动态调整分块大小和召回数量
|
||
|
||
在RAGFlow中已使用了上述的方法对数据进行召回增强,我们在使用的时候可以对相关参数进行调整验证,以达到更好的效果。 |