Jev Router 是什么:什么时候该路由,什么时候该死守 Jev 1.13

更新于 适用版本 Jev 1.13

OpenRouter 上挂着两个都叫 Jev 的 TypeSafe 条目,而它们不是同一个东西。一个是本站一直在写的判断模型 typesafe/jev-1.13——你问类型化的问题,它回概率。另一个是 typesafe/jev-router,它根本不回答你的问题,它决定由谁来回答,然后把位置让开。

这个区别值得单独写一篇,因为两者的失败方式正好相反。钉住 jev-1.13,你拿到的是机器可判的类型化答案,代价是它天生不擅长写散文式长回答和开放式推理。调 jev-router,你拿到的是某个被选中模型写的普通文本,而”选谁”这一步由 Jev 来做。用错工具,你会花一周时间跟一个本来就不负责这件事的东西较劲。

下面所有内容都来自 OpenRouter 官方 Jev Router 文档和 OpenRouter models API,读取时间是 2026-11-03。文中出现数字的地方,就是当天 API 返回的数字。

TL;DR:typesafe/jev-router 是个可以直接填进 model 的 slug:不装插件也能用,Chat Completions、Responses、Messages 三种形状都通,响应的 model 字段告诉你这次是谁答的。只有要传 cost_tier(low/medium/high)、包含偏好(models / allowed_models)或硬排除(excluded_models)时才加那个可选的 jev-router 插件。包含是软的——候选池空掉时会回退;排除是硬的。cost tier 只是路由偏好,不是固定模型,不保证分数,也不是单次请求的价格上限。需要能 if 判断的类型化结果,就去钉 jev-1.13;路由器解决的是「一批普通生成请求,怎么控成本」。

两个产品,一个名字

先看各自返回什么,因为这决定了后面所有工程选择。

Jev 1.13(typesafe/jev-1.13)Jev Router(typesafe/jev-router)
返回什么类型化判断:选中的答案 + 概率被选中模型写的普通文本
谁组织答案Jev 自己路由器选出来的那个模型
你发什么状态 + 按判断题/选择题/打分题措辞的问题普通的 completions / responses / messages 请求
类型化输出决策 JSON由服务模型自己决定
适合什么分支逻辑、闸门、打分、代码内部的路由决策一个端点接一堆模型,配成本策略和偏好
模型在哪确定你自己在配置里钉死由响应里的 model 字段告诉你,每次请求决定

目录数据也印证了这个分野。2026-11-03 我读 models API 时,typesafe/jev-1.13 条目报的输出模态是 decisions,端点信息里上下文 262,144 tokens、最大补全 235,929 tokens。typesafe/jev-router 条目报的是文本输出、上下文 1,000,000 tokens、最大补全 65,536 tokens,输入支持 text / image / file / audio / video——而 endpoints 数组是空的,因为它背后没有某一个固定 provider。

还有一条要多说一句:路由器的 pricing 里 prompt 和 completion 都是 -1。也就是说路由器本身没有公布按 token 计的固定费率——你付的是它选中的那些模型的钱。它不是一张独立价目表,而是包在别人模型外面的一套决策流程。做预算要对池子里的模型做,不要对着一个”路由器费率”做。

路由器到底在决定什么

OpenRouter 把机制拆成三步。

评估请求。 Jev 读对话,判断这个任务需要什么。这就是判断模型在做它本职的事:判断请求的形状和难度,而不是生产输出。

选模型和推理强度。 路由层按当前的 cost 策略、候选模型的能力,以及你设的模型/供应商限制来选。这里的 effort 指的是 reasoning effort,只对暴露这个参数的模型有意义。

跨轮次自适应。 在支持的 agentic 工作流里,路由器可以在任务推进过程中保留同一个模型、调整强度,或者换模型。策略允许时,还能拉一个 expert advisor 来协助干活的模型。

文档里有两句提醒,能挡掉大部分错误预期。第一句:可用的模型和路由策略会随时间变化。第二句更要紧:cost tier 是一种路由偏好,不是固定模型、不是保证的分数、也不是单次请求的价格上限。真要硬性控花费,靠路由器档位做不到——那需要用账户级的 spend limit,或者干脆钉一个固定模型。

两种请求写法

最省事的接法完全不用插件,把 slug 填上就发:

