Superlinked查询加权数学原理:搜索结果排序背后的权重算术
【免费下载链接】sieOpen-source inference server and production cluster for all the models your agent needs.项目地址: https://gitcode.com/GitHub_Trending/su/sie
Superlinked 是一款开源的语义搜索框架,它的查询加权(Query Weighting)机制决定了多路搜索结果如何融合排序。本文从源码出发,拆解 Superlinked 权重算术的三大核心公式——加权向量求和、L2 归一化、输入域聚合,帮你彻底理解搜索排序背后的数学。
Superlinked查询时间权重示意:不同空间在查询时的权重设置
一、权重从哪来:每个空间一个权重参数
在 Superlinked 中,一次查询往往同时命中多个"空间"(Space):文本空间、数字空间、时间新近度空间、类别空间……每个空间各自产出一个向量,而查询加权就是给每个空间的向量分配一个系数,控制它对最终排序的贡献度。
权重的默认值定义在 const.py 中:
DEFAULT_WEIGHT = 1.0:默认参与融合DEFAULT_NOT_AFFECTING_WEIGHT = 0.0:权重为 0 表示该空间"完全不影响结果",相当于被静默关闭
当用户对某个空间的字段做"看起来像"(looks like)过滤时,框架会通过 looks_like_filter_clause_weights_by_space.py 中的LooksLikeFilterClauseWeightBySpace把用户传入的权重绑定到具体空间上,权重映射由 space_weight_map.py 的SpaceWeightMap统一管理,未传权重时自动回落到默认值 1.0。
Superlinked多路向量嵌入组合示意:多空间向量如何参与融合
二、核心公式①:加权向量求和
这是整个排序系统最重要的一步,实现在 aggregation.py 的VectorAggregation类中。给定每个空间产出的向量 vᵢ 和对应权重 wᵢ,聚合公式为:
V = Σ (wᵢ · vᵢ)(跳过权重为 0 的项),再对 V 做 L2 归一化
对应源码逻辑(第 61–78 行):先把负过滤位置替换为 0,再乘以权重,然后逐个累加。几个关键细节:
- 权重是逐分量缩放:向量每个维度都乘以同一个 wᵢ,相当于整体"拉伸"该方向的信号强度;
- 0 权重直接剔除:
weight == 0的项根本不进入求和,这正是"该空间不参与排序"的数学含义; - 负过滤位保护:所有参与聚合的向量若在同一维度都标记了负过滤,聚合后该维度继续保留负过滤语义,保证"排除项"不会被权重计算悄悄抹掉。
三、核心公式②:L2 归一化让权重"可比较"
加权求和之后,结果向量的模长会随权重大小而变化。Superlinked 在 normalization.py 中提供了完整的归一化工具箱:
| 归一化 | 公式 | 适用场景 |
|---|---|---|
L2Norm | 除以 ‖v‖₂(欧几里得范数) | 向量聚合后的标准收尾步骤 |
L1Norm | 除以 Σ|vᵢ| | 稀疏向量的鲁棒归一 |
ConstantNorm | 除以固定常数 | 需要保持绝对量纲的空间 |
CategoricalNorm | 按类别数做期望最大值的归一 | 类别相似空间 |
对VectorAggregation而言,L2 归一化是权重算术的关键一环:它把不同权重大小产生的模长差异抹平,使最终比较只保留"方向"信息。也就是说,权重改变的是方向占比,而不是距离尺度——这保证了不同空间的结果在余弦相似度下公平比较。
四、核心公式③:输入域聚合(Min-Max 数字空间)
文本向量可以直接相加,但数字空间的向量先被编码进了嵌入空间,"直接加权求和"在语义上并不合理。Superlinked 的解法是InputAggregation(见 aggregation.py):
- 反向解码:用
inverse_embed把每个空间的向量还原成原始数值 xᵢ; - 在原始数值上做权重聚合,三种模式可选:
- 加权平均:x = Σ(wᵢ·xᵢ) / Σwᵢ(
InputAvg,用np.average实现) - 取最小:x = min(xᵢ)(
InputMin) - 取最大:x = max(xᵢ)(
InputMax)
- 加权平均:x = Σ(wᵢ·xᵢ) / Σwᵢ(
- 重新嵌入:把聚合后的数值 x 再次 embed 成向量参与后续流程。
这就是为什么 Min-Max 数字空间可以表达"价格在 100~500 之间"这种带权区间约束——权重在数值域生效,语义才正确。
五、权重如何流到执行层:DAG 节点权重表
用户设置的权重不会直达向量,而是先翻译成节点权重表。QueryWeighting(query_weighting.py)负责把"用户对某字段的权重"映射到查询 DAG 中对应的嵌入节点 ID 上,并以SPACE_WEIGHT_PARAM_NAME为键注入执行上下文。执行时,weight_arithmetics.py 提供两个原子操作:
apply_vector_weight:取出节点权重,执行vector * weightget_weight_abs_sum:对一组节点求权重绝对值之和,用于需要"归一化后权重"的场景
这一层设计让用户权重与 DAG 拓扑解耦:同一个QueryWeighting映射既能服务查询,也能被 NLQ(自然语言查询)复用——NLQ 场景下权重被限定为 -1/0/1 三档(NLQ_WEIGHT_TYPE,见 const.py),语义分别是"排除/忽略/包含"。
六、实践建议:如何设置合理的权重
- 起点从 1.0 开始:所有空间等权是最中性 baseline;
- 用 0 做开关而不是删除空间:权重 0 会优雅地跳过该空间,方便 A/B 对比;
- 数字区间约束优先用 Min-Max 模式,让权重在数值域生效;
- 权重只改变方向占比:由于 L2 归一化兜底,把全部权重翻倍不会改变排序,调整的是空间之间的相对比例。
小结
Superlinked 的查询加权可以浓缩为三步算术:加权向量求和 → L2 归一化 → 输入域聚合(数值空间)。权重 0 表示不参与、1.0 为默认参与,配合 DAG 节点权重表,把用户的一个浮点数变成最终排序结果的确定性影响。理解这套权重算术,你就能精准调控多路语义搜索的融合行为。
更多查询机制细节,可参考官方文档 query_weighting 参考 与 查询子句概览。
【免费下载链接】sieOpen-source inference server and production cluster for all the models your agent needs.项目地址: https://gitcode.com/GitHub_Trending/su/sie
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考