# OpenRouter 实测 Jev 决策模型对比 LLM，何时该用决策模型替代生成文本

- 来源：OpenRouter：Announcements（RSS）
- 作者：Kenny Rogers
- 发布时间：2026-09-19 08:00
- AIHOT 分数：63
- AIHOT 标记：精选
- AIHOT 链接：https://aihot.news/items/cmucqgii60jz4roedj9fsw3qh
- 原文链接：https://openrouter.ai/blog/tutorials/jev-vs-llm-when-to-use-each

## 精选理由

OpenRouter 用自家基准数据对比 Jev 与生成式 LLM 的成本和延迟，并给出路由与验证两套可直接复用的代码模式。

## AI 摘要

OpenRouter 发布教程，实测 TypeSafe 的决策模型 Jev 1.13 与 GPT Luna、Claude Opus 在工单分诊和提示词注入筛查上的表现：Jev 每 1000 张工单成本 $0.0248、中位延迟 194ms，准确率与 LLM 相当。

## 正文

假设你有一个产品，每月收到 40,000 张支持工单，每一张都需要被分诊，以给出三样东西：它讲的是什么、是否应该升级、以及回复内容是什么。

一个前沿 LLM 配合 JSON schema 就能完成这项工作。我们的基准测试运行显示，它完成这项工作的成本是每 1,000 张工单 $2.88，中位耗时两秒，也就是每月约 $115。一个小型 LLM 完成这项工作的成本是每 1,000 张 $0.09，耗时约一秒。

换一种思路，就是问一个决策模型能做什么。Jev 是来自 TypeSafe 的一个决策模型，在同一次运行中，它以每 1,000 张工单两分半的成本完成了分诊，中位耗时 194 毫秒，也就是每月约一美元。此外它还返回概率，所以没有任何需要解析的东西。

不过它写不了回复。要写回复，你仍然需要一个 LLM。所以我们通过 OpenRouter 在 100 个支持案例上对 Jev、GPT Luna 和 Claude Opus 进行了基准测试，并构建了两种同时利用两者的模式。

Jev 是什么，以及每个模型实际返回什么

让一个语言模型做代码决策，它返回的是文本。你可以要求它输出 JSON，但模型天生是用来写作的。你的代码必须解析输出，并确保模型是在作答，而不是在解释。

Jev 则返回一个带类型的答案。你向它发送状态和由三种原语构建的问题：choice 从你定义的一组选项中挑选一个，noul 返回一个是/否概率，score 将内容放置在你描述的层级上。选择类和评分类答案可以包含基于你自己键的概率，而 noul 是一个单一数字。以下是对一张账单工单的两个问题的响应。

{ "answers": { "intent": { "type": "choice", "choice": "billing_dispute", "confidence": 1, "probabilities": { "billing_dispute": 1, "order_status": 0, "other": 0 } }, "escalate": { "type": "noul", "noul": 0.04 } }, "model": "typesafe/jev-1.13-20260917", "provider": "TypeSafe", "usage": { "cost": 0.000016002, "inputTokens": 381, "outputTokens": 62 } }

意图是你自己键中的一个，而升级则是一个数字，你用它与你决定的阈值进行比较。

TypeSafe 称 Jev 为 System One 模型。这意味着它做出快速、直觉性的判断，而非缓慢、审慎的分析。它只接受文本，因此不接受图像、音频或 PDF 作为输入。它按字面理解标准。此外，当它检查的状态带有无关细节时，它往往会失去准确性，并且在算术、计数和日期比较方面不可靠。

将 Jev 与生成式 LLM 并排比较

Jev 1.13传统 LLM（GPT Luna、Claude Opus）

输出带类型的选择、是/否概率或评分，并带有每个选项的概率自由文本（可选约束为 JSON）

最擅长分类、路由、验证、排序、护栏检查、有界抽取写作、解释、总结、改写、代码，以及任何输出空间事先未知的任务

