决策模型Jev

决策模型 Jev:从类型化判断到可控分流

本文整理自本目录的 01_认识Jev.ipynb 第 1~6 节,面向会一点 Python、刚接触 AI Agent 的读者。示例中的客户消息、赛事消息和离线答案均为教学合成数据;它们用于理解数据结构与代码路径,不代表真实 API 返回、准确率或安全保证。

先建立全景:Jev 在系统里做什么

Jev 是 TypeSafe 的 System One 决策模型。它接收两样东西:

  1. 状态(state):待理解的文本或结构化文本;
  2. 类型化问题(questions):程序预先规定“要判断什么、可有哪些答案”。

它返回的是答案及概率分布,不是供人阅读的一段长文本。因而一个典型链路是:模型负责理解语义,应用代码负责不可妥协的规则、阈值和最终动作。

flowchart LR
    A[状态 state\n工单、消息、上下文] --> B[Jev\n类型化判断]
    B --> C[答案与概率分布]
    C --> D[确定性代码策略\n阈值、权限、业务规则]
    D --> E[路由、排序、自动回复或人工复核]

这张图也说明了责任边界:概率很高不等于可以跳过权限、安全或人工复核。


1. Jev 是什么

一句话概括:Jev 能读懂自然语言,但把输出限制为程序可直接处理的类型化判断和概率。

维度 聊天式 LLM Jev(System One)
主要输出 自由文本、代码或解释 类型化取值和概率分布
典型消费者 人 程序的分支、排序和路由逻辑
擅长任务 写作、开放问答、解释、创作 有限选项的分类、评分、核验、路由
常见后处理 解析文本或 JSON,再校验 直接读取字段,再应用业务策略

三种原语

原语 要回答的问题 结果长什么样 适用例子
Choice “属于哪一类?” 选中的 key + 每个选项的概率 工单意图、风险类型、队列
Score “程度有多高?” 有序档位的概率 + 概率加权得分 严重度、相关性、受挫程度
Noul “这个陈述是否成立?” 0~1 的概率 是否紧急、是否含敏感信息

例如,Score 的三个档位是“平静 / 有些不满 / 强烈不满”,其概率若为 0.05 / 0.35 / 0.60,则得分是:

1
0 × 0.05 + 1 × 0.35 + 2 × 0.60 = 1.55

提问要原子化。 一个问题只应让领域专家花几秒钟就能判断。例如,把“这条工单应不应该升级、怎么解决、是否退款”拆成紧急性、意图、受挫程度等独立问题;组合优先级留给代码。这样规则变化时改的是代码,而不是模糊地重写提示词。

不能做什么

Jev 不替代生成式模型:需要长文写作、开放推理或面向用户的解释时,应使用 LLM。它也不替代业务安全机制:医疗、法务、理赔、招聘淘汰等高风险场景,必须把确定性约束和人工终审放在模型输出之后。


2. 三分钟上手

准备环境

Python 需要 3.10 或更高版本。密钥只从环境变量读取,不要写进 Markdown、Notebook 或代码仓库。

1
2
python -m pip install typesafe-sdk==0.7.0
export TYPESAFE_API_KEY=你的真实密钥

也可以先在官方 Playground 添加一个问题观察结果。若直接调用 HTTP API,最小请求如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
curl -X POST https://api.typesafe.ai/v1/systemone \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "连续三天连不上 Stripe,每天在丢订单,尽快处理!",
"model": "jev-latest",
"questions": {
"urgency": {
"type": "noul",
"instructions": "这条消息是否表达了紧迫性?"
}
}
}'

一次调用,同时提出三类问题

下面的 Python 示例把同一条求助信息作为 state,同时询问紧急性、主要诉求和受挫程度。三个问题共享同一份状态,但在语义上应彼此独立。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import os
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

client = TypeSafeClient(
api_key=os.environ["TYPESAFE_API_KEY"],
model=os.environ.get("TYPESAFE_DEFAULT_MODEL", "jev-1.13.0"),
)

state = "用户连续三天无法连接 Stripe,每天都在丢订单,请尽快处理!"
questions = {
"urgency": Noul(instructions="这条消息是否表达了紧迫性?"),
"intent": Choice(
instructions="用户的主要诉求是什么?",
criteria={
"troubleshoot": "希望排查或修复连接问题",
"refund": "要求退款或赔偿",
"inquiry": "只是咨询,不要求立即处理",
},
),
"frustration": Score(
instructions="用户的受挫程度如何?",
criteria=["平静,仅陈述事实", "有些不满", "强烈不满,有流失风险"],
),
}

