重排序与筛选
重排序与过滤
相关源文件
本章引用的主要源码文件:
agent/tools/retrieval.pyapi/apps/llm_app.pyapi/db/__init__.pyapi/db/db_models.pyapi/db/services/dialog_service.pyapi/db/services/document_service.pyapi/db/services/file_service.pyapi/db/services/knowledgebase_service.pyapi/db/services/llm_service.pyapi/db/services/task_service.pyapi/db/services/user_service.pyconf/llm_factories.jsonrag/llm/__init__.pyrag/llm/chat_model.pyrag/llm/cv_model.pyrag/llm/embedding_model.pyrag/llm/rerank_model.pyrag/llm/sequence2txt_model.pyrag/llm/tts_model.pyrag/nlp/search.pyrag/raptor.pyrag/svr/task_executor.pyweb/src/components/rerank.tsxweb/src/components/similarity-slider/index.tsxweb/src/components/svg-icon.tsxweb/src/components/switch-fom-field.tsxweb/src/components/top-n-item.tsxweb/src/components/use-knowledge-graph-item.tsxweb/src/constants/llm.tsweb/src/pages/agent/form/retrieval-form/next.tsxweb/src/pages/agent/form/tool-form/retrieval-form/index.tsxweb/src/pages/user-setting/setting-model/constant.tsweb/src/utils/common-util.ts
本文档介绍 RAGFlow 的双层重排序系统和过滤机制,这些机制会在搜索结果呈现给大语言模型(LLM)进行答案生成之前对其进行优化。该系统结合了基于相似度的评分、可选的基于模型的重排序、排序特征评分(标签、PageRank)以及阈值过滤,以优化片段选择。
有关初始搜索和检索过程的信息,请参阅 9.2 查询处理与混合搜索。有关将检索到的片段格式化为上下文的后续步骤,请参阅 9.4 响应生成与引用。
系统概览
重排序与过滤系统作为混合搜索检索后的后处理层运行。它接收来自文档存储(Elasticsearch、Infinity 或 OpenSearch)的初始搜索结果,并应用额外的评分和过滤逻辑。核心逻辑位于 rag/nlp/search.py 的 Dealer 类中 rag/nlp/search.py:37-41。
高层重排序管线
来源: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 与用户查询进行评分。
基于相似度的重排序数据流
来源:rag/nlp/search.py:296-333, rag/nlp/query.py:23-25, rag/nlp/query.py:41-43
Token 加权策略
系统对不同 Token 类型应用差异化的权重,以反映其语义重要性:
| Token 来源 | 权重乘数 | 字段名 | 用途 |
|---|---|---|---|
| 内容 Token | 1x | content_ltks | 基础内容匹配 |
| 标题 Token | 2x | title_tks | 文档标题相关性 |
| 重要关键词 | 5x | important_kwd | 大语言模型提取的关键概念 |
| 问题 Token | 6x | question_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.RERANK 的 LLMBundle 实例传入 api/db/services/llm_service.py:85-86。该模型的 similarity() 方法 rag/llm/rerank_model.py:34-35 计算查询与每个片段文本之间的相关性分数。
基于模型的重排序架构
来源: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。
标签特征评分算法
来源: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。
检索中的阈值应用
来源: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。
后端特定的重排序逻辑
来源:rag/nlp/search.py:132-180, common/settings.py:92-92