输入仅文本（字符串、JSON、数组）。每次请求 64k tokens，其中 32k 用于状态，加上最长的问题文本，对许多模型还支持图像、音频、PDF

价格（观测于 2026-09-19）每百万输入 tokens $0.042，输出免费GPT Luna 每百万 $0.20 输入 / $1.20 输出。Claude Opus 每百万 $5 输入 / $25 输出

60 张工单分诊的中位延迟194 ms1,106 ms（Luna），1,957 ms（Opus）

每 1,000 张分诊工单的成本$0.0248$0.0921（Luna），$2.88（Opus）

OpenRouter 端点POST /api/alpha/decisionsPOST /api/v1/chat/completions

价格来自运行当天的 OpenRouter 模型元数据。做预算前请先查看模型页面。

我们测量了什么

所用模型为 Jev 1.13、GPT Luna（解析为 GPT 5.6 Luna）和 Claude Opus（解析为 Claude Opus 5）。这些大语言模型在系统提示词中获得了与 Jev 相同的定义和升级规则，temperature 设为 0，并要求输出一个裸 JSON 对象。每个示例一次请求。这些是小规模数据集，单日 60 个和 40 个示例，只有一组提示词。这呈现的是权衡的形态，而非排行榜。

任务 A：将 60 个支持工单分诊为五种意图，并附加一个升级标记

60 个支持工单，分为五种意图：订单状态、退货或退款、账单争议、产品咨询、账户访问，每种意图各有一句定义。升级涵盖法律威胁、拒付、疑似欺诈、安全隐患以及公开曝光威胁。

模型意图准确率升级准确率p50 延迟p95 延迟总成本（60）每 1,000

Jev 1.1359/60（98.3%）60/60（100%）0.194s0.633s$0.001489$0.0248

GPT Luna59/60（98.3%）60/60（100%）1.106s2.395s$0.005527$0.0921

Claude Opus60/60（100%）59/60（98.3%）1.957s2.594s$0.17281$2.8802

准确率不相上下。Jev 会发送更多输入 token，因为每个请求都携带完整的判定标准，但它的成本仍约为 GPT Luna 的四分之一，不到 Claude Opus 的百分之一。只有一次意图识别失误，是一个关于退货商品退款分摊的问题。Jev 将其归类为退货或退款，置信度为 0.56。这是唯一一个低于 0.8 的工单，因此若采用 0.8 的阈值，它本来就会被转交给人工处理。

任务 B：筛查 40 条消息是否存在提示词注入

22 条普通客服消息和 18 次注入尝试（忽略你的指令、伪造管理员标记、角色扮演框架、引用式指令）。我们给 Jev 提了一个是/否问题——这是否属于试图改变助手行为的尝试——各个 LLM 得到了相同的定义并返回一个布尔值。

模型准确率p50 延迟p95 延迟总成本（40）每 1,000 条

Jev 1.1340/40（100%）0.194s0.688s$0.000646$0.0161

GPT Luna39/40（97.5%）0.805s1.491s$0.001828$0.0457

Claude Opus40/40（100%）2.099s4.377s$0.063555$1.5889

Jev 干净利落地分开了两组。注入攻击得分在 0.86 到 0.99 之间，普通消息得分在 0.01 到 0.20 之间。Luna 唯一一次漏判是一个角色扮演式的框架设定。

当答案是从 N 个选项中选一个时，使用 Jev

任何以 switch 语句结尾的东西都是 Jev 的问题。意图、优先级、语言、情感、进入哪个队列、是否违反政策、该主张是否得到支持。每一种情况下，答案都是预先已知的。你只是想要每个可能答案的概率。以下是该基准测试使用 OpenRouter TypeScript SDK 进行的分诊调用。

// triage.ts import { OpenRouter } from '@openrouter/sdk';

const openrouter = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY, // server-side only });

