跳到主要内容
版本:v0.4

配置

Semantic Router 在 CLI、控制面板、Helm 和 Operator 之间使用同一份 canonical YAML 文档。顶层结构为:

version:
listeners:
providers:
evaluation:
routing:
entrypoints:
recipes:
global:

大多数部署从 version、listeners、providers 和一个顶层 routing 配置开始。当一个部署需要多个隔离策略时,添加 entrypoints 和 recipes。仅当共享服务或运行时行为与内置默认值不同时,才添加 global 设置。

各节的职责​

节拥有
versionCanonical schema 版本。使用 v0.3。
listeners公共 Router 监听器和超时。
providers逻辑 provider 模型、物理后端端点、定价、能力和默认值。
evaluation可选的运维人员拥有的基准定义、带版本的索引 DAG,以及与模型关联的记录。
routing默认配方:model card、信号、投影、决策、strategy、算法和路由插件。
entrypoints映射到命名配方的公共虚拟模型别名。
recipes共享 providers 和全局基础设施的额外隔离路由配置。
globalRouter 服务、存储、集成、可观测性、学习和 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 的安全编写循环。

参考来源​

避免将详尽示例复制为应用配置。从描述部署的最小文档开始,然后仅添加它使用的能力和服务。