跳至主要內容
HK Learn AI
AI 開發工具

Jev API 教學:用 JavaScript 發出第一個 TypeSafe 請求、讀取答案與處理錯誤

用 Node.js 與 fetch 呼叫 Jev:完整 model/state/questions 示例,讀取 Choice、Noul 和 usage,處理 401、422、429、529,並固定模型版本。

HK Learn AI 編輯部標誌

HK Learn AI 編輯部

編輯部

發佈於 2026年9月20日

最後審閱:2026年9月20日

分享這篇文章
本頁內容
Jev 資訊圖:Jev API 教學:用 JavaScript 發出第一個 TypeSafe 請求、讀取答案與處理錯誤;具體情境與概念分工示意

難度

中階

所需時間

約 30–60 分鐘(含練習與自行驗證)

你需要準備

TypeSafe 官方文件 · Node.js 20+ · 可用的 TypeSafe API 帳戶(執行呼叫時需要)

開始之前

  • 能閱讀 JSON 與基本流程規則
  • 先用教學或去識別資料,保留人手回退

Jev 的直接 HTTP 入口是 POST https://api.typesafe.ai/v1/systemone。請求的三個核心欄位是 model、state、questions;回應則按你的問題 ID 放在 answers。本篇用 JavaScript 原生 fetch 示範,避免把 Jev 當作 chat completion API。

資料核對:2026 年 9 月 21 日。本文依官方文件研究;原創情境、門檻及計算例子均有標明。本站未以 Jev API 執行性能或廣東話準確率測試。模型、價格與 early access 狀態可能更新。

準備環境與 API key

你需要可使用 TypeSafe API 的帳戶,以及 Node.js 20 或以上。本篇示例只在本機或伺服器執行。用終端機的環境變數或部署平台的 secret manager 提供 TYPESAFE_API_KEY;不要加上 NEXT_PUBLIC_ 前綴,不要寫入前端程式或提交到 Git。尚未取得 early access 時,可先完成 request 結構及本地測試,但不能聲稱已成功呼叫模型。

先建立 jev-client.mjs 放下方 evaluate 函式,再建立 run-jev.mjs 放請求與呼叫程式。若偏好官方 SDK,可使用 @typesafe-ai/sdk;截至核對日文件的方法名為 client.systemOne(...)。本文採用直接 HTTP,方便看清楚實際傳送內容。

核對來源:JavaScript SDK、TypeSafe quickstart。

伺服器持有 API key,POST model、state、questions 並處理 answers、usage 與錯誤
這是介面流程示意;可執行內容以下方文字程式碼為準。(HKLearnAI 生成式資訊圖;概念示意,並非產品畫面或測試結果。)

第一個 request:用 Choice 分類,用 Noul 判斷明確退款要求

export const request = {
  "model": "jev-1.13.0",
  "state": {
    "ticket": "我唔係要退款,想查下點解同一張單扣咗兩次錢。"
  },
  "questions": {
    "category": {
      "type": "choice",
      "instructions": "Classify the main support need in state.ticket. Classify the issue, not an action to execute.",
      "criteria": {
        "billing": "Charges, invoices, duplicate payments or refund enquiries.",
        "technical": "Login or software faults.",
        "delivery": "Shipping, delivery or missing goods.",
        "other": "Unclear or outside these categories."
      }
    },
    "refund_requested": {
      "type": "noul",
      "instructions": "Does the customer explicitly request a refund now? A denial of wanting a refund is no. A duplicate-charge enquiry alone is not a refund request."
    }
  }
};

這個例子刻意使用「唔係要退款」的否定句,並在 instructions 寫清楚,查重複扣款不必然代表要求退款。英文 instructions 只是本篇設計選擇,並沒有證據證明這樣一定比中文好;真正上線前應固定測試集比較。問題 ID category 只用於映射答案,不能代替 instructions 裏的完整語意。

核對來源:TypeSafe HTTP API reference、Jev 1.13 jaggedness — 已知能力弱點。

發送請求:處理錯誤和有限次重試

// Node.js 20+;在伺服器或本機執行,API key 由環境提供。
import { setTimeout as sleep } from 'node:timers/promises';

export async function evaluate(request, apiKey, fetcher = fetch) {
  if (!apiKey) throw new Error('Missing TYPESAFE_API_KEY');
  for (let attempt = 0; attempt < 3; attempt++) {
    const res = await fetcher('https://api.typesafe.ai/v1/systemone', {
      method: 'POST',
      headers: { Authorization: 'Bearer ' + apiKey, 'Content-Type': 'application/json' },
      body: JSON.stringify(request),
      signal: AbortSignal.timeout(15000),
    });
    if (res.ok) {
      const data = await res.json();
      if (!data.model || !data.answers || !data.usage) throw new Error('Unexpected response');
      return data;
    }
    if (![429, 529].includes(res.status) || attempt === 2) {
      throw new Error('TypeSafe HTTP ' + res.status);
    }
    const retryAfter = res.headers.get('retry-after');
    let waitMs = 500 * 2 ** attempt + Math.random() * 250;
    if (retryAfter) {
      const seconds = Number(retryAfter);
      const parsed = Number.isFinite(seconds)
        ? seconds * 1000 : Date.parse(retryAfter) - Date.now();
      if (Number.isFinite(parsed)) waitMs = Math.max(waitMs, parsed, 0);
    }
    // 長等待交回工作佇列,避免一直佔住請求。
    if (waitMs > 30000) throw new Error('Retry later through the job queue');
    await sleep(waitMs);
  }
}

