背景介绍
在之前的文章 来自工业界的开源知识库 RAG 项目最全细节对比 中介绍过,现有 RAG 开源项目中,Dify 的生态良好,但是一个明显的短板就是 RAG 检索能力偏弱。因此一直期望能补全这个短板,从而让 Dify 能真正好用起来。
在 基于开源项目二次开发建议方案 探索了 Dify 的增强策略。实际选择了文章中提到的中策,基于模块化增强 Dify。做出这个选择的主要原因如下:
- Dify 的 RAG 已经支持了大量的 RAG 基础能力与可视化页面,如果通过额外的插件拓展支持,那么现有的 RAG 基础流程无法复用,开发的工作量太大。
- 通过插件机制需要整体完成后上线,无法渐进式增强;
最终选择牺牲了部分可维护性,大幅减少开发成本。
方案设计
整体的方案是通过模块化组件替换 Dify 原有的基础模块,逐步替换为更强的 Dify-RAG 模块,从而提升 Dify 的 RAG 能力。简单的 Dify RAG 模块化结构如下所示:
根据之前的 RAG 项目结构化文件解析方案比较 调研,Dify 的文件解析能力偏弱,结构化文件解析时也没有保留好结构信息,从而导致文件的分片效果不佳,最终导致 RAG 的检索效果不理想。
因此从解析模块开始,先对结构化文件的解析方案进行了改造。所有的改造遵循 Dify 现有的框架进行设计,首先支持了 html, markdown, pdf 文件的解析优化,可以将增强的解析模块插入 Dify 框架中,改造后的结构如下所示:
目前所有的代码目前已经开源在 Github 上,欢迎大家关注。
方案实现
模块化增强
方案实施是按照模块进行逐步升级替换的,下面以 html 解析模块为例进行介绍增强方案:
在之前的 RAG 项目结构化文件解析方案比较 中已经大致介绍了不同的开源项目的 html 解析方案,目前 Dify 的解析是基于 BeautifulSoup 实现,解析后的文档没有保留任何的结构信息,最终分片效果必然不佳。
根据实际测试情况来看,基于 html_text + readability 的解析方案更好,可以将与可视化效果更接近的内容分配在同一行中,从而尽可能避免文件内容被切断的问题。基于 html_text 实现的一个 html 解析方案简化后如下所示:
import html_text
import readability
html_doc = readability.Document(text)
# 使用 html_text 解析出文本内容,以 `\n` 分隔,单个段落中的内容会保留在同一行中
content = html_t