agentic_huge_data_base / wiki
页面 RAGFlow · 9.3 重排序与筛选·DeepWiki 中文全文译文

9.3 · 重排序与筛选(Reranking and Filtering)

复杂文档理解与引用检索 · 本章是 RAGFlow DeepWiki 中文译文的独立章节页,保留原始链接、源码锚点、模块标签和章节层级。

项目RAGFlow 章节9.3 状态全文译文 模块检索、召回与索引、文档对象与元数据、模型调用与提供方适配、系统架构
源码线索
  • agent/tools/retrieval.py
  • api/apps/llm_app.py
  • api/db/__init__.py
  • api/db/db_models.py
  • api/db/services/dialog_service.py
  • api/db/services/document_service.py
  • api/db/services/file_service.py
  • api/db/services/knowledgebase_service.py
  • api/db/services/llm_service.py
  • api/db/services/task_service.py
模块标签
  • 检索、召回与索引
  • 文档对象与元数据
  • 模型调用与提供方适配
  • 系统架构
  • 界面与交互

中文译文

重排序与筛选(中文译文)

原始 DeepWiki 页面:https://deepwiki.com/infiniflow/ragflow/9.3-reranking-and-filtering
翻译时间:2026-05-27T08:44:53.585Z
翻译模型:deepseek-chat
原文字符数:16570
项目:RAGFlow (ragflow)

---

重排序与过滤

相关源文件

以下文件被用作生成此维基页面的上下文:

  • agent/tools/retrieval.py
  • api/apps/llm_app.py
  • api/db/__init__.py
  • api/db/db_models.py
  • api/db/services/dialog_service.py
  • api/db/services/document_service.py
  • api/db/services/file_service.py
  • api/db/services/knowledgebase_service.py
  • api/db/services/llm_service.py
  • api/db/services/task_service.py
  • api/db/services/user_service.py
  • conf/llm_factories.json
  • rag/llm/__init__.py
  • rag/llm/chat_model.py
  • rag/llm/cv_model.py
  • rag/llm/embedding_model.py
  • rag/llm/rerank_model.py
  • rag/llm/sequence2txt_model.py
  • rag/llm/tts_model.py
  • rag/nlp/search.py
  • rag/raptor.py
  • rag/svr/task_executor.py
  • web/src/components/rerank.tsx
  • web/src/components/similarity-slider/index.tsx
  • web/src/components/svg-icon.tsx
  • web/src/components/switch-fom-field.tsx
  • web/src/components/top-n-item.tsx
  • web/src/components/use-knowledge-graph-item.tsx
  • web/src/constants/llm.ts
  • web/src/pages/agent/form/retrieval-form/next.tsx
  • web/src/pages/agent/form/tool-form/retrieval-form/index.tsx
  • web/src/pages/user-setting/setting-model/constant.ts
  • web/src/utils/common-util.ts

本文档介绍 RAGFlow 的双层重排序系统和过滤机制,这些机制会在搜索结果呈现给大语言模型(LLM)进行答案生成之前对其进行优化。该系统结合了基于相似度的评分、可选的基于模型的重排序、排序特征评分(标签、PageRank)以及阈值过滤,以优化片段选择。

有关初始搜索和检索过程的信息,请参阅 9.2 查询处理与混合搜索。有关将检索到的片段格式化为上下文的后续步骤,请参阅 9.4 响应生成与引用

系统概览

重排序与过滤系统作为混合搜索检索后的后处理层运行。它接收来自文档存储(Elasticsearch、Infinity 或 OpenSearch)的初始搜索结果,并应用额外的评分和过滤逻辑。核心逻辑位于 rag/nlp/search.pyDealer 类中 rag/nlp/search.py:37-41

高层重排序管线

