OpenRouter Presets:当模型下线时保持 AI 智能体运行
阅读原文· openrouter.ai给 Agent 开发者的实用提醒,硬编码模型名会在供应商限制时塌方,用 Presets 换模型、设降级方案比现改代码省心。
Anthropic 在 Claude Fable 5 发布仅数天后便对其进行了限制。如果代码硬编码模型 slug,该限制也会导致服务中断。OpenRouter 的 Presets 功能将模型选择移至服务器端,使用户无需重新部署即可切换模型、设置回退策略并强制执行数据策略。
当模型消失时,让你的智能体继续保持运行
Kenny Rogers 与 Alex Atallah · 2026 年 6 月 15 日
- 硬编码的模型标识符 vs. 预设引用
- 把它交给你的智能体
- 将一次成功的请求捕获为预设
- 在代码中引用该预设
- 添加备用模型,确保请求持续畅通
- 在预设中设置你的数据策略
- 在团队中推行与回滚
- 将所有环节串联起来
- 从一个预设开始
- 常见问题解答
提供商经常会退役或限制模型。过去几年里,已有超过 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、保留期) | 每次请求中重新声明 | 在预设中一次性设置 |
| 回滚 | 撤销一次提交并重新部署 | 重新指定先前版本 |
把这个交给你的 AI 智能体
希望你的编程智能体自动完成配置?请复制以下提示词:
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 将一次有效的请求捕获为预设
你可以在控制台中创建预设,或者从你已经信任的请求体中捕获一个预设。
将一条已知可用的 chat/completions 请求体发送到预设捕获端点。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)对应的预设已存在,此操作会创建一个新版本并将其设为活跃。如果不存在,则创建该预设。请选择一个尚未使用的简短标识,因为捕获到已有标识上会用一个新活跃版本覆盖其当前配置。响应返回预设及其指定的版本(此处已精简):
{
"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 跳过了被限制的主模型,转而使用了数组中的下一个模型。你的代码无需改动。
model 字段报告的是实际处理该请求的具体版本,因此它与你发送的 slug 会有所不同。此处 anthropic/claude-opus-4.8 在 Anthropic 端解析为带日期的构建版本 anthropic/claude-4.8-opus-20260528。
这里包含两层恢复机制。提供商层故障切换是自动的:对于由多个提供商提供的同一个模型,当遇到 5xx 错误或速率限制时,OpenRouter 会自动重试下一个提供商。模型层回退则通过 models 数组实现,当整个主模型不可用时,会转向另一个模型。每层的具体机制,请参阅可靠性与自动故障切换以及模型路由。
在预设(preset)中设置你的数据策略
提供商规则也在同一个预设中一起传递,因此路由策略无需修改代码即可应用于所有调用方。
{
"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 会将请求限制在遵守零数据留存(Zero Data Retention)的端点上。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/your-slug。这一操作就能将强制迁移变为一次配置编辑。
预设也能很好地配合治理工作:这一在模型弃用时仍能存续的控制点,正是你强制执行数据处理规则的地方,详见《AI 智能体的人工监督》部分。
注意:本文介绍的是工程模式,并非法律建议。关于出口管制、数据驻留或保留义务,请咨询律师,针对你的具体用例和司法管辖区。
常见问题
当模型被弃用或限制时,我的应用会发生什么?
如果你的代码硬编码了模型标识符,请求该模型将开始失败,所有使用该模型的服务都会中断,直到你修改代码并重新部署。通过预设路由,你只需编辑一个配置;调用方无需重新部署即可应用更改。模型的备用数组可以保持请求在备用模型上继续成功执行,同时你决定后续操作。
预设与在代码中传递模型的备用数组有何不同?
模型的数组(models array)仅为单个请求设置备用顺序。而预设则将该数组、提供商规则、参数和系统提示词一起存储在服务器上的一个标识符下。你通过 @preset/slug 引用它,因此配置位于所有服务共用的唯一位置,无需修改代码即可变更。
请求参数是否会覆盖预设值?
可以。请求参数会优先于预设值,以浅合并方式处理。请求级别的字段会覆盖预设中的对应字段,而你没有发送的预设字段则会被保留。
我能否通过预设强制零数据保留?
可以。将 `provider.zdr` 设为 `true`。OpenRouter 只会路由到支持零数据保留的端点,跳过无法满足该要求的模型或提供商,并继续在你的 models 数组中向下寻找下一个符合条件的选项。
如何回滚预设的更改?
每次捕获或编辑都会创建一个新版本并将其设为当前活跃版本。版本历史会被保留,因此你可以重新指定之前的某个版本。通过 API 调用时,始终使用最新指定的版本。