程式只對文件列出的 429、529 作最多三次請求,並尊重可解析的 Retry-After。15 秒 timeout 與 30 秒等待上限是本篇的示例設定,不是 TypeSafe SLA;應配合你的工作佇列調整。網絡中斷、timeout、無法解析 JSON 或缺欄位會拋出例外,讓呼叫端保留人工處理,不能默默視為否定答案。

import { evaluate } from './jev-client.mjs';
// request 使用上方完整物件。
try {
  const result = await evaluate(request, process.env.TYPESAFE_API_KEY);
  const answer = result.answers.category;
  const allowed = Object.keys(request.questions.category.criteria);
  if (answer?.type !== 'choice' || !allowed.includes(answer.choice)) {
    throw new Error('Invalid category answer');
  }
  console.log({ model: result.model, category: answer.choice, usage: result.usage });
} catch (error) {
  console.error(error.message);
  process.exitCode = 1; // 真正系統在此留下待覆核工單。
}

以上是分開展示的程式片段:把 request 宣告與呼叫段放進同一個 run-jev.mjs,然後執行 node run-jev.mjs。不要把終端輸出中的類別當作已授權操作。正式版還應按完整 schema 驗證每題、機率範圍及分佈,再把資料送入業務規則。

如何讀回應,避免自己加出不存在的欄位

位置用途常見錯誤
model記錄實際回答的版本只保存 jev-latest,之後無法重現。
answers.category.choice這題選中的類別把其他欄位或自由文字當成 choice。
answers.category.probabilities每個候選選項的機率只讀最大值,忽略第二選項接近。
answers.category.confidence由分佈導出的信心統計當作相同數值的真實準確率。
answers.refund_requested.noul「有明確退款要求」的機率值讀取不存在的 noul.confidence。
usage記錄 token 用量看到 output_tokens 就以為必然按輸出收費。

本篇不提供偽造的「實際成功回應」數字。你應以自己的 API 回應查看欄位,再在測試資料中核對意圖是否正確。輸出 token 仍可能出現在 usage 裏,而現行模型卡的輸出價格是免費;用量紀錄與計費規則是兩件事。

核對來源:TypeSafe HTTP API reference、Models — Jev 1.13、定價與限制。

Choice、Score、Noul 的答案空間及同一 request 多題的獨立性
一個請求可包含多種問題,但答案不會自動成為其他題目的輸入。(HKLearnAI 生成式資訊圖;概念示意,並非產品畫面或測試結果。)

401、422、429、529 應分開處理

狀態先檢查不應怎樣做
401key 是否存在、有效及放在 Bearer header無限重試同一把無效 key。
422state、model、questions,以及每種題目的 criteria把格式錯誤當作模型認為「其他」。
429速率與並行工作量、Retry-After同時啟動更多工作搶重試。
529供應端暫時過載、延後工作與回退阻塞整條客服流程直到成功。

核對來源:TypeSafe HTTP API reference。

批次大小與版本:不要只看「64k context」

現行文件有兩個同時適用的預算:state 加所有 questions 合計最多 64k tokens;state 加最長單題最多 32k tokens。Choice 最多 255 個選項,Score 應有至少兩級、API 接受最多十級。超過限制應重新切分工作,不是把錯誤吞掉。

上線前固定模型 ID、instructions 及 criteria;更改任何一項都應視作新版本。你不需要把大量歷史訊息全部塞入 state;較短而相關的上下文通常更容易檢查,實際準確性仍以自己的測試為準。

核對來源:Models — Jev 1.13、定價與限制、TypeSafe HTTP API reference。

下一步閱讀

資料來源與引用

我們附上第一手及官方來源,方便你逐一核實。

  1. 1.TypeSafe HTTP API reference — TypeSafe AI
  2. 2.TypeSafe quickstart — TypeSafe AI
  3. 3.JavaScript SDK — TypeSafe AI
  4. 4.Models — Jev 1.13、定價與限制 — TypeSafe AI
  5. 5.Jev 1.13 jaggedness — 已知能力弱點 — TypeSafe AI

常見問題

Jev API endpoint 是甚麼?

POST https://api.typesafe.ai/v1/systemone,使用 Authorization: Bearer API_KEY,body 包含 model、state 及 questions。

Noul 為甚麼沒有 confidence?

API 的 Noul answer 只有 type 和 noul;不要假設它與 Choice/Score 的欄位完全相同。

示例已在 Jev 上跑過嗎?

沒有。本篇按官方 API 編寫並做本地程式檢查;沒有把模擬回應或算術例子稱作 Jev 實測。

本文遵循我們的 編輯準則.

HK Learn AI 編輯部標誌

關於作者

HK Learn AI 編輯部

HK Learn AI 編輯部負責研究、查證同編寫每一篇內容,並引用官方及第一手來源。