Jev 是 TypeSafe AI 的决策模型。你向它传入一段状态和一组带类型的问题,它会用概率而不是自然语言来回答。本文覆盖 Jev API Key 的创建和第一次请求;如果你想先弄清 Jev 是什么、为什么它返回数字而不是文本,请先阅读《什么是 Jev》。需要先说明一点,因为搜索结果比较混乱:这里的 Jev 指的是 TypeSafe AI 的模型,不是 YouTuber FaZe Jev,也不是 JEV 疫苗。
Jev API Key 的用法和任何 bearer token 一样,如果你对这个模式还不熟悉,《什么是 API Key》讲了基础知识。直接 API 访问目前处于 early access 阶段,所以第一步是从等待名单里出来。之后你要创建 Key、了解请求结构、用 curl 和 Python SDK 调用接口、读懂概率字段,再把请求接进 Apifox 并对这些概率做断言。如果你等不及,同一个模型也挂在 Vercel AI Gateway 上且没有等待名单,FAQ 里介绍了这条路径。
AI Coding 交流群
如果你也在用 AI 写代码,或者正在研究 Cursor、Claude Code 这些工具,欢迎加入以下交流群。群里平时会聊一些 AI 编程的实际用法、开发工作流,还有各种新工具和新玩法。
第 1 步:先拿到 early access,再创建 Key
截至本文写作时,Jev 仍处于 early access。TypeSafe 的发布公告说它“正在尽快让开发者从等待名单中出来”,所以先在 typesafe.ai 加入等待名单,等待控制台邀请;目前还没有自助注册。控制台账号激活后,进入 console.typesafe.ai/settings/keys 创建 Key。复制一次就够,然后像对待密码一样对待它。
把它导出为环境变量,而不是直接粘进代码:
export TYPESAFE_API_KEY="ts_..."
官方 curl 示例和 Python SDK 都会从环境里读取 TYPESAFE_API_KEY,所以一个变量就能覆盖下文所有示例。如果 Key 一旦进了提交记录,就在控制台轮换它,并对整个代码仓库做一次 API Key 泄漏检查。
第 2 步:了解请求结构
每次 Jev 调用都是一个 POST https://api.typesafe.ai/v1/systemone,请求体包含三个字段,详见 TypeSafe API 参考:
| 字段 | 类型 | 说明 |
|---|---|---|
model |
string | jev-latest(当前解析为 jev-1.13.0),或写 jev-preview 使用最新构建 |
state |
string、object 或 array | 待评估的内容:一条工单、一条 JSON 记录、一段消息历史 |
questions |
name 到 question 的 map | Jev 针对该 state 回答的带类型问题 |
每个问题属于三种原语之一:
| 原语 | 请求条件 | 响应字段 |
|---|---|---|
noul(是/否) |
可选 {"true": "...", "false": "..."} |
noul:0(否)到 1(是) |
choice |
必填的“选项到描述”map,最多 255 个选项 | choice、confidence、每个选项的 probabilities |
score |
必填的、2 到 10 个等级描述的有序数组 | score、confidence、legend、每个等级的 probabilities |
响应还会带上 model 以及 usage.input_tokens / usage.output_tokens。不同类型的问题可以共用同一个 state,并在一次往返里一起返回。
第 3 步:用 curl 发出第一次请求
下面这个请求把三种原语都跑在同一个客服工单上:
curl https://api.typesafe.ai/v1/systemone \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "jev-latest",
"state": "My card was charged twice for one order and nobody has replied in three days.",
"questions": {
"needs_review": {
"type": "noul",
"instructions": "Does this ticket need a human agent?",
"criteria": {
"true": "money, legal, or an unanswered complaint",
"false": "a routine question a bot can close"
}
},
"route": {
"type": "choice",
"instructions": "Route this ticket to a team.",
"criteria": {
"billing": "payment or charge problems",
"shipping": "delivery problems",
"technical": "application bugs"
}
},
"urgency": {
"type": "score",
"instructions": "How urgent is this ticket?",
"criteria": ["low", "medium", "high"]
}
}
}'
响应大致如下(数值仅作示意):
{
"model": "jev-1.13.0",
"answers": {
"needs_review": { "type": "noul", "noul": 0.97 },
"route": {
"type": "choice",
"choice": "billing",
"confidence": 0.98,
"probabilities": { "billing": 0.98, "shipping": 0.01, "technical": 0.01 }
},
"urgency": {
"type": "score",
"score": 1.6,
"confidence": 0.62,
"legend": { "0": "low", "1": "medium", "2": "high" },
"probabilities": { "0": 0.02, "1": 0.36, "2": 0.62 }
}
},
"usage": { "input_tokens": 190, "output_tokens": 0 }
}
第 4 步:读懂概率字段
这些数字要读得精确:
noul是“是”的概率。0.97 表示 Jev 有 97% 的把握认为这条工单需要人工处理。choice是概率最高的选项,probabilities列出了每个选项,confidence告诉你这个选择有多果断。0.98 的路由可以放心自动化;而 0.51 的路由、次高 0.47,基本等于抛硬币。score是在有序等级上的概率加权位置,所以 1.6 落在“medium”(1)和“high”(2)之间。legend把每个下标映射回标签,probabilities展示完整分布。
因为输出是一个分布而不是一个标签,阈值由你来定,而不是模型来定。这也是第 6 步的断言针对数字而不是文本的原因。
第 5 步:用 Python SDK 发起同样的调用
安装 SDK;客户端会从环境里读取 TYPESAFE_API_KEY:
pip install typesafe-sdk
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
with TypeSafeClient() as client:
response = client.system_one(
state="My card was charged twice for one order and nobody has replied in three days.",
questions={
"needs_review": Noul(
instructions="Does this ticket need a human agent?",
criteria={"true": "money, legal, or an unanswered complaint",
"false": "a routine question a bot can close"},
),
"route": Choice(
instructions="Route this ticket to a team.",
criteria={"billing": "payment or charge problems",
"shipping": "delivery problems",
"technical": "application bugs"},
),
"urgency": Score(
instructions="How urgent is this ticket?",
criteria=["low", "medium", "high"],
),
},
)
print(response.nouls["needs_review"].noul)
print(response.choices["route"].choice, response.choices["route"].probabilities)
print(response.scores["urgency"].score)
答案在响应对象上按类型分组(nouls、choices、scores)。还有一个结构相同的 JavaScript SDK;如果你已经在用 Vercel AI Gateway,AI SDK 7 的 experimental_evaluate 能以 typesafe-ai/jev 调用该模型,但有一处差异:布尔型问题返回的是 probability 字段,而不是 noul。
第 6 步:在 Apifox 中保存并测试 Jev API Key
curl 只能证明这个 Key 能用一次。Apifox 能让这个请求可重复执行、可断言、可 mock,并且对整个团队可用。
把 Key 存成 secret 变量。 新建一个名为 TypeSafe 的环境,添加 TYPESAFE_API_KEY 并标记为 secret,这样它的值在界面上会保持掩码、也不会出现在导出内容里;《Apifox 环境与 secret 变量》介绍了具体设置。把请求的 auth 设为 Bearer Token,值填 {{TYPESAFE_API_KEY}}。
构造 POST 请求。 添加一个指向 https://api.typesafe.ai/v1/systemone 的 POST,把第 3 步的 JSON body 粘进去并发送。响应面板会以树形渲染 answers,所以你可以在写断言之前先核对概率。
对概率断言,而不是对文本断言。 在可视化断言构建器里,把 JSONPath 表达式指向你关心的字段:
$.answers.needs_review.noul大于0.9$.answers.route.choice等于billing$.answers.route.probabilities.billing大于0.8$.answers.urgency.score大于或等于1$.usage.input_tokens小于1000
如果你更习惯写脚本,后置操作支持大家熟悉的 pm API:
const body = pm.response.json();
pm.test("ticket flagged for a human", () => {
pm.expect(body.answers.needs_review.noul).to.be.above(0.9);
});
pm.test("routed to billing", () => {
pm.expect(body.answers.route.choice).to.eql("billing");
});
把它保存为测试场景。 把请求放进一个测试场景,配上一份包含工单和预期路由的小型 CSV,并在每次修改 instructions 或 criteria 时运行。prompt 的改动就是代码改动;一个十行的场景就能抓住那种悄悄把 0.95 变成 0.6 的编辑。同一个场景可以通过 Apifox CLI 在 CI 里运行,这样回归会直接挡住合并。
对声明的响应结构做 mock。 在接口上定义响应数据结构(三个 answer 对象加 usage),Apifox 的智能 mock 会立刻返回逼真的模拟概率。前端可以在后端上线前,先基于 mock 把“需要人工复核”徽标和路由界面做出来,之后只改一个环境变量就能把 mock 地址换成真实接口。
关于席位规划:Apifox 免费版包含 4 个成员,付费版按席位计费。
代码里的阈值
断言通过之后,同一批数字就该驱动生产逻辑。把阈值集中放在一处并给它们命名:
REVIEW_THRESHOLD = 0.9
AUTO_ROUTE_CONFIDENCE = 0.85
needs_review = response.nouls["needs_review"].noul >= REVIEW_THRESHOLD
route = response.choices["route"]
if route.confidence >= AUTO_ROUTE_CONFIDENCE and not needs_review:
assign(ticket, team=route.choice)
else:
queue_for_human(ticket, suggested=route.choice)
把完整的 probabilities map 随每次决策一起记录,这样以后可以用真实数据微调阈值;并且当 confidence 偏低时,默认走人工复核——模型是在告诉你它并不确定。
限制、定价与模型
以下内容直接来自 TypeSafe 模型页面:
| 项目 | 值 |
|---|---|
| 价格 | 每百万输入 token $0.042;输出 token 不计费 |
| 速率限制 | 每秒 250,000 token、每分钟 1,200 次请求,会随负载动态调整 |
| 上下文 | 每次请求 64k token;其中 32k 用于 state 加最长的那一个问题 |
| 输入 | 仅文本:字符串、JSON 对象或数组。不支持图片、音频和视频 |
| 语言 | 英文准确率最高;其他语言可用,但效果并不等同 |
| 别名 | jev-latest 是稳定默认值;jev-preview 跟随最新发布 |
按这个价格,一百万条短工单的成本不到 $10。TypeSafe 同时声明,Jev 不会用客户的请求或响应做训练。
常见错误与修复方式
| 状态码 | 含义 | 修复方式 |
|---|---|---|
| 401 Unauthorized | API Key 缺失或无效 | 检查 Authorization: Bearer header,并确认你运行所在的那个 shell 或环境里确实设置了该环境变量 |
| 422 Unprocessable Entity | 请求体未通过校验 | 常见原因:choice 缺少 criteria、score 的等级少于 2 个、type 拼写错误,或者 questions 被当成数组而不是 map 发送 |
| 429 Too Many Requests | 超出速率限制 | 带抖动退避后重试;把多个问题合并到一个请求里以降低请求数 |
| 529 Overloaded | TypeSafe 暂时过载 | 用指数退避重试;这个请求可以安全重复 |
迭代过程中最常碰到的是 422;第 6 步的接口数据结构能在请求离开你的机器之前挡掉其中大部分。
FAQ
Jev API 有免费额度吗? 公开文档只列出了按 token 计费的价格,没有描述免费额度或启动赠金,而且访问本身目前仍需等待名单。等邀请到手后到控制台查看当前政策,其他任何地方看到的数字都当作非官方信息处理。
一次请求能拿到多个答案吗? 可以。questions 是 map,所以 noul、choice 和 score 可以在一次调用里针对同一个 state 全部跑完。这比发三次请求更便宜,而且因为共用同一份输入,答案之间也是一致的。
这和聊天模型上的 structured outputs 有什么区别? structured outputs 强制语言模型输出合法 JSON,但里面的值仍然是生成的 token,而“confidence”字段是模型关于自己写的文本。Jev 把测量出来的概率作为原生输出返回,所以你才能断言 noul > 0.9 并信任这个比较。
如果我用 Vercel,还需要 TypeSafe 的 SDK 吗? 不需要。Vercel AI SDK 通过 experimental_evaluate 暴露 Jev,模型 id 是 typesafe-ai/jev。你改用 AI Gateway key 鉴权而不是 TypeSafe key,布尔型答案则以 probability 返回。
下一步
现在你已经有了 Jev API Key、一份可用的 curl 与 Python 请求,也清楚 noul、choice 和 score 该怎么读。把请求放进 Apifox,加上概率断言,并保存成测试场景,让 prompt 的修改像代码一样被测试。
开发必备:API 全流程管理神器 Apifox
介绍完上文的内容,我想额外介绍一个对开发者同样重要的效率工具 —— Apifox。作为一个集 API 文档、调试、设计、测试、Mock、自动化测试于一体的工具,Apifox 是目前提升研发效率的首选。
如果你正在开发项目,不妨试试其极其友好的界面设计,它完全兼容 Postman 和 Swagger 数据格式,导入数据非常方便,,即使是新手也能很快上手,点击这里即可注册使用。

值得一提的是,除了个人和常规团队使用,针对有高安全合规要求、或需要在内网环境协作的企业,Apifox 还提供了深度定制的私有化部署方案。
获取专属报价与部署方案
详细的私有化部署系统架构与安全白皮书
针对您公司规模的专属报价单
免费的 1v1 专属产品演示 (Demo) 机会