服务分级是怎么回事:OpenRouter 的 service_tier 影响的是哪一段体验

2026-08-18

先说一个很容易撞上的现象:你在请求体里写了 "service_tier": "priority",回来的响应里那个 service_tier 字段却不是 priority;换一个 API 形态去读,甚至在响应顶层根本找不到这个字段。这两件事都不是 bug,它们分别对应 OpenRouter 官方文档《Service Tiers》页(openrouter.ai/docs/guides/features/service-tiers)里写明的两条规则。这篇就沿着文档描述的路径,把一次带分档的请求从发出到读响应走一遍,途中把关键字段点出来。

需要先说清楚的边界:OpenRouter 是闭源商业平台,我们没有源码,也没有对下面这些机制做过任何实测,全文只复述官方文档写明的内容。平台迭代频繁,字段语义与取值随时可能调整,以官方文档最新内容为准。

请求侧:档位是一个顶层参数

service_tier 是请求体的顶层参数,不在 provider 对象里,也不在 messages 里。文档写明支持的取值是 flex(更低成本、更高延迟)和 priority(更快、更高成本),另外 fast 被接受为 priority 的别名。

文档给的 cURL 示例是这样的(其中的模型 slug 只是官方文档当时用的示例值,平台上有哪些模型随时在变,别当清单用):

curl https://openrouter.ai/api/v1/chat/completions \
  -H "Authorization: Bearer <OPENROUTER_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5",
    "service_tier": "flex",
    "messages": [
      { "role": "user", "content": "What is the meaning of life?" }
    ]
  }'

这个参数不只 Chat Completions 认。文档写明 Responses API 与 Anthropic Messages API 同样接受 service_tier,Messages API 的示例走的是 https://openrouter.ai/api/v1/messages 这个端点。

Windows 侧要单独提一句:上面这段是文档原样给出的 shell 写法,单引号包裹整段 JSON 在 Linux/macOS 的 shell 里没问题,但 Windows 的 cmd 与 PowerShell 对引号的处理规则不同,直接粘过去经常会在 JSON 解析这一步失败。把请求体写进一个 .json 文件再用 -d "@<你的项目目录>/body.json" 传,或者干脆改用文档里那几段 Python / TypeScript 示例,都能绕开这一层。这一段是命令行的通用做法,不是 OpenRouter 官方文档的内容,文档本身没有讨论 Windows 的引号问题。

选档有两条路,而且默认哪条都不走

文档在《How Routing Works》一节写得很直接:非默认档的端点(flexpriority)只有在你的请求主动要它时才会被纳入考虑。要的方式有两种。

一种就是上面的 service_tier 参数。另一种是在 provider.orderprovider.only 里直接写分档端点的 slug——每个档有自己的端点 slug,规则是把档位追加到 provider slug 后面,文档举的例子是 openai/prioritygoogle-vertex/flex。比如:

"provider": { "only": ["openai/priority"] }

文档明说,两种方式都没用到的请求,永远不会被路由到非默认档。这句话反过来读更有用:你没显式要,就不会莫名其妙被送到贵的那一档。

这里还有一处很容易踩的细节,写在《Provider Routing》页(openrouter.ai/docs/guides/routing/provider-selection)的 base slug 匹配那一节:在 orderonlyignore 里写基础 provider slug 会匹配该 provider 的所有端点,包括各种变体与区域后缀——但分档端点是例外,文档写明它们不被 base slug 匹配,必须通过 service_tier 参数或带档位后缀的 slug 显式选入。也就是说,你写了一个基础 slug 想「把这家全放进来」,分档端点不会跟着进来。

priority 和 flex 的回退规则是两套

这是本页最值得记住的一段,两个档的路由行为并不对称。

priority:匹配到的端点会被优先尝试,排序依据文档写的是 throughput;如果这些端点都没成功,请求会回退到其它端点。计费始终跟随实际用到的端点——所以一个 priority 请求如果回退到了非该档的端点,按那个端点的标准费率计费,而不是按档位费率。

flex:路由被限制在 flex 端点内,排序依据是价格。文档写明 flex 不会回退到默认档端点,并给出了理由(文档自述):那样会比你请求的这一档更贵;因此这种情况下你拿到的是一个 flex 容量错误,而不是一次悄悄变贵的成功请求。但还有一个例外要分清楚:如果候选池里压根没有 flex 端点(例如这个模型没有支持 flex 的供应商),请求会按标准费率正常路由。

这两条放在一起,就是排查时的判断依据:flex 请求报容量错误,说明池子里有 flex 端点但没容量;flex 请求正常返回却报 default,那更像是池子里根本没有 flex 端点这一种情况。

