拓冰建站拓冰建站
首页 / 资讯中心 / 正文

LlamaIndex 系列【22】检索增强策略:混合检索(Hybrid Search)

文章目录1. 前言2. 工作流程3. 核心原理3.1 两路并行召回机制3.2 分数归一化3.3 结果融合排序3.3.1 方案 1RRFReciprocal Rank Fusion倒数排名融合3.3.2 方案 2自定义加权分数融合4. QueryFusionRetriever 多路融合检索器4.1 工作流程4.2 构造方法4.3 融合模式枚举 FUSION_MODES4.4 其他方法4.5 对外公共 API5. 案例演示5.1 构建 BM25 检索器5.2 构建向量索引检索器5.3 构建融合检索器5.4 执行检索5.5 封装成完整问答引擎1. 前言在之前我们学习了BM25/TF‑IDF、语义检索关键词检索BM25 / TF‑IDF基于关键词字面匹配擅长抓取专有名词、专业术语、编号语义检索Embedding 向量库基于向量余弦相似度理解同义改写、自然语言语义。基础检索直接使用用户原始问句进行检索不对查询做改写、拆解、路由等二次加工仅执行关键词或语义召回链路简短环节少。是RAG体系中最基础、最简的检索范式也是各类高级检索策略的基线基准。只使用单一检索方案都存在短板只用BM25换一种句式表达、同义词替换后就检索不到只用向量语义检索容易忽略业务强关键词把无关但句式相似的文档召回。基础检索适合问题简短、语义明确、歧义少、用户表述与文档文本措辞相近、知识库体量不大的事实类问答场景。面对复杂、准确性要求高的等场景时就需要使用更高级的检索策略。高级检索Advanced Retrieval是RAG体系中在基础检索之上扩展得到的一类增强检索方案用于解决基础检索单一检索方式带来的短板。它不再直接拿用户原始问句做单次检索而是在检索全链路中增加查询改造、多路召回、多轮检索、结果重排等增强逻辑。混合检索Hybrid Search是最常用的增强技术方案它通过「稀疏关键词检索稠密向量检索」双路召回再经过分数归一化与排名融合算法同时兼顾精准命中与语义理解能力。2. 工作流程流程描述用户输入查询语句Query并行执行两条检索链路链路1BM25关键词检索 → 生成候选列表A链路2Embedding向量化 → 向量数据库检索 → 生成候选列表B将候选列表A、候选列表B合并并去重使用RRF/Cross‑Encoder对合并文档重排序输出排序后的Top‑K文档交付给大模型3. 核心原理3.1 两路并行召回机制用户提交查询Query之后系统不会只执行一种检索逻辑而是并行启动两条独立的召回链路分别生成候选文档列表。两条链路各司其职解决不同场景的检索需求稀疏关键词检索BM25 / 倒排索引基于分词、倒排索引做字面匹配依靠BM25打分公式计算文本相关性。优势精准命中专有名词、产品编号、故障码、代码片段、固定术语关键词命中权重高结果可解释性强。短板不理解语义同义词、转述句式无法召回目标文档。稠密向量检索Embedding 向量数据库余弦相似度将用户Query与知识库文本通过Embedding模型转为高维向量计算向量之间的余弦相似度召回语义相近的文档。优势具备语义理解能力可以识别同义表达、模糊提问、换一种说法的自然语言问题。短板对强标识类字段不敏感容易召回语义相似但关键词不匹配的无关文档。两条链路独立执行检索各自返回一组Top‑K候选文档此时我们得到两份独立的候选集合与各自的原始打分。3.2 分数归一化两路检索输出的原始分数不在同一个数值区间不能直接相加做加权融合。BM25得分取值范围[0, ∞)文档越长、关键词命中越多分数可以无限增大余弦相似度取值范围[-1, 1]1代表向量方向完全一致-1代表语义完全相反。原始分数量级完全不对等如果直接加权计算某一路的打分将会完全主导最终排序结果导致融合失效。因此必须做分数标准化归一化把两组分数映射到统一区间一般是[0,1]。工程中两种主流归一化方案BM25 分数处理先做对数log变换压缩高分区间再使用min‑max缩放将全部分值压缩至0~1余弦相似度处理线性映射把区间[-1,1]平移缩放为[0,1]。完成归一化之后两份候选文档才具备数值对比与加权融合的基础。3.3 结果融合排序LlamaIndex默认支持四种方案这里列举常用的两种。3.3.1 方案 1RRFReciprocal Rank Fusion倒数排名融合RRF是目前RAG项目中最主流、开箱即用的融合策略它完全抛弃原始检索分数只使用文档在各自列表中的排名位置计算综合得分规避了归一化带来的调参成本。计算公式R R F _ s c o r e 1 k r a n k v e c t o r 1 k r a n k t e x t RRF\_score \frac{1}{krank_{vector}}\frac{1}{krank_{text}}RRF_scorekrankvector​1​kranktext​1​r a n k v e c t o r rank_{vector}rankvector​文档在向量检索结果里的排名第1名rank1r a n k t e x t rank_{text}ranktext​文档在BM25关键词检索结果里的排名k kk平滑常量工业实践默认取值k 60 k60k60核心特点排名越靠前贡献的分值越高文档在两个列表排名都靠前最终综合得分最高不需要人工配置权重无需反复调试归一化参数开箱即用、稳定性强不会让某一条检索链路单方面控制最终召回顺序平衡语义与关键词两种能力。3.3.2 方案 2自定义加权分数融合如果业务需要人为控制两路检索的优先级可以在分数归一化完成后配置权重做线性加权f i n a l _ s c o r e w 1 × v e c t o r _ s c o r e w 2 × s p a r s e _ s c o r e final\_score w_1 \times vector\_score w_2 \times sparse\_scorefinal_scorew1​×vector_scorew2​×sparse_scorew 1 w_1w1​向量检索权重w 2 w_2w2​BM25稀疏检索权重w 1 w 2 w_1w_2w1​w2​一般等于1根据业务场景调参知识库术语多则调高w 2 w_2w2​面向自然问答场景调高w 1 w_1w1​。加权融合灵活性更高但需要标注数据集反复评估调优适合后期精细化优化阶段使用原型开发阶段优先选择RRF降低维护成本。4. QueryFusionRetriever 多路融合检索器QueryFusionRetriever属于多路混合检索组件继承自BaseRetriever对外保持统一的retrieve()/aretrieve()调用规范。它同时具备两大核心能力LLM 查询改写扩展多检索器结果融合重排可以同时接入向量检索、BM25、自动检索器等多个召回源解决单一检索方式召回不全、排序偏差的问题。4.1 工作流程整体执行链路分为5 个核心步骤接收原始查询接收用户输入的问句封装为QueryBundle对象作为基准查询。LLM 生成扩展查询可选如果num_queries 1通过内置Prompt调用大模型自动生成多条语义相近、表述不同的检索问句原始问句 扩展问句共同构成查询集合。多检索器并发召回将每一条查询分别分发到配置列表内的全部底层检索器支持同步串行或异步并发执行多路检索拿到多组独立召回结果。结果融合打分与去重根据指定的融合模式对来自不同查询、不同检索器的文档重新计算融合分值对重复文档做去重处理。提供四种融合策略SIMPLE简易融合重复文档保留最高分RECIPROCAL_RANKRRF倒数排名融合仅依赖排序位次不受原始分值范围影响RELATIVE_SCOREMin‑Max归一化加权融合DIST_BASED_SCORE基于均值、标准差的分布归一化加权融合截断返回最终 Top‑K将融合后的文档按新分数降序排序截取前similarity_top_k条返回标准格式List[NodeWithScore]。核心特点上层调用完全无感融合检索器和普通向量检索器调用方式完全一致可以直接送入问答引擎使用。4.2 构造方法构造函数QueryFusionRetriever(retrievers:List[BaseRetriever],llm:Optional[LLMType]None,query_gen_prompt:Optional[str]None,mode:FUSION_MODESFUSION_MODES.SIMPLE,similarity_top_k:intDEFAULT_SIMILARITY_TOP_K,num_queries:int4,use_async:boolTrue,verbose:boolFalse,callback_manager:Optional[CallbackManager]None,objects:Optional[List[IndexNode]]None,object_map:Optional[dict]None,retriever_weights:Optional[List[float]]None)参数说明参数类型说明retrieversList[BaseRetriever]必填底层检索器集合可以传入向量检索器、BM25检索器、自动检索器等任意实现BaseRetriever的实例llmOptional[LLMType]用于生成扩展查询的大模型为空时读取全局配置Settings.llmquery_gen_promptOptional[str]自定义查询改写提示词不传则使用内置默认模板modeFUSION_MODES结果融合算法枚举共4种策略similarity_top_kint融合重排之后最终返回的文档条数num_queriesint总共生成的查询总数包含原始问句等于1时关闭LLM查询扩展能力use_asyncbool是否启用异步并发检索True并发执行提升速度False同步串行执行verbosebool调试开关开启后打印LLM生成的扩展问句callback_managerOptional[CallbackManager]回调管理器用于日志、埋点、链路追踪retriever_weightsOptional[List[float]]每个检索器的权重系数内部会自动归一化仅在加权融合模式生效4.3 融合模式枚举 FUSION_MODESclassFUSION_MODES(str,Enum):RECIPROCAL_RANKreciprocal_rerank# RRF倒数排名融合工业常用RELATIVE_SCORErelative_score# 最值归一化加权融合DIST_BASED_SCOREdist_based_score# 统计分布归一化加权融合SIMPLEsimple# 简易去重取最高分4.4 其他方法Prompt管理方法_get_prompts() - PromptDictType获取当前使用的查询生成提示词模板用于框架内部Prompt管理。_update_prompts(prompts: PromptDictType)动态更新查询改写Prompt支持运行时替换自定义模板。查询生成工具方法_get_queries(original_query: str) - List[QueryBundle]同步方式调用LLM生成多条扩展检索问句返回QueryBundle列表。_aget_queries(original_query: str) - List[QueryBundle]异步方式非阻塞调用LLM生成扩展问句适配异步服务。多路检索执行方法_run_sync_queries(queries)同步串行执行全部检索任务_run_nested_async_queries(queries)框架封装的异步任务调度执行_run_async_queries(queries)原生asyncio.gather并发执行融合打分私有方法_simple_fusion()简易去重融合逻辑_reciprocal_rerank_fusion()RRF倒数排名融合算法实现_relative_score_fusion()归一化加权融合支持普通 / 分布归一化两种分支检索入口实现父类抽象接口_retrieve(query_bundle: QueryBundle) - List[NodeWithScore]同步检索主逻辑对外暴露为retrieve()_aretrieve(query_bundle: QueryBundle) - List[NodeWithScore]异步检索主逻辑对外暴露为aretrieve()4.5 对外公共 API.retrieve(用户问题)同步调用await .aretrieve(用户问题)异步调用5. 案例演示实现稀疏BM25关键词检索 稠密向量检索的混合召回架构通过QueryFusionRetriever完成多路结果融合最终封装成完整问答引擎。两个容易踩的坑QueryFusionRetriever构造函数无条件解析Settings.llm即使num_queries1根本不调用LLM也会报No API key found for OpenAI。所以必须显式传入llmllm。新版RetrieverQueryEngine.__init__已去掉llm参数只能通过Settings.llm指定否则会TypeError: unexpected keyword argument llm。5.1 构建 BM25 检索器说明新版llama-index-retrievers-bm25默认用英文正则分词需用jieba分词自定义检索器。importcopyimportjiebafromllama_index.coreimportSimpleDirectoryReaderfromllama_index.core.node_parserimportSentenceSplitterfromllama_index.core.vector_stores.utilsimportnode_to_metadata_dictfromllama_index.retrievers.bm25importBM25Retrieverdefzh_seg(text:str)-str:return .join(jieba.cut(text))classChineseBM25Retriever(BM25Retriever):classmethoddeffrom_defaults(cls,nodes,similarity_top_k2,**kwargs):original_nodesnodes segmented_nodes[copy.deepcopy(n)forninnodes]forninsegmented_nodes:n.set_content(zh_seg(n.get_content()))retrieversuper().from_defaults(nodessegmented_nodes,similarity_top_ksimilarity_top_k,token_patternr(?u)\b\w\b,skip_stemmingTrue,**kwargs,)retriever.corpus[node_to_metadata_dict(n)|{node_id:n.node_id}forninoriginal_nodes]returnretrieverdef_retrieve(self,query_bundle):query_bundle.query_strzh_seg(query_bundle.query_str)returnsuper()._retrieve(query_bundle)documentsSimpleDirectoryReader(./data).load_data()splitterSentenceSplitter(chunk_size512)nodessplitter.get_nodes_from_documents(documents)bm25_retrieverChineseBM25Retriever.from_defaults(nodesnodes,similarity_top_k3,)5.2 构建向量索引检索器fromllama_index.coreimportVectorStoreIndexfromllama_index.embeddings.openai_likeimportOpenAILikeEmbedding embed_modelOpenAILikeEmbedding(model_nametext-embedding-v3,api_keyos.environ[DASHSCOPE_API_KEY],api_basehttps://ws-jfb8j8mx0n7e2k6a.cn-beijing.maas.aliyuncs.com/compatible-mode/v1,)vector_indexVectorStoreIndex(nodesnodes,embed_modelembed_model)vector_retrievervector_index.as_retriever(similarity_top_k3)5.3 构建融合检索器fromllama_index.core.retrieversimportQueryFusionRetrieverfromllama_index.llms.openai_likeimportOpenAILike llmOpenAILike(modelqwen3.8-max,api_keyos.environ[DASHSCOPE_API_KEY],api_basehttps://ws-jfb8j8mx0n7e2k6a.cn-beijing.maas.aliyuncs.com/compatible-mode/v1,is_chat_modelTrue,)fusion_retrieverQueryFusionRetriever(retrievers[vector_retriever,bm25_retriever],llmllm,# 构造时必传即使 num_queries1 不真正调用num_queries1,# 1 不做 LLM 查询扩展仅结果融合modereciprocal_rerank,# RRF 融合也可用 relative_score / simplesimilarity_top_k3,use_asyncFalse,)5.4 执行检索query星云知识库怎么私有化部署resultsfusion_retriever.retrieve(query)fori,iteminenumerate(results,1):print(f[{i}] 融合分数:{item.score:.4f})print(f 节点ID:{item.node.node_id})print(f 文本:{item.node.text[:60]}\n)BM25稀疏检索关键词结果---BM25 稀疏检索关键词---[1.5594]# 星云知识库产品说明星云知识库是星云科技推出的企业级 RAG 知识管理平台[0.5927]# 星云科技公司介绍星云科技成立于2018年总部位于杭州是一家专注于[0.3087]# 售后政策与常见问题向量稠密检索语义[0.6936]# 星云知识库产品说明星云知识库是星云科技推出的企业级 RAG 知识管理平台[0.5737]# 星云科技公司介绍星云科技成立于2018年总部位于杭州是一家专注于[0.5441]# 售后政策与常见问题## 售后服务政策1.订阅期内提供 7x24 小融合结果[1] 融合分数: 0.0333 节点ID: 2172779d-41ef-42b7-a89d-61be9608352e 文本: # 星云知识库产品说明 星云知识库是星云科技推出的企业级 RAG 知识管理平台帮助企业把散落在各处的文档转化为可检索 [2] 融合分数: 0.0328 节点ID: e519aeff-47c1-4461-bd70-70c23ffc1463 文本: # 星云科技公司介绍 星云科技成立于 2018 年总部位于杭州是一家专注于企业级人工智能应用的高新技术企业。公司核 [3] 融合分数: 0.0323 节点ID: 72ca9309-84d2-4580-aa50-fc1a8784baa9 文本: # 售后政策与常见问题最终回答星云知识库的私有化部署方式是将系统部署在企业内网中支持完全离线环境运行数据不出企业内网。 部署要求方面私有化版本的最低配置为4核 CPU、16G 内存。 实施服务方面私有化版本提供一次免费现场实施后续如需现场服务按次收费。如果选择旗舰版还可以按需定制并包含专属模型调优与现场实施服务。 此外私有化部署时也可以接入企业内部自建模型服务。 Process finishedwithexit code05.5 封装成完整问答引擎fromllama_index.coreimportSettingsfromllama_index.core.query_engineimportRetrieverQueryEngine Settings.llmllm# RetrieverQueryEngine 不再接收 llm 参数统一走 Settings.llmquery_engineRetrieverQueryEngine(retrieverfusion_retriever)answerquery_engine.query(query)print(answer)
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门