dify实现分析-rag-内容检索rerank的两种实现

dify实现分析-rag-内容检索rerank的两种实现

概述

本文介绍dify的rerank的实现原理。rerank可以对检索到的多个文档进行重排序。通过重排序可以找到更加合适的文档分块。

dify中的两种rerank实现方式

dify中提供两种rerank的方式:

  • 使用rerank模型:一种是通过rerank模型来直接对输入文档列表(documents)和问题(query)的相关性进行评估,打分,并返回与问题最合适的文档列表。
  • 根据权重计算:嵌入向量以及文档分词与query相似度的综合分数。先对文档和query进行分词处理,然后计算每个文档和query的相似度分数;在对文档列表以及query进行向量化处理,并计算每个文档和query向量的相似度分数。然后根据权重把两者的分数和权重相乘,并加起来。就得到了每个文档的最终相似度。然后取分数最大的top_n个文档。

rerank的两种rerank模式的定义代码如下:

class RerankRunnerFactory:
    @staticmethod
    def create_rerank_runner(runner_type: str, *args, **kwargs) -> BaseRerankRunner:
        match runner_type:
            case RerankMode.RERANKING_MODEL.value:
                return RerankModelRunner(*args, **kwargs)
            case RerankMode.WEIGHTED_SCORE.value:
                return WeightRerankRunner(*args, **kwargs)
            case _:
                raise ValueError(f"Unknown runner type: {runner_type}")

权重rerank的实现:WeightRerankRunner

基于权重的rerank是在WeightRerankRunner.run()函数中实现的,该函数的实现逻辑如下:

  1. 相对document进行去重处理
  2. 使用BM25算法对query和每个doucment进行分词处理,并计算每个文档和query的相似度分数。这样就得到每个document和query的相似度分数。
  3. 对query和document进行向量化处理,并计算每个document和query向量的相似度分数。这样就得到每个document和query的向量的相似度分数。
  4. 针对每个document:将基于分词和向量的两个分数按照给定的权重综合计算,得到每个document和query相似度的最终评分。
  5. 根据document的得分对其进行排序,并选择得分最高的top_n的个document返回。

WeightRerankRunner中rerank的实现代码如下:

class WeightRerankRunner(BaseRerankRunner):
	def run(
        self,
        query: str,
        documents: list[Document],
        score_threshold: Optional[float] = None,
        top_n: Optional[int] = None,
        user: Optional[str] = None,
    ) -> list[Document]:
        """
        Run rerank model
        :param query: search query
        :param documents: documents for reranking
        :param score_threshold: score threshold
        :param top_n: top n
        :param user: unique user id if needed

        :return:
        """
        docs = []
        doc_id = []
        unique_documents = []
        # 对文档列表去重
        for document in documents:
            if document.metadata["doc_id"] not in doc_id:
                doc_id.append(document.metadata["doc_id"])
                docs.append(document.page_content)
                unique_documents.append(document)

        documents = unique_documents

        rerank_documents = []
        # 对query和每个文档分块进行分词处理,并计算每个文档和query的相似度分数。
        query_scores = self._calculate_keyword_score(query, documents)

        # 对query和document进行向量化处理,并计算每个document和query向量的相似度分数
        query_vector_scores = self._calculate_cosine(self.tenant_id, query, documents, self.weights.vector_setting)
        # 针对每个document:将基于分词和向量的两个分数按照给定的权重综合计算,得到最终的评分
        for document, query_score, query_vector_score in zip(documents, query_scores, query_vector_scores):
            # format document
            # 计算综合得分
            score = (
                self.weights.vector_setting.vector_weight * query_vector_score
                + self.weights.keyword_setting.keyword_weight * query_score
            )
            # 如果设置了 score_threshold 且文档的综合评分为负数,则跳过
            if score_threshold and score < score_threshold:
                continue
            # 添加文档的综合评分到元数据中
            document.metadata["score"] = score
            rerank_documents.append(document)
        # 将所有符合要求的文档按分数从高到低排序。
        rerank_documents = sorted(rerank_documents, key=lambda x: x.metadata["score"], reverse=True)
        # 根据 top_n 参数返回评分最高的前 N 个文档;如果不设置 top_n,则返回所有符合条件的文档。
        return rerank_documents[:top_n] if top_n else rerank_documents

使用rerank模型的实现:RerankModelRunner

使用rerank模型来实现document的rerank的实现比较简单,实现逻辑如下:

  1. 对document进行去重处理,若是dify文档,记录doc_id。
  2. 调用rerank模型来对document进行重拍处理,并输出重排序后的document列表。这里要注意,rerank模型的输入参数:
     rerank_result = self.rerank_model_instance.invoke_rerank(
            query=query, docs=docs, score_threshold=score_threshold, top_n=top_n, user=user
        )
  1. 格式化重新排序后的document,生成Document对象,并把排序后的分数添加到document.metadata[“score”]字段中。

说明:rerank模型是用户通过页面配置的。

使用rerank模型实现的代码如下:

