混合查询中当结构化SQL查询如精确的订单、用户信息与非结构化向量检索如语义化的菜单、菜品描述结果在内容、优先级或相关性上出现冲突时有效的加权融合是确保最终结果准确、合理的关键。其核心在于建立统一的评分体系并设计融合策略。一、 冲突场景与融合目标分析首先需明确“冲突”的具体类型这决定了融合策略的侧重点冲突类型典型场景核心矛盾融合目标信息重叠但优先级冲突SQL查得用户“曾点过A菜品”向量检索“推荐B、C菜品”。用户问“有什么好吃的”历史偏好SQL vs. 全局语义匹配向量平衡个人化与新鲜度决定排序。信息矛盾SQL显示“订单状态为已完成”但向量检索的FAQ片段包含“订单一般需30分钟”用户问“我的订单到哪了”实时事实SQL vs. 通用知识向量事实优先确保准确性。结果集异构SQL返回“订单号123菜品辣子鸡丁”向量返回“菜品辣子鸡丁图片、描述、口味”。用户问“我上次点的辣子鸡丁辣吗”结构化记录 vs. 非结构化详情信息互补合并为完整答案。相关性评分尺度不一SQL查询通过时间、金额等字段排序向量检索通过余弦相似度打分。两者结果需统一排序。分数不可比性分数归一化实现公平加权。二、 加权融合的核心方法融合的核心是将来自不同检索系统的、尺度不一的结果映射到一个可比较的分数上然后进行加权合并与重排序。主要方法如下方法一分数归一化与线性加权融合这是最直接和常用的方法尤其适用于需将不同类型结果进行统一排序的场景。分数归一化将SQL查询的“相关性指标”如时间倒序的排名、金额等和向量检索的“相似度分数”统一映射到[0, 1]区间。Min-Max归一化score_norm (score - min_score) / (max_score - min_score)Z-Score归一化score_norm (score - mean) / std然后可进行缩放。排名倒数归一化对于只有排序没有分数的情况如SQL按时间倒序可使用score_norm 1 / rank。def normalize_scores(score_list, methodminmax): 归一化分数列表 import numpy as np scores np.array(score_list) if method minmax: if np.max(scores) np.min(scores): return np.ones_like(scores) return (scores - np.min(scores)) / (np.max(scores) - np.min(scores)) elif method softmax: exp_scores np.exp(scores - np.max(scores)) # 防溢出 return exp_scores / np.sum(exp_scores) # 其他归一化方法...线性加权融合为不同来源分配权重计算最终分。def linear_weighted_fusion(sql_items, vector_items, sql_weight0.3, vector_weight0.7): sql_items: list of dicts [{id: order123, norm_score: 0.8, data: {...}}, ...] vector_items: list of dicts [{id: menu456, norm_score: 0.9, data: {...}}, ...] fused_dict {} # 处理SQL结果 for item in sql_items: fused_dict[item[id]] { final_score: item[norm_score] * sql_weight, source: sql, data: item[data] } # 处理向量结果若ID已存在则分数相加 for item in vector_items: if item[id] in fused_dict: fused_dict[item[id]][final_score] item[norm_score] * vector_weight fused_dict[item[id]][source] hybrid else: fused_dict[item[id]] { final_score: item[norm_score] * vector_weight, source: vector, data: item[data] } # 按最终分排序 sorted_results sorted(fused_dict.values(), keylambda x: x[final_score], reverseTrue) return sorted_results权重设定sql_weight和vector_weight是超参数。在餐厅场景下事实查询优先当查询明确指向订单、用户信息时sql_weight应设高如0.9。探索推荐优先当查询为开放式菜品推荐时vector_weight应设高如0.8。平衡模式对于“我点过的菜里有什么辣的”这类混合意图可设sql_weight0.4,vector_weight0.6既考虑历史记录又强调语义匹配。方法二基于 Reciprocal Rank Fusion (RRF) 的融合当不同检索系统返回的结果只有排名Rank没有原始分数或者分数尺度差异极大难以归一化时RRF是一种简单有效的无参数融合方法。其核心思想是一个文档在多个列表中的排名越靠前排名数字越小其融合得分越高。公式为score_rrf Σ (1 / (k rank_i))其中rank_i是文档在第i个列表中的排名k是一个常数通常取60用于降低低排名文档的影响。def rrf_fusion(ranked_lists, k60): ranked_lists: [ [{id: A}, {id: B}, {id: C}], # SQL结果列表 (按时间排序) [{id: B}, {id: D}, {id: A}] # 向量结果列表 (按相似度排序) ] scores {} for list_idx, single_list in enumerate(ranked_lists): for rank, item in enumerate(single_list, start1): doc_id item[id] if doc_id not in scores: scores[doc_id] 0 scores[doc_id] 1 / (k rank) # 将得分字典转换为按得分排序的列表 fused_results [{id: doc_id, rrf_score: score} for doc_id, score in scores.items()] fused_results.sort(keylambda x: x[rrf_score], reverseTrue) return fused_results优点无需分数归一化对异构排名鲁棒性强。缺点未考虑各检索系统本身的置信度差异如精确匹配的SQL理应比模糊的向量检索更可信。方法三带权重的RRFWeighted RRF结合方法一和方法二的优点为不同检索列表赋予权重以体现其重要性差异。score_wrrf Σ (weight_i / (k rank_i))def weighted_rrf_fusion(ranked_lists, weights, k60): ranked_lists: [sql_ranked_list, vector_ranked_list] weights: [sql_weight, vector_weight] # 例如 [0.7, 0.3] scores {} for weight, single_list in zip(weights, ranked_lists): for rank, item in enumerate(single_list, start1): doc_id item[id] if doc_id not in scores: scores[doc_id] 0 scores[doc_id] weight / (k rank) fused_results sorted([{id: k, wrrf_score: v} for k, v in scores.items()], keylambda x: x[wrrf_score], reverseTrue) return fused_results这种方法在餐厅混合路由中非常实用。例如对于订单状态查询可以给SQL列表极高的权重如0.9给向量检索可能匹配到相关FAQ较低的权重如0.1确保最终排序中精确的订单信息永远在最前面。三、 餐厅场景下的融合策略与实践建议在实际的餐厅问答智能体中融合不仅是分数计算更是业务逻辑的体现。分层决策事实优先第一层意图过滤。若LLM或分类器判定为纯事实查询如订单状态、个人信息则直接采用SQL结果忽略向量检索结果无需融合。第二层加权融合。对于混合意图如“推荐一些像我上次点的辣子鸡丁那样的菜”启动融合流程。步骤1并行查询。SQL获取用户历史订单中的“辣子鸡丁”记录向量检索获取与“辣子鸡丁”描述相似的菜品。步骤2结果对齐。尝试通过“菜品ID”或“菜品名称”将两个结果集关联。SQL结果中的菜品作为“种子”。步骤3融合排序。采用加权RRF。为SQL结果中的“种子菜品”赋予高基础分体现历史偏好为向量结果中与“种子菜品”高度相似的新菜品也给予较高排名。权重可配置为sql_weight0.4,vector_weight0.6。信息互补结果合成对于异构结果融合的目标不是排序而是信息合并。例如SQL返回{“dish_name”: “麻婆豆腐”, “order_count”: 5}向量返回{“dish_name”: “麻婆豆腐”, “description”: “麻辣鲜香...”, “spicy_level”: 5}。策略以SQL结果中的业务数据为主键将向量检索中的描述性信息作为补充字段进行拼接合成一条完整信息返回给LLM生成答案。动态权重调整权重不应是固定的。可以基于以下因素动态计算查询意图置信度若意图分类器判定为“订单查询”的置信度达95%则大幅提高sql_weight。查询模糊度若用户查询包含具体订单号高精度则SQL权重提高若查询为“好吃的牛肉”高模糊度则向量权重提高。结果集质量若SQL查询返回结果为空则自动将sql_weight降为0完全依赖向量检索。四、 总结与选型建议方法适用场景优点缺点餐厅场景示例线性加权融合各检索系统能提供可归一化的置信度分数。直观可解释性强能灵活调整权重。严重依赖分数归一化的合理性权重需仔细调优。融合“菜品热度分SQL”与“语义匹配分向量”进行推荐排序。RRF只有排名或分数尺度迥异且认为各检索系统同等重要。无需调参简单鲁棒直接对排名操作。未考虑不同检索模态的重要性差异。快速融合“最新订单SQL按时间排”和“相似菜品向量按相似度排”的初始列表。加权RRF需要综合考虑排名和不同检索模态的重要性。兼具RRF的鲁棒性和权重的灵活性是实践中的推荐首选方法。需要确定权重参数。处理混合意图的核心方法。为历史订单SQL和语义推荐向量分配不同权重进行融合排序。实施路线图建议基线实现首先实现加权RRF作为核心融合引擎因为它平衡了效果与复杂度。业务规则覆盖在融合引擎上层添加基于明确业务规则的前置过滤器如查询中含订单号则直接返回SQL结果确保关键事实的绝对准确。动态化演进收集用户交互数据分析不同查询类型下哪种权重配置或融合策略的答案满意度更高逐步将静态权重升级为基于简单规则的动态权重。评估与迭代定义评估指标如答案准确率、推荐点击率通过A/B测试持续优化融合策略和参数。参考来源基于加权RRF的混合检索与RAG系统融合方法详解OceanBase混合检索Hybrid Search多模态检索实战指南为什么你的混合检索不准Dify结果融合机制大揭秘