AB
AiBoss
Tutorials

Jev 使用入门:用 System One 模型做快速结构化判定

Tutorials

Jev 使用入门:用 System One 模型做快速结构化判定

Jev 是一类只返回判定、不生成文章的模型,适合把分类、打分、是否判断这类工作塞进程序流程里。本文从概念、请求结构、三种问题类型讲到账号准备、SDK 调用与完整示例,并说明置信度读取、语言差异与不适合交给它的任务。

Jev 是一类只做判定、不写文章的模型。它接收一段自然语言或 JSON 作为输入,针对这段输入回答若干问题,返回的不是句子,而是预先给定选项中的一个、一个分数,或者一个概率值。因为省掉了逐字生成的过程,它的响应通常在百毫秒量级,价格也按输入 token 计费、输出不计费。它适合嵌在程序里当「聪明的 if 语句」:邮件分流、工单归类、内容打标、给上游模型的输出做校验。它不适合需要写回复、写代码、写解释的场景,那些仍然交给常规大语言模型。

本文按「先理解输入输出结构,再动手跑通」的顺序展开。读完之后,应当能判断自己的流程里哪一步可以换成 Jev,并能从零完成一次调用。

准备工作

账号与访问方式

Jev 由 TypeSafe AI 提供,通过其控制台创建 API 密钥后调用。控制台早期采用邀请制,需要先加入等待列表;后续是否仍为邀请制、等待时长多久,会随时间变化,请以官网当前说明为准。如果直接访问控制台被拦下,再去找等待列表入口即可。

如果不想等邀请,也可以通过第三方网关调用。部分聚合网关已经接入该模型,使用网关自己的密钥并把请求地址指向网关端点,模型名按网关文档填写。网关侧的上下文长度、计费方式、促销活动都可能与直连不同,同样以官网当前信息为准。

创建密钥

登录控制台后,在左侧菜单找到 API Keys,点击创建,给密钥起一个能看出用途的名字。密钥只在创建时完整显示一次,关闭弹窗后就无法再次查看,所以务必先复制再关闭。密钥通常以固定前缀开头,把它放进环境变量,SDK 会默认读取:

export TYPESAFE_API_KEY="你的密钥"

密钥属于组织级别,创建者离开组织后密钥仍然有效,这一点在控制台中有说明。

安装 SDK

Python 需要 3.10 及以上版本:

pip install typesafe-sdk
# 或者
uv add typesafe-sdk

JavaScript / TypeScript 需要 Node.js 20 及以上版本:

npm install @typesafe-ai/sdk

不装 SDK 也可以,直接向接口发一个 JSON 格式的 POST 请求即可,鉴权用 Bearer 头带上密钥。

操作步骤

第一步:理解请求的两个字段

一次调用只需要两个东西。

  • state:要判定的数据。可以是纯字符串,也可以是结构化 JSON。做邮件分流时,这里放邮件正文。
  • questions:针对这份数据要问的问题。一次调用可以带多个问题,它们会基于同一份 state 一起评估。增加问题数量对响应时间影响很小。

返回的是 answers,每个问题对应一项,包含答案本身、各选项的概率分布,以及答案的置信度。全部是结构化值,可以直接参与条件判断。

第二步:选择问题类型

问题只有三种类型。

类型返回内容示例
Choice从给定选项中选一个,并给出每个选项的概率这封邮件该由 billing / technical / sales 哪个团队处理
Score落在某个区间的哪个位置,可以返回区间内的中间值客户愤怒程度在 0 到 2 之间的哪个点
Noul返回「是」的概率这件事是否紧急

三种类型都会附带概率。Choice 和 Score 还会额外给出 confidence,也就是答案的置信度。

第三步:写出请求体

以工单归类为例,请求体大致是这样:

{
  "state": "Help! My payouts have been failing for 3 days.",
  "model": "jev-latest",
  "questions": {
    "department": {
      "type": "choice",
      "instructions": "Which team should handle this?",
      "criteria": {
        "billing": "Payments, invoicing, refunds",
        "technical": "Bugs, outages, integrations",
        "sales": "Pricing, upgrades, new accounts"
      }
    }
  }
}

instructions 说明要问什么,criteria 给出选项以及每个选项的含义。criteria 里的描述文字会直接成为模型的判断依据,写得越具体,判定越稳定。

第四步:读取返回结果

对应的返回大致如下:

{
  "model": "jev-latest",
  "answers": {
    "department": {
      "type": "choice",
      "choice": "technical",
      "probabilities": {
        "billing": 0.08,
        "technical": 0.85,
        "sales": 0.07
      },
      "confidence": 0.82
    }
  },
  "usage": {
    "input_tokens": 312,
    "output_tokens": 48
  }
}

返回里没有任何自然语言句子,只有值,可以直接写进 if 分支。

第五步:用置信度做分流

probabilities 是模型给每个选项分配的概率,总和为 1;confidence 表示这些概率有多集中,取值 0 到 1。两者含义不同,不要混用。

置信度高说明模型对这次判定有把握,可以放心自动处理;置信度低说明它自己也拿不准,这种样本应当交给人来看。注意「置信度低」并不等于「属于某一类」,无论最终答案是哪一类,只要置信度低就值得人工复核。阈值由使用者自己定,没有默认值。

if a.confidence < 0.7:
    send_to_human(mail)
