跳到主要内容
版本:最新版(main)

迁移到 v0.5

v0.5 是一次破坏性版本。配置 schema 为 v0.5,决策模型通过 System One 回答每个路由判断,Router 不再读取的每种形式都会在加载时失败,并用一行说明该怎么做。vllm-sr config migrate 会改写所有这类形式;你只需迁移一次,然后检查它打印的说明。发布说明总结了变化及其原因。

1. 运行迁移​

vllm-sr config migrate --config config.yaml

迁移后的配置写入 config.migrated.yaml,并且只有在 Router 自身的校验接受时才会写入。所有改写都在 Router 中完成,所以 CLI、Dashboard 和 vllm-sr config validate 得到的结果一致;migrate 需要一个可以询问的 Router 二进制或镜像,没有离线模式。采用 config v0.3 之前布局的配置(顶层的 vllm_endpoints 等,或 CLI 的 schema v0.1)也在同一次运行中迁移:migrate 先把它写成 v0.3 布局,再写成 v0.5。

校验按配置所服务的网关进行:默认为 standalone,除非 VLLM_SR_GATEWAY 指定 extproc。早期版本总是在 Envoy 之后提供服务。如果文件中的 authz 信号、按用户的限流或 authz 提供方读取认证网关设置的身份(x-user-id、x-user-groups),例如 v0.4 参考配置,它可以按原样为该网关迁移:

VLLM_SR_GATEWAY=extproc vllm-sr config migrate --config config.yaml

若要改为 standalone 方式提供服务,请在迁移后的文件中设置 listeners[].identity.trust_headers: true,并且只在会认证客户端并设置这些请求头的代理之后这样做。

无法精确改写的形式,会在保留其含义的范围内尽量改写,并由 migrate 打印需要检查的内容:需要重新拟合的阈值、被丢弃的权重、被丢弃的示例库,以及无法拆分的条件。少数形式完全无法改写,例如 image_gen 插件或带音频查询的 embeddings 规则:migrate 会拒绝这个文件,错误信息在 it has no mechanical rewrite: 之后说明应该改写成什么。

2. 读懂加载错误​

仍在使用已移除形式的配置无法加载。每个错误占一行:形式所在的位置、错误代码、移除了什么,以及它变成什么:

<path>: <code>: <what was removed>; run `vllm-sr config migrate` (<what it becomes>)
代码含义
removed_signal_type已不存在的信号类型
removed_algorithm_type已不存在的算法类型
removed_plugin_type已不存在的插件类型
removed_fieldRouter 不再读取的字段
removed_sectionRouter 不再读取的整个段落
invalid_value含义已经改变的值,例如 version: v0.3

有三种形式因为只是改名,仍能加载并给出警告:signals.decision 和 type: decision 条件按 systemone 加载(renamed_signal_type),algorithm.type: decision 按 systemone 选择器加载(renamed_algorithm_type),router_replay 插件的 capture_personal_data 按它的 prompt_capture 加载,false 为 verified,true 为 raw(renamed_field)。migrate 会改写这三种形式;Dashboard 按同样方式读取前两种,保存时写为 systemone。

3. 检查变化​

配置结构​

顶层 routing 块已移除:配置的路由位于扁平的 recipes 中。模型事实位于 providers.models[],默认插件位于 global.plugins。

version: v0.3
routing:
signals:
keywords:
- name: urgent
operator: OR
keywords: [urgent, asap]
version: invalid_value: config schema v0.3 is removed; run `vllm-sr config migrate` (version: v0.5)
version: v0.5
recipes:
- name: default
signals:
keywords:
- name: urgent
operator: OR
keywords: [urgent, asap]
之前之后
version: v0.3version: v0.5
顶层 routingrecipes: [{name: default, ...}],存在其他配方时附带一个标记为 default: true 的入口
routing.modelCards每张卡的字段移到同名的 providers.models[] 条目上
recipes[].routing.<field>recipes[].<field>
routing.model_bindingsrecipes[].model_bindings
memory、replay 和 cache 存储与服务上的 enabledglobal.plugins 中的一个插件条目

信号​

每个由模型判断的信号都是向决策模型提出的问题。用于配置旧实现的字段已移除;阈值是规则的 predicate:

