
Jev Python API 入门:用类型化判断替代文本生成
Jev Python API 入门:用类型化判断替代文本生成
Jev 是一种不生成文章、只返回类型化判断的 AI 模型。本教程从环境准备讲起,逐步介绍 Python SDK 的安装、API 密钥配置、首次调用,以及 Noul、Choice、Score 三种判断原语与 State 的配合方式,并给出一个可直接运行的完整示例。
Jev 是一类不生成自然语言的 AI 模型:它接收一段文本作为评估对象,针对你提出的问题,直接返回带类型的判断结果——某个选项、一个分数,或者一个 0 到 1 之间的概率值。它解决的是「把 AI 判断嵌进软件逻辑」时最麻烦的一环:传统大语言模型返回的是给人读的句子,程序还得从句子里把真正需要的那点信息解析出来,输出格式稍有波动,解析逻辑就会崩。Jev 把这一步从流程里彻底去掉,返回值本身就是程序可以直接使用的数据结构。
这篇教程适合已经会用 Python 写基本脚本、想把模型判断接进业务流程的开发者。阅读前不需要机器学习背景,但需要能看懂字典、函数调用和条件分支。文中涉及的价格、速度、版本号等易变信息,请以官网当前公布的内容为准。
准备工作
Python 版本要求
使用 Jev 的 Python SDK 需要 Python 3.10 或更高版本。在终端里执行下面的命令确认当前版本:
python --version输出形如 Python 3.11.6 即满足要求。如果版本低于 3.10,需要先升级解释器再继续。
安装 SDK
官方提供的 Python 包名为 typesafe-sdk。使用 pip 安装:
pip install typesafe-sdk如果习惯用 uv 这类较新的包管理器,也可以写成:
uv add typesafe-sdk两种方式效果一致。安装完成后,可以在 Python 交互环境里验证包是否可导入:
python -c "import typesafe_sdk; print(typesafe_sdk.__name__)"没有报错并打印出 typesafe_sdk,说明安装成功。
获取并配置 API 密钥
调用 Jev 需要一枚 API 密钥,用于识别调用方身份并统计用量。密钥在服务方的控制台页面创建,注册账号后即可在相应设置页签发。
拿到密钥后,不要把它硬编码进源码。推荐的做法是写入环境变量,SDK 会自动读取。macOS 与 Linux 的终端:
export TYPESAFE_API_KEY="粘贴你的 API 密钥"Windows 命令提示符:
set TYPESAFE_API_KEY=粘贴你的 API 密钥PowerShell:
$env:TYPESAFE_API_KEY="粘贴你的 API 密钥"变量名 TYPESAFE_API_KEY 是 SDK 默认查找的名字,写错会导致认证失败。把密钥放在环境变量里,也能避免代码被推到公开仓库时连带泄露凭据。
如果只想先感受一下模型行为,服务方还提供了浏览器端的试用页面,粘贴文本、添加问题即可看到结果,无需写代码。正式开发仍建议走 SDK 或 HTTP 接口。
操作步骤
第一步:理解 State 与 Questions 这对基本结构
Jev 的每一次调用都由两部分组成:state 是你要评估的对象,questions 是你要问的问题集合。返回值放在 answers 里,按你在 questions 中定义的键名取用。这个「传入 state 与 questions、取回 answers」的结构在所有调用场景中都不变,理解它之后剩下的都是组合问题。
state 目前只支持文本,具体可以是三种形式之一:字符串、JSON 对象、字符串数组。图像、音频、视频这类多模态输入暂不支持。文本能承载的信息其实很广——客服工单、用户评论、合同条款、日志片段、应用状态的 JSON 快照,都可以作为 state 传进去。
第二步:发出第一次调用
下面这段代码把一条客服消息作为 state,问一个 Yes/No 问题:这条消息是否传达了紧迫性。
from typesafe_sdk import Noul, TypeSafeClient
# 客户端会自动从环境变量 TYPESAFE_API_KEY 读取密钥
client = TypeSafeClient()
message = "我中午点的餐到现在还没送到,配送员也联系不上,午休都快结束了。"
response = client.system_one(
state=message,
questions={
"is_urgent": Noul(
instructions="这条消息是否传达了紧迫性?",
),
},
)
print(response.answers["is_urgent"].noul)输出形如 0.97。这个数字表示「是」的概率,越接近 1 越倾向于肯定,越接近 0 越倾向于否定。
逐项拆开看:
TypeSafeClient()创建与服务通信的客户端对象,后续所有调用都通过它发起。client.system_one(...)是发送请求的核心方法,名字来自 Jev 所属的 System One 模型类别。state=message传入待评估的文本。questions={...}用字典描述问题,键名"is_urgent"只是程序侧的标识符,不会发给模型。Noul(instructions="...")表示一个 Yes/No 型问题,具体问法写在instructions里。response.answers["is_urgent"].noul按键名取出答案,再读它的.noul属性,即 0 到 1 的概率值。
第三步:一次请求里混合多种问题类型
Jev 允许在同一次请求中同时提出多个问题,而且这些问题可以是不同类型。除了 Noul(是/否概率),还有 Choice(从给定选项中选一个)和 Score(按给定档位打分)。
下面的例子对同一条消息同时问三件事:该由哪个部门处理、顾客有多恼火、是否紧急。
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
client = TypeSafeClient()
message = "我中午点的餐到现在还没送到,配送员也联系不上,午休都快结束了。"
response = client.system_one(
state=message,
questions={
"department": Choice(
instructions="这条消息应该由哪个部门处理",
criteria={
"delivery": "配送状态或配送员相关的问题",
"order": "订单内容或门店备餐相关的问题",
"payment": "支付或账单相关的咨询",
},
),
"frustration": Score(
instructions="这位顾客有多恼火",
criteria=[
"冷静,只是在陈述事实",
"有些不满,但语气仍然礼貌",
"非常生气,用词强烈",
],
),
"is_urgent": Noul(
instructions="这条消息是否传达了紧迫性",
),
},
)
print("部门:", response.answers["department"].choice)
print("恼火程度:", response.answers["frustration"].score)
print("紧迫性:", response.answers["is_urgent"].noul)输出形如:
部门: delivery
恼火程度: 0.72
紧迫性: 0.97一次调用拿到三个不同视角的判断,且每个都是带类型的数据。Choice 的 criteria 是「选项名 → 选项说明」的字典,返回值一定是其中某个键;Score 的 criteria 是档位说明的列表,返回值是归一化后的分数。
第四步:直接用 HTTP 调用
SDK 之外,Jev 也提供标准 Web API。想用 Python 以外的语言接入,或者想弄清 SDK 底层做了什么,可以直接发 HTTP 请求。
请求方式为 POST,认证信息放在 Authorization 头里,格式是 Bearer <API密钥>,同时把 Content-Type 设为 application/json。用 curl 试一次:
curl -X POST \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "我中午点的餐到现在还没送到,配送员也联系不上,午休都快结束了。",
"model": "jev-latest",
"questions": {
"is_urgent": {
"type": "noul",
"instructions": "这条消息是否传达了紧迫性?"
}
}
}'返回的 JSON 形如:
{
"model": "jev-1.13.0",
"answers": {
"is_urgent": {
"type": "noul",
"noul": 0.97
}
},
"usage": {
"input_tokens": 84,
"output_tokens": 9
}
}可以看到,SDK 里读到的 0.97 就位于 answers.is_urgent.noul。Python SDK 做的事,本质上就是替你完成这次 HTTP 通信,再把结果包装成对象。
请求体里的 model 字段写成 jev-latest,表示使用当前最新版本的模型;响应里的 model 字段会告诉你实际应答的具体版本。如果希望线上行为长期稳定,可以改为直接指定具体版本号。版本号会随时间更新,请以官网当前信息为准。
一个完整示例
下面把前面的内容串成一个可运行的脚本:读取一条工单文本,同时判断处理部门、顾客情绪和紧迫程度,并根据结果打印一条分派建议。
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
client = TypeSafeClient()
ticket = """
我上周五下的订单,说好三天内发货,现在都周二了物流信息还停在
「已揽收」。我打了三次客服电话都没人接,如果今天还没有明确答复,
我就申请退款并投诉。
"""
response = client.system_one(
state=ticket,
questions={
"department": Choice(
instructions="这条工单应该分派给哪个团队",
criteria={
"logistics": "物流时效、包裹状态相关",
"support": "客服响应、沟通渠道相关",
"refund": "退款、取消订单相关",
},
),
"frustration": Score(
instructions="这位顾客的情绪激烈程度如何",
criteria=[
"平静陈述问题",
"明显不满但仍在沟通",
"已经提出投诉或退款等强硬诉求",
],
),
"is_urgent": Noul(
instructions="这条工单是否需要优先处理",
),
},
)
dept = response.answers["department"].choice
frustration = response.answers["frustration"].score
urgent = response.answers["is_urgent"].noul
print(f"分派团队: {dept}")
print(f"情绪强度: {frustration:.2f}")
print(f"优先处理概率: {urgent:.2f}")
if urgent > 0.8:
print("建议: 立即人工介入")
elif frustration > 0.6:
print("建议: 两小时内回访")
else:
print("建议: 进入常规队列")
这个脚本展示了 Jev 的典型用法:模型负责给出各个维度的判断值,业务规则由代码里的条件分支承担。想调整优先级策略时,改的是阈值和分支逻辑,不需要重写提问措辞。
注意事项
把大问题拆成原子问题
这是使用 Jev 时最关键的一条设计原则:每个问题只问一件明确的事,小到「一个有经验的人看一眼就能凭直觉回答」。这类判断被称为原子问题。
反例是直接问「这份商业计划书值得投资吗」。这个判断由市场规模、技术可行性、竞争差异化等多个独立因素共同决定,需要长时间推理和多方权衡,不适合交给以快速直觉判断为定位的模型。
更好的做法是拆成三个独立问题分别提问:市场规模是否足够大、技术是否现实可行、相比竞品是否有明确差异化。拿到三个数值后,在代码里加权合成最终评分。这样做还有一个额外好处:想调整权重时,改的是代码里的系数,而不是反复修改提示词。AI 的行为因此变成软件逻辑的一部分,可以被显式控制。
输入只支持文本
当前 Jev 接受的输入限于文本,具体为字符串、JSON 对象或字符串数组三种形式,不支持图像、音频、视频等多模态输入。官方文档在说明这一限制时留有扩展余地,但就目前而言,用途集中在文本判断上。
输出不会越出定义范围
Jev 在设计上无法返回超出预设类型范围的值。这意味着「本该是三个分类之一,却答出一个不存在的分类名」或「输出格式崩坏」这类生成式模型常见的问题,在结构上不会发生。这也是它被称为类型安全的原因。
关于性能与价格数据
速度与成本方面的具体数字由服务方自行公布,尚未全部经过第三方独立验证,且会随时间更新。做容量规划或成本估算时,请以官网当前信息为准,不要直接沿用本文或任何二手资料中的数值。
密钥管理
API 密钥只放在环境变量里,不要写进源码、不要提交到版本库。环境变量名必须是 TYPESAFE_API_KEY,SDK 依赖这个固定名称完成认证。