提交原生分类、评分和真假判断
curl --request POST \
--url https://your-onehub.example/typesafe/v1/systemone \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "jev-latest",
"state": "The customer requests a refund.",
"questions": {
"refund_requested": {
"type": "noul",
"instructions": "Does the customer request a refund?"
}
}
}
'import requests
url = "https://your-onehub.example/typesafe/v1/systemone"
payload = {
"model": "jev-latest",
"state": "The customer requests a refund.",
"questions": { "refund_requested": {
"type": "noul",
"instructions": "Does the customer request a refund?"
} }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'jev-latest',
state: 'The customer requests a refund.',
questions: {
refund_requested: {type: 'noul', instructions: 'Does the customer request a refund?'}
}
})
};
fetch('https://your-onehub.example/typesafe/v1/systemone', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://your-onehub.example/typesafe/v1/systemone",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'jev-latest',
'state' => 'The customer requests a refund.',
'questions' => [
'refund_requested' => [
'type' => 'noul',
'instructions' => 'Does the customer request a refund?'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-onehub.example/typesafe/v1/systemone"
payload := strings.NewReader("{\n \"model\": \"jev-latest\",\n \"state\": \"The customer requests a refund.\",\n \"questions\": {\n \"refund_requested\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer request a refund?\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://your-onehub.example/typesafe/v1/systemone")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"jev-latest\",\n \"state\": \"The customer requests a refund.\",\n \"questions\": {\n \"refund_requested\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer request a refund?\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-onehub.example/typesafe/v1/systemone")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"jev-latest\",\n \"state\": \"The customer requests a refund.\",\n \"questions\": {\n \"refund_requested\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer request a refund?\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"model": "jev-1.13.0",
"answers": {
"refund_requested": {
"type": "noul",
"noul": 0.99
}
},
"usage": {
"input_tokens": 100,
"output_tokens": 10
}
}{}原生决策 API(预览)
System One 调用
通过原生 HTTP 提交 Jev 分类、评分、真假判断与图片定位,并使用官方客户端调用文本决策。
POST
/
typesafe
/
v1
/
systemone
提交原生分类、评分和真假判断
curl --request POST \
--url https://your-onehub.example/typesafe/v1/systemone \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "jev-latest",
"state": "The customer requests a refund.",
"questions": {
"refund_requested": {
"type": "noul",
"instructions": "Does the customer request a refund?"
}
}
}
'import requests
url = "https://your-onehub.example/typesafe/v1/systemone"
payload = {
"model": "jev-latest",
"state": "The customer requests a refund.",
"questions": { "refund_requested": {
"type": "noul",
"instructions": "Does the customer request a refund?"
} }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'jev-latest',
state: 'The customer requests a refund.',
questions: {
refund_requested: {type: 'noul', instructions: 'Does the customer request a refund?'}
}
})
};
fetch('https://your-onehub.example/typesafe/v1/systemone', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://your-onehub.example/typesafe/v1/systemone",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'jev-latest',
'state' => 'The customer requests a refund.',
'questions' => [
'refund_requested' => [
'type' => 'noul',
'instructions' => 'Does the customer request a refund?'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-onehub.example/typesafe/v1/systemone"
payload := strings.NewReader("{\n \"model\": \"jev-latest\",\n \"state\": \"The customer requests a refund.\",\n \"questions\": {\n \"refund_requested\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer request a refund?\"\n }\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://your-onehub.example/typesafe/v1/systemone")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"jev-latest\",\n \"state\": \"The customer requests a refund.\",\n \"questions\": {\n \"refund_requested\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer request a refund?\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-onehub.example/typesafe/v1/systemone")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"jev-latest\",\n \"state\": \"The customer requests a refund.\",\n \"questions\": {\n \"refund_requested\": {\n \"type\": \"noul\",\n \"instructions\": \"Does the customer request a refund?\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"model": "jev-1.13.0",
"answers": {
"refund_requested": {
"type": "noul",
"noul": 0.99
}
},
"usage": {
"input_tokens": 100,
"output_tokens": 10
}
}{}预览功能,需在目标环境开通 Jev。基础地址、令牌、可用模型和收费规则见 TypeSafe / Jev。
请求字段
| 字段 | 说明 |
|---|---|
model | 必填,使用当前令牌模型列表中的名称。 |
state | 必填,待判断的材料,可以是字符串、JSON 对象或数组。 |
questions | 必填,非空对象;键是你为问题取的名称,结果使用相同名称关联。 |
assets | 图片请求使用的资源对象;本页示例通过唯一标识引用 PNG/JPEG 的 Base64 数据。 |
type 指定类型,instructions 描述判断要求,criteria 定义选项或等级。
| 类型 | criteria 要求 |
|---|---|
choice | 对象,包含 1–255 个选项;键为选项名,值为说明,允许空字符串或 null 说明。 |
score | 数组,包含 2–10 个等级说明,顺序表示等级顺序。 |
noul | 可用 instructions 描述条件;也可用对象中的 true、false 描述判断标准,至少提供一种有效描述。 |
box | 不要求 criteria;必须用 instructions 描述要定位的目标,需要具备 Box 能力的 Jev 1.14 供给。 |
cURL
先按接入说明设置ONEHUB_BASE_URL 和 ONEHUB_API_KEY:
curl "$ONEHUB_BASE_URL/typesafe/v1/systemone" \
-H "Authorization: Bearer $ONEHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "jev-latest",
"state": "The same order was charged twice. Please refund the duplicate charge.",
"questions": {
"refund_requested": {
"type": "noul",
"instructions": "Does the customer request a refund?"
}
}
}'
model、answers 和 usage。下面仅展示结构,判断值与用量不是固定结果:
{
"model": "jev-1.13.0",
"answers": {
"refund_requested": {"type": "noul", "noul": 0.99}
},
"usage": {"input_tokens": 100, "output_tokens": 10}
}
JSON 图片与 Box 定位
图片与 Box 属于 Jev 1.14 的实验能力,需确认当前令牌选择的模型及上游渠道支持。支持 JSONassets 中的 PNG/JPEG Base64;multipart、图片 URL 下载和新版 SDK 文件上传方式不在本页支持范围内。上面的文本示例和下方两个已验证版本的 SDK 文本示例继续适用。
请求添加 TypeSafe-Danger-Zone-Images: true,并在 state 中引用 assets 的同一个唯一标识。渠道若已显式配置该图片开关,其配置优先于客户请求头;平台不会因出现 Box 自动开启其他实验功能。
以下示例只使用 Python 标准库,生成一张 512×512 白底图,中央红块覆盖 x/y 的 128 至 383 像素,再生成 JSON 请求文件,不在命令中展开长 Base64。ONEHUB_MODEL 可指定当前令牌已获授权且有 1.14 供给的模型;默认使用 jev-latest。
python3 - <<'PY'
import base64
import json
import os
import struct
import uuid
import zlib
from pathlib import Path
def chunk(kind, data):
return struct.pack(">I", len(data)) + kind + data + struct.pack(">I", zlib.crc32(kind + data))
pixels = b"".join(
b"\x00" + b"".join(
b"\xff\x00\x00" if 128 <= x < 384 and 128 <= y < 384 else b"\xff\xff\xff"
for x in range(512)
) for y in range(512)
)
png = b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", 512, 512, 8, 2, 0, 0, 0))
png += chunk(b"IDAT", zlib.compress(pixels)) + chunk(b"IEND", b"")
Path("red-square.png").write_bytes(png)
asset_id = str(uuid.uuid4())
request = {
"model": os.environ.get("ONEHUB_MODEL", "jev-latest"),
"state": "请观察这张测试图片:" + asset_id,
"assets": {asset_id: {"type": "image", "format": "png", "data_base64": base64.b64encode(png).decode()}},
"questions": {
"has_rectangle": {"type": "noul", "instructions": "图中是否存在一个红色矩形?"},
"rectangle": {"type": "box", "instructions": "图片中央的红色矩形"},
},
}
Path("box-request.json").write_text(json.dumps(request, ensure_ascii=False), encoding="utf-8")
PY
curl "$ONEHUB_BASE_URL/typesafe/v1/systemone" \
-H "Authorization: Bearer $ONEHUB_API_KEY" \
-H "Content-Type: application/json" \
-H "TypeSafe-Danger-Zone-Images: true" \
--data-binary @box-request.json
{
"type": "box",
"box": {"top": 0.25, "bottom": 0.75, "left": 0.25, "right": 0.75},
"confidence": 0.9
}
left < right、top < bottom。confidence 也是 0–1 的数字,Box 不要求 Choice/Score 所需的 probabilities 或 legend。它始终给出一个矩形,目标不存在时也不能只凭框判断存在性;需要时像示例一样搭配 Noul。Box、Noul、Choice、Score 可以放在同一请求,仍按该请求的最终用量结算。
Python 官方客户端
以下示例基于已验证的typesafe-sdk==0.7.4:
pip install typesafe-sdk==0.7.4
import os
from typesafe_sdk import TypeSafeClient, RetryPolicy, Choice, Score, Noul
with TypeSafeClient(
api_key=os.environ["ONEHUB_API_KEY"],
base_url=os.environ["ONEHUB_BASE_URL"].rstrip("/") + "/typesafe",
retry=RetryPolicy(max_retries=0),
timeout=35,
) as client:
print([model.name for model in client.models.list().models])
result = client.system_one(
model="jev-latest",
state={"ticket": "The same order was charged twice. Please refund the duplicate charge."},
questions={
"team": Choice(
instructions="Which team handles this ticket?",
criteria={"billing": "Payments and refunds", "technical": "Software problems", "other": "Other topics"},
),
"refund_requested": Noul(instructions="Does the customer request a refund?"),
"urgency": Score(
instructions="How urgent is the ticket?",
criteria=["Routine", "Time sensitive", "Immediate emergency"],
),
},
)
print(result.choices["team"].choice)
print(result.nouls["refund_requested"].noul)
print(result.scores["urgency"].score)
print(result.model, result.usage.input_tokens, result.usage.output_tokens)
JavaScript 官方客户端
以下示例基于已验证的@typesafe-ai/sdk@0.6.0,使用 Node.js 的 .mjs 文件运行:
npm install @typesafe-ai/sdk@0.6.0
import { TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient({
apiKey: process.env.ONEHUB_API_KEY,
baseURL: process.env.ONEHUB_BASE_URL.replace(/\/$/, "") + "/typesafe",
retry: { maxRetries: 0 },
timeout: 35000,
});
const models = await client.models.list();
console.log(models.map((model) => model.name));
const result = await client.systemOne({
model: "jev-preview",
state: ["The same order was charged twice.", "Please refund the duplicate charge."],
questions: {
team: {
type: "choice",
instructions: "Which team handles this ticket?",
criteria: { billing: "Payments and refunds", technical: "Software problems", other: "Other topics" },
},
refund_requested: { type: "noul", instructions: "Does the customer request a refund?" },
urgency: {
type: "score",
instructions: "How urgent is the ticket?",
criteria: ["Routine", "Time sensitive", "Immediate emergency"],
},
},
});
console.log(result.answers);
console.log(result.model, result.usage);
client.models.list().models,JavaScript 的 client.models.list() 直接返回数组。调用时使用自己的平台令牌;不要把管理员配置的上游密钥放进客户应用。
读取答案与失败处理
answers 按问题名称返回答案。Choice 的 choice 对应提交的选项,Score 的 legend 解释等级;概率和置信度应按业务需要使用,不应直接视为判断必然正确的保证。
默认只按有效的最终输入用量收费,输出字段仍保留用于对账。错误、断开、重试和扣费的关系见失败时是否收费;查询消费记录时同时保留本次请求的模型名称和 X-Oneapi-Request-Id 响应头。Body
application/json