recipes:
- name: default
signals:
jailbreak:
- name: attack
threshold: 0.88
include_history: true
recipes[default].signals.jailbreak[attack]: removed_field: a jailbreak rule's threshold, direction and include_history are its predicate, stage and input.history, and method and patterns are removed; run `vllm-sr config migrate` (predicate: {gte: <threshold>}, stage, input.history)
recipes:
- name: default
signals:
jailbreak:
- name: attack
predicate: {gte: 0.88}
input:
history: true

reasks 和 topic_continuity 合并为一个信号 turn_relation:

recipes:
- name: default
signals:
reasks:
- name: repeated
lookback_turns: 2
recipes[default].signals.reasks: removed_signal_type: the reask signal is a turn_relation rule; run `vllm-sr config migrate` (signals.turn_relation with labels [reask]; input.previous_turns is twice lookback_turns)
recipes:
- name: default
signals:
turn_relation:
- name: repeated
labels: [reask]
input:
previous_turns: 4
之前之后
signals.decision、algorithm.type: decisionsystemone(加载时给出警告)
domains[].mmlu_categoriesdomains[].labels
自行声明领域的 domain 条件为条件指定的每个领域各写一条 domains 规则
没有 labels 或 mmlu_categories、名称是其他大小写形式领域的 domains 规则(如 Math)改为小写的领域名,规则以及引用它的每个条件、分数输入和分区一并修改
没有 labels 或 mmlu_categories、名称又不是领域的 domains 规则删除:分类器只报告领域,这条规则从未匹配过;需要它的决策、它在 OR 中的那一项和读取它的分数输入也一并删除(migrate 会逐一说明)。投影分区引用的规则保留并写成 labels: [other],因为分区的默认成员曾匹配它。加载时会提示近似领域的名称(如 maths)只要仍有条件读取它,就保留该错误
jailbreak 的 threshold、direction、include_historypredicate、stage、input.history;method: contrastive 的阈值界定的是相似度之差而不是概率,migrate 会提示重新拟合
jailbreak 的 method、jailbreak_patterns、benign_patterns已移除:决策模型直接读取请求。需要确定性的硬拦截时,把这些模式写成一条 keywords 规则,并由一个拦截决策读取它
on_error: block 下的 jailbreak 和 pii 规则规则上的 on_unknown: match
on_error: allow 下的 jailbreak 和 pii 规则规则上的 on_unknown: no_match,因为 v0.5 的这些规则默认失败即拦截
on_unscanned: allow 或 block 下的 jailbreak 和 pii 规则规则上的 on_unscanned: best_effort(根据已读窗口判断)或 match
safety 的 threshold、labels、unsafe_labels、modelpredicate;labels 指定危害类别;deployment
safety 的 hazard它的 categories 对应的危害类别写进规则的 labels,hazard.threshold 成为 predicate;不安全判定的 threshold 没有对应项,类别都对应不上的规则保留不安全判定(migrate 会说明这两点)
pii 的 threshold、pii_types_allowed、include_history、source: tool_resultpredicate、ignore_labels、input.history、input.tool_results;source: tool_result 只读取工具结果,因此变为 input: {tool_results: true, request: false} 并去掉 include_history
名为 no_fact_check_needed 且没有 labels 的 fact_check 规则labels: [NO_FACT_CHECK_NEEDED] 加一个 predicate
没有 labels、以名称决定选项的 user_feedbacks 和 modality 规则把选项写进 labels;若有条件以 label 指定该规则的某个选项,或有分数输入写成 <rule>:<label>,该规则是按 v0.5 写的,保持原样
reasks、topic_continuity带 labels 的 turn_relation;lookback_turns 大于 1 的 reask 规则要求的连续重问没有对应项,input.previous_turns 最多为 32,migrate 会说明这两点
complexity 的示例库和阈值;name: difficulty:hard 条件complexity;{name: difficulty, label: hard}
modality 名称 AR、DIFFUSION、BOTH;关键词回退labels text、image、text_image;回退变为一条 keywords 规则(需检查)
classifiers、preferences、文本 embeddings 规则systemone 问题
带文本锚点的图片 embeddings 规则带 input.image 的 systemone 问题
kb 规则、kb 条件和 kb_metric 分数输入删除:kb 规则永远不会匹配,所以 migrate 会删除需要它的决策、它在 OR 中的那一项以及基于它的分数输入;每条规则的说明会给出替代它的、覆盖其标签的 systemone set 问题
图片锚点和音频 embeddings 规则没有改写:编写一个 systemone 问题(错误信息会说明)
eventsoperator: OR 的 keywords 规则
structuremethod: regex 加 count 或 density predicate 的 keywords 规则;text_bytes 规则用四个区分大小写的正则模式统计当前轮次的 UTF-8 字节数
actionssystemone choice 问题 action
conversation 的 image_contentmodality: image 的 input_modality 规则
global.model_catalog.modules.* 及其 system 行已移除;模块的阈值变为使用它的规则的 predicate,prompt_compression 变为 context 插件的 compress.signals(见插件)