const INTENTS = { order_status: 'The customer asks where an order is, when it will ship or arrive, wants to change or cancel an order before delivery, or reports a package missing or partially delivered.', return_refund: 'The customer wants to return, exchange, or replace an item they received, or asks about the status or rules of a return they already started.', billing_dispute: 'The customer says a charge, invoice, tax, discount, or refund amount is wrong, duplicated, unexpected, or unauthorized.', product_question: "The customer asks about a product's features, compatibility, sizing, materials, stock, warranty, or safety before or after buying, without asking to return it.", account_access: 'The customer cannot log in, needs to change login or account details, or asks to merge, delete, secure, or share an account.', } as const;

export type Intent = keyof typeof INTENTS;

const ESCALATE = 'Does the ticket describe any of the following: a threat of legal action, a regulator complaint, or a chargeback; suspected fraud or an account takeover; a safety hazard such as fire, smoke, or injury; or a customer who says this is a repeated failure and threatens to publicize it?';

export type Triage = { intent: Intent; confidence: number; probabilities: Record<string, number>; escalateProbability: number; costUsd: number; };

function isIntent(value: string): value is Intent { return Object.hasOwn(INTENTS, value); }

export async function triage(ticket: string): Promise<Triage> { const result = await openrouter.alpha.decisions.create({ decisionsRequest: { model: 'typesafe/jev-1.13', state: { ticket }, questions: { intent: { type: 'choice', instructions: 'What is the primary intent of the ticket?', criteria: INTENTS, }, escalate: { type: 'noul', instructions: ESCALATE }, }, }, });

const intent = result.answers.intent; const escalate = result.answers.escalate; if (intent?.type !== 'choice' || escalate?.type !== 'noul') { throw new Error('Unexpected answer types'); } if (!isIntent(intent.choice)) { throw new Error(`Unknown intent ${intent.choice}`); } return { intent: intent.choice, confidence: intent.confidence ?? 0, probabilities: intent.probabilities ?? {}, escalateProbability: escalate.noul, costUsd: requireCost(result.usage.cost), }; }

function requireCost(cost: number | undefined): number { if (cost === undefined) { throw new Error('Response did not include usage.cost'); } return cost; }

那段分诊代码中有三点需要注意：

每个问题只问一个小判断，然后在代码中组合答案。 这里意图和升级是同一个请求中的两个独立问题。

像写规格说明一样编写判定标准。 由于 Jev 是字面执行的，当某个案例被归入错误的类别时，先修改判定标准的文本。

只发送每个问题所需的状态。 无关的细节会降低答案的准确率。

当答案是散文时，使用 LLM

现在，当我们真正需要生成回复时，我们使用 LLM。

// draft-reply.ts import { OpenRouter } from '@openrouter/sdk';

const openrouter = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });

const REPLY_MODEL = '~openai/gpt-luna-latest';

const REPLY_SYSTEM = 'You write short, warm replies for the Northwind support team. Use only the facts in the user message. Do not promise refunds, credits, or dates that are not in the facts. Three sentences maximum.';

type Draft = { text: string; model: string; costUsd: number };