flowchart LR
    subgraph Input["输入数据"]
        SearchResults["SearchResult<br/>(来自混合搜索)"]
        Query["用户查询"]
        Config["重排序配置<br/>similarity_threshold<br/>vector_similarity_weight<br/>rerank_mdl"]
    end

    subgraph "Dealer.search() 执行"
        SearchPhase["Dealer.search()<br/>混合搜索<br/>(向量 + BM25)"]
        RerankDecision{"rerank_mdl<br/>是否提供?"}
        ModelRerank["Dealer.rerank_by_model()<br/>基于大语言模型的重排序"]
        SimilarityRerank["Dealer.rerank()<br/>基于相似度的重排序"]
        InfinityScore["使用 Infinity 融合分数<br/>(预归一化)"]
    end

    subgraph "评分逻辑"
        RankFeatures["_rank_feature_scores()<br/>TAG_FLD + PAGERANK_FLD"]
        HybridSim["hybrid_similarity()<br/>Token + 向量加权"]
        FinalScore["最终分数<br/>(sim + rank_fea)"]
    end

    subgraph "过滤逻辑"
        ThresholdFilter["应用 similarity_threshold"]
        AvailabilityFilter["过滤 available_int 片段"]
        TopN["选择前 N 个结果"]
    end

    subgraph Output["输出结果"]
        RankedChunks["排序后的片段<br/>(按分数排序)"]
    end

    SearchResults --> SearchPhase
    Query --> SearchPhase
    Config --> SearchPhase

    SearchPhase --> RerankDecision

    RerankDecision -->|是| ModelRerank
    RerankDecision -->|否,ES| SimilarityRerank
    RerankDecision -->|否,Infinity| InfinityScore

    ModelRerank --> RankFeatures
    SimilarityRerank --> RankFeatures
    InfinityScore --> RankFeatures

    RankFeatures --> FinalScore
    HybridSim --> FinalScore

    FinalScore --> ThresholdFilter
    ThresholdFilter --> AvailabilityFilter
    AvailabilityFilter --> TopN
    TopN --> RankedChunks

来源:rag/nlp/search.py:132-167, api/db/services/dialog_service.py:176-181

基于相似度的重排序

Dealer.rerank() 方法通过计算混合相似度分数来实现基于相似度的重排序,该分数结合了基于 Token 的相似度(BM25 风格)和基于向量的相似度 rag/nlp/search.py:296-300。这是未指定外部重排序模型时的默认行为。

实现

重排序过程从每个片段中提取可搜索的 Token,包括内容、标题、重要关键词和问题关键词。然后,使用 Token 重叠度和向量余弦相似度,将这些 Token 与用户查询进行评分。

基于相似度的重排序数据流

flowchart TB
    subgraph Input["输入(Dealer.rerank)"]
        SRes["sres: SearchResult<br/>ids, fields, query_vector"]
        Query1["query: str"]
        Weights["tkweight, vtweight<br/>(默认:0.3, 0.7)"]
    end

    subgraph "Token 提取"
        ExtractTokens["为每个片段提取 Token:<br/>content_ltks<br/>title_tks x2<br/>important_kwd x5<br/>question_tks x6"]
        QueryTokens["query.FulltextQueryer.question()<br/>提取查询关键词"]
    end

    subgraph "向量准备"
        ExtractVectors["从 fields 中提取 q_N_vec<br/>(如果缺失则使用零向量)"]
    end

    subgraph "评分(qryr.hybrid_similarity)"
        TokenSim["token_similarity()<br/>Jaccard 相似度<br/>在查询与片段 Token 之间"]
        VectorSim["vector_similarity()<br/>余弦相似度<br/>在 query_vector 与片段向量之间"]
        WeightedSum["sim = tkweight * tksim<br/>+ vtweight * vtsim"]
    end

    subgraph "排序特征"
        RankFea["_rank_feature_scores()<br/>TAG_FLD 余弦相似度<br/>+ PAGERANK_FLD"]
    end

    subgraph Output["输出"]
        FinalSim["final_sim = sim + rank_fea"]
        ReturnScores["返回 (sim, tksim, vtsim)"]
    end

    SRes --> ExtractTokens
    SRes --> ExtractVectors
    Query1 --> QueryTokens

    ExtractTokens --> TokenSim
    QueryTokens --> TokenSim
    ExtractVectors --> VectorSim
    SRes --> VectorSim

    TokenSim --> WeightedSum
    VectorSim --> WeightedSum
    Weights --> WeightedSum

    WeightedSum --> RankFea
    SRes --> RankFea

    RankFea --> FinalSim
    FinalSim --> ReturnScores

来源:rag/nlp/search.py:296-333, rag/nlp/query.py:23-25, rag/nlp/query.py:41-43

Token 加权策略

系统对不同 Token 类型应用差异化的权重,以反映其语义重要性:

Token 来源权重乘数字段名用途
内容 Token1xcontent_ltks基础内容匹配
标题 Token2xtitle_tks文档标题相关性
重要关键词5ximportant_kwd大语言模型提取的关键概念
问题 Token6xquestion_tks为问答匹配生成的问题

