1613 字
8 分鐘

Jev API 教學:用 TypeScript 實作分類、評分與條件判斷

Jev 最容易理解的方式不是看效能圖,而是把它放進一個小流程:收到客服訊息後,判斷部門、緊急程度與是否要求退款,接著由程式決定自動分流或交給人工。

這篇使用 TypeSafe 官方 JavaScript/TypeScript SDK。範例依 2026 年 9 月 22 日的 SDK 0.6.0 與 Jev 1.13 文件撰寫;程式碼採伺服器端 Node.js 20 以上環境,API 金鑰不應放進瀏覽器。

先準備 API 金鑰與套件#

在 TypeSafe Console 建立 API 金鑰後,把它放進環境變數:

Terminal window
export TYPESAFE_API_KEY='你的 API 金鑰'
npm install @typesafe-ai/sdk

官方 SDK 預設讀取 TYPESAFE_API_KEY,並呼叫 jev-latest。正式環境若已針對某個版本調整門檻,建議固定版本 ID;jev-latest 會隨新版本移動,答案分布可能改變。

不要在前端直接呼叫

SDK 會拒絕預設的瀏覽器執行方式,因為這會把 TypeSafe API 金鑰暴露給使用者。請從伺服器、Serverless Function 或受控後端呼叫。

用一個請求完成三種判斷#

Choice 選固定分類,Score 評估有順序的程度,Noul 回傳某個條件成立的機率。三個問題可以共用同一份 state

import {
choice,
noul,
score,
TypeSafeClient,
} from '@typesafe-ai/sdk';
const client = new TypeSafeClient({
defaultModel: 'jev-1.13.0',
});
const message = {
subject: '三月帳單重複扣款',
body: '信用卡被扣了兩次,請今天協助退款,不然我會取消服務。',
};
const response = await client.systemOne({
state: message,
questions: {
department: choice('哪個部門應處理這則訊息?', {
billing: '帳單、付款、重複扣款與退款',
technical: '系統錯誤、服務中斷與串接問題',
sales: '價格、升級與新合約',
other: '不符合其他選項',
}),
urgency: score('這則訊息的處理急迫程度?', [
'沒有期限或阻塞問題',
'希望儘快處理,但沒有明確期限',
'有明確期限、營運阻塞或高流失風險',
]),
refundRequested: noul('使用者是否明確要求退款?', {
true: '訊息直接要求退款或退還款項',
false: '沒有要求退款',
}),
},
});
console.log(response.model);
console.log(response.answers.department);
console.log(response.answers.urgency);
console.log(response.answers.refundRequested);

這段程式不要求 Jev 產生回覆內容。department.choice 是最高機率選項,urgency.score 是各量表等級的機率加權值,refundRequested.noul 則是「是」的機率。

把判斷結果留給程式控制#

不要把 confidence 直接解讀成「正確率」,也不要看到最高選項就執行不可逆動作。先把政策寫在程式裡:

const department = response.answers.department;
const refund = response.answers.refundRequested;
if (department.confidence < 0.6) {
await sendToManualReview({ message, reason: 'department_uncertain' });
} else if (department.choice === 'billing') {
await enqueueBillingTicket(message);
} else {
await enqueueDepartmentTicket(department.choice, message);
}
if (refund.noul >= 0.8) {
await addTicketFlag('refund_requested');
}

這裡的 0.60.8 只是流程範例,不是官方建議門檻。正式使用前,應拿自己的標註資料測量不同門檻造成的 false positive、false negative 與人工審核量。

退款旗標也不代表程式可以直接退款。Jev 適合判斷語意,金額、訂單狀態、付款資格與實際退款仍應交給可驗證的商業邏輯。

問題與選項怎麼寫比較穩定#

每個問題只處理一個判斷。不要把「是否緊急、應由誰處理、要不要退款」合併成一句,再期待模型回傳一個難以解釋的總分。

Choice 的選項說明要彼此能區分,並在可能沒有合適答案時加入 othernone。TypeSafe API 最多接受 255 個 Choice 選項,但分類樹很大時,分層選擇會比一次塞進所有項目更容易評估。

Score 的 criteria 必須是有順序且能獨立理解的等級,API 接受 2 到 10 級。避免只寫「低、中、高」卻不說明界線,也不要拿 Score 插值還原精確金額或日期。

Noul 適合檢查單一條件。如果多個標籤可以同時成立,應替每個標籤各問一個 Noul,而不是用 Choice 強迫它只能選一個。

處理 rate limit 與服務錯誤#

TypeSafe API 可能回傳 401422429529。官方 SDK 預設會針對 rate limit 與暫時過載執行退避重試;應用程式仍要定義最終失敗時的行為:

try {
const response = await client.systemOne({
state: message,
questions: {
department: choice('哪個部門應處理這則訊息?', {
billing: '帳單與付款',
technical: '系統與串接問題',
other: '其他',
}),
},
});
await routeWithPolicy(response.answers.department);
} catch (error) {
console.error('TypeSafe 判斷失敗', error);
await sendToManualReview({ message, reason: 'typesafe_unavailable' });
}

對客服分流來說,失敗後送人工通常比丟棄訊息安全;對低風險推薦功能,則可能選擇顯示預設排序。fallback 必須由產品風險決定,不能由模型替你決定。

上線前先跑 shadow mode#

先保留既有路由結果,只讓 Jev 在旁邊產生判斷與紀錄。每筆至少留下模型版本、原始機率、實際正確標籤、延遲及最後採取的路徑,但不要把敏感原文寫進不受控的 log。

等累積足夠案例後再回答:哪一種問題最常判錯?中文與英文是否需要不同門檻?低信心 fallback 會不會吃掉所有成本收益?模型版本更新後,分布是否漂移?

如果你還在判斷 Jev 是否適合這項工作,先讀 Jev 的用途、限制與成本;要交給 Codex 協助整合,可再看 Jev Skill 與 Codex 路由的實際邊界。若資料不能送到外部 API,Laya 本機模型是另一條可評估的路徑。

常見問題#

Q: Jev API 可以同時問幾個問題?#

A: 同一請求可以混用多個 Choice、Score 與 Noul,問題會以相同 state 獨立評估。官方建議把可能需要的獨立問題放在同一請求,以利用平行處理;額外問題仍會增加輸入 Token,應以實際請求量測成本。

Q: jev-latest 和固定版本該選哪個?#

A: 開發初期使用 jev-latest 方便取得最新穩定版;正式流程若已針對機率與信心門檻完成校正,應固定如 jev-1.13.0 的版本,等新版本重新評估後再切換。

Q: 可以直接用 Jev 判斷後自動退款嗎?#

A: 不建議。Jev 可以辨識「使用者是否要求退款」,但退款資格、金額、訂單狀態與防詐規則應由確定性程式碼驗證。高影響操作還要加入授權、冪等及人工覆核機制。

參考資料:

TypeSafe AI:JavaScript SDK

TypeSafe AI:API reference

TypeSafe AI:Choice

TypeSafe AI:Confidence

TypeSafe JavaScript SDK v0.6.0

Jev API 教學:用 TypeScript 實作分類、評分與條件判斷
https://laplusda.com/posts/jev-typescript-api-choice-score-noul/
作者
Zero
發佈於
2026-09-22
許可協議
CC BY-NC-SA 4.0