curl https://openrouter.ai/api/v1/responses \
  -H "Authorization: Bearer $OPENROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe/jev-router",
    "input": "Explain the difference between a mutex and a semaphore."
  }'

响应里的 model 字段就是这次实际服务的模型。Chat Completions、Responses、Messages 都能用,流式和非流式都行,所以你现有的客户端不用换 SDK。

第二种写法是加插件,让路由配置跟着单次请求走:

curl https://openrouter.ai/api/v1/responses \
  -H "Authorization: Bearer $OPENROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe/jev-router",
    "plugins": [
      { "id": "jev-router", "cost_tier": "medium" }
    ],
    "input": "Summarize this incident report."
  }'

插件参数:

参数类型行为
idstring必填,必须正好是 "jev-router"
cost_tierstring"low"、"medium"、"high";不写则用 Jev 的默认路由策略
modelsstring 数组带兜底的包含偏好,在动态池选择之前生效
allowed_modelsstring 数组models 的别名,同样的兜底行为;两个字段的条目会合并
excluded_modelsstring 数组硬排除。匹配到的模型永不被选中,包含回退时也一样

除 id 外全部可选。未知字段和非法值一律返 400——文档举的例子是 allowed_model(少了 s)不被当作别名接受。这种拼写错误很贵,好在它是大声失败而不是默默降级。

cost tier 的实际含义

档位意图
low优先压估成本
medium在估成本和能力之间平衡
high当预期收益值那份钱时,优先更强的模型

cost_tier 选的是路由策略,不是模型的 reasoning effort——这是两个独立的旋钮,文档写得很明确。你在模型和供应商上设的限制,仍然叠在档位之上生效。不写 cost_tier 等于接受默认策略;想明确用平衡策略就写 "medium"。写了个不认识的档位名,返 400。

有一个后果需要在设计阶段就吃掉:换档位可能在同一段对话里换掉模型。如果你的应用默认”风格和输出格式跨轮次保持稳定”,逐轮改档位就会打破这个假设。除非你确实想要这种切换,否则档位按工作流定,不要按单次调用定。

模型偏好:包含是软的,排除是硬的

真正容易搞错的语义都在这一节。

models 和 allowed_models 是带兜底的包含偏好,不是硬白名单。路由器先在合并后的包含集合里组一个可路由的池子;池子空了,它会不带包含列表重试一次。所以 models: ["anthropic/*"] 是「偏好 Anthropic」,但包含列表把候选筛空时会退到别的作者那里。文档原话是:不要用包含列表来强制实现作者限制。

excluded_models 正相反——硬限制,两次尝试里都保留。由此直接推出两种失败方式:

对动态池来说,这些过滤在排序和池子上限之前生效。所以排掉一个排名靠前的模型,可能正好给另一个合格模型腾出位置。包含从不绕过程序的资格检查、端点策略、能力或 token 预算;显式指定的 operator pool 和内置池保持它们配置好的成员。

还有一个会坑到调成本的人:列表可能把能力档位压下来。当请求本身需要比列表允许的更强的模型时,路由器可以降低自己的能力要求,这一步在 stage 里报成 list_tier_cap。它和 low/medium/high 那个 cost tier 不是一回事,混淆两者会让你去调错的旋钮。如果池子里一个合格模型都不剩,请求 404,错误信息会点出你发的字段,并给出 widen allowed_models 或 remove excluded_models 这类提示。

通配语法和它的边界

偏好列表里的每个条目可以是四种东西之一:

尺寸限制文档也给了:每个列表最多 1,024 个模式,每个模式最多 1,024 个字符,每个列表总计 65,536 个字符。最容易踩的是大小写——*Flash* 和 *flash* 是两个不同的模式,只有一个小写 slug 会命中后者。

推理强度只是提示,不是设置

路由器正常自己决定 reasoning effort。你可以传标准的顶层 reasoning.effort 当提示,它和 cost_tier 相互独立:

{
  "model": "typesafe/jev-router",
  "plugins": [{ "id": "jev-router", "cost_tier": "medium" }],
  "reasoning": { "effort": "high" },
  "input": "Analyze the tradeoffs in this design."
}

Chat Completions 上还接受旧的顶层 reasoning_effort。但路由器可以改选别的强度,也可以跨轮次调整,所以提示不保证最终发给模型的设置就是它。另外两个字段直接被拒:reasoning.max_tokens 和 reasoning.mode: "pro" 都返 400。如果你的配置里设了这两个,指向路由器之前先删掉。

