Jev 1.14 版本说明:Box 题目、图片输入与长上下文
TL;DR: Jev 1.14 于 2026-10-14 发布,模型 ID 为
jev-1.14.0。官方更新日志只写了四条:多语言支持改进、新增 Box 题型(在图片里定位目标并返回边界框)、图片可以放进state/instructions/criteria、以及一个把两个上下文上限同时抬到 262k 的长上下文请求头。其中图片和长上下文在 1.13 上同样可用,只有 Box 是 1.14 独占。价格没变:每十亿输入 token 42 美元(每百万 0.042 美元),输出 token 免费;默认上下文仍是每请求 64k、每问题 32k。图片和 Box 被官方标为 Dreamer-ready——只适合做原型,格式随时可能变。
这页之所以单独存在,是因为 1.14 一次动了两件事:多出一个原语,同时图片输入第一次成为可能。这两件事合在一起,会让本站所有纯文本页面上的若干默认假设失效。所以下面的写法是分层的:官方到底说了什么、新东西的请求与响应长什么样、以及一个钉在 1.13 的部署需要动哪些地方。
本文所有事实来自两个在 2026-11-04 实际读取的来源:TypeSafe 官方文档(更新日志、models 页、Box 页、图片页),以及 OpenRouter 的模型接口 GET /api/v1/models/typesafe/jev-1.14/endpoints。两边数字不一致的地方,本文把两个值都摆出来并点名分歧,不做平滑处理。
官方更新日志:四条,没有第五条
1.14 的更新日志就是四行。全部改动如下:
| # | 改动 | 生效范围 |
|---|---|---|
| 1 | 模型 ID 变为 jev-1.14.0 | 仅 1.14 |
| 2 | 多语言支持改进 | 仅 1.14——官方未公布任何按语言的数字 |
| 3 | 新增 Box 题型:在图片里找目标,返回边界框 | 仅 1.14 |
| 4 | 图片可放进 state、instructions、criteria | 1.14 与 1.13 |
| 5 | 长上下文把两个上下文上限抬到 262k | 1.14 与 1.13 |
第 4、5 条最容易被误读。它们不是 1.14 的新功能——日志在宣布它们的那句话里就写了「This also works on Jev 1.13」。也就是说,如果你钉在 1.13,只想用图片输入或更长的上下文,你根本不需要升级版本。只有 Box 是必须 1.14 的。
1.14 在哪两个渠道上
同一个模型,两条路:
- 官方 API。
POST https://api.typesafe.ai/v1/systemone,model填jev-1.14.0,或者填别名jev-latest(官方 models 页明确写它指向jev-1.14.0)。这就是渠道对比教程里视为权威来源的那条 TypeSafe 直连通道。 - OpenRouter。 版本化 slug 为
typesafe/jev-1.14,模型页返回 200,端点接口里只有一条 TypeSafe 自建的端点,名为typesafe/jev-1.14-20261014。
OpenRouter 这条记录值得细看,因为它的数字和官方 models 表并不完全是一回事:
| 字段(OpenRouter 端点接口,2026-11-04 实测) | typesafe/jev-1.14 | typesafe/jev-1.13 |
|---|---|---|
| 端点名 | typesafe/jev-1.14-20261014 | typesafe/jev-1.13-20260917 |
| 提供方 | TypeSafe | TypeSafe |
context_length | 262144 | 262144 |
max_prompt_tokens | 262144 | 262144 |
max_completion_tokens | 235929 | 235929 |
pricing.prompt(每 token) | 0.000000042 | 0.000000042 |
pricing.completion | 0 | 0 |
uptime_last_1d | 100 | 100 |
| 输入模态 | text + image | text + image |
| 输出模态 | decisions | decisions |
把 pricing.prompt 换算过来是每百万 prompt token 0.042 美元,和官方那句「$42 / Btok、$0.042 / Mtok」完全对得上。
上下文那一栏才是真正需要小心的地方:OpenRouter 对两个版本都报 262,144,而官方 models 页写的是默认每请求 64k、每问题 32k,只有带上长上下文请求头才是 262k。两种说法可以同时成立——如果 OpenRouter 列出的是天花板而不是默认值——但这是推断,两个来源都没这么写。结论不受影响:第一版请求按 64k 来算,要更多就显式加请求头。 不要因为列表写 262k,就假设 20 万 token 的请求在默认状态下能跑。
改动一:多语言「更好」,但「更好」没有数字
日志的原话就是「Better multilingual support」,然后结束。没有按语言的准确率表,没有样本量,没有前后对比,也没有说具体是哪些语言变好了。任何现在给你一张 1.14 多语言排名表的文章,都是编的。
能拿来行动的,是文档一直在用的那套说法:英文是主要训练语言、当前准确率最好;其他语言(包括中日韩文字)能用,但表现并不对等;非英语负载必须在你自己的内容上测。1.14 只把第一句往「没那么差」的方向挪了一点,并且没给你任何量化的手段。
所以对多语言流量来说,唯一负责任的迁移动作是做一次测量,而不是升一个版本号。本站的语言支持教程已经把流程写死:按语言分层抽取你自己的真实生产样本,用你自己的业务专家打标签,把同一批问题在 1.13 和 1.14 上各跑一遍,并排比较一致率与置信度分布,而不是混在一起看平均。如果你的中文审核队列在 1.13 下和人工标注的一致率是 88%,那么关于 1.14 唯一有意义的问题就是:这个数字现在是多少。
还有一个坑必须点名:不同版本之间的 confidence 不能直接比。 如果 1.14 在同一批输入上报出更高的置信度,那恰恰是会让 1.13 上调好的阈值「该升级却直接放行」的那类漂移。置信度兜底教程里反复强调「阈值放配置、不要写死在代码里」,就是为了这一刻。
改动二:Box——唯一真正的新原语
Box 是本站开站以来覆盖的那三个原语之外,第一次出现的题型。判断题返回 yes/no/unclear,选择题返回一个选项,打分类返回一个刻度上的位置;而 Box 返回的是位置:目标在图片里的矩形四条边。
请求结构
Box 只有两个字段,而且没有 criteria:
type:字符串"box"。instructions:找什么、在哪张图里。官方明确说这不一定要写成疑问句——"the coffee mug in photo"就是一条完整指令。
因为不需要 criteria,Box 是唯一一个除了指令之外没有任何可调参数的原语。好处是发起来极便宜,代价是很难调:目标是什么全部压在一句话里。
响应结构
{
"model": "jev-1.14.0",
"answers": {
"mug": {
"type": "box",
"box": { "top": 0.25, "bottom": 0.82, "left": 0.44, "right": 0.84 },
"confidence": 0.92
}
},
"usage": { "input_tokens": 290, "output_tokens": 21 }
}
这四个数是占图片宽高的比例,从左上角起算,不是像素。left/right 是宽度的比例,top/bottom 是高度的比例,恒有 left < right、top < bottom。这一条就是会让粗糙集成翻车的地方:{left: 0.44, right: 0.84} 在一张宽 1600px 的图上意味着 x 从 704 到 1344;乘错维度,你得到的裁剪框形状对、位置全错。
官方给的示范就是裁剪:每个边乘对应的宽或高、取整,得到一个四元组交给图像库。文档里还有一个很实用的防御式写法——当裁剪绝不能切掉目标时,先把每个边往外推一点再裁,并夹在 0–1 之间。
Box 表达不了的那个失败态
**Box 永远返回一个框。**它没有「没找到」这种答案。在一张根本没有杯子的图上问杯子在哪,你依然会拿到四条边,而答案里没有任何字段告诉你目标并不存在。官方给的解法是同一个请求里再问一个 Noul——「photo 里有没有咖啡杯?」——当 Noul 概率很低时把 box 丢掉。同一个请求里的所有问题共用同一份 state 且彼此独立并行,所以这多问一句的代价只是一点点 token,不增加往返。
另外两条操作性约束:
- 一问一框。 Box 只找一个目标、只返回一个框。要找几个不同的东西,就在同一个请求里发几个 Box 问题。如果图里可能有多个同类目标,要么把你要的那一个描述到只有它符合,要么在 Box 旁边加一个选项为
none/one/several的选择题;答案是several时,先把图切块再逐块问。 - 找小东西先切图。 一张很大的图里,一个只有几十像素宽的目标可能被漏掉。官方推荐的两段式:先用一个选择题定位区域(选项是图的各个切片),再在那个切片上问 Box,最后把它的边换算回整图的比例。
门槛与上线姿势
Box 需要 Jev 1.14,也需要把图片打开。两个都是开关,不是默认:
- 每个含图片或 Box 的请求都必须带
TypeSafe-Danger-Zone-Images: true。不带直接400。 - 官方 API 上
model填jev-1.14.0(或别名jev-latest),OpenRouter 上填typesafe/jev-1.14。用 1.13 的模型去答 Box 题,不是受支持的组合。
改动三:图片可以放进 state、instructions、criteria
图片支持是更大的那个改动,而且 1.13 与 1.14 都有。图片可以放在任何文本能放的地方:state 里、某一道题的 instructions 里、以及 criteria 里。所有题型都接受图片,不只是 Box。
机制是请求顶层的一个 assets 映射,键是引用字符串。你把引用写进图片该在的位置——可以是整个值,也可以嵌在一句话中间——模型就在那里收到图片。官方那个三合一的示范很能说明问题:门铃照片作为 state 的一个值、工牌照片直接塞进某个 Noul 的 instructions、缩略图作为某个选择题选项的 criteria 描述。
资源字段
| 字段 | 含义 |
|---|---|
type | "image"。可选;写了就必须是这个值。 |
part | multipart 请求里承载该图片的文件段名。与 data_base64 二选一。 |
data_base64 | 文件内容,标准 base64 字母表、带 = 填充、无空白、无 data: 前缀。 |
format | "png"、"jpg" 或 "jpeg",小写。配 data_base64 时必填。 |
每张图只用一种方式发。如果某个资源同时有 part 和 data_base64,API 会用 part。
引用规则:400 的主要来源
- 每个资源都必须被引用。 有一张图没在任何地方被引用,整个请求
400。没有部分答案——一张图出问题,全部失败。 - 每引用一次就多传一份图。 文件只上传一次,但引用出现的每一个位置都会再给模型一份副本,每一份都计入「展开后请求」的体积上限。
- 引用是纯文本匹配。
cat这样的引用会命中category里的字符串。官方建议每张图每次请求用一个新 UUID——SDK 已经替你这么做。 - 对象键不会被替换。 选择题的选项名、题目 ID 永远是文本;想给某个选项配图,把引用写在该选项的描述里。
- 答案里回传的是引用,不是图片——如果打分类的
legend会把你的 criteria 原样带回来,别指望那里有图像数据。 - 引用长度:单条上限 1,024 字节,一个请求内所有引用合计上限 65,536 字节。
限制
| 限制项 | 取值 |
|---|---|
| 格式 | 仅 PNG 或 JPEG 静态图;动态 PNG 被拒 |
| 单文件大小 | 16 MiB(base64 按解码后算) |
| 边长 | 每边 280–1568 px,任一边低于 280 直接被拒 |
| 总像素 | 78,400–2,458,624(相当于 280×280 到 1568×1568) |
| 请求体 | 32 MiB,含 JSON、base64 文本与 multipart 分帧 |
| 所有去重图片 | 经 API 重新编码后合计 32 MiB |
| 展开后请求 | 所有引用替换成图片后 32 MiB |
两个后果要提前想清楚。第一,重新编码可能让图片比你发的文件更大,所以一批小图也可能顶爆合计上限。第二,不做等比缩放——超出范围直接拒,不会帮你缩。官方建议:最长边缩到 1568 px 以内、把像素本身转正(EXIF 方向会被丢弃而不是应用)、把 GIF/WebP/HEIC 转成 PNG/JPEG、并优先用 baseline JPEG 而不是 progressive。
文档明确说 multipart 优于 base64:base64 会让每张图大约胖三分之一,而这份膨胀同样计入 32 MiB 的请求体上限。图片 token 按和文本相同的输入单价计费,响应里的 usage.input_tokens 已包含它们。
失败码
| 状态 | 原因 |
|---|---|
400 | 用了图片但没有 TypeSafe-Danger-Zone-Images: true 头 |
400 | 图片或资源被拒:格式不对、损坏、动态、低于最小边长、未被引用、base64 或 format 非法、引用为空 |
400 | max_tokens_exceeded——图片加文本超出该请求的上下文长度 |
413 | 超出体积限制:单文件、边长、总像素、请求体、全部图片、展开后请求,或引用长度 |
改动四:长上下文,262k 藏在一个请求头后面
长上下文默认关闭,1.13 与 1.14 都能用。打开的方式是每个需要的请求都带 TypeSafe-Danger-Zone-Long-Context: true;带上之后,每请求与每问题两个上限都变成 262k。不带就还是 models 表里的默认值。
文档在这件事上说得异常直白:长上下文的单价和普通请求一样,但它更慢、也更不准,所以应该按请求开,而不是全局开。对一条偶尔要吃进超长合同的批处理流水线来说,这意味着双层路径——普通样本走默认上限,尾部样本走带头的那条——而不是给每个调用都挂上。
要小心的理由,和本站反复讲的 state 体积问题同源:准确率会随着 state 变大而移动,文档自己指向 jaggedness 那页。为了不做切分而塞进 20 万 token 上下文,很可能在答案质量上亏掉的比切分省下的更多。
没有变的部分
看版本说明容易过度解读,所以这几条值得单独写明:
- 价格。 每十亿输入 token 42 美元(每百万 0.042),输出免费——官方页对 1.13 与 1.14 完全相同,OpenRouter 端点数据对两个 slug 也完全相同。
- 默认上下文。 每请求 64k、每问题 32k,没变。长上下文是选择性开启。
- 三个文本原语。 Choice、Score、Noul 的请求字段与答案结构照旧。
- 端点。
POST /v1/systemone依然服务所有模型,model决定谁上。没有单独的图片端点,也没有单独的 Box 端点。 - 输出 token 依然免费。 成本完全取决于你发了多少 state、多少问题、多少图片。
从 1.13 迁移到 1.14 的检查清单
顺序很重要,因为便宜的步骤应该先验证贵的那一步。
- 先决定钉版本还是跟别名。 钉
jev-1.13.0的话,你不改字符串就不会动。跟jev-latest的话,写这句话的时候你其实已经在 1.14 上了——不管你有没有察觉。官方 models 页写得很清楚:jev-latest指向jev-1.14.0,而jev-preview当前也指向同一个模型,因为没有预览构建。 - 把应答的模型记进日志。 每个响应都带
model字段,给出实际作答的版本化 ID。如果你是在 1.13 上调的阈值,这个字段是事后唯一能分清哪条历史记录来自哪个版本的东西。 - 动生产之前先重跑固定样本集。 冻结 20–30 条有代表性的输入,在 1.13 上记录答案和置信度区间,用同一批在 1.14 上再跑一遍做 diff。多语言流量请按语言分开看 diff——混在一起的平均值会把你真正要看的那个变化藏掉。
- 对着新的置信度分布重校阈值。 如果之前就分了语言,现在继续分开。一个在总量上看起来是「提升」的漂移,在某个语言里可能是回归。
- 版本字符串只在一处改。 如果 slug 同时出现在代码、配置和某个面板里,先把它们收敛成一个配置项,再翻版本。回滚应该是一行的事。
- 要用图片或 Box 就先做开关。 先在预发环境开请求头、先把「Noul + Box」配对加上(应对目标不存在的情况),并保留纯文本通路,确保一张被拒的图片不会拖垮原本好好的端点。
- 盯住 413 和合计上限。 重新编码会放大体积,测试环境过得了的请求,可能纯粹因为载荷大小在生产上失败。
诚实标注的未知项
有三件事没有公开,本文不会替它们编答案:
- 多语言准确率究竟改善了多少、在哪些语言上改善。 日志只说「better」,没有任何测量。
- 两个版本之间的 confidence 是否按同样方式校准。 两次发布都没有公布校准数据。
- OpenRouter 那个 262,144 到底是强制默认,还是长上下文的天花板。 官方 models 页说默认 64k,端点接口报 262,144,没有任何一处说明 OpenRouter 这条路上该按哪种理解。
这三件都在你自己的流量上测。关于置信度、阈值和语言质量,本站一直就是这个建议;一次版本号变化并不改变这一点。