elif a.choice == "template":
    archive(mail)
else:
    inbox_worth_reading(mail)

一个完整示例

下面用两封销售邮件做一次完整的分流。两封都是虚构文面:A 是群发式的推广,完全没有提到收件人的具体内容;B 引用了收件人发布过的具体作品,并提出合作意向。人一眼能分辨,但每天读很多封就很累,正好交给 Jev。

Python 调用代码

import time
from typesafe_sdk import Choice, TypeSafeClient

client = TypeSafeClient()  # 读取环境变量 TYPESAFE_API_KEY

MAILS = {
    "A_template": "您好,我们是某某公司,提供社交媒体代运营与涨粉服务,希望能约个时间沟通。",
    "B_worth_reading": "您好,我看了您关于自动化剪辑的那期视频,对其中脚本化的思路印象很深。我们正在做一款会议记录工具,受众和您的频道有重叠,想请您做一期评测,不知是否方便聊聊。",
}

Q = {
    "mail_type": Choice(
        instructions="这封销售邮件属于哪一类",
        criteria={
            "template": "群发式模板,没有提到收件人的具体活动或作品内容",
            "worth_reading": "基于收件人的具体作品或活动撰写,值得进一步沟通",
        },
    )
}

for name, mail in MAILS.items():
    t0 = time.perf_counter()
    r = client.system_one(state=mail, questions=Q)
    ms = (time.perf_counter() - t0) * 1000
    a = r.answers["mail_type"]
    print(f"{name}: choice={a.choice} probabilities={a.probabilities} "
          f"confidence={a.confidence} round_trip={ms:.0f}ms")

预期输出

两封邮件会被干净地分开,A 被判为 template,概率接近 1.0,置信度也接近 1.0;B 被判为 worth_reading,概率约 0.99,置信度约 0.98。往返耗时通常在几百毫秒量级,具体数值受网络状况影响。

输入 token 数取决于邮件长度,输出 token 虽然会出现在 usage 里,但不计费。

在浏览器里验证

控制台提供的 Playground 可以免写代码验证同样的逻辑:把邮件正文粘到 State 区域,把 questions 的 JSON 粘到 Questions 区域,点击运行即可。返回面板会同时显示模型评估耗时和网络往返耗时,右上角可以切换到原始 JSON,看到的就是 choice、confidence、probabilities 和 usage 这些字段,没有任何句子。

JavaScript 版本

import { choice, TypeSafeClient } from "@typesafe-ai/sdk";

const client = new TypeSafeClient();

const response = await client.systemOne({
  state: { document: "I was charged twice. Please fix this ASAP." },
  questions: {
    category: choice("What is this ticket about?", {
      billing: null,
      technical: null,
      other: null,
    }),
  },
});

console.log(response.answers.category.choice);

注意事项

它不会写文章

官方明确说明,该模型不生成回复文本、不写代码、也不输出解释理由。理论上可以通过串联多个 Choice 问题硬凑出文本,但效果很差且非常慢,不要这么做。需要成文输出的环节,仍然交给常规大语言模型。

它不做计算

计数、算术、日期比较都不属于它的能力范围。像「这封邮件是不是 30 天内收到的」这种判断,应当先用代码算出结果,再把结果作为 state 的一部分交给它。

一个问题里不要塞多个判断

把「是否紧急,并且是否属于 billing 团队」合成一个问题问,会明显降低准确率。正确做法是拆成两个问题分别问,组合逻辑放在自己的代码里。

无关信息会拉低准确率

state 里塞进与问题无关的内容会干扰判定,官方把这种现象称为 context rot。处理邮件时只传正文,签名、引用历史、页脚都去掉。

非英语场景需要自行验证

官方文档指出,模型的主要训练语言是英语,其他语言包括中日韩文字也能处理,但精度不在同一水平,建议在正式使用前用自己的数据测试,并在路由时特别关注 confidence。实际对比中,情绪强度、紧急程度这类问题在英语和日语下结果接近,但分类问题可能出现答案翻转、置信度明显下降的情况。因此非英语场景下,置信度阈值应当设得更保守。

响应时间受地理位置影响

官方给出的端到端响应区间是在美国西海岸测得的,从其他地区调用会因为网络往返而变长。实际使用中仍处于几百毫秒量级,与常规大语言模型动辄数秒的等待相比差距明显,但不要直接套用官方数字做容量规划。

价格与配额

计费只针对输入 token,输出不计费。具体单价、免费额度、上下文长度上限、各网关的促销活动都会变动,请以官网当前信息为准。通过第三方网关调用时,上下文长度和计费规则可能与直连不同,长 state 场景要特别留意。

「不会编造选项」不等于「不会选错」

由于答案被限制在给定选项内,模型不可能返回一个不存在的类别,这是结构上的保证。但它仍然可能在给定选项里选错,比如正确答案是 billing 却选了 technical。判断是否可靠要看 confidence,而不是把「不会越界」当成「一定正确」。

适合放置的位置

常见的用法有四类:替代脆弱的硬编码规则做分类与分流;放在实时交互路径里做即时判断;对大批量数据逐行打标签或打分;作为上游模型输出的校验层,用低成本的判定拦住不合规内容。最后一种尤其划算,因为可以做到对每一次生成都跑一遍检查,而用常规大语言模型做同样的检查,时间和费用都会成倍增加。