OpenRouter Auto Router 是怎么选模型的?路由机制与可控项
数据截至 2026-08,价格与限额以各官网为准。本文只讲计费与接入机制,不列具体价格数字。
把 model 填成 openrouter/auto,请求就交给 Auto Router 决定用哪个模型。官方文档把它的工作方式说得很直白:先用一个轻量分类器判断这条 prompt 属于哪类任务,再去查 OpenRouter 社区在这类任务上按滚动窗口统计的花费份额排名,然后套用你指定的 cost_tier 成本档,最后把幸存下来的头部模型排成”主选 + 若干 fallback”。它不是一个”更聪明的模型”,而是一个把市场行为当排序信号的选择器——所以你真正能控制的,是喂给它的候选池(allowed_models / excluded_models)、成本档(cost_tier)和会话粘性(session_id),而不是它的判断本身。最容易被坑的一点是:openrouter/auto 和 openrouter/auto-beta 各读各的插件 id,写错了不会报错,设置会被静默忽略。
它一次请求里到底做了哪几件事
官方在 How It Works 一节把流程拆成四步,值得逐步看,因为每一步都对应一个你能不能干预的位置。
第一步是任务分类。文档写的是由一个”快速、轻量”的分类器给每条 prompt 打上一个细粒度任务类型标签,类型总数官方给的是约三十种这个量级(以官方文档当前版本为准),并举了 code:debugging、agent:multi_step_planning、qa_knowledge、math、customer_support、research_report 这几个例子。这里有一句对合规评估很重要的说明:官方称 prompt 是”in-flight”分类的,不需要留存。
第二步是按真实花费份额排名。对上一步得出的任务类型,路由器去查 OpenRouter 社区在一个滚动窗口内对各模型的花费份额,也就是官方 rankings 页面里的 “Share of Spend” 视图。文档强调这是一个”活的”信号:当开发者把某个工作负载迁移到新模型上,路由器会在几天之内跟上,不需要重新训练也不需要人工维护名单。官方给它的比喻是”市场指数”。
第三步是套用成本档,也就是 cost_tier。
第四步是带 fallback 落地。官方原话是,排在前面且幸存下来的模型(仍按市场花费份额排序)会成为主选加上若干 fallback,而”幸存”的前提是先满足这几类约束:你账号层面的模型与供应商限制、guardrails、ZDR 策略、allowed_models 限制,以及输出模态要求。还有一条兜底设计值得记住——如果分类或排名信号暂时不可用,路由器会退化到一个默认模型集,官方明确说请求不会因为路由基础设施出问题而失败。
理解这四步之后,很多”它为什么选了这个模型”的疑问就能自己回答了:你没设 cost_tier,它就按接近最低成本档的方式路由;你设了 allowed_models,候选池在第四步之前就被裁掉了;账号级的模型与供应商限制也会参与进来——官方把它列为路由要遵守的约束之一,但没有说明它与请求参数之间的优先级顺序。
两个 slug,两套插件 id,写错不报错
官方给 Auto Router 挂了两个 slug:openrouter/auto 是正式轨,像普通模型 slug 一样用,把它填进 model 就够了;openrouter/auto-beta 是早期接入轨,新的路由行为会先落在这里,再进入正式轨。
坑在这句 Warning 上:每个 slug 只读自己那个插件 id 下的设置。正式轨用 auto-router,beta 轨用 auto-beta-router。如果你把 model 换成了 openrouter/auto-beta,插件 id 却还留着 auto-router,官方说这些设置”会被接受但静默忽略”——allowed_models、excluded_models、cost_tier 三个字段全部不生效。注意”被接受”这个词:请求不会报错,你拿到的是一个看起来完全正常的响应,只是你的路由约束根本没参与决策。所以从正式轨切到 beta 轨时,插件 id 是必须一起改的第二处。
怎么确认它到底选了谁
最省事的办法是看响应里的 model 字段。Auto Router 的响应结构和普通请求一样,model 里放的是实际被选中的那个模型,不是你请求时填的 openrouter/auto。官方给的三份示例代码(TypeScript SDK、fetch、Python)末尾都特意加了一行打印 completion.model / data['model'],就是为了这件事。做批量任务时把这个字段跟结果一起落盘,路由决策才是可追溯的。
想看得更细,就开 router metadata。这是一个按请求的 opt-in 开关:发 X-OpenRouter-Metadata: enabled 请求头(官方说旧的 X-OpenRouter-Experimental-Metadata 也仍然被接受,默认值是 disabled,以官方文档当前版本为准),响应里会多出一个 openrouter_metadata 对象。这里面对排查路由问题最有用的几个字段是:
requested:客户端发过来的模型 slug 或别名,官方注明它可能和实际服务请求的模型不同——用 Auto Router 时这里就是openrouter/autostrategy:本次用的路由策略,官方列出的取值有direct、auto、free、latest、alias、fallback、pareto、bodybuilder、fusion(以官方文档为准)attempt:从 1 开始计数的”第几次尝试成功”,大于 1 就意味着前面的尝试失败并 fallback 了endpoints:本次考虑过的候选 endpoint 快照,以及哪一个被选中summary:一句人类可读的路由结论,比如候选数量和被选中的供应商pipeline:真正改动过请求或响应的插件阶段列表
要看分类结果落在哪个任务类型上,官方指的正是这个 pipeline:opt-in 之后,router 阶段会在 data.task_type 上带出标签,比如 code:debugging;分类不可用时这个字段直接缺席。顺带记两条容易踩的读取规则:流式请求的 openrouter_metadata 是在 data: [DONE] 之前的最后一个 chunk 上给的;而缓存命中的响应永远不带这个字段,官方说这是有意为之,免得客户端拿旧的路由数据当依据。所以你如果连着几次都读不到 metadata,先想想是不是命中了缓存,而不是急着怀疑请求头写错了。缓存这一层本身的计费口径,可以对照API 缓存计费机制那篇看。
可控项一:把候选池收窄
allowed_models 是限制 Auto Router 能从哪些模型里选的字段,放在插件配置里,接受通配符模式。官方给的语法说明是:写成 anthropic/* 这种形式可以匹配某一家的全部模型,写成带星号的前缀可以匹配某个系列的全部变体,写完整 slug 则是精确匹配,星号也可以放在前面来匹配”任意供应商下名字里带某关键词的模型”。不配任何模式时,路由器会考虑该任务类型下的全部已排名候选。
excluded_models 是反向的排除名单,用的是同一套通配符语法。这里有一条顺序规则必须记住:排除是在 allowed_models 之后应用的,所以一个模型即使命中了允许模式,只要同时命中排除模式,就永远不会被选中。官方给的使用场景是合规限制、成本上限,以及”在你的任务上表现不好的模型”。
收窄是有代价的:如果你的限制把候选池清空了,请求会以 404 失败,报错信息官方写的是 No models match your request and model restrictions。这个报错和另一类”没有可用供应商”的报错不是一回事——后者是 provider.only 把供应商偏好卡死导致的,排查路径完全不同,可以对照 No allowed providers are available 的排查和模型不可用的区分方法两篇。
可控项二:成本档 cost_tier
cost_tier 是选”市场的哪一段成本带”来路由,官方从便宜到强的顺序列出的取值是 low、medium、high、xhigh、max。low 偏向”最便宜的够用模型”,max 偏向”不计价格的最强模型”。没有设置任何成本相关参数的请求,官方说会按大致相当于 low 那一档的方式路由(默认行为以官方文档当前版本为准)。
有一句话反直觉,得单独拎出来:档位是一条带,不是一个天花板。官方原文的意思是,比这一档更便宜的模型同样会被排除,不只是比它贵的被排除。所以选 high 不等于”上限抬到 high”,而是”就在 high 这一带里挑”。在你选定的档位内部,模型仍然按市场花费份额排序。
另外,cost_quality_tradeoff 属于上一代 Auto Router,官方标注为已废弃,但为向后兼容仍被接受;两个参数同时传时,cost_tier 优先。老代码迁移时不用急着删,但新写的配置没有理由再用它。
账号默认值与请求参数谁说了算
不想每个请求都带插件配置,可以在工作区的 Routing 页面保存账号级默认值,Auto Router 那一节存的是允许的模型和一个成本偏好。规则是:保存的值对每个 Auto Router 请求生效,除非该请求自己设了同名字段——这时以请求为准;但如果你打开了这一节的 “prevent overrides” 开关,保存的值就是最终值,请求覆盖不了。保存的值对 openrouter/auto 和 openrouter/auto-beta 同时生效。
这个”请求优先、除非锁定”的设计对团队场景很实用:想给全组兜一条底线(比如统一排除某些模型)就锁上,想让各项目自己调就别锁。
多轮对话为什么会换模型
Auto Router 和固定 slug 最大的行为差异在这里:它每一轮都可能选出不同的模型。为了让多轮对话不至于风格跳来跳去,路由器会记住这段会话上一次落在哪个模型上,并在后续轮次优先复用它。会话的识别方式是显式的 session_id,或者在你没传时用消息内容的指纹。
但复用是有条件的,官方说得很清楚:路由器每一轮仍然从头排一遍候选,只有当记住的那个模型仍然在本轮的头部候选里时才会复用它。一旦对话转向了另一类任务,更合适的模型就会赢过它。判断依据还是每次响应里的 model 字段。
会话同时还会把请求钉在同一个供应商上,这一套就是通用的 provider sticky routing:官方说它按账号、按模型、按会话三个维度追踪;不传 session_id 时默认用”首条 system(或 developer)消息 + 首条非 system 消息”的哈希来识别会话;粘性会话在闲置十分钟后过期,每次成功请求都会重置计时(以官方文档为准);如果粘性供应商返回了错误,缓存不会被更新,下一次请求就会重新路由。还有一条容易忽略的互斥关系:当你用 provider.order 手动指定了供应商顺序时,粘性路由不生效,你的显式排序优先。session_id 可以放在请求体顶层,也可以用 x-session-id 头传,两者都给时以请求体为准,官方对它的长度有上限约束,具体值见官方文档。都不设时,OpenRouter 会退回用 OpenAI 风格的 prompt_cache_key 字段当粘性键。
费用怎么算,能不能封顶
计费口径官方只有两句话,但很关键:你按被选中的那个模型的标准价付费,使用 Auto Router 本身不额外收费。也就是说这层路由不是一个加价服务,它省钱的方式是帮你把简单任务落到更便宜的模型上,而不是给你打折。
想给单次请求的花费封顶,官方指出 provider.max_price 仍然适用:它会对路由器解析出来的那些模型的 endpoint 做过滤。注意这和前面提到的两个”偏好类”参数性质不同——官方在供应商路由那一节明确说过,preferred_max_latency 和 preferred_min_throughput 只是让达标的供应商被优先,不保证也不会阻止请求执行,而 max_price 是会在价格不可得时直接阻止请求跑起来的。想做长期成本口径,可以配合 API 成本监控那套做法。
边界与同族路由器
官方列出的限制只有三条,都很短但都会影响接入方式:路由器要求用 messages 格式(不支持 prompt);流式是支持的;工具调用之类的标准能力跟着被选中的模型走。另外文档在别处提到一句,非推理模型和 openrouter/auto、openrouter/free 这类动态路由模型会省略响应里的 reasoning 字段——如果你的代码硬读这个字段,用 Auto Router 时要做好缺失处理。
顺带分清几个容易混淆的东西。models 参数(Model Fallbacks)是另一回事:你自己给出一个按优先级排列的模型 ID 数组,主模型的供应商宕机、被限流或因内容审核拒绝回复时,OpenRouter 自动试下一个。它是你指定名单,Auto Router 是它选名单。同族还有几个 slug 各管一摊:openrouter/free 是免费模型路由器,从可用免费模型里随机选一个,并会按你请求需要的能力(图像理解、工具调用、结构化输出等)做过滤;openrouter/pareto-code 面向编码场景,用一个最低编码分偏好来决定路由到哪一档模型;Latest Model Resolution 处理 latest 别名;Body Builder 把自然语言变成多个可并行执行的请求体。这几个 slug 各自的适用场景不同,别把它们当成同一个东西的不同开关。
最后:什么时候别用它
Auto Router 适合”你不知道用户会发什么样的 prompt”的通用场景,也适合让简单任务自动落到便宜模型上。但它的取舍也很明确:你放弃了模型的确定性。同一段 prompt 在不同时间可能落到不同模型上,因为排名是按滚动窗口从社区花费里算出来的,会随市场变化。如果你的系统对输出格式、tool call 行为或提示词适配有强依赖,稳妥做法是用 allowed_models 把候选池收到你验证过的范围内,再配合 session_id 稳住多轮,并把每次响应的 model 字段记下来。这样既保留了自动选择的好处,又不至于某天线上行为悄悄换了个模型你还不知道。
留言讨论
评论发布后会被人工复核,违规内容将被删除。
如果发表没有反应,可以前往联系我们告诉我们。