文档还提到可以配合 allow_fallbacks: false 使用,把路由限制在该档位排在最前面的那个端点上。allow_fallbacksprovider 对象里的布尔字段,语义是「主选不可用时是否允许备用供应商」,文档写明它的默认值是 true(这是文档写明的默认值,随版本可能变动)。

{
  "model": "openai/gpt-5",
  "service_tier": "flex",
  "provider": { "allow_fallbacks": false },
  "messages": [{ "role": "user", "content": "..." }]
}

以上为按官方文档中的字段语义组合的示例,未经实测,以官方文档与 API 的实际响应为准。

fast 模式:三种写法指向同一件事

《Fast mode》一节把几个来源不同的写法拉平了:service_tier: "fast"(文档说明这是 OpenAI 对优先处理的 Fast mode 改名)、service_tier: "priority"、以及 Anthropic 原生的 speed: "fast" 参数,在所有 API 与供应商上完全可互换。三者中任意一个都是在请求 priority 档,响应统一报 priority。此外,对于存在 fast 兄弟型号的 Anthropic 模型(文档举的例子是 anthropic/claude-opus-5-fast),会被改路由到那个兄弟型号。

反直觉的一条在后面:如果你显式设置了互相冲突的值(文档举的例子是 speed: "standard"service_tier: "priority"),两个都按你写的照办,谁也不会从谁那里推导出来。所以别指望写了一个另一个会自动跟上。

还有一条必须照实标出来:文档转述了 Anthropic 官方口径,Anthropic 自己已经**弃用(deprecated)**了它的 priority tier——容量承诺不再对外销售,已有合约的组织可以用到合约到期为止。这是文档引述的上游状态,不是 OpenRouter 侧的能力描述。

至于哪些供应商提供 flex 与 priority 端点,文档在《Supported Providers》一节列了名单,并且注明这些档位只对部分模型开放,名单里也有被单独标注为仅支持 priority 的条目——也就是说「这家支持分档」并不等于「这家的每个模型都能选这两档」。这份名单会随平台变动,需要的时候去那一页看当时的内容,别把它写死在代码里,更别在代码里按供应商名硬编码分档能力。

响应侧:字段在哪、能是什么值

回到开头那个现象。文档写明响应里的 service_tier 字段报告的是实际用来服务这次请求的档,不是你请求的档;计费也按实际服务的档来算。所以请求写 priority、响应报别的,恰恰是回退规则生效的证据。

字段位置按 API 形态不同,一共三种情况:

API响应里 service_tier 的位置
Chat Completions(/api/v1/chat/completions响应对象顶层
Responses(/api/v1/responses响应对象顶层
Messages(/api/v1/messagesusage 对象内部

前两种是对齐 OpenAI 的原生格式,第三种是对齐 Anthropic 的原生格式。你的读取代码如果是从 Chat Completions 抄过来的,换到 Messages API 上就会在顶层读到 undefined。

取值一共四种可能:defaultflexpriority,以及上游没有可用服务档时的 null。这里还有一层归一化:OpenRouter 会把供应商侧等价的基础档标签(文档举的例子是 Google 的 standard)归一成 default——但 Anthropic Messages API 是例外,它保留 standard 以匹配 Anthropic 的规范。所以同一次「走的是基础档」,在 Chat Completions / Responses 里读到 "default",在 Messages API 里读到 "standard"。做统计或者做告警的时候,这两个值要当成一回事处理。

两处顺手记下的口径

一是分档端点在模型端点列表 API 里的样子:文档写明它们与标准端点并列出现,各自是一条独立条目,tag 带档位后缀(例子是 openai/priority),价格已经应用了该档的倍数(与计费用的是同一份价格)。但文档同时强调,出现在这份列表里并不改变路由行为——它们依然是上面说的那种「你不要就不会走」的 opt-in。

二是一处口径不一致,值得提前知道:Python SDK 的 chat 参数表里,service_tier 那一行的示例列写的是 auto,而《Service Tiers》页只写明了 flexpriority 和作为别名的 fast。文档没有说明 auto 的语义,也没有把它列进支持取值里。两处放在一起就是这样,我们不做进一步推断,真要用之前建议以官方文档与 API 的实际响应为准。


本文依据 OpenRouter 官方文档(openrouter.ai/docs)于 2026-08-18 的公开内容整理。 该平台闭源,本文只复述官方文档写明的机制,不推断其内部实现我们没有对文中涉及的功能做过实测,因此不涉及界面外观与运行表现的任何描述。 该平台的供应商、模型与路由策略随时变动,文中不列具体供应商名单与模型清单; 价格、额度与限流的具体数值请以官方定价页与用量说明为准。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。