TypeSafe 判断型模型
TypeSafe System One(jev-latest):不生成文本,只返回类型化判断——是/否概率、选项分布、档位分布。POST /v1/systemone 的请求与响应结构、三种问题原语、confidence 用法、按次计费与限制、官方 SDK 接法、错误速查,附 Agent Skill
POST /v1/systemone
TypeSafe 的 System One 模型(当前是 Jev,模型名 jev-latest)和对话模型不是一类东西:
你给它一份 state(要评估的内容)和若干个带类型的 questions,它对每个问题返回一个
概率,不返回文字。三种问题类型——Noul(是 / 否的概率)、Choice(在你定义的选项里选一个,
附完整概率分布)、Score(在你定义的有序档位上按概率加权打分)——覆盖了路由、分类、打分、抽取、
校验这一类「代码里需要一小块常识判断」的场景。它快(本网关实测单次 1 秒左右)、便宜、输出可直接进 if。
本页讲在本网关上怎么调:地址、请求响应结构、三种原语怎么选、confidence 怎么用、计费与限制、错误。 概念与更多模式以 TypeSafe 官方文档 为准。最后验证:2026-09-19。
给 AI 编程代理装 Skill
TypeSafe 官方给 Claude Code 等代理写了一份 skill,教代理怎么把「提示词 + 解析文本」改成结构化判断、
三种原语怎么选、怎么组合与验证。我们把它完整译成中文,加上了本网关的差异(端点、令牌、按次计费、不支持 models.list()),
并附上 API 参考、模型页的中文版和本页的 Markdown 版。
把这句话发给你的代理,它自己会装:
帮我安装这个 Skill:https://docs.vibeapi.cn/typesafe-skill.zip想手动装:解压得到 typesafe/(SKILL.md、references/、VERSION、scripts/update.sh),放进代理的 skills 目录。
它和主 skill 一样会自己检查更新,机制见快速开始。
装了VibeAPI 主 skill 的代理,也能从它的 references/typesafe.md 读到本页。
与官方的差异
官方 SDK 和文档里的代码只改两处就能用:base_url 指到本网关,api_key 换成 VibeAPI 的令牌。
| 官方 | 本网关 | |
|---|---|---|
| 端点 | https://api.typesafe.ai/v1/systemone | https://www.vibeapi.cn/v1/systemone |
| 认证 | TypeSafe 的 key | Authorization: Bearer <VibeAPI 的 sk- 令牌>,任意分组 |
| 模型 | jev-latest / jev-preview / jev-1.13.0 | 只开放 jev-latest(三者当前指向同一个模型) |
| 计费 | 按输入 token | 按次:一次请求一个价,与 state 长度、问题数量、返回 token 无关 |
models.list() | 返回 TypeSafe 形状 | 不支持——本网关 /v1/models 是 OpenAI 形状,SDK 会报响应校验错误;模型名直接写死 |
| 请求校验 | 上游 422 | 网关先做一层结构校验返回 400,再由上游做语义校验(422 逐条透出) |
基本调用
curl https://www.vibeapi.cn/v1/systemone \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "jev-latest",
"state": "Help! My payouts have been failing for 3 days.",
"questions": {
"is_urgent": {"type": "noul", "instructions": "Does this convey urgency?"},
"department": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"billing": "Payments, invoicing, refunds",
"technical": "Bugs, outages, integrations",
"sales": "Pricing, upgrades, new accounts"}},
"frustration": {"type": "score", "instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]}
}
}'# pip install typesafe-sdk
from typesafe_sdk import TypeSafeClient, Choice, Noul, Score
client = TypeSafeClient(api_key="YOUR_API_KEY", base_url="https://www.vibeapi.cn")
response = client.system_one(
model="jev-latest",
state={"document": "Help! My payouts have been failing for 3 days."},
questions={
"is_urgent": Noul(instructions="Does this convey urgency?"),
"department": Choice(
instructions="Which team should handle this?",
criteria={"billing": "Payments, invoicing, refunds",
"technical": "Bugs, outages, integrations",
"sales": "Pricing, upgrades, new accounts"},
),
"frustration": Score(
instructions="How frustrated is the customer?",
criteria=["Calm", "Frustrated", "Very angry"],
),
},
)
print(response.model) # 实际应答版本,如 jev-1.13.0
print(response.answers["is_urgent"].noul) # 0.95
dept = response.answers["department"]
print(dept.choice, dept.confidence, dept.probabilities)
print(response.answers["frustration"].score) # 1.05,落在 Frustrated 附近// npm install @typesafe-ai/sdk (Node.js 20+)
import { TypeSafeClient, noul, choice, score } from "@typesafe-ai/sdk";
const client = new TypeSafeClient({ apiKey: "YOUR_API_KEY", baseURL: "https://www.vibeapi.cn" });
const response = await client.systemOne({
model: "jev-latest",
state: { document: "Help! My payouts have been failing for 3 days." },
questions: {
is_urgent: noul("Does this convey urgency?"),
department: choice("Which team should handle this?", {
billing: "Payments, invoicing, refunds",
technical: "Bugs, outages, integrations",
sales: "Pricing, upgrades, new accounts",
}),
frustration: score("How frustrated is the customer?", ["Calm", "Frustrated", "Very angry"]),
},
});
console.log(response.answers.is_urgent.noul); // 0.95
console.log(response.answers.department.choice); // "billing"
console.log(response.answers.frustration.score); // 1.05上面这次请求在本网关的真实响应(2026-09-19):
{
"model": "jev-1.13.0",
"answers": {
"is_urgent": { "type": "noul", "noul": 0.95 },
"department": { "type": "choice", "choice": "billing", "confidence": 0.82,
"probabilities": { "billing": 0.88, "technical": 0.12, "sales": 0.0 } },
"frustration": { "type": "score", "score": 1.05, "confidence": 0.93,
"legend": { "0": "Calm", "1": "Frustrated", "2": "Very angry" },
"probabilities": { "0": 0.0, "1": 0.95, "2": 0.05 } }
},
"usage": { "input_tokens": 395, "output_tokens": 73 }
}三个问题、一次请求、一次计费。SDK 也支持环境变量:TYPESAFE_API_KEY 填 VibeAPI 令牌,
TYPESAFE_BASE_URL=https://www.vibeapi.cn,TYPESAFE_DEFAULT_MODEL=jev-latest,然后 TypeSafeClient() 不传参。
请求结构
modelstring必填固定写
jev-latest。这是别名,始终指向 Jev 当前稳定版;响应的model字段会报告实际应答的版本号(如jev-1.13.0), 把它记进日志,方便日后对比。statestring | object | array必填要评估的内容。一段文字传字符串;有多个部分(消息、订单、策略)传带名字字段的对象,让每部分含义清楚、关系明确; 一串消息或记录传数组。同一次请求里所有问题看到的是同一份 state,各自独立评估。
只接受文本。 图片、音频、视频要先自己转成文字或结构化字段再放进来。英文是主要训练语言、准确率最高; 中文能处理但官方自述「不同等」,中文场景先用自己的数据测一轮,路由时多看 confidence。
questionsobject · key → Question必填问题映射,key 由你定,答案在同一个 key 下返回。key 不会发给模型,问题的完整含义要写在
instructions里。 本网关要求至少 1 条、至多 256 条。
三种问题
每个问题都有 type 和 instructions,criteria 的形状因类型而异。
noul是 / 否instructions写一个是 / 否问题;criteria可选,{"true": "是的含义", "false": "否的含义"}。 返回noul:0(否)到 1(是)的概率。没有 confidence——接近 0.5 表示「是」「否」概率相近,不是「中等程度」。 多个标签可能同时成立时,每个标签一个 noul,不要用 choice 单选。choice多选一必填criteria必填,是{选项: 说明}的对象,说明可为null,至少一个选项。 返回choice(概率最高的选项)、probabilities(每个选项的概率,总和为 1)、confidence。 可能什么都不匹配时,自己加一个"other"/"none"选项——模型选不出你没给的值。score有序档位必填criteria必填,是有序的档位描述数组,至少两档,每一档要描述一个具体、独立成立的情形。 返回score(按概率加权的位置,可落在两档之间,如 1.6)、legend(档位编号 → 描述)、probabilities(每档概率)、confidence。 要给一批条目做分级排序,就给每个条目一个可比较的 score。
instructions 和 criteria 的值都接受字符串、对象或数组:简单问题用字符串;需要定义、对比、排除项或示例时用结构化写法。
引用 state 里的嵌套字段用反引号包路径,例如 `ticket.messages[0].text`。
响应结构
modelstring实际执行评估的模型版本号。
answersobject · key → Answer每个问题一个答案,
type与问题一致。各类型的字段见上一节。usageobjectinput_tokens/output_tokens。原样透传,不参与本网关计费,可用来观察 state 有多长。
用 confidence 分流
Choice 和 Score 的 confidence(0–1)是把 probabilities 的集中程度压成的一个数:分布集中在一个选项上就高,摊开就低。
它衡量的是「模型对这一题有多确定」,不是整条业务流程的正确性,也不是「可以执行」的许可。一个常用起点是分三段:
action = response.answers["action"]
if action.confidence < 0.5:
route_to_human() # 模型真的不确定,别猜
elif action.choice == "check_balance":
show_balance() # 低风险动作,错了可恢复,直接做
elif action.choice == "approve_transfer":
if action.confidence > 0.9:
confirm_then_execute() # 高风险 + 高确定:带确认执行
else:
ask_user_to_confirm() # 高风险 + 中等确定:先核实阈值随风险走:同一套系统里,只读操作和破坏性操作用不同的门槛。数字要在你自己的数据上试出来,从保守开始。 几个都可接受的备选项也会把概率摊开——对无害的偏好选择,低 confidence 不一定作废。
一次问多个问题
一次请求评估一份 state、回答任意多个问题,问题之间并行、互不可见。本网关按次计费,多问不加钱, 所以把能一起问的都放进同一次请求,包括「如果是 A 分支,那 X 是多少」这类推测性问题—— 把前提写进问题里,由代码只消费命中的分支。只有当前一个答案是取证据、构造新 state 或决定下一步选项的前提时, 才值得发第二次请求。
上限:一次请求 64k token(state + 全部问题),其中 state + 单个最长问题不超过 32k;问题数不超过 256。
计费与限制
| 项 | 值 |
|---|---|
| 计费 | 按次,jev-latest 每次请求一个固定价,见价格页。与 state 长度、问题数、token 数无关;usage 只是信息 |
| 失败 | 400 / 401 / 422 / 429 / 5xx 不计费 |
| 上下文 | 64k token / 请求;state + 最长问题 ≤ 32k |
| 问题数 | 1–256 条 / 请求 |
| 输入 | 仅文本;英文最佳,中文可用但先测 |
| 超时 | 非流式、单次实测约 1 秒,不受对话模型 120 秒流式建议的影响 |
| 限流 | 按令牌 / 模型限流,超限 429;上游过载 529。用官方 SDK 自带退避重试,直接调 HTTP 自己做指数退避 |
错误速查
| 状态 | 现象 | 先查 |
|---|---|---|
| 400 | question "q": score criteria must contain at least two levels 之类 | 网关本地校验:state / model / questions 必填;type 只认 noul / choice / score;choice 的 criteria 非空对象;score 至少两档;问题 ≤ 256 条 |
| 401 | Invalid token | 用的是 VibeAPI 的 sk- 令牌吗(不是 TypeSafe 的 key);Anthropic / OpenAI SDK 那种带 /v1 的 base_url 在这里不要带 |
| 422 | questions/q/choice/instructions/str: Input should be a valid string; ... | 上游校验:字段类型不对(如 instructions 传了数字、criteria 的值不是字符串)。路径用 / 分隔指到出错的字段 |
| 429 / 529 | 限流 / 上游过载 | 退避重试 |
SDK 报 Invalid response data at 'models' | 调了 models.list() | 本网关不支持这个方法,模型名写死 jev-latest |
503 No available channel for model ... | 模型名写错 | 只有 jev-latest |
官方文档
概念、更多模式与 cookbook 以官方为准,Mintlify 站在路径后加 .md 可拿 Markdown:
- 文档索引 · System One 是什么 · 如何用 TypeSafe 构建
- State · 原语:Choice / Noul / Score · Confidence
- HTTP API · Python SDK · JavaScript SDK
- 模式:推测性扇出 · 复合打分 · 用例地图
最后更新于