class RerankModelRunner(BaseRerankRunner):
    def __init__(self, rerank_model_instance: ModelInstance) -> None:
        self.rerank_model_instance = rerank_model_instance

    def run(
        self,
        query: str,
        documents: list[Document],
        score_threshold: Optional[float] = None,
        top_n: Optional[int] = None,
        user: Optional[str] = None,
    ) -> list[Document]:
        """
        Run rerank model
        :param query: search query
        :param documents: documents for reranking
        :param score_threshold: score threshold
        :param top_n: top n
        :param user: unique user id if needed
        :return:
        """
        docs = []
        doc_id = set()
        unique_documents = []
        # 对文档列表去重,针对dify的文档,记录doc_id
        for document in documents:
            if document.provider == "dify" and document.metadata["doc_id"] not in doc_id:
                doc_id.add(document.metadata["doc_id"])
                docs.append(document.page_content)
                unique_documents.append(document)
            elif document.provider == "external":
                if document not in unique_documents:
                    docs.append(document.page_content)
                    unique_documents.append(document)

        documents = unique_documents

        # 调用rerank模型对文档进行重排,该方法返回一个包含重新排序后的document(如文本和索引)
        rerank_result = self.rerank_model_instance.invoke_rerank(
            query=query, docs=docs, score_threshold=score_threshold, top_n=top_n, user=user
        )

        rerank_documents = []

        # 格式化重新排序后的文档
        for result in rerank_result.docs:
            # format document
            rerank_document = Document(
                page_content=result.text,
                metadata=documents[result.index].metadata,
                provider=documents[result.index].provider,
            )
            # 将重新排序后的分数添加到新文档的元数据中
            rerank_document.metadata["score"] = result.score
            # 添加到rerank_documents结果列表中
            rerank_documents.append(rerank_document)

        return rerank_documents

说明:dify支持多种rerank模型的实现,都继承了RerankModel类。

总结

本文介绍了dify的两种rerank方式的实现。目前dify中支持2种rerank方式,一种通过rerank模型来实现,一种是通过计算分词和向量与query的相似度来实现。另外,dify支持多种rerank模型,可以根据需要进行选择。

<think>好的,我现在要帮用户解决在Dify中配置Rerank模型的问题。首先,我需要回忆一下用户提供的引用内容,特别是引用[1]和引用[2]里提到的相关信息。用户提到他们想了解配置方法、示例和参数设置,所以需要详细说明这些部分。 首先,引用[1]提到以文心的bce-reranker-base为例进行二次开发,本地部署。这说明配置Rerank模型可能需要通过代码修改,而不仅仅是界面操作。接下来,引用[2]中的案例提到了在Dify中创建知识库时设置Rerank模型,可能涉及到工作流的创建和参数调整。引用[3]则提到将SQL示例作为知识库的一部分,这可能与Rerank模型的应用场景相关,但用户的问题更关注配置方法。 接下来,我需要将配置步骤分点说明,确保结构清晰。第一步应该是环境准备,包括安装Dify和获取模型API密钥。第二步是代码集成,可能需要修改Dify的源代码或插件,添加Rerank模型的调用。这里需要示例代码,比如Python中的请求示例,或者Dify插件的配置方式。第三步是参数设置,比如top_k、score_threshold这些常见参数,需要解释每个参数的作用和推荐值。第四步是工作流配置,在Dify的界面中如何将Rerank模型加入到知识库检索流程中,可能涉及到可视化操作步骤的说明。 另外,用户可能需要示例参数配置,比如在YAML文件或设置界面中的具体参数值。需要确保示例具体,比如使用bce-reranker-base模型,API端点、密钥的位置,参数如何影响结果。同时,要注意用户可能遇到的常见问题,比如API连接失败、参数设置不当导致的结果不准确,需要给出排查建议。 还要注意引用文献的正确标注,比如在提到二次开发时引用[^1],在创建知识库时引用[^2]。最后,生成的相关问题需要围绕Dify的模型配置、优化和应用场景展开,帮助用户深入了解后续可能的需求。 现在需要检查是否有遗漏的步骤,比如是否需要重启服务或测试配置是否生效。此外,是否需要权限设置或模型版本的选择?可能需要补充这些细节。确保语言口语化,避免技术术语过多,但又要准确。最后,验证所有步骤是否符合Dify的最新版本,假设用户可能使用的是当前版本,所以不需要考虑过时的信息。</think>在Dify中配置Rerank模型主要涉及代码集成、参数调整和工作流设计,以下是具体步骤和示例: --- ### **一、配置步骤** 1. **环境准备** - 确保已部署Dify开发环境并安装相关依赖 - 获取Rerank模型API(如文心`bce-reranker-base`的API密钥或本地模型地址) 2. **代码集成** ```python # 在Dify自定义模块中添加Rerank调用 from dify_client import RerankClient rerank_config = { "model_name": "bce-reranker-base", "api_endpoint": "https://api.wenxin.baidu.com/rerank", "api_key": "your_api_key", "top_k": 5 # 控制返回的相似片段数量 } client = RerankClient(config=rerank_config) ``` 3. **参数设置** | 参数 | 说明 | 示例值 | |---------------|--------------------------|-------------| | `score_threshold` | 相似度分数阈值 | 0.7 | | `top_k` | 最大返回候选片段数 | 5 | | `temperature` | 模型输出的多样性控制 | 0.8 | 4. **工作流配置** -Dify界面中创建知识库时,选择**混合检索模式**,勾选**启用Rerank模型** - 在**高级设置**中填入API参数,并关联上一步的代码模块 --- ### **二、操作示例** 以文心Rerank模型为例的YAML配置片段: ```yaml rerank: provider: wenxin model: bce-reranker-base params: top_k: 3 score_threshold: 0.65 api_key_env: WENXIN_API_KEY # 从环境变量读取密钥 ``` --- ### **三、注意事项** 1. 本地部署时需开放模型服务的端口(如默认8000端口) 2. 若使用云API,注意请求频率限制和计费规则 3. 可通过调整`top_k`和`score_threshold`平衡召回率与精确度 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值