---
title: TypeSafe Jev 学习笔记
slug: typesafe-jev-learning-notes
date: 2026-09-20
author: Frankie 徐
category: ai
tags: ['jev', 'typesafe', 'ai-agents', 'system-one', 'structured-output']
description: TypeSafe 的 System One 模型 Jev：用 Choice / Noul / Score 把自然语言映射成程序可消费的结构化判断，并接入外贸询盘分诊等业务路由。
permalink: https://www.210k.cc/typesafe-jev-learning-notes
---

## 1. Jev 是什么

Jev 是 TypeSafe 的第一个 System One 模型。它不是用来生成长文本、代码或解释的聊天模型，而是把自然语言和业务状态转换成程序可以直接消费的结构化判断。

```text
业务状态 + 明确的问题定义 → Jev → typed answer + 概率 → JavaScript 组合规则并执行动作
```

当前 Jev 接收文本、JSON 对象和文本数组；图片、音频、视频不在当前输入范围内。

## 2. 三种基础问题类型

这是三种 primitive / 判断输出类型，不是三个独立模型。

| 类型 | 要问的问题 | 主要输出 |
| --- | --- | --- |
| `Choice` | “它属于哪一个？” | 一个选项、完整概率分布、confidence |
| `Noul` | “这个条件成立吗？” | “是”的概率 |
| `Score` | “程度有多高？” | 期望分数、等级概率、confidence |

### Choice：从封闭选项中选择一个

```js
import { choice } from "@typesafe-ai/sdk";

const topic = choice("这条客户消息主要属于哪个主题？", {
  quotation: "询价、报价或采购需求",
  delivery: "交期、物流或出货安排",
  technical: "图纸、材料、工艺或技术规格",
  complaint: "质量、服务或交付投诉",
  other: "以上都不符合，或信息不足"
});
```

返回形态：

```json
{
  "type": "choice",
  "choice": "delivery",
  "probabilities": { "quotation": 0.03, "delivery": 0.91, "technical": 0.04, "complaint": 0.01, "other": 0.01 },
  "confidence": 0.89
}
```

`Choice` 的关键是先由业务方定义选项和边界。选项应尽量互斥，并保留 `other` 或 no-match，避免强行分类。

### Noul：判断一个条件是否成立

```js
import { noul } from "@typesafe-ai/sdk";

const isUrgent = noul(
  "这条消息是否明确表达了需要尽快处理的紧迫性？",
  {
    true: "提到截止时间、延误后果、取消订单或要求立即处理",
    false: "没有明确的时间压力或严重后果"
  }
);
```

返回：

```json
{ "type": "noul", "noul": 0.97 }
```

`noul` 是“是”的概率。Noul 没有单独的 confidence；是否自动执行由代码根据风险设阈值。

### Score：沿着有序等级打分

```js
import { score } from "@typesafe-ai/sdk";

const frustration = score("客户的不满程度如何？", [
  "平静地陈述事实，没有明显不满",
  "有轻微不满或抱怨，但仍然合作",
  "明显不满，质疑服务或要求升级处理",
  "强烈不满，威胁取消订单、投诉或终止合作"
]);
```

Score 的 criteria 必须是从 0 开始的有序数组。返回的 `score` 可以是小数：

```json
{
  "type": "score",
  "score": 2.76,
  "confidence": 0.91,
  "probabilities": { "0": 0.01, "1": 0.04, "2": 0.12, "3": 0.83 }
}
```

## 3. 一次请求可以问多个问题

同一个 `state` 上彼此独立的问题可以批量请求：