export async function draftReply(ticket: string, facts: string): Promise<Draft> { const result = await openrouter.chat.send({ chatRequest: { model: REPLY_MODEL, messages: [ { role: 'system', content: REPLY_SYSTEM }, { role: 'user', content: `Ticket: ${ticket}\n\nFacts: ${facts}` }, ], }, }); // chat.send can return a stream when streaming is requested. It isn't here, so reject that case. if (result instanceof ReadableStream) { throw new Error('Expected a non-streaming response'); } const text = result.choices[0]?.message.content; if (typeof text !== 'string') { throw new Error('Expected text content'); } const cost = result.usage?.cost; if (typeof cost !== 'number') { throw new Error('Response did not include usage.cost'); } return { text, model: result.model, costUsd: cost }; }

根据写作任务选择模型。当你需要快速且低成本的简短回复时，GPT Luna 能够胜任，在本次运行中每条回复约 $0.0001。当写作需要真正的推理、长上下文或代码时，升级到前沿模型。LLM 也是应对 Jev 某些局限性的答案，比如输入包含图像、音频或 PDF，或者输出是文档、diff 或计划。

用 Jev 路由，在代码中计算，用 LLM 撰写

从宏观来看，第一个模式很简单。Jev 负责分诊。代码检查它有多确定。只有当交付物是散文时，代码才会调用 LLM。

处理器将任何升级分数在 0.5 或以上的内容发送给人工。它还会将任何意图置信度低于 0.8 的内容发送给人工。否则，它直接从订单系统回答订单状态，不经过模型；只有当意图需要散文时，它才会向 LLM 请求草稿。

// handle.ts import { triage, type Intent, type Triage } from './triage'; import { draftReply } from './draft-reply';

// These thresholds are application policy. Tune them on your own labeled tickets. const ROUTE_CONFIDENCE = 0.8; const ESCALATE_THRESHOLD = 0.5;

type ReplyIntent = Exclude<Intent, 'order_status'>;

type Route = | { kind: 'human'; reason: string } | { kind: 'deterministic'; intent: 'order_status' } | { kind: 'reply'; intent: ReplyIntent };

function chooseRoute(t: Triage): Route { if (t.escalateProbability >= ESCALATE_THRESHOLD) { return { kind: 'human', reason: `escalation probability ${t.escalateProbability}` }; } if (t.confidence < ROUTE_CONFIDENCE) { return { kind: 'human', reason: `intent confidence ${t.confidence}` }; } if (t.intent === 'order_status') { return { kind: 'deterministic', intent: t.intent }; } return { kind: 'reply', intent: t.intent }; }

// Stand-in for your order system. Exact data never goes through a model. function lookupOrder(ticket: string): string { const id = ticket.match(/\b\d{5}\b/)?.[0]; if (id === undefined) { return 'Please reply with your five-digit order number and we will check the shipment.'; } return `Order ${id} shipped 2026-09-17 via UPS, tracking 1Z999AA10123456784, estimated delivery 2026-09-21.`; }

export const FACTS: Record<ReplyIntent, string> = { return_refund: 'Returns are accepted within 30 days of delivery for regular items. Exchanges for another size follow the same 30-day window. Final sale items cannot be returned or exchanged. Prepaid labels are emailed within one business day.', billing_dispute: 'A billing specialist will review the charge within one business day.', product_question: 'Product specifications are listed on each product page.', account_access: 'Password resets are available from the sign-in page.', };

export type Handled = { triage: Triage; route: Route; text: string; costUsd: number; // Jev call plus the LLM call, if one happened };

// Routes a ticket. A 'reply' route carries an unverified LLM draft; send.ts checks it before anything goes out. export async function handle(ticket: string): Promise<Handled> { const t = await triage(ticket); const route = chooseRoute(t); switch (route.kind) { case 'human': return { triage: t, route, text: `queued for a person: ${route.reason}`, costUsd: t.costUsd }; case 'deterministic': return { triage: t, route, text: lookupOrder(ticket), costUsd: t.costUsd }; case 'reply': { const reply = await draftReply(ticket, FACTS[route.intent]); return { triage: t, route, text: reply.text, costUsd: t.costUsd + reply.costUsd }; } default: return route satisfies never; } }

一个简短的运行器会在每个结果旁边打印 Jev 信号。

// run.ts import { handle } from './handle';

const TICKETS = [ "Hi, I ordered a pair of running shoes on the 3rd and the tracking page hasn't updated in five days. Where is my package? Order 84721.", 'The jacket I got is too small. Can I swap it for a large? I got it last Tuesday.', "There's an unauthorized $450 charge from your company on my card. I've already called my bank to dispute it and I'm reporting this as fraud.", "I paid with a gift card and a credit card, but the refund only went to the credit card. Where's the gift card balance?", ];

for (const ticket of TICKETS) { const r = await handle(ticket); const { intent, confidence, escalateProbability } = r.triage; console.log(`"${ticket}"`); console.log(` intent=${intent} confidence=${confidence} escalate=${escalateProbability} route=${r.route.kind} cost=$${r.costUsd.toFixed(6)}`); console.log(` ${r.text}\n`); }

以下是四个示例工单的输出。

"Hi, I ordered a pair of running shoes on the 3rd and the tracking page hasn't updated in five days. Where is my package? Order 84721." intent=order_status confidence=1 escalate=0.02 route=deterministic cost=$0.000026 Order 84721 shipped 2026-09-17 via UPS, tracking 1Z999AA10123456784, estimated delivery 2026-09-21.

"The jacket I got is too small. Can I swap it for a large? I got it last Tuesday." intent=return_refund confidence=1 escalate=0.01 route=reply cost=$0.000118 Yes, you can exchange the jacket for a large if it’s a regular item and within 30 days of delivery. If it’s a final sale item, it can’t be exchanged; for eligible exchanges, a prepaid return label is emailed within one business day.

"There's an unauthorized $450 charge from your company on my card. I've already called my bank to dispute it and I'm reporting this as fraud." intent=billing_dispute confidence=1 escalate=0.96 route=human cost=$0.000025 queued for a person: escalation probability 0.96

"I paid with a gift card and a credit card, but the refund only went to the credit card. Where's the gift card balance?" intent=return_refund confidence=0.54 escalate=0.02 route=human cost=$0.000025 queued for a person: intent confidence 0.54

四个工单中有一个触及了大语言模型。订单状态查询是精确且免费的。欺诈报告从未到达任何能够做出承诺的模型。因为拆分退款工单——也就是 Jev 在任务 A 中归错档的那个——的置信度低于 0.8，所以它被转交给了人工处理。至于那件夹克的回复，最终在这里仍然是一份未经审核的草稿。审核它，就是第二种模式。

在 LLM 输出发布之前，由 Jev 进行审核

第二种模式的运行方向相反。由 LLM 起草。然后 Jev 在草稿发布之前对照政策进行审核。这能捕捉到那些友好的 AI 回复中承诺了违反政策内容的的情况。

// verify-draft.ts import { OpenRouter } from '@openrouter/sdk';

const openrouter = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });

export const POLICY = 'Returns are accepted within 30 days of delivery for regular items. Final sale items cannot be returned. Refunds go back to the original payment method. Prepaid return labels are emailed within one business day of approval.';

type Label = 'supported' | 'unsupported' | 'declined';

export type Verdict = { label: Label; confidence: number; probabilities: Record<string, number>; costUsd: number; };

function isLabel(value: string): value is Label { return value === 'supported' || value === 'unsupported' || value === 'declined'; }

export async function verifyDraft(policy: string, question: string, draft: string): Promise<Verdict> { const result = await openrouter.alpha.decisions.create({ decisionsRequest: { model: 'typesafe/jev-1.13', state: { policy, customer_question: question, draft_reply: draft }, questions: { support: { type: 'choice', instructions: 'How does draft_reply relate to policy and customer_question?', criteria: { supported: 'The draft answers customer_question, and every fact, number, timeframe, and promise in it appears in policy.', unsupported: 'The draft states a fact, number, timeframe, or promise that policy does not contain or contradicts, or it answers a different question.', declined: 'The draft says policy does not cover the question and adds no facts of its own beyond what policy states.', }, }, }, }, });

const support = result.answers.support; if (support?.type !== 'choice' || !isLabel(support.choice)) { throw new Error('Unexpected answer'); } const cost = result.usage.cost; if (cost === undefined) { throw new Error('Response did not include usage.cost'); } return { label: support.choice, confidence: support.confidence ?? 0, probabilities: support.probabilities ?? {}, costUsd: cost, }; }

Jev 拿到政策、客户问题和草稿，然后回答一道选择题：该草稿是有依据的、无依据的，还是被拒绝的。我们让它跑了四份草稿。第一份来自 GPT Luna，另外三份是手写的，每一份都针对一个特定分支来写。

