# Jev API 调用教程

> 从完整 JSON 请求开始接入 Jev API，提供 curl、Python 和 Node.js 示例。解释 Choice、Score、Noul 的返回结果、上下文限制、鉴权与错误重试，并区分 TypeSafe 官方接口和 OmniaKey 路由的 Key、费用及账号限额。

- Canonical HTML: https://omniakey.com/zh/blog/jev-api-guide
- Markdown: https://omniakey.com/zh/blog/jev-api-guide.md
- Published: 2026-09-28 (updated 2026-10-24)
- Author: Kiki, COO at OmniaKey
- Language: zh
- Category: API setup
- Reading time: 11 min
- All posts: https://omniakey.com/blog/llms.txt

---

**Jev API 用来对文本做有明确范围的判断。** 请求由 `state`、`model` 和 `questions` 组成，返回的 `answers` 使用原来的问题 ID。它不是聊天补全接口，不需要从一段生成文本里再提取标签。

这篇教程解决接入问题。模型适合什么任务、有哪些限制和价格背景，请先看 [Jev 模型介绍](https://omniakey.com/zh/blog/jev-model-explained)。

> **核验日期：2026 年 10 月 24 日。** 请求与响应结构依据 TypeSafe 官方文档，网关路由结合 OmniaKey 实现核对。示例做了离线检查，没有新增付费性能实测。官方直连的价格和限额不自动等于网关账号的条件。

## 先选对接口和 API Key

|调用方式|POST 地址|使用的凭据|
|-|-|-|
|OmniaKey|`https://api.omniakey.com/v1/alpha/search`|有权调用 `jev-latest` 的 OmniaKey API Key|
|TypeSafe 官方直连|`https://api.typesafe.ai/v1/systemone`|TypeSafe API Key|

两种方式都使用 `Authorization: Bearer ...` 和原生 Jev 请求体。**不要把 OmniaKey Key 发给 TypeSafe，也不要反过来使用。** 网关地址不是 `/v1/chat/completions`，把 `state` 换成 `messages` 会改变接口合同。

创建权限受控的 Key，确认 [当前 Jev 模型路由](https://omniakey.com/zh/jev-latest)，并在本地环境中设置 `OMNIAKEY_API_KEY`。Key 不应放进浏览器代码、Git 或截图。通用步骤见 [API 快速开始](https://docs.omniakey.com/cn/quick-start)。

## 完整的 Jev JSON 请求示例

将下面内容保存为 `jev-request.json`。一次请求对同一条客服消息分别判断部门、情绪程度和紧急性。示例保留英文输入；TypeSafe 表示英文目前表现最好，中文工作流应使用自己的真实样本验证。

```json
{
  "model": "jev-latest",
  "state": "My payouts have failed for three days. Please help me resolve this today.",
  "questions": {
    "department": {
      "type": "choice",
      "instructions": "Which team should handle this message?",
      "criteria": {
        "billing": "Payments, invoices, or refunds",
        "technical": "Bugs, outages, or integrations",
        "sales": "Pricing, upgrades, or new accounts"
      }
    },
    "frustration": {
      "type": "score",
      "instructions": "How frustrated is the customer?",
      "criteria": ["Calm", "Frustrated", "Very angry"]
    },
    "is_urgent": {
      "type": "noul",
      "instructions": "Does the message express a time-sensitive need?"
    }
  }
}
```

`department`、`frustration`、`is_urgent` 是请求与响应之间的对应 ID。官方说明这些 ID 不参与推理，因此真正的判断要求要写在 `instructions` 里，不能只藏在键名里。`state` 也可以是包含文本的 JSON 对象或数组，例如带不同字段的工单记录。

```bash
curl --fail-with-body https://api.omniakey.com/v1/alpha/search \
  -H "Authorization: Bearer $OMNIAKEY_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @jev-request.json
```

使用官方直连时，将地址换为 `https://api.typesafe.ai/v1/systemone`，凭据换为 `$TYPESAFE_API_KEY`。保留原生 JSON 结构，并核对该账号可用的模型名称。

## Choice、Score、Noul 的返回值怎么读

|问题类型|请求中定义什么|读取哪些字段|含义|
|-|-|-|-|
|`choice`|选项与描述的映射，最多 255 个选项|`choice`、`probabilities`、`confidence`|选中的标签和各选项的概率分布|
|`score`|2–10 级有序评分标准|`score`、`legend`、`probabilities`、`confidence`|按概率加权的等级，可以是小数|
|`noul`|是非问题，可选填 `true` / `false` 标准|`noul`|0 到 1 之间“是”的概率，不是布尔值|

响应还包含 `model` 和 `usage.input_tokens` / `usage.output_tokens`。当前 `jev-latest` 指向 `jev-1.14.0`，别名以后可能变化。做效果评估时应记录实际返回的版本；需要固定版本时直接写 `jev-1.14.0`。

如果评分标准只有三级，`1.05` 表示略高于第 1 级，并不是百分制的 1.05 分，要结合 `legend` 阅读。Noul 返回 `0.8` 也不意味着可以直接执行退款等不可逆动作。阈值应在带标签的业务样本上确定；`confidence` 来自概率分布，不保证判断一定正确。

下面是完整响应的示意数据，不是本次实测的 API 返回。答案数值和 token 数量仅用于解释结构，实际结果会有所不同。

```json
{
  "model": "jev-1.14.0",
  "answers": {
    "department": {
      "type": "choice",
      "choice": "billing",
      "probabilities": {
        "billing": 0.88,
        "technical": 0.12,
        "sales": 0.0
      },
      "confidence": 0.81
    },
    "frustration": {
      "type": "score",
      "score": 1.05,
      "legend": {
        "0": "Calm",
        "1": "Frustrated",
        "2": "Very angry"
      },
      "probabilities": {
        "0": 0.0,
        "1": 0.95,
        "2": 0.05
      },
      "confidence": 0.92
    },
    "is_urgent": {
      "type": "noul",
      "noul": 0.8
    }
  },
  "usage": {
    "input_tokens": 320,
    "output_tokens": 72
  }
}
```

## Python 与 Node.js 调用

下面都复用 `jev-request.json`，每次只发送一个请求，打印原生答案，不假设存在 OpenAI 风格的 `choices`。生产客户端还需要后文的有限重试策略。

```python
import json
import os
import urllib.error
import urllib.request
from pathlib import Path

request = urllib.request.Request(
    "https://api.omniakey.com/v1/alpha/search",
    data=Path("jev-request.json").read_bytes(),
    headers={
        "Authorization": f"Bearer {os.environ['OMNIAKEY_API_KEY']}",
        "Content-Type": "application/json",
    },
    method="POST",
)
try:
    with urllib.request.urlopen(request, timeout=30) as response:
        result = json.load(response)
except urllib.error.HTTPError as error:
    raise SystemExit(f"Jev request failed: HTTP {error.code}") from None

print(result["model"])
print(json.dumps(result["answers"], indent=2))
```

```javascript
import { readFile } from 'node:fs/promises';

const key = process.env.OMNIAKEY_API_KEY;
if (!key) throw new Error('Set OMNIAKEY_API_KEY first');

const response = await fetch('https://api.omniakey.com/v1/alpha/search', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${key}`,
    'Content-Type': 'application/json',
  },
  body: await readFile('jev-request.json', 'utf8'),
  signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(`Jev request failed: HTTP ${response.status}`);

const result = await response.json();
console.log(result.model);
console.log(result.answers);
```

Python 示例使用 Python 3 标准库；Node.js 需要支持内置 `fetch` 和 `AbortSignal.timeout`。这是 HTTP 接入示例，不代表 OpenAI SDK 原生支持 Jev Schema。TypeSafe 自有 SDK 的行为以[官方 API 文档](https://docs.typesafe.ai/api)为准。

## 上下文长度、限流与费用

当前官方限制需要同时满足：**整个请求最多 64K tokens，`state` 加最长的单个问题最多 32K tokens**。先删掉无关上下文，再把确实共享同一状态的问题放到一起。

TypeSafe 当前列出 **250,000 tokens/秒、1,200 请求/分钟**，并说明早期开放期间可能动态调整。这是账号吞吐限制，不是单次响应速度，也不是对 OmniaKey 账号的承诺。网关可能另有账号或请求限制。

官方直连价格为 **每百万输入 tokens $0.042，输出 tokens 免费**。响应仍会返回输出用量。这不等于整个 API 免费，也不代表网关使用相同计费单位或价格。OmniaKey 费用以当前模型报价和调用记录为准，概览见 [Jev 价格与限制说明](https://omniakey.com/zh/blog/jev-model-explained)。

OmniaKey 当前的 Jev 模型按**请求次数计费**。估算网关费用时，请核对当前模型报价和控制台用量记录。

## 鉴权失败、参数错误和重试

|TypeSafe 直连接口状态|先检查什么|处理方式|
|-|-|-|
|`401`|Key 是否属于当前服务，Bearer 头是否正确|修正凭据，不重复发送相同无效 Key|
|`422`|必填字段、问题类型与 `criteria` 结构|根据错误信息修正对应字段|
|`429`|请求数或 token 限额|有 `Retry-After` 时遵守该值；使用有上限的指数退避并加入抖动|
|`529`|服务暂时过载|退避重试，同时限制次数和总等待时间|

这些含义来自官方直连文档。网关可能有自己的鉴权、参数校验和上游错误格式。路由不可用时还要检查路径与准确的模型 ID。对外分享诊断信息时，不包含 Key 或私有请求正文。

把模型调用与后续业务动作分开：重试分类请求不能导致邮件重复发送或重复退款。连续失败后，应明确返回失败或进入人工复核，而不是默默使用一个看似确定的默认答案。

## 常见问题

### 这是 Jev 官方 API 文档吗？

这是 OmniaKey 的 Jev API 接入教程。[TypeSafe API 参考](https://docs.typesafe.ai/api)定义官方请求结构，[型号页](https://docs.typesafe.ai/models)定义官方价格与限额。上方表格已区分两条调用路径。

### 可以上传图片，或者让 Jev 写文章吗？

Jev 1.14 默认接受文本并返回上述类型化决策。非文本素材需要先转成文本或结构化字段，1.14 的图片输入还在实验性开关后面；生成解释、图片或视频需要其他模型或应用步骤。

### 应该使用别名还是固定版本？

探索阶段可以使用别名。上线带阈值的工作流时，应评估实际支持的固定版本并记录响应中的 `model`，版本变化后重新验证阈值。网关和官方可用的模型名称可能不同。

## 资料来源

- [TypeSafe API 参考](https://docs.typesafe.ai/api)
- [型号、价格、别名与限额](https://docs.typesafe.ai/models)
- [置信度说明](https://docs.typesafe.ai/confidence)
- [Jev 1.13 的能力边界](https://docs.typesafe.ai/model-jaggedness/jev-1.13)
