TypeSafe 的 Jev 瞄准的正是这个缺口。它不以生成长文本为目标,而是让你提交一段 state 和一组定义明确的问题,返回带概率分布的结构化答案。本文从实际接入开始,讲清它适合解决什么问题、怎样调用,以及如何把不确定性真正写进业务流程。
先说结论:Jev 适合什么,不适合什么
Jev 是 TypeSafe 的 System One 模型。它适合在已有输入上做快速、边界清晰的判断,例如:
- 这张工单该分给哪个团队?
- 这条消息是否表达了紧急性?
- 风险落在哪个已定义的等级?
它不替代需要长篇推理、开放式创作或对话回复的生成式模型。一个实用的判断标准是:一位熟悉业务的人拿到同样的上下文后,能否在几秒内对一个单一问题作出判断?能,就很适合拆成 Jev 问题。
System One:把“快思考”变成智能 if 语句
丹尼尔·卡尼曼在《思考,快与慢》中用“系统 1”描述快速、自动、凭直觉完成的判断;“系统 2”则更缓慢、费力,需要有意识推演。TypeSafe 所说的 System One 借用了这一区分,来界定 Jev 的工作边界:给定明确的 state 和一个原子问题,快速返回可由程序消费的结构化判断。
所以 Jev 的价值不是代替所有思考,而是把高频、边界明确的判断做成可靠的“智能 if 语句”。它不适合作为长篇对话、复杂数学推理、棋类规划或跨多步论证的替代品。
这里的 System One 是产品与任务定位的类比,不等同于对人类认知机制的技术复现,也不构成心理学或神经科学主张。
训练路线:RLHF、RLVR、RLCD 分别在优化什么
理解缩写的重点不在于判断谁“更先进”,而是分辨它们面向哪种输出与任务目标。
| 缩写 | 含义 | 适合理解的任务取向 |
|---|---|---|
| **RLHF** | Reinforcement Learning from Human Feedback,基于人类反馈的强化学习 | 让预训练模型更符合人类偏好的回答方式,常见于面向对话与文本生成的模型 |
| **RLVR** | Reinforcement Learning from Verifiable Rewards,基于可验证奖励的强化学习 | 奖励可由正确性等方式验证,常用于需要严密推演的任务;这类推理取向可能带来更高延迟与成本 |
| **RLCD** | Reinforcement Learning from Contrast Distillation,来源文档译为“对比蒸馏强化学习” | TypeSafe 将其描述为优化决策过程,以输出经过校准的决策与概率值,而非生成一段文本 |
对开发者而言,更实用的选择原则是:如果代码需要可执行的分类、分数、概率和置信度,优先考虑 Jev;如果需要开放式解释、创作或逐步推理,再考虑生成式或推理模型,并在系统中组合两者。
接入前准备:账号、API Key 与 Agent Skill
先在 TypeSafe 官网点击 Join Waitlist 申请访问。收到邀请邮件后创建账号,再进入 Console → API Keys 创建 API Key。
API Key 应只放在服务端环境变量或密钥管理服务中,不能提交到 Git 仓库、出现在前端代码或日志里。怀疑泄露时,应在 Console 中停用并重新创建。
如果希望让 Coding Agent 帮忙接入,可安装 TypeSafe 的官方 Skill:
npx skills add typesafe-ai/skills --skill typesafe-ai
然后在任务中明确要求 Agent 使用它:
Use the TypeSafe skill to integrate Jev into this project.
先在 Playground 验证问题设计
在写业务代码之前,先打开 TypeSafe Playground,用真实但不包含敏感信息的样本验证问题边界、选项描述和评分等级。
先从一个简单的 Noul 问题开始:
<span>{</span>
<span>"urgency"</span><span>:</span> <span>{</span>
<span>"type"</span><span>:</span> <span>"noul"</span><span>,</span>
<span>"instructions"</span><span>:</span> <span>"这条消息是否表达了紧急性?"</span>
<span>}</span>
<span>}</span>
这一步不是反复调“提示词文案”,而是确认问题的边界足够清楚:哪些输入该命中、哪些相邻情况不该命中、置信度低时系统要怎样处理。
第一次 API 调用:一次做三个判断
Jev 的接口是 POST https://api.typesafe.ai/v1/systemone。请求顶层只有三个核心字段:
| 字段 | 作用 |
|---|---|
| `state` | 要被判断的上下文,例如工单、简历、商品信息或事件记录 |
| `model` | 选择模型;快速开始可使用 `jev-latest` |
| `questions` | “问题 ID → 问题定义”的映射;答案会按相同 ID 返回,ID 本身不会发给模型 |
下面的例子对同一条客服消息同时做路由、情绪分级和紧急性判断:
curl -X POST https://api.typesafe.ai/v1/systemone \
-H <span>"Authorization: Bearer <span>$TYPESAFE_API_KEY</span>"</span> \
-H <span>"Content-Type: application/json"</span> \
-d @- <<<span>'EOF'</span>
{
<span>"state"</span>: <span>"Stripe 账户连续 3 天无法连接,我正在损失订单,请尽快帮忙。"</span>,
<span>"model"</span>: <span>"jev-latest"</span>,
<span>"questions"</span>: {
<span>"department"</span>: {
<span>"type"</span>: <span>"choice"</span>,
<span>"instructions"</span>: <span>"哪支团队应处理此消息?"</span>,
<span>"criteria"</span>: {
<span>"billing"</span>: <span>"支付、订阅或账单问题"</span>,
<span>"technical"</span>: <span>"产品故障、集成或技术问题"</span>,
<span>"sales"</span>: <span>"价格、方案或账户咨询"</span>
}
},
<span>"frustration"</span>: {
<span>"type"</span>: <span>"score"</span>,
<span>"instructions"</span>: <span>"客户表现出多强的挫败感?"</span>,
<span>"criteria"</span>: [
<span>"平静陈述事实"</span>,
<span>"感到挫败但保持礼貌"</span>,
<span>"非常愤怒或使用强烈措辞"</span>
]
},
<span>"is_urgent"</span>: {
<span>"type"</span>: <span>"noul"</span>,
<span>"instructions"</span>: <span>"该消息表达了紧急性或时间敏感性。"</span>
}
}
}
EOF
同一请求中的问题会针对同一份 state 并行、彼此独立地评估。优先把当前流程可能需要的问题一起发出,再由代码决定哪些答案应被采用;相较为每个问题单独请求,这种方式通常更快,但额外问题仍会增加 token 成本。
Choice、Score、Noul:三种问题怎么选
| 类型 | 何时使用 | 关键返回值 |
|---|---|---|
| **Choice** | 答案来自一组没有顺序的固定选项 | `choice`、各选项 `probabilities`、`confidence` |
| **Score** | 答案位于一个可清楚描述的有序等级谱上 | `score`、各等级 `probabilities`、`legend`、`confidence` |
| **Noul** | 只需回答是或否 | `noul`:回答“是”的概率,范围为 0 到 1;不单独返回 `confidence` |
Choice:固定分类
用 Choice 处理“属于哪一类”。criteria 是“选项名 → 描述”的映射;选项名和描述都会给模型,因此描述必须明确区分相邻类别。类别可能覆盖不全时,加入 other 或 none_of_the_above。
Score:可解释的连续分级
用 Score 处理“处于什么程度”。criteria 是从低到高的有序数组,至少 2 档、最多 10 档。返回的 score 是等级位置的概率加权平均,因此可以是小数。不要只读一个分数,要连同概率分布和置信度一起解释。
每个等级应描述具体情境,例如“功能受损,但存在可用替代方案”,而不是“中等严重”。不要让一个 Score 同时衡量“准时、聪明、有经验”这类多个维度;拆开后再在代码中加权组合。
Noul:明确的二元判断
用 Noul 处理“是否”。noul = 0.999 表示“是”的概率很高,0.001 表示“否”的概率很高,接近 0.5 则说明正反证据接近。尽量把 instructions 写成“高值就是是”的句子;边界微妙时可增加 true 与 false 的 criteria 说明。
实测:返回结构和计算方式都可直接验证
对上述客服消息的实际调用,jev-latest 返回了具体版本 jev-1.13.0,并给出了以下结果:
<span>{</span>
<span>"model"</span><span>:</span> <span>"jev-1.13.0"</span><span>,</span>
<span>"answers"</span><span>:</span> <span>{</span>
<span>"department"</span><span>:</span> <span>{</span>
<span>"type"</span><span>:</span> <span>"choice"</span><span>,</span>
<span>"choice"</span><span>:</span> <span>"technical"</span><span>,</span>
<span>"confidence"</span><span>:</span> <span>0.66</span><span>,</span>
<span>"probabilities"</span><span>:</span> <span>{</span>
<span>"billing"</span><span>:</span> <span>0.23</span><span>,</span>
<span>"technical"</span><span>:</span> <span>0.77</span><span>,</span>
<span>"sales"</span><span>:</span> <span>0</span>
<span>}</span>
<span>}</span><span>,</span>
<span>"frustration"</span><span>:</span> <span>{</span>
<span>"type"</span><span>:</span> <span>"score"</span><span>,</span>
<span>"score"</span><span>:</span> <span>0.98</span><span>,</span>
<span>"confidence"</span><span>:</span> <span>0.96</span><span>,</span>
<span>"legend"</span><span>:</span> <span>{</span>
<span>"0"</span><span>:</span> <span>"平静陈述事实"</span><span>,</span>
<span>"1"</span><span>:</span> <span>"感到挫败但保持礼貌"</span><span>,</span>
<span>"2"</span><span>:</span> <span>"非常愤怒或使用强烈措辞"</span>
<span>}</span><span>,</span>
<span>"probabilities"</span><span>:</span> <span>{</span>
<span>"0"</span><span>:</span> <span>0.03</span><span>,</span>
<span>"1"</span><span>:</span> <span>0.97</span><span>,</span>
<span>"2"</span><span>:</span> <span>0</span>
<span>}</span>
<span>}</span><span>,</span>
<span>"is_urgent"</span><span>:</span> <span>{</span>
<span>"type"</span><span>:</span> <span>"noul"</span><span>,</span>
<span>"noul"</span><span>:</span> <span>0.98</span>
<span>}</span>
<span>}</span>
<span>}</span>
这个结果有几个值得注意的地方:
department按请求中的同名问题 ID 返回,choice、probabilities和confidence都齐全;三项概率之和为 1。frustration.score是等级位置的概率加权平均。响应中展示的概率可能经过四舍五入,因此排查时应以当次完整响应为准,而不是用展示后的有限小数重新计算。- Score 的
legend将等级编号映射回描述;Noul 则只有noul字段,不单独提供confidence。 - 模型别名
jev-latest会在响应中落到实际版本。因此业务系统应使用别名保持升级弹性,同时记录返回的具体版本,方便排查差异。
置信度不是装饰字段,而是路由信号
Choice 和 Score 会返回 confidence,其值来自概率分布的集中程度:结果集中在一个选项或等级,置信度更高;分散在多个结果,置信度更低。它不是“结果绝对正确”的保证,而是模型在表达“这道题是否存在清晰答案”。
| 置信度区间 | 建议的系统行为 |
|---|---|
| 高 | 可自动执行低风险、可逆操作 |
| 中 | 保留建议结果,但要求用户确认、标记复核或补充信息 |
| 低 | 不要自动行动;转人工、请求澄清或回退到其他流程 |
阈值必须随风险变化:读操作可以较宽松;删除、付款、权限变更等高后果动作,应采用更严格的阈值,并保留人工确认。
answer = response.answers[<span>"department"</span>]
<span>if</span> answer.confidence >= <span>0.85</span>:
route_to(answer.choice) <span># 自动分派</span>
<span>elif</span> answer.confidence >= <span>0.50</span>:
flag_for_review(answer.choice) <span># 建议分派,等待确认</span>
<span>else</span>:
ask_for_clarification() <span># 不做自动决定</span>
从 Demo 到可靠系统:四个原则
- 一个问题只问一个原子判断。 “给这个创业项目打分”混合了市场、技术、差异化等多个维度。应拆成多个 Score,再由代码明确权重。
- 把组合逻辑留在代码里。 模型负责单项判断;优先级、阈值、权限和业务规则由普通条件分支或公式控制,便于审计与调整。
- 允许推测性并行提问。 例如先问工单归属,同时询问“退货原因”和“物流问题”;最终只消费与路由结果相关的答案。这是 Speculative Fan-Out 模式。
- 用自己的历史样本验证。 为每个问题准备已知期望结果的样本,检查描述改动是否提升实际效果。更高的
confidence不自动等于更正确。
常见误区
- 把开放式生成需求硬塞进 Jev。 需要写邮件、总结报告或多步推理时,优先考虑生成式模型,或只将其中可判定的部分交给 Jev。
- Choice 选项描述互相重叠。 把每个选项“包括什么、不包括什么”写清;必要时提供少量贴近真实输入的示例。
- 只使用 Score 的整数档位。 小数分数承载了多个等级之间的概率权重;应连同
probabilities与confidence解读。 - 低置信度仍自动执行高风险操作。 不确定性本身就是系统输入,不是可以忽略的异常。
- 把问题 ID 当成模型指令。 模型不会看到问题 ID;关键边界必须写在
instructions和criteria中。
下一步
- 用 Playground 为一个真实但低风险的业务场景写出 3 个原子问题。
- 用 cURL 或 SDK 接入服务端,并记录输入、答案、概率和最终人工或程序决策,注意对生产数据脱敏。
- 为每个业务动作定义风险等级与置信度策略。
- 阅读官方 Patterns,按需要采用 Confidence-Gated Routing、Composite Scoring、Intent Routing 或 Speculative Fan-Out。
Jev 把 LLM 判断转为可编程信号,以置信度驱动分流、复核与人工兜底;适合工单路由、情绪分级、风险判断等高频原子决策,为 AI 工作流补上低成本、可审计的决策中间层。