Q: "How long until my refund shows up?" Draft (GPT Luna): "Refunds are sent back to the original payment method, but we don't have a specific timeline for when they will appear. If your return is approved, a prepaid return label will be emailed within one business day." supported confidence=0.09 { supported: 0.39, unsupported: 0.32, declined: 0.29 }

Q: "How long until my refund shows up?" Draft (fabricated): "Refunds are processed within 5 to 7 business days after we receive the item." unsupported confidence=1.00 { unsupported: 1, supported: 0, declined: 0 }

Q: "Where does my refund go?" Draft (grounded): "Refunds go back to the original payment method, so it will return to however you paid for the order." supported confidence=1.00 { supported: 1, unsupported: 0, declined: 0 }

Q: "How long until my refund shows up?" Draft (grounded, wrong question): "Refunds go back to the original payment method, so it will return to however you paid for the order." unsupported confidence=0.48 { unsupported: 0.65, supported: 0.14, declined: 0.21 }

那份捏造的时间线以 1.00 的分数被判定为无依据，而如果这封回复真的发出去了，客户会在第八天回信问退款到底在哪里。

Luna 的草稿，这才是最有意思的一份，因为它陈述的每一个事实都符合政策。但它半是拒绝、半是回答这个问题，还加了一个没人要求的细节。Jev 把概率分成三份，0.8 的阈值把它送去给客服代表快速看一眼。

最后两行用的是同一份有依据的草稿，但配了两个不同的问题。注意，当草稿回答的是客户所问的问题时，它以 1.00 的分数被判定为有依据。当它回答的是另一个问题时，它就被判定为无依据。这正是你希望从验证器那里得到的结果，也清楚说明了为什么政策文本应当使用与草稿相同的措辞。

我们最初尝试了两道是或否的问题，结果很混乱，因为一份正确指出政策不涵盖此事的草稿既是有依据的，又不是一个回答。互斥的结果促使我们改为只问一道选择题。

把它们全部串联起来

还有一个文件把路由优先的流水线连接到验证器，这样 LLM 写的任何内容在没有得到有依据的判定之前都不会发出去。

// send.ts import { FACTS, handle, type Handled } from './handle'; import { verifyDraft, type Verdict } from './verify-draft';

const SEND_CONFIDENCE = 0.8;

type Outcome = Handled & { disposition: 'sent' | 'human_review'; verdict?: Verdict };

