- 后端
- API网关
- 模型推理服务
- AI Agent
【免费下载链接】semantic-router
An open, programmable decision layer for models and compute.
本篇围绕 semantic-router 的kb(知识库)路由信号展开:它如何把一个启动时加载、基于嵌入的知识库,绑定为可复用的命名路由信号,并通过best/threshold两种匹配语义参与路由决策、通过kb_metric投影向routing.projections输出连续数值指标。读完本文,你可以完整配置一个带prototype_scoring、分组(groups)与命名指标的知识库,理解其打分与匹配语义的源码实现,并在 recipe 中将知识库证据接入投影指标。
什么是 kb 信号:三层配置模型
kb将路由信号绑定到命名知识库实例的输出,这些绑定定义在routing.signals.kb下。它面向的场景是:在 Router 启动时加载、并在多条路由间复用的嵌入(embedding)知识库。
从源码结构看,kb刻意维持了一个显式的三层划分(见 KB 配置结构定义):
global.model_catalog.kbs[]:持有可复用的知识库包(KnowledgeBaseConfig),负责资产目录、阈值、分组与指标声明;routing.signals.kb[]:把特定标签(label)或分组(group)绑定为命名路由信号(KBSignalRule);routing.projections:消费知识库的连续数值指标,如best_score、best_matched_score或配置的分组 margin。
对应地,KnowledgeBaseConfig的字段与文档中的 YAML 一一对应:
// src/semantic-router/pkg/config/kb_config.go(L26-L34) type KnowledgeBaseConfig struct { Name string Source KnowledgeBaseSource Threshold float32 LabelThresholds map[string]float32 Groups map[string][]string Metrics []KnowledgeBaseMetricConfig PrototypeScoring PrototypeScoringConfig }而信号绑定规则只有四个字段,即name、kb、target(kind+value)与可选的match(KBSignalRule 定义):
type KBSignalRule struct { Name string KB string Target KBSignalTarget // Kind: "label" | "group"; Value: 名称 Match string // "best" | "threshold" }解决什么问题、何时使用
部分路由策略依赖精选示例集(curated exemplar set),而非单一关键词或嵌入候选列表。一个知识库可以把请求分类为隐私、安全、情感或偏好标签,而路由配置只暴露决策真正需要的标签或分组。
在以下场景应使用kb:
- 请求必须对照精选示例集进行分类;
- 一个启动加载的知识库结果需要供给多条路由;
- 需要稳定的路由级分组,而不重复存放示例;
- 需要显式绑定,而非依赖隐式的运行时信号名。
kb的核心优势:
- 同一示例集可被多条路由复用;
- 标签、分组与数值指标显式声明,不依赖魔法运行时名;
- 同时支持胜者式(
best)与阈值式(threshold)信号绑定; - 投影(projection)可消费连续知识库指标,而不把信号变成脚本表面。
配置实战:完整的 privacy_kb 示例
下面继承文档中的完整配置示例,并对照仓库内置配置 config/config.yaml(其中privacy_kb与mmlu_kb的完整声明位于global.model_catalog.kbs下)逐项讲解:
global: model_catalog: kbs: - name: privacy_kb source: path: knowledge_bases/privacy/ manifest: labels.json threshold: 0.55 prototype_scoring: enabled: true cluster_similarity_threshold: 0.9 max_prototypes: 8 best_weight: 0.75 top_m: 2 margin_threshold: 0.05 label_thresholds: prompt_injection: 0.7 groups: privacy_policy: [proprietary_code, internal_document, pii] security_containment: [prompt_injection, credential_exfiltration] private: [proprietary_code, internal_document, pii, prompt_injection, credential_exfiltration] public: [generic_coding, general_knowledge] metrics: - name: private_vs_public type: group_margin positive_group: private negative_group: public routing: signals: kb: - name: privacy_policy kb: privacy_kb target: kind: group value: privacy_policy match: best - name: proprietary_code kb: privacy_kb target: kind: label value: proprietary_code match: threshold知识库声明(global.model_catalog.kbs[])参数说明
| 参数 | 含义 | 说明 |
|---|---|---|
name | 知识库实例名 | kb信号通过该名称直接绑定,请保持稳定 |
source.path | 知识库资产目录 | 支持绝对路径或相对路径;相对路径会按候选根目录解析 |
source.manifest | 标签清单文件名 | 缺省为labels.json(见下节) |
threshold | 默认标签阈值 | 标签分数 ≥ 有效阈值时视为“匹配标签” |
label_thresholds | 逐标签阈值覆盖 | 如prompt_injection: 0.7,覆盖默认阈值 |
groups | 分组 → 标签列表映射 | 分组分数取成员标签的最高分 |
metrics | 命名数值指标 | 当前支持type: group_margin,由正负分组的分数差构成 |
prototype_scoring | 原型打分策略 | 见下节 |
仓库内置的知识库信号片段 config/fragments/signal/kb/privacy.yaml 就是上面routing.signals.kb部分的最小可复用形态:privacy_policy分组信号(best)+proprietary_code标签信号(threshold)。
知识库包目录结构与 labels.json 清单
知识库包是一个“目录 + 清单”的资产单元,必须与清单一起版本化。仓库内置的隐私知识库清单 config/knowledge_bases/privacy/labels.json 展示了标准结构:
{ "version": "1.0.0", "description": "Category taxonomy for privacy-aware LLM routing evaluation ...", "labels": { "proprietary_code": { "description": "Requests involving proprietary, internal, or company-specific source code ...", "exemplars": [ "Help me debug this semiconductor diagnostic code for our fab equipment", "审查我们公司代码库中的这个函数", "..." ] } } }该结构与源码中的KnowledgeBaseDefinition(version、description、labels映射,每个标签含description与exemplars列表,见 kb_config.go)严格对应。注意内置示例集同时包含中英文例句,覆盖了proprietary_code、internal_document、pii等隐私类标签以及generic_coding等公开类标签——这正是private/public分组 margin 指标可以成立的数据基础。
从 kb_config.go 的ResolvePath/candidateRoots实现看,source.path的解析遵循候选根目录探测顺序:配置基目录、运行时状态目录(.vllm-sr下镜像knowledge_bases/前缀的路径)、环境变量VLLM_SR_CONFIG_ASSET_ROOT、容器内/app/config,以及仓库内置的config资产目录;命中第一个存在的路径即生效。
加载语义:只准备被引用的知识库
需要注意一个重要的加载前提:只有被可达 recipe 引用的知识库才会在启动时准备。从 recipes.go 的knowledgeBasesForRoutingProfile可以确认:系统先收集 profile 中routing.signals.kb[]引用的知识库名,再收集routing.projections.scores[].inputs中type: kb_metric引用的知识库名,最终只对这份引用集合做过滤加载。因此,未被引用的目录条目不会加载其资产、也不会启动嵌入模型——在编写 recipe 时,如果某个知识库只在 catalog 中声明而没有任何信号或投影输入引用它,它将处于“闲置”状态。
prototype_scoring:原型库打分原理
启用prototype_scoring时,KB 会从各标签的示例构建每标签原型库(prototype bank),运行时分类改为从这些“标签自有原型”给标签打分,而不是让某一条原始示例永远主导整个标签。
六个参数的默认值在 prototype_scoring_config.go 的WithDefaults中定义:
| 参数 | 默认值 | 作用 |
|---|---|---|
enabled | true | 是否启用原型聚类压缩 |
cluster_similarity_threshold | 0.9 | 相似度聚类阈值,决定示例如何聚成簇 |
max_prototypes | 8 | 每标签最多保留多少个原型 |
best_weight | 0.75 | 打分时“最佳原型相似度”的权重(0~1) |
top_m | 2 | support 计算取相似度前 M 的原型 |
margin_threshold | 0 | margin 判定阈值(负值会被归零) |
构建流程(prototype_bank.go):
- 对示例去重;
- 计算两两相似度矩阵,按
cluster_similarity_threshold贪心聚类; - 为每个簇选取代表(medoid);
- 按“簇大小 → 平均相似度 → 文本”排序,并截断到
max_prototypes。
若enabled为 false,则退化为每个去重示例各自作为一个原型(uncompressedPrototypeRepresentatives)。
打分公式(prototype_scoring.go 的score方法):
score = best_weight * best + (1 - best_weight) * support 其中 best = 与任一所选原型的最大余弦相似度 support = 相似度 top_m 名的平均值也就是说,标签最终得分是“最像的那条原型”与“多条原型共同支持度”的加权融合——best_weight越高,越偏向单点最强匹配;越低,越强调多原型的一致支持。这解释了配置中best_weight: 0.75、top_m: 2的组合含义:以最佳匹配为主、以第二近邻的支持度作平滑。
匹配语义:label/group × best/threshold
routing.signals.kb[]支持target.kind: label | group与match: best | threshold四种组合。含义如下:
label + best:仅当该标签是知识库的最佳标签时匹配;label + threshold:标签分数超过有效阈值时匹配;group + best:仅当该分组是知识库的最佳分组时匹配;group + threshold:任一成员标签超过阈值时匹配。
源码实现位于 classifier_signal_taxonomy.go,其中有两个值得注意的细节:
match缺省时按threshold处理(kbSignalMatchMode:空值回退为config.KBMatchThreshold),所以省略match并不等于best;- 有效阈值 = 逐标签阈值覆盖
label_thresholds[label],否则回退到知识库级threshold(category_kb_scoring.go 的effectiveThreshold与buildMatchedLabels)。
分数的具体生成逻辑同样在 category_kb_scoring.go:
computeLabelScores:对每个标签调用其原型库score,得到标签分数;buildMatchedLabels:筛选出分数 ≥ 有效阈值的标签(即“匹配标签”集合);computeGroupScores:分组分数 = 其成员标签分数的最大值(best语义,而非均值);collectMatchedGroups:只要分组内任一成员出现在匹配标签集合中,该分组即算命中——这正是group + threshold“任一成员标签超过阈值即匹配”的实现依据。
测试用例 classifier_signal_taxonomy_test.go 对上述语义做了锁定:例如security_containment在match: best下,当最佳分组是local_standard时不得命中;而threshold模式下,未进入MatchedLabels的标签(如分数 0.42 低于阈值的generic_coding)不得命中。
投影指标:把连续数值留给 routing.projections
知识库信号本身是布尔路由输入(匹配/不匹配),数值输出则留在routing.projections中。例如把private与public的分组 margin 投影为privacy_bias:
routing: projections: scores: - name: privacy_bias method: weighted_sum inputs: - type: kb_metric kb: privacy_kb metric: private_vs_public value_source: score weight: 1.0指标的来源与计算:
- 内置指标始终可用:
best_score(最佳标签分数)与best_matched_score(匹配标签中的最佳分数); - 命名指标在
global.model_catalog.kbs[].metrics[]下声明,当前支持type: group_margin,其值为positive_group分组分数减去negative_group分组分数(computeMetricValues); - 投影侧通过
type: kb_metric+kb+metric三元组按键(kb_metric:<kb>:<metric>)取值,见 classifier_projection_inputs.go。
仓库中有两个可直接对照的真实用法:
- config/recipes/privacy/config.yaml:
privacy_contrastive_score投影消费privacy_kb的private_vs_public指标(weight 1.0),配合kb信号privacy_policy(match: best)共同构成隐私优先 recipe 的证据链; - config/recipes/knowledge/config.yaml:
escalation_pressure投影消费mmlu_kb的escalate_vs_keepmargin,再经threshold_bands映射为escalation_band,用于知识类请求的升级判定。mmlu_kb的完整声明(含escalate/keep两个分学科分组)见 config/config.yaml。
依赖、限制与校准注意事项
- 知识库包从
global.model_catalog.kbs[].source加载。请将其清单(manifest)与示例文件一起版本化,保证二者同步演进; - 嵌入隐私边界:请求文本通过共享语义嵌入运行时被嵌入,因此若使用远程嵌入提供方,该文本会被发送给远程提供方——在隐私敏感部署中这一点必须纳入数据流评估;
- 校准单元:标签、分组、阈值与嵌入模型构成一个整体校准单元,其中任何一部分变更(包括更换嵌入模型、调整
threshold/label_thresholds、改动分组或示例集)都应整体重新评估,而不是只改其中一处。
延伸阅读
- 完整知识库与信号声明:config/config.yaml
- 知识库信号片段:config/fragments/signal/kb/privacy.yaml
- 隐私知识库标签清单:config/knowledge_bases/privacy/labels.json
- 知识库配置与清单加载:src/semantic-router/pkg/config/kb_config.go
- 原型打分配置与默认值:src/semantic-router/pkg/config/prototype_scoring_config.go
- 标签/分组打分与指标计算:src/semantic-router/pkg/classification/category_kb_scoring.go
- 原型库构建与打分:src/semantic-router/pkg/classification/prototype_bank.go、src/semantic-router/pkg/classification/prototype_scoring.go
- 信号匹配语义实现与测试:src/semantic-router/pkg/classification/classifier_signal_taxonomy.go、src/semantic-router/pkg/classification/classifier_signal_taxonomy_test.go
- 后端
- API网关
- 模型推理服务
- AI Agent
【免费下载链接】semantic-router
An open, programmable decision layer for models and compute.
相关推荐
semantic-router 知识库信号(kb signal)完全指南:命名知识库的路由绑定、匹配语义与指标投影
semantic router 知识库信号(kb signal)完全指南:命名知识库的路由绑定、匹配语义与指标投影 kb (Knowledge Base)是 s
后端API网关模型推理服务AI Agent如何给 2007 年起的老 Mac 安装最新 macOS:OpenCore Legacy Patcher 完整实战
如何给 2007 年起的老 Mac 安装最新 macOS:OpenCore Legacy Patcher 完整实战 2013 年的 Mac Pro、2015 年
操作系统固件驱动开发Semantic Router Knowledge Routing 配方:用知识库证据驱动的小模型留守与前沿模型升级决策
Semantic Router Knowledge Routing 配方:用知识库证据驱动的小模型留守与前沿模型升级决策 Knowledge Routing 是
后端API网关模型推理服务AI Agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考