Jev 的语言支持:英文最佳、CJK 可用,但必须在你自己的语料上验证
一句话结论: models 页给语言支持只留了一段话,而且完全不是营销话术——英文是主要训练语言、其他语言「能用但并不对等」,文档自己给出的补偿手段就是 Confidence。本文把这段指令拆成四步:先建按语言分层的验收测试,再看置信度分布而不是只看一个准确率数字,然后给每种语言单独设阈值,最后在第一次低置信度的中文请求到来之前就把降级链路定好。
官方文档到底写了什么
两个页面给出了同一个事实,而且互相一致。
Models 页有一段标题为 Language support 的原文:
Jev accepts natural-language text. English is the primary training language and where accuracy is currently best. Other languages, including CJK scripts, are handled but not equally well; test on your own content before relying on Jev for a non-English workload, and pay close attention to Confidence when routing.
(译文:Jev 接受自然语言文本。英文是主要训练语言,也是目前准确率最好的语言。其他语言,包括 CJK 文字,是可以处理的,但表现并不对等;在把 Jev 用于非英语负载之前,请在你自己的内容上测试,并在做路由时特别留意 Confidence。)
State 页在描述 state 可以放什么的那条警告里,重复了同一个限制:
Jev’s primary training language is English; other languages, including CJK scripts, are accepted but currently have lower accuracy.
(译文:Jev 的主要训练语言是英文;其他语言,包括 CJK 文字,被接受,但目前准确率更低。)
三条推论,只要你的流量不是纯英文,就没有一条可以跳过。
- 语言是一个路由参数,不是部署细节。 文档没说一句「支持」就结束,它同时说了「准确率更低」和「用 Confidence 来兜」——补偿手段是写在同一句话里的。
- 官方没有按语言的准确率表格。 models 页只给了一段话就结束。任何网站递给你一张带百分比的「支持语言排名」,那些数字都不是厂商公布的。
- 文档给出的解法是流程性的。「test on your own content」是一条让你去建测试的指令,不是让你去读兼容性清单。
必须先说清本文做不到什么:它无法告诉你 Jev 在你的语言上表现如何,因为这取决于你的 state、你的问题措辞,以及你怎么定义「正确答案」。它能做的是让你自己的测量变得便宜、可重复。
「被接受」不等于「一样准」
假设你把一条中文客服消息放进 state,然后问一个带四个路由选项的 Choice。你会拿回:被选中的选项、每个选项各自的概率、以及一个 0 到 1 的 confidence —— 这正是 Choice 和 Confidence 文档描述的契约。响应里没有任何字段会告诉你输入不是英文。
这种「外形一致」就是陷阱所在。响应的结构与语言无关,响应的质量不是。换掉输入语言,会同时动到三个量,而它们的方向并不一致:
| 量 | 是什么 | 换成另一种语言之后 |
|---|---|---|
| 准确率 | 选中的答案与业务专家会选的答案一致的频率 | 可能下降,降多少只有你自己的测试能回答 |
| 校准度 | confidence 0.9 是否还意味着「大约十次对九次」 | 可能漂移,于是按英文调好的阈值不再承载原来的含义 |
| 分布 | 有多少比例的请求落在「想转人工」的中间带 | 通常会摊开,而这恰恰是文档让你拿来路由的信号 |
第三行是最常被团队跳过的一行。一个准确率低 12%、但把这种下降如实体现为更平的概率分布的模型,远比一个准确率同样低 12%、却在同样面值的置信度上不动声色的模型好相处。Jev 之所以在返回答案的同时返回 probabilities,就是为了把这种形状暴露出来——所以面对一个表现较弱的语言,诚实的反应不是「那别用」,而是「给它加闸」。
为什么文档让你在非英语场景盯住 Confidence
confidence 不是额外的模型调用,也不是你要自己算的字段。它由答案里本来就有的概率分布推导出来:所有概率都压在某个结果上时是 1,均匀摊开时是 0。Choice 带的是选项上的分布,Score 带的是有序等级上的分布。Noul 是例外——它没有单独的 confidence,因为它那一个概率 p 本身就是不确定性,取值接近 0.5 就意味着模型不确定。
正是这个机制,让文档可以把置信度当作语言差距的补偿手段交给你:它是从分布算出来的,不是从措辞算出来的,因此只要返回值里还有分布,它在哪种语言里都还成立。
Confidence 文档给出的三档,是最小可用的形状:
- 高置信度 —— 直接自动执行。
- 中置信度 —— 谨慎处理:请用户确认、标记复核,或补充信息。
- 低置信度 —— 不要执行:转人工、要求澄清,或降级到另一套系统。
置信度门控路由那篇文档强调阈值从来不是一个数字:风险越高的动作,门槛越高;它那个银行场景的例子直接把低于某条线的请求全部转人工。放到非英语负载上,规则再往前一步——门槛既要按动作分,也要按语言分,因为你正在取阈值的那个分布本身已经移动了。
换成第二语言后,最咬人的几个「锯齿」
Jev 1.13 自己的锯齿页(最后复核于 2026-10-02)列了九个已知失效模式。它们都不是语言专属的,但其中几个会和一个模型处理得较弱的外语相互作用,而这几条就是最该优先设计的。
| 失效模式(文档原文) | 文档怎么说 | 为什么非英语负载更明显 |
|---|---|---|
| 字面理解 | 「回答你写下来的问题,而不是你想问的问题」;限定词、否定和隐含条件都按字面读 | 任何在翻译里被抹平的委婉、否定或语气词,都会被照字面执行 |
| 指令与 criteria 互相矛盾 | 当 instructions 与 criteria 要求的方向不一致,模型会被绕晕 | 指令一种语言、state 另一种语言,天然就是持续漂移的温床 |
| 计数 | 「不能可靠计数」,且误差随被数对象的规模增长 | 这条与语言无关——那就一次在代码里修好,对所有语言生效 |
| 塞满无关内容的大 state | 无关细节「起到干扰项的作用」,准确率因此下降 | 你扫不快的外语长文,正是最容易不加筛选被整段贴进去的东西 |
| 多层间接 | 双重否定与需要多跳推理的问题都会损失准确率 | 翻译过来的双重否定,就是信号更少的双重否定 |
| Choice 选项顺序 | 把选项换序,检查答案是否仍然一致 | 测试成本极低,值得按语言各测一次 |
| 日期与时间比较 | 日期按文本读,不按有序量读;格式混用时更差 | 多语言内容里混格式日期非常常见 |
| 数学与数字 | 「不是计算器」;Score 的等级在数值校准上偏弱 | 一切算术与插值都留在代码里 |
| 对抗性内容 | state 默认不被当作敌对内容处理 | 置信带越宽,筛查质量越重要 |
其中两行值得单独展开,因为它们是你能百分之百控制的两行。
关于字面理解:文档给的修法是「把确切条件写进 instructions」,把边界情形写进 criteria,并且——当你发现自己在解释「我其实想说的是……」时,那句解释就是指令缺失的那一半。在双语管线里,这条建议会更锋利:如果指令用英文写、state 是中文,你等于在每一次判断里插了一个翻译环节。让指令与你要评判的内容使用同一种语言,就等于把这一环拿掉,而且不花任何成本。
关于指令与 criteria 矛盾:文档给的例子是一个 true 表示「否」的 Noul。与其引用布尔值,不如把 criterion 写成映射关系一目了然的样子,并让 criterion 与 instruction 一直对齐到读起来像同一句话。这件事值得按语言各做一遍——一句在英文里读来精确的 criterion,翻译之后可能读来含糊。
第 1 步:在你自己的数据上建按语言的验收测试
这一步就是文档要求的那一步,也是几乎没人做的那一步。下面这个形状,一个下午能跑完。
按语言分层抽样,且要从真实流量里抽。 不要抓前 200 条了事:覆盖你实际预期的标签分布,而不是你希望的分布。如果投诉类消息只占队列的 8%,样本里也得占到 8%。
用你自己的业务专家打标签。「这算不算退款请求」的真相在退款团队手里,不在任何公开 benchmark 里。如果你们今天已经在人工处理这类条目,那批历史判定就是最便宜可用的标签集——前提是你要意识到它们带着当时决策者的偏差。
留出一片不参与调参的样本。 在一片上调阈值,在另一片上汇报结果。否则你设的每个阈值都是对着你测过的那片样本拟合出来的。
每种语言跑同一批问题。 相同的 instructions、相同的 criteria、相同的选项——是翻译,不是改写。标签本身用 Choice,答案是分级的时候用 Score,二元筛查用 Noul。
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
client = TypeSafeClient(model="jev-1.13")
# 一个 state、多个问题、一次请求。标签问题做决定,
# 置信度各档告诉你这个决定该信几分。
sentiment = client.system_one(
{"ticket": ticket_text, "language": "zh"},
{
"intent": Choice(
"Which queue should this ticket go to?",
refund="Requests money back for a completed charge",
technical="Reports the product not working",
billing="Asks about an invoice or a plan change",
),
"urgent": Noul("Does this ticket describe an outage, an outage risk, or a safety issue?"),
"quality": Score(
"How complete is the reported information?",
levels=["No detail", "Minimal", "Enough to act", "Reproducible"],
),
},
)
for name, answer in sentiment.choices.items():
print(name, answer.choice, round(answer.confidence, 3))
要比较的是两样东西,不是一样。 每种语言都同时记录:与标签的一致率,以及置信度的分布。这一对数字才能回答「英文上已经跑着的自动化,中文上还能不能照着跑」。
如果你想要一个「量要多大」的客观标准,而不是拍脑袋:样本量要大到「两种语言之间 5 个百分点的差异不会是噪声」,且每个标签类别的样本要足够多,以致某个稀有类别上的失效能被看见。按你自己的流量规模把这两个数算出来,并且在看结果之前就写下来。
第 2 步:看置信度分布,不要只看那个准确率数字
按语言,把有标签样本上的 confidence 画成直方图。两种形状承载了大部分信息。
集中在高位、一致率也跟得上 —— 这种语言在你的内容上表现得和英文接近,阈值可以沿用。
摊到中间 —— 模型仍然给答案,但它在告诉你选项之间没有被清晰地区分开。Confidence 文档说得很明确:Choice 上分布偏平,通常意味着没有任何一个选项明显胜出;Score 上偏平,则往往意味着等级本身含糊、维度太多,或者 state 里的信息不足以判断。这是一个路由层面的发现,而不是自动等同于模型失败:正确的应对可能是收窄选项集、把缺失的上下文补进 state,或者把复核带放宽。
这一步防住的失效模式很隐蔽、也很贵:团队在德语上测了准确率,看到一个能接受的数字,于是沿用了英文阈值,却始终没注意到分布的中间段已经移动——结果是本该进人工复核的那部分请求,悄悄从复核队列里消失了。所以先比直方图,再比那个头条数字。
第 3 步:阈值按语言分开设,不要一个数管全站
Confidence 文档结尾的建议是「从保守的阈值开始,用自己的数据测试,并随着观察到的结果调整」。把这句话横着用在多语言上,就是一张多一列语言的阈值表。
下面这张表是用来讨论的起始形状,不是本站测出来的数值——表里每一个数字都是你根据自己第 1 步的结果做的策略决定:
| 动作 | 风险 | 英文门槛 | 第二语言门槛 |
|---|---|---|---|
| 自动路由到正确队列 | 低,可回滚 | 0.75 | 高于英文,幅度等于你测出来的差距 |
| 批准退款或抵扣 | 钱真的会出去 | 0.90 | 还应更高,并叠加第二个信号 |
| 涉及安全或法律维度 | 最高 | 永不完全自动 | 永不完全自动 |
两条规则能让这张表站得住。第一,灰度期间永远不要把第二语言的门槛放到比英文更低——语言差距就是这样变成事故的。第二,把阈值版本和决策一起记日志,这样日后复盘时才能分清错答是来自模型,还是来自你的团队改过的一个数。
第 4 步:在你需要之前,先把降级链路定好
一条置信带只有在「请求有地方可去」时才有意义。请提前把去向定好,并且按语言分别定:
| 信号 | 首选动作 | 理由 |
|---|---|---|
| 低置信度、低风险 | 用用户的语言要求补充信息 | 便宜,而且请求没有离开产品 |
| 低置信度、高风险 | 人工复核 | 文档对「不要执行」给的默认答案 |
选项集本身含糊(Choice 分布偏平) | 收窄选项或补齐缺失的 state 后重问 | 偏平通常是问题设计问题 |
| 属于真正的生成式任务 | 交给生成式模型 | 锯齿页明确说生成不是 Jev 的活 |
| 算术、日期、计数 | 交给你的代码 | 「把算术留在代码里」 |
值得单独点名的是「第二次请求」。由于一次请求可以围绕同一个 state 提多个问题、且彼此独立求值,你完全可以在已经预算好的调用里,用收窄后的选项集重问一次,而不必为此再搭一条管线。
工程约束:只吃文本、可以混语言、以及上下文预算
models 页里有三条工程事实,任何多语言部署都绕不开,而在调阈值的阶段又特别容易被忘掉。
- 只吃文本。
state必须是字符串、JSON 对象或文本数组。图片、音频、视频不被接受为输入,所以它们必须在进入请求之前被预处理成文本或结构化字段。一张扫描的中文发票,先是一个文本抽取问题,然后才是一个判断问题。 - 一个 state 一次请求,问题并行求值。 每个问题看到同一个
state,彼此独立求值,而且同一次请求里可以混用Choice、Score和Noul。一条中英混排的工单不需要按语言各发一次调用。 - 预算按请求算。 每次请求 64k token,其中
state加最长的一个问题可用 32k。非英语段落不会自动变大或变小——请实测你自己的 token 用量而不是假设一个比例;并且在代码里先过滤state,因为锯齿页已经警告过无关细节会拉低准确率。 - 限流与价格。 Jev 的限流是每秒 100K token、每秒 80 次请求,超过任一即返回
429 Too Many Requests;计费按输入 token,每十亿 token 42 美元(即每百万 token 0.042 美元),输出 token 免费。所以放宽复核带很便宜,真正花钱的是把state撑肥。
非英语负载的上线前清单
-
instructions的语言与所评判内容的语言一致,中间没有翻译环节。 - 每种语言都有一份带标签的样本,且留出了没有参与调参的切片。
- 每种语言都同时记录了一致率与置信度直方图。
- 阈值按语言分开,且从不低于对应的英文门槛。
- 每一条置信带都有明确去向:澄清、复核,或降级。
- 计数、日期运算与数值插值都在代码里,不在问题里。
-
state发送前经过过滤,并且实测过它的 token 规模。 - 每次决策旁边都记了阈值版本号。
这件事在整条管线里的位置
语言支持是本站在别处描述的同一条纪律的一个维度:Jev 负责判断,你的代码负责决定。与它配套的三篇是:置信度与降级讲上面这些带子背后的机制,设计 state 与问题讲怎么组织双语内容以便一次请求就能评判,三大原语讲在这个测试骨架里怎么在 Choice、Score、Noul 之间选。
想看一个多语言判断从头跑到尾的实际样子,多语言评论审核案例逐参数拆解了一次请求与它的响应,内容安全场景则从产品规模看同一种形状。当阈值表开始给出反常结果、而不是一条稳定的分界线时,先去排错手册看;如果复核带最后成了整条管线最贵的部分,成本与延迟讲的是真正决定账单的是什么。