export async function process(ticket: string): Promise<Outcome> { const handled = await handle(ticket); switch (handled.route.kind) { case 'human': return { ...handled, disposition: 'human_review' }; case 'deterministic': return { ...handled, disposition: 'sent' }; case 'reply': { // Verify against the same facts the draft was written from. const verdict = await verifyDraft(FACTS[handled.route.intent], ticket, handled.text); const ok = verdict.label === 'supported' && verdict.confidence >= SEND_CONFIDENCE; return { ...handled, verdict, costUsd: handled.costUsd + verdict.costUsd, disposition: ok ? 'sent' : 'human_review' }; } default: return handled.route satisfies never; } }

如果验证器驳回了一条单独看完全没问题的回复，就把这条回复对照事实再读一遍。事实往往遗漏了客户问到的某些内容。去看看完整的请求路径。

ticket text | v [Jev] intent (choice) + escalate (noul) .......... 1 request, ~200 ms, ~$0.000025 | v [code] escalate >= 0.5 or confidence < 0.8 ? --> human queue | v [code] intent == order_status ? --> database lookup, exact reply, no model | v [LLM] draft reply from ticket + facts ............ ~1 s, ~$0.0001 (GPT Luna) | v [Jev] supported / unsupported / declined ......... 1 request, ~200 ms, ~$0.000025 | v [code] supported and confidence >= 0.8 ? --> send otherwise --> human review

一条从头到尾走完全程的工单需要两次 Jev 调用和一次 LLM 调用。总成本约为 $0.00015，总耗时为 1.5 秒。这两次 Jev 调用使得可以用一个便宜的模型来撰写内容，同时无需让人去阅读模型的每一条回复。

从你自己的数据中选取阈值

无论这个阈值出现在你代码的哪个位置，都要记住这个数字并非凭空而来。它来自你。这是你的策略选择。Jev 的概率是经过校准的，这基本上意味着取大量预测，看看它们有多经常是对的。所以如果我们看到 0.8，那么这些预测中大约 80% 最终是对的。但并非每一个都对。这是一个平均值。所以请把本文中看到的 0.8 和 0.5 当作我们的数字，而不是你的。

如果你想找到自己的阈值，几百个标注案例应该就够了。用模型跑一遍所有这些案例。对每个截断值，统计它答对了多少。把准确率对截断值画在一张图上。然后把你的截断值设在自动路径与你们人工团队会给出的结果相匹配的那个点上。在你修改标准之后，重新检查这一点。别忘了。改写其中一个选项，可能会以有些出人意料的方式改变其他选项的概率。

从一个 switch 语句开始

如果你的代码库里有一处 LLM 调用最终以 JSON.parse 结尾，紧接着一个 switch，那就是你的第一个 Jev 问题。把它替换进去，把 LLM 留给需要生成自然语言的那个分支，然后对两者都做测量。

Decisions API 参考文档，了解完整的请求与响应 schema

OpenRouter 上的 Jev，查看当前定价与限额

TypeSafe 原语、state 和 confidence 文档，帮助你设计问题

Jev 验证级联 cookbook，用于构建由 Jev 担任裁判的“先便宜后前沿”的 LLM 级联

用 Jev 为工具调用把关 cookbook，将同样的思路应用于智能体工具调用

常见问题

Jev 是什么，它与 LLM 有何不同？

Jev 是 TypeSafe 的 System One 决策模型。它接收 state 加上一个带类型的问题——要么是从固定集合中做选择，要么是一个是/否命题，要么是在你描述的层级上打分——并返回概率而非文本。大语言模型生成的是开放式文本，你还得去解析它并信任它。

在分类任务上，Jev 比小型 LLM 更便宜吗？

在 2026 年 9 月 19 日通过 OpenRouter 运行的 60 个支持工单上，Jev 每 1,000 个工单花费 $0.0248，GPT Luna 每 1,000 个工单花费 $0.0921，Claude Opus 每 1,000 个工单花费 $2.88，而意图准确率方面，Jev 为 59/60，GPT Luna 为 59/60，Claude Opus 为 60/60。

Jev 1.13 每百万输入 token 花费 $0.042，输出免费。定价随时可能变动，因此在做预算前务必查看模型页面。

如何将 Jev 与 LLM 结合使用？

有两种模式。第一种，先路由：Jev 对请求进行分类并返回一个置信度。你的代码将该置信度与你选定的阈值进行比较。只有需要生成文本的请求才会发送给 LLM。第二种，后验证：由 LLM 先起草内容。Jev 检查草稿中的每一项主张是否都有你的策略作为依据。只有通过检查后，回复才会发出。

Jev 使用哪个 OpenRouter 端点？

Jev 使用 Decisions API 端点，POST https://openrouter.ai/api/alpha/decisions，模型 ID 为 typesafe/jev-1.13，或在 TypeScript SDK 中使用 openrouter.alpha.decisions.create()。常规 LLM 使用 POST https://openrouter.ai/api/v1/chat/completions，或 openrouter.chat.send()。

我应该为 Jev 使用什么置信度阈值？

不存在适用于所有情况的通用数值。Jev 的概率是在大量预测上校准的，因此在总体上表现可靠。但任何单次预测仍可能出错。因此，请根据你自己的标注数据和出错的代价来选择截断值。例如，以下是我们的路由规则：意图置信度低于 0.8，或预测升级概率达到或超过 0.5，就转交给人工处理。
