概述
本文对dify的检索服务的检索过程的实现逻辑进行了分析。通过本文可以对检索服务的检索过程有一个比较清晰的理解,若是要关注实现细节,可以阅读对应部分的代码。
检索的分类
dify实现了三种类型的检索
- 语义搜索
- 全文搜索
- 混合搜索
检索的类型定义如下:
class RetrievalMethod(Enum):
SEMANTIC_SEARCH = "semantic_search"
FULL_TEXT_SEARCH = "full_text_search"
HYBRID_SEARCH = "hybrid_search"
在进行检索的过程中,会根据检索类型来执行不同的流程。
检索服务的总流程
检索服务的实际执行过程在RetrievalService.retrieve(…)函数中实现。该函数的主要实现逻辑如下:
- 若检索方法为关键词检索(
retrieval_method == "keyword_search"
),启动关键词检索线程,来根据查询语句来查询相关文档。结果保存到all_documents中。 - 若检索服务支持语义检索(
is_support_semantic_search
),则根据参数query查询嵌入向量,返回top_k个最相似的documents。结果保存到all_documents中。 - 若检索服务支持全文检索(
is_support_fulltext_search
),则根据参数query在对应向量数据库中进行全文检索。注意,有些向量数据库不支持全文检索。结果保存到all_documents中。 - 若检索方法是混合检索
retrieval_method == RetrievalMethod.HYBRID_SEARCH.value
,则启动数据后处理相关流程。结果保存到all_documents中。
关键词检索的实现
关键词检索功能是在函数:RetrievalService.keyword_search()中实现,该函数在 Flask应用程序的上下文中进行关键词搜索操作。该函数的实现逻辑如下:
- 在给定的应用程序上下文中,从数据库中获取指定ID的数据集。
- 使用该数据集创建一个关键词检索对象(Keyword),并执行关键词搜索。检索的时候,会根据关键词的存储类来构建检索的类。默认是:JIEBA。然后再调用Keywor