算法​

providers:
models:
- name: small
backend_refs: [{name: small, endpoint: "127.0.0.1:8000", protocol: http}]
- name: large
backend_refs: [{name: large, endpoint: "127.0.0.1:8001", protocol: http}]
recipes:
- name: default
decisions:
- name: verified
priority: 100
rules: {operator: AND, conditions: []}
modelRefs: [{model: small}, {model: large}]
algorithm:
type: confidence
confidence:
confidence_method: avg_logprob
threshold: 0.7
recipes[default].decisions[verified].algorithm: removed_algorithm_type: algorithm type confidence is removed; run `vllm-sr config migrate` (type: escalate, with its method and threshold under escalate.accept)
providers:
models:
- name: small
backend_refs: [{name: small, endpoint: "127.0.0.1:8000", protocol: http}]
- name: large
backend_refs: [{name: large, endpoint: "127.0.0.1:8001", protocol: http}]
recipes:
- name: default
decisions:
- name: verified
priority: 100
rules: {operator: AND, conditions: []}
modelRefs: [{model: small}, {model: large}]
algorithm:
type: escalate
escalate:
accept:
confidence:
method: avg_logprob
gte: 0.7
之前之后
prompt、router_dcsystemone,用同样的说明或候选描述询问决策模型;无可选候选时与 knn 一样为 static
knn、kmeans、svm、mlpsystemone,每个模型只保留第一个 modelRefs 项(migrate 会说明丢弃的 LoRA 适配器);所有候选都是同一个模型(例如只有一个候选,或同一模型的多个 LoRA 适配器)时为 static;不再使用训练出的模型
automix、hybrid、latency_awaremulti_factor,由 migrate 写出权重
confidence(Looper)带 escalate.accept.confidence 的 escalate
cascade(System One)带 escalate.stages 的 escalate
automix_entailment 验证器escalate.accept.systemone,即 answer_check 问题
algorithm.<executor>.on_erroralgorithm.on_error,所有执行器都读取它
选择器上的 algorithm.on_error已移除:失败的选择器回退到第一个候选
global.router.model_selection.ml随训练式选择器一起移除

插件​

之前之后
tool_selection、global.integrations.toolstools 插件的 select 块,包含 tools_db_path 和 match.judge
写在 tools 配置顶层的字段(mode、allow_tools 等)放到 policy 下
rag、memory、context_compressioncontext 插件的源、compress 和 budget
global.model_catalog.modules.prompt_compressionglobal.plugins 中 context 插件的 compress.signals
RAG 的 top_k、similarity_threshold、rerank;记忆的 retrieval_limit;压缩的 scoringmatch.recall 和 match.judge
RAG 的 min_confidence_threshold决策 rules 中的一个 fact_check 条件
rag.reranker 绑定和 provider: rerank 部署已移除:由决策模型上的 relevance 评审代替
已启用插件中 backend: mcp 的 RAG 来源,或 hybrid 来源的 mcp 回退删除:Router 没有 MCP 工具调用器(已禁用插件中的来源保持不变);请通过 HTTP 提供检索,并用 backend: external_api 读取
hallucination、response_jailbreak基于响应阶段信号的 response_guard 规则
semantic-cache、semantic_cache、response-cache;扁平的缓存字段带 semantic.match 的 response_cache
global.stores.semantic_cacheglobal.stores.response_cache
shadow_dispatchrouter_replay 的 shadow 块
配方的 data_policy配方的 router_replay 插件:replay: false 对应 enabled: false,replay_personal_data: false 对应 prompt_capture: verified,其决策上的插件也一样
emits[].retention决策的 retention 属性
masking 的 thresholdmasking.signal,指定一条 pii 规则,使用它的 predicate
system_prompt 的 mode: appendmode: replace,它丢弃调用方发送的所有 system 和 developer 指令,而 append 只替换第一条 system 消息
request_params 的 strip_unknown已移除:路由器从未读取它,并且会拒绝客户端线路格式未声明的请求字段