这种加权方案优先考虑与大语言模型生成的元数据(问题、关键词)的匹配,而非原始内容的匹配,从而提高了语义相关性 rag/nlp/search.py:318-323

来源:rag/nlp/search.py:318-323

向量维度处理

重排序逻辑会处理片段向量与查询向量维度不同(例如,当嵌入模型发生更改时)的情况。维度不匹配的片段会收到零向量,以防止崩溃 rag/nlp/search.py:310-315

来源:rag/nlp/search.py:310-315

基于模型的重排序

当通过 Dialog 模型中的 rerank_id 配置了重排序模型时,系统会使用 Dealer.rerank_by_model() 来计算基于大语言模型的相关性分数 rag/nlp/search.py:335-340。这提供了比纯相似度指标更复杂的语义理解能力。

重排序器模型接口

重排序模型作为配置了 LLMType.RERANKLLMBundle 实例传入 api/db/services/llm_service.py:85-86。该模型的 similarity() 方法 rag/llm/rerank_model.py:34-35 计算查询与每个片段文本之间的相关性分数。

基于模型的重排序架构

flowchart TB
    subgraph Input["输入(rerank_by_model)"]
        RerankMdl["rerank_mdl: LLMBundle<br/>(LLMType.RERANK)"]
        SRes2["sres: SearchResult"]
        Query2["query: str"]
        Weights2["tkweight, vtweight"]
    end

    subgraph "Token 处理"
        ExtractToks["提取 Token:<br/>content_ltks<br/>title_tks<br/>important_kwd"]
        PrepareTexts["拼接 Token<br/>remove_redundant_spaces()"]
    end

    subgraph "双重评分"
        TokenScore["token_similarity()<br/>(传统 BM25 风格)"]
        ModelScore["rerank_mdl.similarity()<br/>(基于大语言模型的相关性)"]
    end

    subgraph "组合"
        WeightedCombine["tkweight * tksim<br/>+ vtweight * vtsim"]
        AddRankFea["+ _rank_feature_scores()"]
    end

    subgraph Output2["输出"]
        FinalScore2["(final_scores, tksim, vtsim)"]
    end

    RerankMdl --> ModelScore
    SRes2 --> ExtractToks
    Query2 --> TokenScore
    Query2 --> ModelScore

    ExtractToks --> PrepareTexts
    PrepareTexts --> ModelScore
    ExtractToks --> TokenScore

    TokenScore --> WeightedCombine
    ModelScore --> WeightedCombine
    Weights2 --> WeightedCombine

    WeightedCombine --> AddRankFea
    SRes2 --> AddRankFea
    AddRankFea --> FinalScore2

来源:rag/nlp/search.py:335-356, api/db/services/dialog_service.py:181-183, rag/llm/rerank_model.py:34-35

排序特征评分

_rank_feature_scores() 方法添加了超越纯文本相似度的领域特定排序信号。它基于标签匹配和 PageRank 值计算分数 rag/nlp/search.py:269-272

标签特征评分

基于标签的评分计算查询的标签特征与每个片段标签之间的余弦相似度。标签存储在 TAG_FLD 字段中 rag/nlp/search.py:28-28

标签特征评分算法

flowchart TB
    subgraph Input3["输入"]
        QueryRfea["query_rfea: dict<br/>{tag: score, ...}"]
        ChunkTags["chunk TAG_FLD<br/>JSON 编码的字典"]
        ChunkPagerank["chunk PAGERANK_FLD"]
    end

    subgraph "查询归一化"
        CalcQDenor["q_denor = sqrt(sum(score^2))<br/>(排除 PAGERANK_FLD)"]
    end

    subgraph "逐片段评分"
        ParseTags["eval(chunk[TAG_FLD])"]
        DotProduct["nor = sum(query[tag] * chunk[tag])<br/>用于匹配的标签"]
        ChunkNorm["denor = sqrt(sum(chunk_score^2))"]
        CosineSim["score = nor / (sqrt(denor) * q_denor)"]
    end

    subgraph "组合"
        ScaleTag["tag_score * 10.0"]
        AddPagerank["+ chunk[PAGERANK_FLD]"]
        FinalRank["final_rank_score"]
    end

    QueryRfea --> CalcQDenor
    ChunkTags --> ParseTags

    CalcQDenor --> CosineSim
    ParseTags --> DotProduct
    DotProduct --> CosineSim
    ParseTags --> ChunkNorm
    ChunkNorm --> CosineSim

    CosineSim --> ScaleTag
    ScaleTag --> AddPagerank
    ChunkPagerank --> AddPagerank
    AddPagerank --> FinalRank