response = client.system_one(state, questions)
print(response.nouls["urgency"].noul)
print(response.choices["intent"].choice)
print(response.choices["intent"].probabilities)
print(response.scores["frustration"].score)
client.close()

Notebook 的离线教学结构示例会呈现为:urgency = 0.94、intent = troubleshoot,其三个意图概率为 0.82 / 0.03 / 0.15;受挫程度的期望得分为 1.55。这些数值只是为了演示如何读结果。真实调用时,应记录实际模型版本、输入、延迟、错误和返回来源。

Choice 和 Score 会给出选项概率及 confidence;Noul 没有单独的 confidence 字段,不确定性直接表现为其概率接近 0.5。一次请求能混合多种原语,但问题数量是否影响延迟、成本或稳定性,仍应在自己的数据和模型版本上测量,不能预设结论。


3. 场景地图:什么活儿适合交给 Jev

判断一个场景是否适合,先问:答案空间是否有限、可以清楚写成问题和选项、后续能由代码执行吗? 若答案是“是”,Jev 通常很合适。

场景 典型问题 常用原语 后续代码做什么
意图与风险分类 “这是退款、技术故障还是咨询?” Choice 进入相应队列
内容核验 “这条文本是否包含欺诈或敏感信息?” Noul 拦截、抽检或转人工
质量与严重度 “相关性或风险有多高?” Score 排序、过滤、设置优先级
工具/队列路由 “应该调用哪个工具?” Choice + 规则 选择工具或负责人
RAG 与检索 “候选段落是否相关?” Score / Noul 重排候选、舍弃无关上下文
字段抽取 “购买意图处于哪个等级?” Choice / Score 填表、喂给下游预测模型

一个实用分工是:让 Jev 快速判断“该走哪条路”,让 LLM 在被选中的分支生成解释、回复或草稿。空结果、低概率和高风险边界都应设计明确的人工出口。


4. 概率为什么可信:训练目标与校准

Notebook 用三个缩写对比训练侧重:RLHF 侧重让模型给出更符合人类偏好的回答;RLVR 侧重可验证的推理结果;Jev 所介绍的 RLCD(面向校准决策的强化学习)则侧重让模型给出可用于决策的概率。无论训练方法如何,工程上最重要的概念都是校准(calibration)。

如果一大组被预测为 0.8 的事件,长期实际发生率也接近 80%,这组概率就是校准的。它不表示某一条 0.8 的预测必然正确。

下面的最小代码构造两组各 10 条的人工数据:0.2 这一组实际发生 20%,0.8 这一组实际发生 80%。两组都可以说“校准良好”,但每一组中仍有预测错误的个体。

1
2
3
4
5
6
7
8
groups = {0.2: [1] * 2 + [0] * 8, 0.8: [1] * 8 + [0] * 2}

for predicted_p, labels in groups.items():
observed_rate = sum(labels) / len(labels)
print(
f"预测 {predicted_p:.0%}:实际发生 {observed_rate:.0%};"
f"其中 {labels.count(0)} 条没有发生"
)
1
2
预测 20%:实际发生 20%;其中 8 条没有发生
预测 80%:实际发生 80%;其中 2 条没有发生

因此,概率最适合服务于成组决策:排序、队列路由、抽检比例和人工复核优先级。单条高风险动作还应叠加业务阈值、硬规则和人工确认;不要把“模型给出高概率”等同于“系统可以自行处置”。


5. 知识补充:社区实测认知(jev-cookbook)

以下是原 Notebook 摘录的社区报告结论,适合作为“在哪里值得进一步测”的线索,而不是对当前 API 的承诺。报告的模型版本、端点、题集和运行时间可能与今天不同,落地前请在目标数据上复测。

