配置
Semantic Router 在 CLI、控制面板、Helm 和 Operator 之间使用同一份 canonical YAML 文档。顶层结构为:
version:
listeners:
providers:
evaluation:
routing:
entrypoints:
recipes:
global:
大多数部署从 version、listeners、providers 和一个顶层 routing 配置开始。当一个部署需要多个隔离策略时,添加 entrypoints 和 recipes。仅当共享服务或运行时行为与内置默认值不同时,才添加 global 设置。
各节的职责
| 节 | 拥有 |
|---|---|
version | Canonical schema 版本。使用 v0.3。 |
listeners | 公共 Router 监听器和超时。 |
providers | 逻辑 provider 模型、物理后端端点、定价、能力和默认值。 |
evaluation | 可选的运维人员拥有的基准定义、带版本的索引 DAG,以及与模型关联的记录。 |
routing | 默认配方:model card、信号、投影、决策、strategy、算法和路由插件。 |
entrypoints | 映射到命名配方的公共虚拟模型别名。 |
recipes | 共享 providers 和全局基础设施的额外隔离路由配置。 |
global | Router 服务、存储、集成、可观测性、学习和 Router 拥有的模型资产。 |
保持这些边界清晰:
- 信号检测事实;
- 投影组合证据;
- 决策定义资格和路由策略;
- algorithm 选择或协调候选模型;
- 插件在路由特定钩点添加行为;以及
- provider 将逻辑模型名称绑定到推理端点。
Provider 定价放在每个具体模型旁边,位于 providers.models[].pricing。它接受可选的大写三字母 currency,以及非负的 prompt_per_1m、completion_per_1m、cached_input_per_1m 和 cache_write_per_1m 费率。路由 model card 不重复部署价格或凭据。
评估测量属于 evaluation.records[],并通过 model 引用 canonical Model Card 身份。内置基准 ID 可以直接使用;在 evaluation 下的记录旁边定义新的基准语义和索引。参见自定义评估。
使用协议兼容性选择模型的后端 api_format。然后在 Docker、Helm、Operator 和控制面板工作流之间移动其绑定之前,参见后端目标兼容性。目标矩阵区分 canonical 透传与 Kubernetes 发现,并记录每个表面保留哪些 URL、路径、权重和 provider 字段。
Router 范围的调试表面默认关闭。global.services.observability.profiling 提供 Go pprof 端点,并且仅在显式启用时提供;然后它绑定 127.0.0.1:6060,因此除非显式更改 bind,否则 profile 永远不会到达可路由接口。该开关在启动时读取一次,因此更改它需要重启 Router。参见 API 与可观测性。
当未配置远程后端时,内置类别/领域分类使用本地 variant 选择器。要调用命名的外部分类器,在 global.model_catalog.modules.classifier.domain 下附加 backend,并从 global.model_catalog.external[] 解析其 model,设置 model_role: classification。共享后端字段是 protocol、contract、model 和可选的 deadline_ms;类别当前支持带完整 label_distribution.v1 响应契约的 http_classify。省略 backend 以保留本地行为。已弃用的 use_modernbert 和 use_mmbert_32k 键仍可读,而生成的 canonical 配置使用 variant: candle、variant: modernbert 或 variant: mmbert32k。
复杂度在 global.model_catalog.modules.complexity 下附加相同的块,位于 prototype_scoring 旁边。它读取两种契约,因此 contract 不能默认,必须声明:回归模型使用 score.v1,每条规则通过自己的 hard_above/easy_below 边界(或当分数随难度上升而下降时使用 hard_below/easy_above)将分数转换为判定;直接返回 hard/easy/medium 的模型使用 label_distribution.v1。threshold 仍是本地带符号边距的对称简写。score.v1 不报告置信度,因此由这些规则门控的决策按引擎的结构默认值排序;Router 会在启动时发出警告。远程调用通过 llm_remote_connector_* 和 llm_complexity_* 指标可见,评分器失败会记录在每条复杂度规则的信号错误上,而不是被丢弃。
PII 在 global.model_catalog.modules.classifier.pii 下附加相同的块。它读取一种契约 token_spans.v1,因此可以省略 contract。远程模型将实体跨度作为它收到的精确请求字符串的码点偏移返回,并且它返回的每个标签都必须存在于配置的 pii_mapping_path 中;契约拒绝的响应是后端失败,而不是干净的“无 PII”结果。后端旁边的 on_error 选择此类失败或 provider 声明的 truncated_at 对消费它的规则做什么:allow(默认)将内容视为不匹配,block 将其匹配为 classification_error。在声明截断之前返回的跨度在两种策略下都计入。后端与本地 use_mmbert_32k 选择器互斥。
路由流水线解释该设计。能力下的能力页面记录每个信号、投影、决策、算法、插件和全局块。
能力目录
使用此目录选择可复用的构建块,然后打开其指南了解配置细节。清单来自 config/fragments/;每一行目标来自匹配指南的 概览。文档构建会重新生成此块,如果签入的目录已漂移则会失败。
信号
| 家族和类型 | 用于 | 可复用片段 | 指南 |
|---|---|---|---|
authz — 启发式信号 | authz 将身份和策略绑定转换为 routing.signals.role_bindings 下可复用的路由输入。 | config/fragments/signal/authz/ | 指南 |
classifier — 学习型信号 | classifier 暴露来自本地原生序列分类器、远程序列分类器或已配置外部 LLM 的可复用标签分数。 | config/fragments/signal/classifier/ | 指南 |
complexity — 学习型信号 | complexity 通过将请求与配置的示例集比较,估计请求是 easy、medium 还是 hard。 | config/fragments/signal/complexity/ | 指南 |
context — 启发式信号 | context 检测需要更大有效上下文窗口的请求。 | config/fragments/signal/context/ | 指南 |
conversation — 启发式信号 | conversation 按聊天结构和协议事实路由,例如消息数、开发者指令、可用工具、显式工具使用约束,或活动工具循环。 | config/fragments/signal/conversation/ | 指南 |
domain — 学习型信号 | domain 分类请求的主题家族。 | config/fragments/signal/domain/ | 指南 |
embedding — 学习型信号 | embedding 通过与代表性示例的语义相似度匹配请求。 | config/fragments/signal/embedding/ | 指南 |
event — 启发式信号 | event 按事件类型、严重性、紧急程度或领域特定动作码路由结构化的类事件请求。 | config/fragments/signal/event/ | 指南 |
fact-check — 学习型信号 | fact-check 决定提示词是否应被视为对证据敏感的流量。 | config/fragments/signal/fact-check/ | 指南 |
hallucination — 学习型信号 | hallucination 对照请求携带的依据上下文(例如工具结果或检索到的文档)检查模型答案,并报告该上下文不支持的声明。 | config/fragments/signal/hallucination/ | 指南 |
input-modality — 启发式信号 | input_modality 确定性匹配解析后的请求中存在哪些输入种类——text、image、audio 或 video。 | config/fragments/signal/input-modality/ | 指南 |
jailbreak — 学习型信号 | jailbreak 在 Router 提交到路由之前检测提示词注入和越狱尝试。 | config/fragments/signal/jailbreak/ | 指南 |
kb — 学习型信号 | kb 将路由信号绑定到命名知识库实例的输出。 | config/fragments/signal/kb/ | 指南 |
keyword — 启发式信号 | keyword 匹配请求中的显式单词和短语。 | config/fragments/signal/keyword/ | 指南 |
language — 启发式信号 | language 检测请求语言,并将其作为路由信号暴露。 | config/fragments/signal/language/ | 指南 |
metadata — 启发式信号 | metadata 匹配调用方在请求元数据中提供的有界字符串值。 | config/fragments/signal/metadata/ | 指南 |
modality — 学习型信号 | modality 检测请求应停留在文本生成、切换到图像生成,还是同时支持两者。 | config/fragments/signal/modality/ | 指南 |
pii — 学习型信号 | pii 检测请求中的敏感个人数据。 | config/fragments/signal/pii/ | 指南 |
preference — 学习型信号 | preference 从示例和分类器设置推断响应风格偏好。 | config/fragments/signal/preference/ | 指南 |
reask — 学习型信号 | reask 检测当前用户轮次是否在语义上重复同一会话中最近的用户轮次。 | config/fragments/signal/reask/ | 指南 |
structure — 启发式信号 | structure 检测请求形状事实,例如许多显式问题、有序工作流标记,或密集约束措辞。 | config/fragments/signal/structure/ | 指南 |
user-feedback — 学习型信号 | user-feedback 从会话中检测纠正、不满或升级反馈。 | config/fragments/signal/user-feedback/ | 指南 |
选择算法
| 家族和类型 | 用于 | 可复用片段 | 指南 |
|---|---|---|---|
automix — 选择算法 | automix 是一个实验性选择器,按配置的质量和成本,加上内部验证和升级估计,对候选模型排序。 | config/fragments/algorithm/selection/automix.yaml | 指南 |
hybrid — 选择算法 | hybrid 将 Elo 评分、Router-DC 描述相似度、AutoMix 的单模型价值估计和成本组合成一个加权候选分数。 | config/fragments/algorithm/selection/hybrid.yaml | 指南 |
kmeans — 选择算法 | kmeans 将请求发送到分配给其最近已学习聚类的模型。 | config/fragments/algorithm/selection/kmeans.yaml | 指南 |
knn — 选择算法 | knn 从在最相似的已记录请求上表现良好的模型中选择候选。 | config/fragments/algorithm/selection/knn.yaml | 指南 |
latency-aware — 选择算法 | latency_aware 使用观察到的 TTFT 和 TPOT 百分位对符合条件的候选排序,并选择相对延迟分数最低的候选。 | config/fragments/algorithm/selection/latency-aware.yaml | 指南 |
mlp — 选择算法 | mlp 在 CPU 上运行已训练的神经分类器,将请求映射到候选模型。 | config/fragments/algorithm/selection/mlp.yaml | 指南 |
multi-factor — 选择算法 | multi_factor 从质量、延迟、成本和负载中选择一个候选。 | config/fragments/algorithm/selection/multi-factor.yaml | 指南 |
prompt — 选择算法 | prompt 使用具体的辅助模型,从匹配决策的 modelRefs 中恰好选择一个模型。 | config/fragments/algorithm/selection/prompt.yaml | 指南 |
router-dc — 选择算法 | router_dc 嵌入请求和每个模型描述,然后选择语义相似度最强的候选。 | config/fragments/algorithm/selection/router-dc.yaml | 指南 |
static — 选择算法 | static 提供确定性的模型选择,无需指标或已学习状态。 | config/fragments/algorithm/selection/static.yaml | 指南 |
svm — 选择算法 | svm 使用已训练的线性或 RBF 支持向量分类器,将请求特征映射到候选模型。 | config/fragments/algorithm/selection/svm.yaml | 指南 |
Looper 算法
| 家族和类型 | 用于 | 可复用片段 | 指南 |
|---|---|---|---|
confidence — Looper 算法 | confidence 按顺序尝试候选模型,并在响应置信度达到配置阈值时停止。 | config/fragments/algorithm/looper/confidence.yaml | 指南 |
fusion — Looper 算法 | fusion 让多个模型回答请求,并由评判模型合成一个最终答案。 | config/fragments/algorithm/looper/fusion.yaml | 指南 |
ratings — Looper 算法 | ratings 调用每个候选模型,并为每个成功的模型返回一个 OpenAI 兼容 choice。max_concurrent 限制并行工作;它不限制执行的候选总数。 | config/fragments/algorithm/looper/ratings.yaml | 指南 |
remom — Looper 算法 | remom 在有界轮次中运行多个候选模型,并将它们的响应合成为一个答案。 | config/fragments/algorithm/looper/remom.yaml | 指南 |
workflows — Looper 算法 | workflows 在一个 OpenAI 兼容模型名称背后运行有界的多步 Router Flow。 | config/fragments/algorithm/looper/workflows.yaml | 指南 |
插件与包
| 家族和类型 | 用于 | 可复用片段 | 指南 |
|---|---|---|---|
content-safety — 插件包 | 内容安全将受支持的路由局部安全插件组合成一个可复用 策略。 | config/fragments/plugin/content-safety/ | 指南 |
context-compression — 路由插件 | context_compression 是路由局部请求插件,在所选 provider 收到请求之前缩减大型工具/函数输出。 | config/fragments/plugin/context-compression/ | 指南 |
fast-response — 路由插件 | fast_response 是立即返回确定性回退消息的路由局部插件。 | config/fragments/plugin/fast-response/ | 指南 |
hallucination — 路由插件 | hallucination 是在决策已匹配后进行事实核查和响应质量筛查的路由局部插件。 | config/fragments/plugin/hallucination/ | 指南 |
header-mutation — 路由插件 | header_mutation 是添加、更新或删除下游标头的路由局部插件。 | config/fragments/plugin/header-mutation/ | 指南 |
memory — 路由插件 | memory 是检索和存储会话记忆的路由局部插件。 | config/fragments/plugin/memory/ | 指南 |
rag — 路由插件 | rag 在生成之前为匹配的路由检索外部上下文。 | config/fragments/plugin/rag/ | 指南 |
request-params — 路由插件 | request_params 是在转发到后端之前校验并裁剪 OpenAI Chat Completions 请求正文的路由局部插件。 | config/fragments/plugin/request-params/ | 指南 |
response-cache — 路由插件 | response_cache 是复用精确或语义兼容的先前响应的路由局部插件。 | config/fragments/plugin/response-cache/ | 指南 |
response-jailbreak — 路由插件 | response_jailbreak 是在返回之前筛查模型响应的路由局部插件。 | config/fragments/plugin/response-jailbreak/ | 指南 |
router-replay — 路由插件 | router_replay 是在一条路由上覆盖回放/调试捕获的路由局部插件。 | config/fragments/plugin/router-replay/ | 指南 |
shadow-dispatch — 路由插件 | shadow_dispatch 是将已批准请求的有界采样副本发送到次级模型,并在不更改或延迟主响应的情况下记录结果的路由局部插件。 | config/fragments/plugin/shadow-dispatch/ | 指南 |
system-prompt — 路由插件 | system_prompt 是在匹配流量上插入或修改系统提示词的路由局部插件。 | config/fragments/plugin/system-prompt/ | 指南 |
tool-selection — 路由 插件 | tool_selection 是控制匹配路由如何选择工具的决策插件。 | config/fragments/plugin/tool-selection/ | 指南 |
tools — 路由插件 | tools 是进行工具过滤和语义工具选择的路由局部插件。 | config/fragments/plugin/tools/ | 指南 |
最小示例
version: v0.3
listeners:
- name: http-8899
address: 0.0.0.0
port: 8899
timeout: 300s
providers:
defaults:
model: local/general
models:
- name: local/general
provider_model_id: my-served-model
backend_refs:
- name: primary
endpoint: host.docker.internal:8000
protocol: http
provider: vllm
routing:
strategy: priority
modelCards:
- name: local/general
modality: text
capabilities: [chat]
signals:
keywords:
- name: needs_explanation
operator: OR
keywords: ["explain", "walk me through"]
decisions:
- name: explanatory_answer
description: Prefer an explanatory answer when the request asks for one.
priority: 100
rules:
operator: AND
conditions:
- type: keyword
name: needs_explanation
modelRefs:
- model: local/general
global:
services:
observability:
metrics:
enabled: true
模型配置
模型可以从内置目录继承身份和推理,或在本地定义私有模型。此目录支持的示例让所选 Provider 映射提供原生模型 ID、协议、推理传输和请求路径:
providers:
defaults:
model: production
reasoning_effort: medium
models:
- name: production
catalog: openai/gpt-5.6-sol
backend_refs:
- provider: openai
api_key_env: OPENAI_API_KEY
name 仍是本地 Router 别名。私有或新发布的模型省略 catalog,并可选择在该别名下定义 Model Card 和推理契约。从配置模型开始,然后使用模型配置模式比较目录、自定义、推理、Provider 和副本组合。模型与 provider Day-0 指南面向向仓库目录添加可复用支持的贡献者。
分类器后端失败在评估完整布尔树期间保持为 Unknown。将 rules.on_unknown 设置为 no_match、match 或 fail_request,以解析未确定的终端结果。省略它会保留现有的分类器家族错误行为。
使用自动模型别名的请求进入默认 routing 配置。具体的 provider 模型名称是直接透传请求,并绕过配方信号、决 策、路由插件、缓存、学习和会话路由。
校验并启动服务
vllm-sr config validate --config config.yaml
vllm-sr serve --config config.yaml
校验会在 Router 启动之前捕获 schema 错误、未解析的引用、不兼容的配方边界、无效的 provider 绑定,以及不支持的插件或算法设置。
对于可移植的无模型配方,将 routing.decisions[].algorithm.minimum_candidates 设置为保留该决策预期行为的最小池。空的内置资产仍然有效,而其具体分配不满足已声明基数的已发布入口会被拒绝。
环境引用和密钥
将凭据保留在 YAML 文件之外:
api_key: ${MODEL_API_KEY}
支持的字符串替换为:
${VAR}和$VAR;- 当
VAR未设置或为空时使用${VAR:-default}; - 当
VAR未设置时使用${VAR-default};以及 $$表示字面$。
对于自定义配方,用 --recipe-env NAME 显式授权所需的主机变量。Kubernetes 部署将敏感环境值放入 Secret,而不是 ConfigMap 或 Helm values。参见安全加固。
入口点和配方
入口点将一个或多个公共模型别名映射到配方。配方拥有其信号、投影、决策、算法、插件、缓存、回放、学习和路由状态。Providers、存储和 Router 拥有的分类器资产可以共享,而不允许策略状态跨越配方边界。
在外部 LLM 分类器条目和 MCP 分类器模块上设置 max_response_bytes,以限制一次上游分类器响应。
在 schema 中,entrypoints[].model_names 列出公共别名,entrypoints[].recipe 选择命名配方,recipes[].routing 包含该配方的策略。
如果没有决策匹配,配方使用 providers.defaults.model。虚拟入口点名称永远不会到达后端。
内置虚拟模型、CLI 服务、后端绑定、分叉、打包和迁移见模型、入口点与服务。完整 schema 见虚拟模型。
配方级候选约束和回放策略
可在默认配方或具名配方的 routing 中独立声明以下可选策略:
candidate_requirements:
capabilities: declared
context: known_limits
data_policy:
replay: false
capabilities: declared 要求模型显式声明请求所需的任务能力,包括工具和图像输入,并且提供方协议兼容。
context: known_limits 将估算的输入需求与有效输出预留相加,再检查模型声明的限制。
请求必须提供输出上限,或者 decision 配置正整数 request_params.default_max_tokens。
默认值仅在调用方未指定时生效,之后仍按现有 max_tokens_limit 限制。模型的最大输出容量不是请求默认值。
缺少必要模型事实或有效输出上限的候选不可选。
输入计数仍是估算,尤其是多模态内容,因此不保证精确的提供方 token 容量。省略某个字段会保留该维度原有的兼容行为。
例如,decision 可通过现有插件提供输出上限:
plugins:
- type: request_params
configuration:
default_max_tokens: 4096
max_tokens_limit: 8192
配方的 replay: false 禁止路由器回放捕获,decision 不能重新开启;在尚未得到 decision 时被拒绝的请求同样适用。
省略或 true 不额外限制现有全局和 decision 配置。该字段不控制其他存储、日志或后端留存;运营者仍需选择满足隐私要求的部署。
多因素选择的 latency_metric: ttft 比较首 token 延迟,tpot 比较每个输出 token 的耗时。
省略时保留原有的 TPOT 优先、TTFT 后备行为。如果质量是准入下限,可配合明确的质量证据和字典序目标使用。
使用 vllm-sr config schema --section routing.candidate_requirements 和
vllm-sr config schema --section routing.data_policy 查看当前契约。DSL 的 ROUTING 块支持相同对象。
Kubernetes CRD 导出保留默认 routing 的策略;具名配方和入口点应使用 canonical YAML,CRD 导出会明确拒绝而不会静默丢弃。
配置工作流
canonical 文档可以通过多个界面编写或应用:
- 本地 CLI 和 YAML;
- 控制面板设置和可视化路由工具;
- Helm 或
vllm-sr serve --target k8s; - Kubernetes Operator;以及
- 路由 DSL。
配置工作流解释哪个界面拥有文档的哪一部分,以及如何避免相互竞争的事实来源。配置契约描述生成的机器可读 schema、Router 发现和校验 API,以及工具和 Agent 的安全编写循环。
参考来源
config/config.yaml是详尽的 canonical 示例。config/fragments/包含可复用的信号、决策、算法和插件片段。- Providers 与路由教程描述共享运行时配置。
- 统一配置契约 v0.3 记录当前契约背后的设计。
- 配置契约 是当前 Router 构建的实时发现和校验契约。
避免将详尽示例复制为应用配置。从描述部署的最小文档开始,然后仅添加它使用的能力和服务。