2026年9月26日
如何用 curl、Python 和 JavaScript 调用 Jev API
一个可以直接贴进终端、再贴进应用的 Jev AI /v1/systemone 首请求 — 附真实响应、实测延迟和完整的错误码表。
进行第一次调用之前
Jev 回答类型化的决策:你发送一个状态加上若干命名问题,它会从你声明的答案中返回一个,并附概率。Optio 是一个独立运营的调用 Jev 的网关 — 你需要创建账户、打开仪表板并创建 API key。完整 key 只显示一次,以 jev_live_ 开头;请把它存进服务器端的密钥管理器或环境变量,绝不要放进前端代码或 Git 仓库。
所有客户端使用的端点都一样:
POST https://jevai.website/api/v1/systemone
Authorization: Bearer $JEV_API_KEY
Content-Type: application/json端点与鉴权头最小的有效请求
请求体由两部分组成:state(决策所针对的对象)和 questions(你想知道什么)。state 可以是纯字符串、字符串数组或 JSON 对象,最多 100,000 个字符。questions 是 1 到 8 个命名问题的映射;名称必须是合法标识符(字母、数字、下划线 — 它会成为答案里的键)。
curl https://jevai.website/api/v1/systemone \
-H "Authorization: Bearer $JEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "The payments webhook failed twice overnight. Should I wake up the on-call engineer?",
"questions": {
"page": {
"type": "noul",
"instructions": "Should someone be paged right now?",
"criteria": {
"true": "Revenue-impacting or data loss",
"false": "Can wait until morning"
}
}
}
}'
curl — 一个 yes/no 问题criteria 里的文字是你自己的描述 — 请像写政策条文一样来写。模型正是参照这些描述来判定的,所以一个带有明确 true/false 定义的“该不该现在呼叫人?”远比同一个问题裸问更稳定可复现。
响应长什么样
这个端点真实的 200 响应如下(抓取自线上网关;token 数来自实际请求):
{
"request_id": "req_fe17d05411092c4f7f97947a",
"model": "jev-1.14.0",
"answers": {
"page": { "type": "noul", "noul": 0.91 }
},
"usage": {
"input_tokens": 128,
"output_tokens": 21,
"credits": 1,
"credits_remaining": 4
},
"latency_ms": 432
}
200 响应(节选)答案以你的问题名称为键,所以在代码里做分支很简单:if (answers.page.noul < 0.8) escalate()。每个响应还带有 request_id — 联系支持时请引用它,并在你这边记录日志以便对账。
三种问题类型
- noul — yes/no。返回 noul:答案为“是”的概率(0–1)。带 true/false 描述的 criteria 可选,但建议提供。
- choice — 从 2–20 个带标签的选项中选一个。返回 choice(所选标签)、每个选项的概率以及一个 confidence 值。
- score — 把状态放到 2–10 级的有序量表上,例如 [Calm, Frustrated, Very angry]。返回连续 score(0 = 第一级)、各级概率、把分数区间映射回标签的 legend,以及 confidence。
一个请求最多可携带 8 个问题 — 这对成本很重要,因为计费按输入 token、有 1 积分最低消费,而不是按问题数。只要总量不超 1,000 token,同一状态上问三个问题与问一个花费相同。
用 Python 和 JavaScript 解析答案
import os, requests
resp = requests.post(
"https://jevai.website/api/v1/systemone",
headers={"Authorization": f"Bearer {os.environ['JEV_API_KEY']}"},
json={
"state": {
"ticket": {"subject": "Refund duplicate charge", "order": "A-104"},
"refund_policy": "Duplicate charges are eligible for a full refund.",
},
"questions": {
"policy_supports": {"type": "noul", "instructions": "Does the policy support this refund?"},
"frustration": {"type": "score", "instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]},
},
},
timeout=30,
)
resp.raise_for_status()
answers = resp.json()["answers"]
if answers["policy_supports"]["noul"] > 0.9:
print("auto-approve; frustration =", answers["frustration"]["legend"])Pythonconst resp = await fetch("https://jevai.website/api/v1/systemone", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.JEV_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
state: "Charged twice for order A-104, please refund the duplicate.",
questions: {
route: {
type: "choice",
instructions: "Which team handles this?",
criteria: {
billing: "Payments, payouts, invoicing, refunds",
technical: "Bugs, outages, integrations",
sales: "Pricing, upgrades, new accounts",
},
},
},
}),
});
const { answers, usage, latency_ms } = await resp.json();
console.log(answers.route.choice, answers.route.probabilities, latency_ms);JavaScript / TypeScript错误码与重试
错误始终是同一种结构:{error: {code, message, request_id}}。请按 code 分支,不要按 message 文本。错误表如下:
- 401 missing_api_key / invalid_api_key — 缺少 Bearer 头,或 key 已被吊销。不要重试。
- 402 insufficient_credits — 工作区余额不足以完成预扣。不要重试;请充值。
- 422 invalid_request — 请求体格式错误、问题名称非法、问题数量为零、state 超过 100,000 字符。不要重试;修正请求。
- 429 rate_limited — 触发了套餐的并发或每分钟请求数上限。用指数退避重试;响应带有 Retry-After 和 X-RateLimit-Remaining 头。
- 502 upstream_error(还有 upstream_timeout、upstream_unreachable)— 模型提供方失败,或 15 秒上游窗口超时。用退避重试;你不会被扣费。
- 529 upstream_overloaded — 提供方容量不足。处理方式与 502 相同。
import time
def decide(body, max_retries=3):
for attempt in range(max_retries + 1):
resp = requests.post(URL, headers=HEADERS, json=body, timeout=30)
if resp.status_code in (429, 502, 529):
time.sleep(min(2 ** attempt, 8))
continue
resp.raise_for_status()
return resp.json()
raise RuntimeError("upstream kept failing; give up or degrade")值得复用的 Python 重试循环积分在模型运行前预扣,并按实际 token 数事后结算;如果提供方失败,预扣自动退回。失败的请求绝不会在账本上留下扣费。
费用与响应速度
1 积分 = 1,000 输入 token;计费为 ceil(输入 token / 1,000)、最低 1,输出 token 免费。在上面的测试里,一个 401 token、带两个问题的请求恰好花 1 积分。按 Starter 包($10 = 100,000 积分)算,即每次决策 $0.0001。
延迟:在同一个工作日连续 16 次线上调用中,单词和双问题请求报告的 latency_ms 都集中在 400–560 ms,中位数约 445 ms。闲置后的第一次调用偶见约 3 s 冷启动;在此样本量下未观察到更长的尾部。请按你所在地区的 p99 设定超时,而不是只信这一个测量。
一个请求能问超过 8 个问题吗?
不能 — 每个请求上限 8 个问题。可以把其余问题拆成对同一状态的第二个请求,或把价值较低的问题转去更便宜的批处理路径。
在哪里领取我的首批免费积分?
每个新工作区自带 5 个免费积分,且 Playground 在浏览器里免费(匿名每天 30 次,登录后 50 次)。5 个积分足以在付费之前用真实数据验证一个决策。
这是 TypeSafe 官方的端点吗?
不是。Optio 是一个独立运营的 Jev 调用网关,与 TypeSafe 无关联、未经其认可,也不是其官方产品。请求结构遵循相同的 /v1/systemone 契约,现有客户端可以直接指向它。
试试 Jev AI Playground ,读完这篇指南就发出你的第一次免费决策。