```js
import { choice, noul, score, TypeSafeClient } from "@typesafe-ai/sdk";

const client = new TypeSafeClient();
const response = await client.systemOne({
  model: "jev-latest",
  state: {
    message: "客户说模具已经延误两周，如果本周还不能出货就要取消订单。",
    customer: { country: "Germany", previous_orders: 2 }
  },
  questions: {
    topic: choice("这条消息主要属于哪个主题？", {
      quotation: "询价或采购需求",
      delivery: "交期、物流或出货",
      technical: "技术规格或图纸",
      other: "其他或信息不足"
    }),
    isUrgent: noul("这条消息是否表达了紧迫性？", {
      true: "有明确期限、延误后果或要求立即处理",
      false: "没有明确时间压力"
    }),
    frustration: score("客户的不满程度如何？", [
      "平静", "轻微不满", "明显不满，需要优先跟进", "强烈不满或威胁取消订单"
    ])
  }
});
```

一次请求里的问题不能看到彼此的答案。如果后一个问题依赖前一个问题的结果，就分成两次调用：第一次判断意图，代码检索资料，第二次把新增资料放入 state 再判断。

## 4. Jev 和普通代码的边界

Jev 负责理解自然语言、在定义好的选项中选择、判断条件概率、沿等级评分，并返回概率和 confidence。代码负责阈值、业务政策、组合判断、数据库/队列/通知和人工升级。

```js
function route({ topic, isUrgent, quoteReady, frustration, churnRisk }) {
  if (churnRisk.noul >= 0.8 || frustration.score >= 2.5) return "urgent_sales";
  if (quoteReady.noul < 0.6) return "need_more_info";
  if (topic.choice === "technical") return "technical_review";
  return isUrgent.noul >= 0.8 ? "priority_sales" : "normal_sales";
}
```

不要让 Jev 直接决定不可逆动作。Jev 输出语义信号，最终动作应由可测试、可审计的程序规则决定。

## 5. 真实例子：外贸询盘分诊

输入客户邮件、客户资料和产品报价所需字段：

```json
{
  "message": "We need 500 aluminum die casting parts. Please quote FOB Ningbo. The tooling has already been delayed for two weeks, and we may cancel if it cannot ship this week.",
  "customer": { "country": "Germany", "previous_orders": 2 },
  "required_fields": ["quantity", "material", "drawing", "surface_finish", "delivery_date", "incoterm"]
}
```

同时问：

```text
Choice：主要意图是报价、样品、技术确认、交期还是投诉？
Noul：是否已经有足够信息开始报价？
Noul：是否存在取消订单或流失风险？
Score：客户不满程度是 0～3 的哪一级？
```

程序再做路由：高风险进入紧急销售队列；资料不足进入补充信息队列；技术意图进入技术评审；其余进入普通销售队列。

这个例子体现的不是“Jev 会读邮件”，而是：一封自然语言输入可以被拆成多个独立、可复用、带概率的语义信号，然后接入普通软件流程。

## 6. 问题设计是核心工作

业务方需要定义：

1. 真正要判断什么
2. 答案集合是什么
3. 每个答案的边界是什么
4. 不确定或不匹配时怎么办
5. 每个结果怎样影响程序动作

好的问题应当窄、独立、可复用。不要把主题、紧急性、客户情绪揉成一个模糊问题；拆开后，代码才能单独调整阈值和组合方式。

不需要一开始设计完美，先用真实询盘跑通闭环：

```text
真实询盘 → Jev 判断 → 程序路由 → 人工确认 → 对比结果 → 修改问题或阈值
```

建议保留原始记录：

```json
{
  "message": "原始询盘",
  "questions": "当时使用的问题定义",
  "answers": "Jev 原始答案",
  "final_route": "程序最终路由",
  "human_result": "人工确认结果"
}
```

## 7. 当前最小实验台

本次创建的本地实验台使用 Node.js 20.6+ 和 JavaScript SDK：

```sh
npm install
npm start
```

根目录 `.env`：

```sh
TYPESAFE_API_KEY=<TYPESAFE_API_KEY>
```

页面会展示实际问题、候选定义、答案、概率分布、confidence 和 token 用量。API key 只在 Node 服务端读取，不进入浏览器。

## 8. 一句话总结

> 我定义清晰的判断空间，Jev 把自然语言映射到这个空间，代码再把多个判断组合成可执行的业务流程。