背景介绍
最近测试时发现 Dify 的 RAG 分片效果一般,不管是使用之前 深入 Dify 源码,洞察 Dify RAG 核心机制 中有调研过的默认解析还是 Unstructured 解析。因此调研比较了 大量的开源框架 实现了特定格式的结构化解析方案,并与 Dify 现有解析流程进行了适配。
为了保证文件的解析能真正发挥出效果,需要保证预处理中其他环节也遵循前面的结构化方案进行处理,其中重要的一块就是文本的分片机制。深入了解 Dify 的实现细节后整理相关内容在这边,方便对 Dify RAG 实现机制感兴趣的同学。
Dify 切片简介
在前面的 深入 Dify 源码,洞察 Dify RAG 核心机制 已经大致了解到,Dify 的切片主要涉及的页面如下所示:
自动分段与清洗对应的就是 EnhanceRecursiveCharacterTextSplitter
, 自定义对应的就是 FixedRecursiveCharacterTextSplitter
,其实这两者实现机制的机制基本相同,主要差异是自定义机制将切片默认的参数提供给用户自由选择,并提供了一个额外的分段标识符。
Dify 切片机制
自动分段与清洗
Dify 的切片方案基本上是参考 langchain 实现,就是按照指定标识符列表进行递归切分,默认的切分的字符列表为 ["\n\n", "。", ". ", " ", ""]
,切分过程举例如下所示:
- 第一步按照第一个标识符
\n\n
进行切分; - 如果切分后分片的大小依旧超过指定的分片阈值,此时按照下一个标识符
。
进行切分; - 长度依旧超过阈值,接下来按照下一个字符
.
切分,递归处理直到切分到的分片长度不超过阈值;
对应的代码在 api/core/rag/splitter/text_splitter.py
中:
def _split_text(self, text: str, separators: list[str]) -> list[