用 JS SDK 读 Jev 模型元数据
先说结论
- 官方 JS SDK 把模型列表暴露为
client.models.list(),返回ModelCard[];ModelCard只有name、description、release_date三个字段。 - 不要在业务里写死限流阈值。官方 Models 页明确 250,000 tokens per second / 1,200 requests per minute 会动态调整,且可无通知变化。
- 每次调用后的响应里有
model字段,记录它才能知道是哪个版本在参与判定;版本升级会带来 jaggedness,没有记录无法归因。 - 工程上建议启动时缓存模型列表、调用日志写入版本化 ID、限流按 429 与 retry-after 退避,而不是把数值写死在配置。
官方暴露的两个 JS SDK 接口
模型元数据入口在 TypeSafeClient.models。根据官方 JS SDK:TypeSafeClient,这个属性是“The models available to the account.”,也就是客户端直接挂载了一个 Models 资源对象。
官方 JS SDK:Models 接口只有一个方法,签名如下:
list(options?: RequestOptions): APIPromise<ModelCard[]>
也就是说,它返回 ModelCard 数组。再看官方 JS SDK:ModelCard 接口,官方对它的概括是:“Metadata for an available model.” 它只有三个属性:
namedescriptionrelease_date
没有 id、version、context_length 之类的额外字段。官方 Models 页给出的 JS 示例很直接:
import { TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient();
const models = await client.models.list();
for (const model of models) {
console.log(model.name, model.release_date, model.description);
}
这段是官方 Models 页的原文示例。注意变量名是 model 而不是 model_card;返回后直接迭代数组,每一个元素就是 ModelCard。所以代码里能拿到的模型元数据只有名称、描述、发布日期这三样。
官方 Models 页还提到一个关键行为:“Versioned IDs such as jev-1.13.0 are accepted by the model field whether or not they appear in the list.” 也就是说,列表可能只列别名,但版本化 ID 即使不出现在列表中,也能作为 model 字段传给 API。这个细节对于固定版本和日志记录很有用。
模型能力与限流:官方口径
官方 Models 页给出的当前模型是 Jev 1.13,模型 ID 为 jev-1.13.0。官方数据如下:
- 价格:每 Btok $42 / 每 Mtok $0.042
- 限流:250,000 tokens per second / 1,200 requests per minute
- 上下文:每个请求 64k tokens;state 加最长问题为 32k tokens
- 输入:仅文本。字符串、JSON 对象或文本值数组;不支持图片、音频、视频
其中限流数值必须标注为官方数据。但更重要的是官方给出的动态调整声明。原文是:
“Rate limits are adjusting dynamically. We are serving a very large volume of demand, and the limits above can change without notice while we do, as upcoming large GPU deals land and we let in more users.”
这段说明限流会被动态调整,而且可能无通知变化。因此,把 1,200 requests per minute 或 250,000 tokens per second 写死在业务配置里,是工程上的坏做法。官方还说,自己的客户端 SDK 会默认重试并处理 429:
“Our client SDKs retry with backoff by default and honor the retry-after header when the response carries one.”
所以如果使用官方 JS SDK,日常调用可以依赖它的默认重试行为;如果绕过 SDK 直连 HTTP API,则需要自己根据 429 和 retry-after 头做动态等待。
为什么记录 model 字段:别名会移动,不记录就没法归因
官方 Models 页花了不小篇幅解释 aliases。jev-latest 和 jev-preview 是别名,不是固定版本。jev-latest 指向当前稳定版本,jev-preview 指向预览版本,目前都指向 jev-1.13.0。但别名会在新版本发布时移动。官方原话是:
“An alias moves when a new release ships, so the answers behind it can change without a change on your side. The response’s model field reports the versioned ID that answered, so you can log which model produced each result.”
这说明响应里的 model 字段非常重要。如果调用时用 jev-latest,实际回答可能是 jev-1.13.0,但下个月官方发布新版本后,同样的调用可能由 jev-1.14.0 回答。没有日志里的 model 字段,就无法做回溯和故障排查。官方还建议,如果已经针对某个版本调过置信度阈值,就应该固定版本 ID,而不是继续使用会移动的别名。原话是:
“If you have tuned confidence thresholds against a specific version, pin that version’s ID instead of the alias and move to the new one on your own schedule.”
模型版本变化不是单纯的性能提升,它会改变判定分布。官方 Models 页还提到 jaggedness 的影响,原文片段是:
“See Speculative fan-out for packing many questions into one request, and Jev 1.13 jaggedness for how accuracy shifts as the state grows.”
这说明准确率会随着 state 大小发生变化,版本切换时可能进一步漂移。因此,如果没有版本记录,就无法判断某个线上结果来自哪个模型版本,也无法判断是 state 变化、问题设计变化还是模型版本变化导致的准确率变化。
给一段骨架:查模型、记录版本、调用、记录 usage 与 model、按 429 退避
下面是我给团队用的示意骨架,属于本文做法/工程实践,不是官方复制粘贴模板。
import { TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient();
// 1. 启动时:拉取模型列表并缓存(本文做法)
const models = await client.models.list();
const availableNames = models.map((m) => m.name);
console.log("available_models:", availableNames);
// 2. 调用时:如果已经调优过阈值,建议固定版本 ID
const result = await client.systemOne({
state: "用户反馈:已支付但未发货",
questions: {
refund_issue: noul("这是退款问题吗?"),
},
model: "jev-1.13.0", // 可选 ModelCard.name 或版本化 ID
});
// 3. 记录响应里的 model 和 usage(字段名来自官方 Models 页与 SDk 返回描述)
console.log("answered_by_model:", result.model);
console.log("usage_object:", result.usage);
// 4. 限流退避:官方 SDK 默认带重试和 backoff;如果绕过 SDK 直连 HTTP API,
// 应当根据 429 状态码和 retry-after 头动态等待,而不是写死 tokens/s 或 RPM
我没有展开 result.usage 的具体内部字段,因为官方 TypeSafeClient只说明返回包含“model and token usage”,但没有在本文引用的页面里展开 Usage 字段结构。把 usage 当成整体对象记录即可。
另外要特别注意题目返回形状:noul 只返回一个 noul 值(0~1),没有 confidence 也没有 probabilities;choice 返回 choice、probabilities、confidence;score 返回 score、legend、probabilities、confidence,且 score 问题的 criteria 是从低到高的有序数组。写日志或门控逻辑时,不要假设所有题目都有 confidence。
为什么别把版本与限流写死在文档里
官方 Models 页已经说明两个动态因素:限流会无通知调整,别名会随版本发布移动。如果把 jev-latest 当作固定能力写进内部文档,实际响应模型已经变了;如果把 1,200 requests per minute 写进配置,官方调整后可能出现误判。更稳妥的做法是:
- 文档里只写“可用模型以启动时
client.models.list()返回为准”。 - 调用日志固定记录响应中的
model字段。 - 限流交给 429 与
retry-after,不要手动设置固定阈值。 - 对模型版本敏感的阈值或规则,固定版本 ID,并定期用新版本做回归。
这些都是工程上的建议/本文做法,不是官方要求。
这次没核实的
SystemOneResult中usage的具体字段名和结构:官方 TypeSafeClient 页面只提到返回包含 model 和 token usage,但本文没有抓到Usage接口的字段详情,因此不展开。- 官方 Model jaggedness 页面完整内容:Models 页只提到“Jev 1.13 jaggedness for how accuracy shifts as the state grows”,本文没有抓取到该页完整正文,所以不作进一步断言。
client.models.list()返回的数组是否可能包含未来新增的字段:官方 ModelCard 当前页面只有三个属性,未来若有扩展,需要重新查询接口页面。
参考来源
评论区
登录后可评论。