模型提供商经常性地退役和限制模型。过去几年里,已有超过 70 个模型被提供商下架或弃用。Anthropic 最近下架 Fable 模型,或许是我们见过的最高调、影响最大的案例,但这种模式并不新鲜,也不会消失。
OpenRouter 已经为你处理了其中一层问题。当一个模型在多个提供商上运行,而其中某个提供商出现故障或触发速率限制时,市场会自动将请求路由到另一个提供商,无需任何配置。我们在另一篇文章中介绍了这种故障转移机制的工作原理。
这能确保单个模型在提供商出现问题时仍可访问,但一旦模型本身消失,它就无能为力了。为此,你需要模型故障转移——当首选模型不可用时,请求会自动切换到另一个模型。预设就是用来实现这一点的。
硬编码模型标识符会将你的选择锁定在使用它的每一个服务中。当该模型消失时,唯一的修复方法是编辑代码并重新部署每个服务,而在此之前,请求会持续失败。
预设则将这个选择从你的代码中抽离出来。它是一个有名称的服务端配置(包含模型、备用模型、提供商规则、参数以及系统提示词),你可以通过标识符来引用它。模型存在于预设中而非代码里,因此你只需在一个地方修改,所有调用该预设的服务都会自动更新,无需重新部署。
以下是一个简单的预设定义。复制它并调整其中的模型:
{
"models": [
"anthropic/claude-fable-5",
"anthropic/claude-opus-4.8",
"openai/gpt-5.5"
],
"provider": { "allow_fallbacks": true }
} models 数组是你的备用链,按优先级排序。如果第一个模型不可用,OpenRouter 会尝试下一个。
硬编码模型标识符 vs 预设引用
| 问题 | 硬编码模型字符串 | 预设引用 |
|---|---|---|
| 提供商限制了该模型 | 每个服务都会中断,直到你编辑并重新部署 | 编辑一次预设;调用方持续运行 |
| 谁负责修复 | 每个代码库的所有者 | 预设的所有者 |
| 变更的影响范围 | 每个仓库、每个服务各需编辑一次 | 编辑一次,全局生效 |
| 数据策略(ZDR,保留期限) | 在每次请求中重新声明 | 在预设中一次性设置 |
| 回滚 | 撤销一次提交并重新部署 | 重新指定一个之前的版本 |
把这个给你的智能体
想让你的编程智能体自动配置这个?复制下面的提示词:
I want to stop hard-coding model slugs so one provider change can't take down my app. Set up an OpenRouter preset and route my calls through it.
1. Create a preset named "customer-support" with a fallback chain: a primary model plus 2 backups in priority order, using the models array.
2. Set provider rules on the preset: allow_fallbacks true, and zdr true if my data policy requires Zero Data Retention.
3. Capture it by POSTing a known-good chat/completions body to https://openrouter.ai/api/v1/presets/customer-support/chat/completions with my OpenRouter API key.
4. Replace the model field in my inference calls with "@preset/customer-support".
5. Keep my OpenRouter API key in an environment variable. Never hard-code it.
Use these references for current shapes:
- Presets: https://openrouter.ai/docs/guides/features/presets
- Provider routing and fallbacks: https://openrouter.ai/docs/guides/routing/provider-selection 将一个有效的请求捕获为预设
你可以在控制台中构建一个预设,或者从你已经信任的请求体中捕获一个。
将一个已知有效的聊天/补全请求体发送到预设捕获端点。OpenRouter 会持久化与预设配置重叠的字段(模型、提供商、温度等),并忽略像 messages 这样的临时字段:
curl https://openrouter.ai/api/v1/presets/customer-support/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"models": [
"anthropic/claude-fable-5",
"anthropic/claude-opus-4.8",
"openai/gpt-5.5"
],
"provider": { "allow_fallbacks": true },
"messages": [
{ "role": "system", "content": "You are a concise support assistant." },
{ "role": "user", "content": "Summarize this ticket in one sentence." }
]
}' 如果具有该 slug 的预设已存在,此操作会创建一个新版本并将其指定为活跃版本。如果不存在,则会创建该预设。请选择一个尚未使用的 slug,因为捕获到已有 slug 上会用新的活跃版本覆盖其当前配置。响应会返回该预设及其指定的版本(此处已精简):
{
"data": {
"name": "customer-support",
"slug": "customer-support",
"status": "active",
"designated_version": {
"version": 1,
"system_prompt": "You are a concise support assistant.",
"config": {
"models": [
"anthropic/claude-fable-5",
"anthropic/claude-opus-4.8",
"openai/gpt-5.5"
],
"provider": { "allow_fallbacks": true }
}
}
}
} 在代码中引用该预设
现在将你的推理调用指向 @preset/customer-support。模型选择保存在预设中,因此当底层模型发生变化时,这行代码保持不变。
首先安装一个 SDK:
pip install openrouter # Python
npm install @openrouter/sdk # TypeScript from openrouter import OpenRouter
import os
client = OpenRouter(api_key=os.getenv("OPENROUTER_API_KEY"))
response = client.chat.send(
model="@preset/customer-support",
messages=[
{"role": "user", "content": "Summarize this ticket in one sentence."}
],
)
print(response.choices[0].message.content) import { OpenRouter } from '@openrouter/sdk';
const client = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });
const response = await client.chat.send({
chatRequest: {
model: '@preset/customer-support',
messages: [
{ role: 'user', content: 'Summarize this ticket in one sentence.' },
],
},
});
console.log(response.choices[0]?.message.content); 默认使用上面所示的 @preset/slug 形式。当你想要指定一个基础模型并在其上叠加预设配置时,可以使用组合形式 model@preset/slug;或者,如果你更愿意将它们作为独立的请求字段,也可以将预设字段与模型字段分开使用。预设文档涵盖了所有三种方式。
添加备用模型以确保请求持续运行
models 数组是能够在模型弃用时幸存下来的部分。按优先级顺序传递模型,当某个模型不可用时,OpenRouter 会遍历该列表。
把你最信任的模型放在最后一个条目,这样你的最终备用方案就是一个你愿意放心上线的底线。对于一个依赖 Fable 5 的编程工作负载,像 anthropic/claude-fable-5,然后是 anthropic/claude-opus-4.8,最后是 openai/gpt-5.5 这样的链路,可以保留强大的模型作为后备。
以下是该备用机制触发的情况。当 Fable 5 受到限制时,一个指定了上述链路的请求仍然成功,并且响应中的 model 和 provider 字段会标明实际提供服务的模型:
{
"model": "anthropic/claude-4.8-opus-20260528",
"provider": "Anthropic",
"choices": [
{
"message": {
"role": "assistant",
"content": "Customer cannot log in because password reset emails are not being received, despite checking spam and confirming the correct email address."
}
}
]
} OpenRouter 跳过了受限的主要模型,并提供了数组中的下一个模型。你的代码无需更改。
模型字段会报告实际处理请求的具体版本,因此其内容与你发送的标识符有所不同。此处,`anthropic/claude-opus-4.8` 解析为 Anthropic 上带有日期的构建版本 `anthropic/claude-4.8-opus-20260528`。
这里有两层恢复机制。提供商层面的故障转移是自动的:对于由多个提供商提供的同一个模型,当遇到 5xx 错误或速率限制时,OpenRouter 会重试下一个提供商。模型层面的回退则通过模型数组实现,当主模型完全不可用时,会切换到数组中的另一个模型。关于每种机制的具体原理,请参阅可靠性、自动故障转移和模型路由。
在预设中设置你的数据策略
提供商规则也包含在同一预设中,因此路由策略无需修改代码即可应用于所有调用方。
{
"models": [
"anthropic/claude-fable-5",
"anthropic/claude-opus-4.8",
"openai/gpt-5.5"
],
"provider": {
"zdr": true,
"data_collection": "deny",
"allow_fallbacks": true
}
} `zdr: true` 确保请求仅在遵守零数据保留策略的端点上处理。`data_collection: "deny"` 会阻止那些训练或存储提示词的提供商。你还可以通过 `only`、`ignore` 和 `order` 参数来固定或排除特定提供商。完整列表请参阅提供商路由。
这就是 Fable 5 问题变得具体的地方。其模型页面指出,Anthropic 的政策“不允许零数据保留”。当预设中设置了 `zdr: true` 时,路由会跳过 Fable 5,因为它无法满足该规则,并会回退到你模型数组中能够满足该规则的下一个模型。只需一个开关,即可在服务端对所有引用该预设的请求强制执行此规则。
在团队中推广和回滚
在组织账户中,每个成员都可以使用组织预设,因此一次做出的路由决策可以共享,而无需复制到每个代码仓库中。
每次捕获或编辑都会创建一个新版本,并将其标记为活跃。版本历史会被保留,因此一个错误的更改只需重新指定版本即可回滚。通过 API,始终运行的是最新指定的版本。你可以在仪表板上重新指定版本和删除预设;API 可以捕获和读取预设,但没有删除端点。
你在请求中传递的参数会覆盖预设中的值,采用浅合并方式。请求中的字段优先级更高,而预设中未在请求中发送的字段则会被保留。这使得单个调用可以调整温度参数,而无需复制整个预设。
将所有部分整合在一起
上述数据策略配置已包含全部三层:模型链、提供商策略,以及(一旦添加)系统提示词。通过 curl 调用一次性捕获该配置,在所有地方引用 @preset/customer-support,下次提供商限制某个模型时,你只需编辑一个配置,而无需在每项服务中逐个查找模型标识符。
如果你完全不想固定主模型,可以将链指向一个自动更新的别名,例如 ~anthropic/claude-opus-latest,该别名始终解析为该系列中最新的模型。
从一个预设开始
选择你流量最高的调用,在 openrouter.ai/settings/presets 为其创建一个预设,设置一个备用链,并将模型字符串替换为 @preset/你的标识符。这一操作就能将强制迁移转变为一次配置编辑。
预设还能很好地配合治理工作:同一个在模型弃用后依然有效的控制点,正是你强制执行数据处理规则的地方,如《AI 智能体的人工监督》中所述。
注意:本文涵盖的是工程模式,而非法律建议。关于出口管制、数据驻留或保留义务,请就你的具体用例和司法管辖区咨询法律顾问。
常见问题
当某个模型被弃用或限制时,我的应用会怎样?
如果你的代码硬编码了模型标识符,对该模型的请求将开始失败,所有使用该模型的服务都会中断,直到你编辑代码并重新部署。通过预设路由,你只需编辑一个配置;调用方无需重新部署即可获取更改。模型的备用数组可以在你决定下一步行动时,让请求在备用模型上继续成功执行。
预设与在代码中传递模型备用数组有何不同?
模型数组为单个请求设置备用顺序。预设则将该数组、提供商规则、参数和系统提示词存储在服务器上的一个标识符下。你通过 @preset/标识符 引用它,因此配置存在于所有服务的同一位置,且无需代码编辑即可更改。
请求参数会覆盖预设值吗?
是的。请求参数优先于预设值,采用浅合并。请求级别的字段会覆盖匹配的预设字段,而你未发送的预设字段则会被保留。
我能否通过预设强制执行零数据保留?
是的。将 `provider.zdr` 设置为 `true`。OpenRouter 仅路由到遵守零数据保留策略的端点,跳过无法遵守的模型或提供商,并遍历你的模型数组,回退到下一个符合条件的选项。
如何回滚预设的更改?
每次捕获或编辑都会创建一个新版本,并将其设为活跃版本。版本历史会被保留,因此你可以重新指定之前的版本。通过 API,始终使用最新指定的版本。