材料 报告中的现象 可得到的谨慎结论
JevBench v1.2(242 个类型化决策) 报告 Jev 1.13.0 综合分 75.4、可解析率 100%、中位延迟 0.65~0.72 秒;两次间隔 16 分钟的运行有 1.2% 答案变化 结构化输出与速度值得评估;约 1 个百分点的差距未必有意义,端点也不是确定性的
SciFact 精排对照(80 条查询) 在固定候选集上,报告 Jev 的 nDCG@10 较不精排提升 0.0778 对“候选已经给定”的语义重排,可作为实验方向;不能外推到所有检索任务
fast-jev-compaction 对工具调用及结果逐条打分,丢弃过期内容、保留原文 判断可用于上下文筛选,避免把全部信息压成有损摘要
智能家居案例 一次绑定意图、设备、房间、动作等多个原子问题,再由代码裁剪分支 “投机式多问 + 原子组合”是可复用的工程模式;分支正确性仍要测试

阅读这些数字时,请同时记录基准集、评测脚本、模型版本、温度/端点设置、延迟分位数及失败率;只看一个综合分,无法决定自己的业务是否可靠。


6. 综合实验:赛事指挥台

现在把前面的分工落到一个小系统。夜跑赛事先后收到三类消息:跑者受伤、补水站缺货、完赛 T 恤的领取咨询。对每一条消息,应用发起一次请求,并一次询问三个原子问题:事件类型、处理优先级、是否需要人工到场。

6.1 定义状态和问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from typesafe_sdk import Choice, Noul, Score

incident_questions = {
"incident_type": Choice(
instructions="这条赛事消息主要属于哪类事件?",
criteria={
"medical_help": "跑者受伤或需要现场医疗",
"supplies": "物资补给问题",
"event_info": "赛事信息咨询",
},
),
"priority": Score(
instructions="需要多快处理?",
criteria=["可赛后处理", "30 分钟内", "10 分钟内", "必须立即"],
),
"requires_human": Noul(instructions="是否需要人工到场介入?"),
}

injury = {
"event": "海湾夜跑 10 公里",
"time": "19:12",
"message": "2.4 公里蓝旗处有跑者脚踝扭伤,无法继续前进,请派人协助。",
}

这里的 injury 是结构化 state:赛事名和时间提供必要背景,message 保留原始语义。不要把模型并不需要的个人资料或内部机密一起塞入 state。

6.2 让代码掌控分流

模型返回答案后,路由策略可以完全用普通 Python 表达。下例特意把“医疗事件必转人工”写成硬规则;0.7 只是示范阈值,实际值应由风险政策和验证数据决定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
routes = {
"medical_help": "现场负责人 / 医疗人员",
"supplies": "补给组(优先处理)",
"event_info": "自动回复赛事 FAQ(模拟)",
}

def dispatch(response):
event_type = response.choices["incident_type"].choice
human_probability = response.nouls["requires_human"].noul

# 不可妥协的业务规则优先于模型概率。
if event_type == "medical_help":
return "现场负责人 / 医疗人员(硬规则:必须人工)"
if human_probability >= 0.7:
return f"{routes[event_type]}(转人工复核)"
return routes[event_type]

response = client.system_one(injury, incident_questions)
print(dispatch(response))

Notebook 的离线演示会将三条合成消息分别路由为:

消息 离线演示路由 为什么
跑者脚踝受伤 现场负责人 / 医疗人员,并转人工 医疗事件、高优先级、需要人员介入
补水站纸杯用完 补给组优先处理 有库存但需要尽快补送
询问 T 恤领取 FAQ 自动回复(模拟) 信息咨询,未触发人工阈值

这不是“把安全决策交给模型”。恰恰相反:Jev 只负责把自然语言转换为明确的候选判断;决定是否派人、谁有权限执行、医疗类是否无条件升级,都由可审计、可测试、可修改的代码和运营流程负责。


小结:初学者的使用清单

  1. 先确认任务是否有清晰、有限的答案空间;开放写作交给 LLM。
  2. 用最少必要信息组成 state,为每个问题定义清楚的选项或档位。
  3. 每个问题只问一件事;将复杂业务判断拆成原子问题后再由代码组合。
  4. 把概率视为成组质量信号,而非单次正确保证;在自己的数据上测试校准、延迟、成本和稳定性。
  5. 把阈值、权限、安全规则和人工升级写进确定性代码,并为低置信度、高风险和空结果设计退路。

相关原始材料:Notebook · 本章说明 · TypeSafe Introduction · Use Case Map


决策模型Jev
https://jiangsanyin.github.io/2026/11/08/决策模型Jev/
作者
sanyinjiang
发布于
2026年11月8日
许可协议