global.model_catalog.modules 已移除。它的 prompt_compression 压缩路由信号读取的文本,现在是 global.plugins 中 context 插件的 compress.signals 块;配方自己的 context 插件可以覆盖它,决策的插件不能包含它:

global:
model_catalog:
modules:
prompt_compression:
enabled: true
max_tokens: 4096
global.model_catalog.modules.prompt_compression: removed_section: global.model_catalog.modules.prompt_compression is removed; run `vllm-sr config migrate` (compress.signals of a context plugin in global.plugins)
global:
plugins:
- type: context
configuration:
enabled: true
compress:
signals:
enabled: true
max_tokens: 4096

只有 signals 的 compress 块不压缩请求本身,与提示压缩原来的行为一致。迁移会给原本为空的决策 compress 块写入 mode: auto,使它继续压缩该决策的请求。

嵌入​

embeddings.default 用一个映射指定它的部署,写法和 system.decision_model 一样:

global:
model_catalog:
deployments:
remote-embed:
provider: openai_embeddings
endpoint: https://embed.example.com/v1
model: BAAI/bge-m3
capabilities: {dimensions: 1024, modalities: [text]}
embeddings:
default: remote-embed
global.model_catalog.embeddings.default: invalid_value: embeddings.default "remote-embed" is a bare deployment name; run `vllm-sr config migrate` (embeddings.default: {deployment: remote-embed}, as system.decision_model names its deployment)
global:
model_catalog:
deployments:
remote-embed:
provider: openai_embeddings
endpoint: https://embed.example.com/v1
model: BAAI/bge-m3
capabilities: {dimensions: 1024, modalities: [text]}
embeddings:
default: {deployment: remote-embed}
之前之后
只写名称的 embeddings.default: <name>embeddings.default: {deployment: <name>}
嵌入模型关键词(mmbert、qwen3 等)以及它们隐含的部署部署名称:global.model_catalog.embeddings.default,或存储的 embedding 块
embeddings.semantic、model_bindings.embeddingembeddings.default
embeddings.semantic 中早期版本的嵌入模型,例如 models/mmbert-embed-32k-2d-matryoshka它的 Vela 1.0 替代模型 Vela Embedding:在 CPU 上即预先声明的 vela-embedding。用早期模型建立的索引需要重新嵌入(migrate 会给出提示)
embeddings.multimodal已移除:嵌入只用于文本召回;关于图片的决策向 systemone 提出带 input.image 的问题
global.services.api.embeddings 以及 Router 的嵌入和相似度端点已移除:召回功能用到嵌入部署时它才启动
远程嵌入的向量宽度和输入它的 openai_embeddings 部署上的 capabilities.dimensions 和 capabilities.modalities
存储的 embedding_model、vector_store.embedding_dimension存储的 embedding: {deployment, dimension}
按嵌入模型关键词设置的准入嵌入部署的准入,按其名称设置

模型资源与连接​

上一版本的模型资源写法不再能加载。绑定只写部署名称,由信号决定该部署回答什么:

recipes:
- name: default
model_bindings:
pii: {deployment: vela, adapter: auto, mapping_path: /models/pii/labels.json}
global:
model_catalog:
deployments:
vela:
provider: model_runtime
artifact: vllm-sr/vela3-fast
device: cpu
recipes[default].model_bindings.pii: removed_field: recipes[default].model_bindings.pii.adapter and mapping_path are removed; run `vllm-sr config migrate` (pii: vela; the signal decides what the deployment answers)
recipes:
- name: default
model_bindings:
pii: vela
global:
model_catalog:
deployments:
vela:
provider: model_runtime
artifact: vllm-sr/vela3-fast
device: cpu

后端的连接方式与部署相同,使用 endpoint、auth 和 headers:

providers:
models:
- name: claude
backend_refs:
- provider: anthropic
base_url: https://gateway.example.com/anthropic
api_key_env: ANTHROPIC_KEY
auth_header: x-api-key
auth_prefix: ""
extra_headers: {X-Org: acme}
providers.models[claude].backend_refs[0]: removed_field: providers.models[claude].backend_refs[0].base_url, api_key_env, auth_header, auth_prefix and extra_headers are removed; run `vllm-sr config migrate` (endpoint (a full URL), auth {header, prefix, api_key_env} and headers, as a deployment connects)
providers:
models:
- name: claude
backend_refs:
- provider: anthropic
endpoint: https://gateway.example.com/anthropic
auth: {header: x-api-key, prefix: "", api_key_env: ANTHROPIC_KEY}
headers: {X-Org: acme}
之前之后
绑定对象:contract、adapter、head、mapping_path、operating_point部署名称,例如 pii: vela
部署上的 operating_point删除:没有任何组件读取它;模型运行时使用其模型包声明的工作点
使用分类器契约(label_distribution.v1、label_scores.v1、label_decision.v1、score.v1、token_spans.v1)的绑定删除:由决策模型回答该信号
针对单条规则的绑定,safety.<rule> 或 complexity.<rule>该规则的 deployment
部署上的 question_typescapabilities.question_types
部署或副本上的 served_namemodel
provider: classify 或 http 的部署删除:没有任何信号询问分类服务
provider: candle、ort 或 openvinoprovider: model_runtime,保留其设备,并使用其工件的 Hub 仓库;precision、profile 等引擎字段见迁移到模型运行时
global.model_catalog.external[]已移除;memory_rewrite 模型改为一个由 global.stores.memory.query_rewrite 指定的 openai_chat 部署,它的访问密钥改为环境变量
后端的 base_url、api_key_env、auth_header、auth_prefix、extra_headersendpoint(完整 URL)、auth: {header, prefix, api_key_env}、headers
global.router.auto_model_names、auto_model_name默认配方的一个入口,使用上一版本所服务的名称:auto_model_names,否则为 vllm-sr/auto、auto 和 auto_model_name(未设置时为 MoM),因此两者都没写的早期版本文件会得到 vllm-sr/auto、auto 和 MoM,但已被某个配置模型占用的名称除外,对它的请求现在会到达该模型;文件自己写了默认配方的入口时,新入口放在它旁边,原入口的名称保持不变,另一个入口已服务的名称也仍归该入口
global.router.include_config_models_in_listglobal.router.list_backend_models
global.integrations.looper.endpoint已移除:Router 在进程内发起 Looper 的模型调用
global.integrations.looper.<algorithm>.model_names使用这些名称的入口,指向迁移写出的配方:默认配方中只保留运行该算法的决策
use_nli 及 NLI 解释器字段已移除:规则的 span 仍保留在响应中

后端内联的 api_key 仍可加载,但不能与 auth.api_key_env 同时使用。迁移模型资源完整展示了每种写法。

Looper 算法的 model_names 让 model 为其中某个名称的请求只经过默认配方中运行该算法的决策(flow 对应 workflows 决策)。迁移保留了这一行为:为每个列表写出一个以默认配方和算法命名的配方,它是默认配方的副本,只保留这些决策;再写出一个使用这些名称、指向该配方的入口。多出一个配方后,默认配方的入口会标记为 default: true。唯一的变化是:这些决策都不匹配的请求,现在与其他入口一样转到默认模型,以前则会失败。没有任何决策运行过的名称从未服务过请求,迁移会将其删除。v0.3 文件若没有为默认配方的决策所运行的某个算法列出名称,则该算法服务的是其内置名称 vllm-sr/remom、vllm-sr/fusion 或 vllm-sr/flow,迁移以同样的方式写出该名称。v0.3 文件的入口若使用了 v0.4 默认服务的名称,例如 vllm-sr/auto、MoM 或 vllm-sr/fusion,则它是为 v0.4 与 v0.5 之间的 main 编写的:v0.4 拒绝这些入口名称,而 main 只服务入口,因此迁移不会为它写出其他名称。

global:
integrations:
looper:
fusion:
model_names: [vllm-sr/fusion]
global.integrations.looper.fusion.model_names: removed_field: the model names of a Looper algorithm are removed; run `vllm-sr config migrate` (an entrypoint whose model_names name a recipe with a decision that runs the fusion algorithm)
recipes:
- name: default
# 它的信号、决策与设置保持不变
- name: default-fusion
description: The fusion decisions of recipe default
# 默认配方的信号与设置,只保留其 fusion 决策
entrypoints:
# 自动模型名称,这里的文件没有写出任何名称
- model_names: [vllm-sr/auto, auto, MoM]
recipe: default
default: true
- model_names: [vllm-sr/fusion]
recipe: default-fusion

模型及其输出​

模型的 modality 关键词改写成它所代表的事实;以生成图片作答的决策在输出契约中声明这一点:

providers:
models:
- name: painter
api_format: images
backend_refs: [{name: images, endpoint: "127.0.0.1:8002", protocol: http}]
modality: diffusion
providers.models[painter].modality: removed_field: modality: diffusion is removed; run `vllm-sr config migrate` (capabilities: [image_generation] and modalities: {input: [text], output: [image]})
providers:
models:
- name: painter
api_format: images
backend_refs: [{name: images, endpoint: "127.0.0.1:8002", protocol: http}]
capabilities: [image_generation]
modalities: {input: [text], output: [image]}
之前之后
modality: ar已移除:除非 modalities 另有说明,模型都以文本作答
modality: diffusioncapabilities: [image_generation] 和 modalities: {input: [text], output: [image]}
modality: omni显式的 modalities:input: [text, image];模型声明了 image_generation 时 output: [text, image]
按模型的 modality 把图片请求发给某个模型的决策决策的 output: {kind: image, action: generate};一个模型同时写文本和图片时为 {kind: [text, image]};通过 chat API 访问的模型改为 api_format: images,若它也以文本回答则改为 responses(请确认其后端提供该 API)
跨两个模型的文本加图片路由删除:本版本没有决策能执行它,它的请求会转到其他决策;若要保留,请引用一个在 api_format: responses 上既以文本回答又能生成图片的模型
image_gen 插件无法改写:决策引用的图片模型(api_format: images,capabilities: [image_generation]),并设置 output: {kind: image, action: generate}
带音频查询的 embeddings 规则无法改写:删除它;目前还没有能读取音频的决策模型

响应头与网关​

响应头不是配置,migrate 不会改写读取它们的地方。请更新网关和客户端:

之前之后
基于 x-selected-model 的自定义 Envoy 路由x-vsr-route-model
x-disable-router-memoryx-vsr-memory: off
x-vsr-matched-*、决策、置信度和协议相关的头x-vsr-trace 的成员,只发给 global.router.headers.debug 允许的调用方
x-vsr-cache-hit、x-vsr-fast-responsex-vsr-response-path
x-vsr-protocol-warnings、x-vsr-response-warningsx-vsr-warnings
x-vsr-selected-modalitytrace 的 modality 成员
x-session-id、x-claude-code-session-idx-vsr-session-id;global.router.headers.session_id_headers 让其他名称继续被接受

VSR 路由头部页面列出了公开集合和每个 trace 成员。

4. 校验并启动​

vllm-sr config validate --config config.migrated.yaml
vllm-sr serve --config config.migrated.yaml

预期的行为变化​

  • 原来属于其他模型的阈值已重新拟合。 没有 predicate 的规则使用回答模型的校准阈值;没有校准阈值的模型使用 0.5,并给出 uncalibrated_preset 警告。
  • 需要 span 的规则必须解析到支持 span 的部署。 pii、hallucination、span 问题和 masking 在不支持 span 的部署(例如 d3 模型)上会以 span_required 加载失败。
  • 模型没有给出答案的请求阶段 jailbreak 或 pii 规则匹配(失败即拦截),除非设置了 on_unknown: no_match。长输入分窗口读取;截止时间提前结束扫描时,规则根据已读窗口作出判断,除非设置了 on_unscanned: match。
  • RAG 相关性和工具选择由决策模型评判,语义缓存命中由它的 same_request 问题确认。
  • 嵌入模型只在召回功能需要时才启动,Router 的嵌入 API 已移除。
  • 每个评审都有 max_candidates 上限;更多的候选会被截断,绝不报错。
  • System One 批量调用只使用 states 形式,Router 需要契约 4.0.0 的模型运行时;见批量请求。
  • 图片决策声明 output 契约,它指定的每个模型都声明所需的能力。POST /v1/images/generations 只会到达这样的决策;其他请求会得到 image_route_required。
  • 响应头是一组公开的头,调试细节放在一个 x-vsr-trace 头中;发布说明把每个旧响应头映射到它的替代者。
  • Looper 算法的名称会回落到默认模型。 请求的名称若列在某个 Looper 算法的 model_names 中,而该算法的决策都不匹配,请求会转到默认模型,而不再失败。
  • kb 规则永远不会匹配。 migrate 会删除它、需要它的决策以及它在 OR 中的那一项;在用 systemone 问题替代之前,这些请求会转到其他决策。
  • 没有决策能执行的部分会被删除:跨两个模型的文本加图片路由,以及已启用插件中 backend: mcp 的 RAG 来源。每条说明都会给出恢复方法。
  • 图片路由背后的扩散模型改用 images API 回答。 migrate 会设置其 api_format: images;请确认其后端提供 POST /v1/images/generations。