看清路由器做了什么

一个静默换模型的路由器是没法排障的,所以 OpenRouter 把决策暴露出来。响应的 model 字段是标题答案。带上 X-OpenRouter-Metadata: enabled 头,openrouter_metadata.pipeline 里那条 jev-router 记录会有这些:

字段含义
resolved_models路由器选中的模型,按兜底顺序
candidates候选,含 model、effort、能力 tier、estimated_cost;估算是估算,不是最终账单
reason策略选择或保留这条路由的原因
pipeline"default" 或 "agentic"
advisor_model选出 advisor 时的那个 advisor
models、excluded_models实际应用的列表;models 里含 allowed_models 的条目
list_fallback包含列表匹配到目录模型、但没匹配到池内模型时为 "models_ignored"
list_tier_cap列表下调请求档位时,被压到的那个档
max_fallback本该有 advisor 的请求最终没有 advisor 时为 "deep"

做账的人要注意那句:candidates 里是估算,估算不是最终计费成本。要对账请看实际的 usage 记录,别把路由器的估算加起来当账单。

实操建议:灰度期间把每次路由调用的 model 和 reason 都记下来。几周后有人问「为什么这请求变贵了」「为什么语气变了」,能回答的就是 reason 这个字段——而事后是重建不出来的。

可用性、报错,和那条区域限制

有三条限制比上面所有参数都更早生效。

只有 global 数据区。 Jev Router 只在 global 数据区可用,而且要工作区允许。用区域路由的请求属于文档列出的 400 情形之一。

路由器权限 + 被选模型的权限。 你既要能访问路由器,也要能访问被选中那些模型。池子里塞满你的工作区调不动的模型,表现出来是失败,不是优雅降级。

不要叠加路由器。 typesafe/jev-router 不能和另一个路由器模型放在同一个请求里,否则 400。实践意义就是:不要在一次调用里同时套 Jev Router 和 auto router 或作者路由。

状态码文档给出的例子
400未知 cost tier 或插件字段、不支持的 reasoning 设置、区域路由、叠加路由器模型
404应用模型偏好和请求要求之后没有合格模型了,或者你没有路由器权限
503Jev Router 不可用

503 当瞬时故障处理——路由器自己挂了不是你请求体的问题。404 当配置问题处理,先查偏好列表和权限。400 当自己写的东西处理,改一版就能修。

作者路由器

还有第二种吃到 Jev 路由的方式:目录里有时会提供 openai/auto、anthropic/auto 这类 <author>/auto 模型,它们用该作者的模型跑 Jev,池发现、任务策略、推理强度和 cost tier 都和 Jev Router 一致。

两条性质要拎清。第一,作者范围是硬限制:调用方的 models / allowed_models 仍然是带兜底的包含偏好,excluded_models 仍是硬限制,三者都在该作者的池子内部运作。包含筛空时,Jev 在同一作者范围内不带包含重试,排除照旧执行;某个作者没有合格模型就返 404。第二,范围限定的是模型作者,不是 provider——一个 OpenAI 模型仍可能由 Azure 之类的 provider 提供。要限 provider 是另一个设置项。

openrouter/auto 是另一个路由器,不走这套作者别名逻辑。别名也是目录产物:一个别名需要目录里自己有对应行,私有的还需要你对那一行的访问权。API 不会按需创建别名,所以你不能靠提要求造一个自己的 yourauthor/auto。

什么情况下路由器是错的工具

有三种场景,钉 jev-1.13 才是对的答案,而且不是”保守”地对。

你要一个能 if 的类型化判断。 如果代码写的是 if answer.confidence > 0.8 then act,一个返回散文、还是随机模型写的散文的路由器毫无用处。判断模型存在的意义就是让文本不需要被解析。路由器不产出判断,它产出文本。

你需要跨批次可复现。 打分、审核、重排这类管线要比较不同时间的结果。路由器的公开行为——模型和策略会变、档位能在同一段对话里换模型——正好是评分卡和基准测试最怕的。钉死 slug、钉死问题措辞,任何变化都当作一次有意的迁移。

你需要单次请求的硬价格天花板。 档位只是偏好,文档自己这么说。预算控制该放在账户级(spend limit)或模型级(固定一个更便宜的 slug),不该放在一个路由偏好里。