来源:rag/nlp/search.py:269-294

PageRank 集成

PageRank 值(PAGERANK_FLD)提供了独立于查询内容的文档级重要性信号。这些值会直接添加到排序特征分数中 rag/nlp/search.py:294

来源:rag/nlp/search.py:272-294, common/constants.py:93-93

阈值过滤

检索管线会应用多个过滤阶段来移除低质量或不相关的片段。

相似度阈值

similarity_threshold 参数根据片段的最终相似度分数进行过滤。该参数按对话进行配置,默认值为 0.2 api/db/services/dialog_service.py:178-178

检索中的阈值应用

flowchart LR
    subgraph "初始搜索"
        HybridSearch["使用相似度参数的<br/>混合搜索"]
    end

    subgraph "重排序"
        Rerank["计算最终分数<br/>(sim + rank_fea)"]
        SortScores["按分数降序排序"]
    end

    subgraph "过滤阶段"
        ThreshFilter["过滤:score >= threshold"]
        TopKFilter["选择前 K 个片段"]
        AvailFilter["过滤:available_int == 1"]
    end

    subgraph Output3["输出"]
        FinalChunks["过滤并排序后的片段"]
    end

    HybridSearch --> Rerank
    Rerank --> SortScores
    SortScores --> ThreshFilter
    ThreshFilter --> TopKFilter
    TopKFilter --> AvailFilter
    AvailFilter --> FinalChunks

来源:rag/nlp/search.py:120-130, api/db/services/dialog_service.py:176-180

可用性过滤

可以使用 available_int 字段将片段标记为不可用。这允许在不删除片段的情况下,手动或自动管理片段的可见性 rag/nlp/search.py:125-129

# 来自 search.py:150-153
src = req.get("fields",
              ["docnm_kwd", "content_ltks", "kb_id", "img_id", "title_tks", "important_kwd", "position_int",
               "doc_id", "chunk_order_int", "page_num_int", "top_int", "create_timestamp_flt", "knowledge_graph_kwd",
               "question_kwd", "question_tks", "doc_type_kwd",
               "available_int", "content_with_weight", "mom_id", PAGERANK_FLD, TAG_FLD, "row_id()"])

来源:rag/nlp/search.py:150-153

在检索管线中的集成

完整的检索流程将重排序和过滤集成为一个统一的管线,由 Dealer.search() 执行 rag/nlp/search.py:132-137

重排序限制与分页

检索逻辑使用分页参数来控制为重排序检索的候选数量 rag/nlp/search.py:144-147

# 来自 search.py:144-147
pg = int(req.get("page", 1)) - 1
topk = int(req.get("topk", 1024))
ps = int(req.get("size", topk))
offset, limit = pg * ps, ps

来源:rag/nlp/search.py:144-147

后端特定的重排序逻辑

系统会根据文档存储后端(Elasticsearch 与 Infinity)调整其重排序策略。Infinity 会预归一化融合分数,而 Elasticsearch 则需要通过 rerank() 方法进行手动归一化 rag/nlp/search.py:174-180

后端特定的重排序逻辑

flowchart TB
    subgraph Config["配置检查"]
        CheckRerank{"rerank_mdl<br/>是否提供?"}
        CheckBackend{"settings.DOC_ENGINE_INFINITY"}
    end

    subgraph "重排序路径"
        ModelPath["使用 rerank_by_model()<br/>(适用于两个后端)"]
        InfinityPath["使用 Infinity 融合分数<br/>(预归一化)"]
        ESPath["使用 rerank()<br/>(ElasticSearch 需要归一化)"]
    end

    subgraph "分数处理"
        UseScores["从 sres.field 提取 _score"]
        NormalizeScores["归一化并组合<br/>Token + 向量分数"]
    end

    subgraph Output4["输出"]
        SortedChunks["按最终分数排序的片段"]
    end

    CheckRerank -->|是| ModelPath
    CheckRerank -->|否| CheckBackend

    CheckBackend -->|True| InfinityPath
    CheckBackend -->|False| ESPath

    InfinityPath --> UseScores
    ESPath --> NormalizeScores
    ModelPath --> NormalizeScores

    UseScores --> SortedChunks
    NormalizeScores --> SortedChunks

来源:rag/nlp/search.py:132-180, common/settings.py:92-92