反过来,路由器值回票价的时候是这样:你的负载很杂,又不想为每个任务手动选模型——一个端点、一个客户端、一套会随任务难度调整的策略,需要时再用偏好把某个工作流圈在某个家族里、或者隔开某个贵的家族。

一份安全的灰度清单

  1. 先确认 slug。 上线前在 OpenRouter 模型页读一遍 typesafe/jev-router。slug 和模型池都会变。
  2. 先只写模型。 不装插件、不加偏好。确认响应里的 model 字段有值,并且你的下游解析能容忍这个值变来变去。
  3. 再加 cost_tier, 一次一个工作流,并记录每个工作流用的哪个档。别让两个工作流不小心共用一个档位常量。
  4. 开 metadata 日志(X-OpenRouter-Metadata: enabled)至少一周,持久化 model、reason、candidates[].tier、list_fallback。这是你唯一的现场记录。
  5. 偏好最后加,而且优先用排除而不是包含。 排除是硬的,包含会静默兜底。意图是「永远不用这个模型」就用 excluded_models;意图是「偏好这个家族」就用 models 并接受兜底。
  6. 偏好一改就盯 404。 404 基本都是列表已经留不出合格模型,或者某个 slug 不再匹配了。
  7. 别叠加路由器。 一个请求一个路由器。需要作者范围就用作者别名,不要叠。

这份清单想挡的失败方式都很贵:包含列表静默兜底、档位在对话中途被换、以及因为当初没记 metadata 而完全解释不清的账单。

接下来读什么

如果你还在判断 Jev 是不是你要的那类工具,从 Jev AI 是什么 开始。已经决定了、只想把第一次调用跑通,第一次 API 调用 和 获取 API Key 是最短的路径。路由之前想先把成本账算清,看 成本与延迟;在官方渠道和 OpenRouter 之间犹豫,看 API 渠道怎么选。如果路由请求开始返你没见过的错误码,排错手册 是按症状组织的。

最后交代一句范围:本页描述的是 OpenRouter 在 2026-11-03 文档里写的路由器行为,没有对 TypeSafe 自己的直连端点做任何断言。如果官方 API 也暴露了路由器,那它的权威行为归 typesafe.ai 的文档,不归一篇第三方文章。

常见问题

+ Jev Router 和 Jev 1.13 到底有什么区别?

Jev 1.13(typesafe/jev-1.13)是判断模型本身:你给它状态和一个类型化的问题,它回一个带概率的类型化答案。Jev Router(typesafe/jev-router)是一层路由:你发一个普通请求,Jev 判断这活有多难,路由层决定由哪个模型、用多高的推理强度来回答。路由器回的是被选中模型写的普通文本,不是类型化判断结果。

+ 用 Jev Router 必须装插件吗?

不必。把 model 设成 typesafe/jev-router 就能用。jev-router 插件是可选的,只有你要传路由配置(cost_tier、models、excluded_models 之类)时才需要。插件的 id 字段必填,值必须正好是 jev-router。

+ Jev Router 里的 models 列表是硬性白名单吗?

不是。models 和它的别名 allowed_models 是「带兜底的偏好包含」:路由器先在合并后的包含集合里找可路由的候选池,池子空了就不带包含列表重试一次。真正的硬限制是 excluded_models,两次尝试里都强制执行。想限制模型作者,别指望用包含列表来做到。

+ 为什么路由器有时直接返 404,而不是给我挑一个模型?

404 的意思是:按你的偏好和请求自身的要求筛完之后,池子里没有可用的模型了;或者你的工作区没有这个路由器的权限。文档里点明的两个具体场景:包含列表里的条目匹配不到目录中任何公开文本模型时会直接 404 并指出是哪个字段;excluded_models 把池子里的模型全排除掉时也返 404,而不会硬塞一个被你排除的模型。

+ 怎么知道路由器最后用了哪个模型?

看响应的 model 字段,它写的就是这次实际服务的模型。要更多细节就带 X-OpenRouter-Metadata: enabled 头,然后读 openrouter_metadata.pipeline 里那条 jev-router 记录:resolved_models、每个候选的 model/effort/tier/estimated_cost、策略给出的 reason、pipeline 模式,以及选出 advisor 时的 advisor_model。

继续阅读