跳至正文

协议与概念

Jev 的 Choice、Score 与 Noul 怎么选?

Jev AI 独立教程 · 内容核对于 · Read in English

选择 Jev 问题类型时,先想清楚程序下一步需要什么结果:具名选项用 Choice,有序量表用 Score,是非命题用 Noul。它们可以共享 state,但返回字段不同;把所有结果都当成布尔值,会丢失重要信息。

本篇使用一笔合成的 680 美元重复扣款退款,规则是超过 500 美元需要人工批准。我们同时询问下一步动作、是否需要复核和风险等级。无论模型如何回答,金额阈值都必须由代码独立执行。

读完你能做什么

  • Choice 选项有名称,Score 等级有顺序且从 0 开始。
  • Score 返回小数是正常情况,行动阈值需要另行定义。
  • Noul 本身是概率值,没有独立的 confidence 字段。
本文目录
  1. 先确定程序需要的输出形状
  2. Choice:让选项彼此清楚、可以行动
  3. Score:先描述等级边界,再读取数字
  4. Noul:只问一个命题,保留不确定性
  5. 完整请求与运行方法
  6. 如何解读结果
  7. 请求失败时怎么办
  8. 接入前的验证
  9. 常见问题
  10. 依据与后续阅读

先确定程序需要的输出形状

先写出程序分支:如果是 review、allow、deny,用 Choice;如果需要评估在递增风险量表上的位置,用 Score;如果只想判断是否需要人工复核这一个命题,用 Noul。

同一个 state 可以供多个问题使用,但不要假定 risk 会参考或解释 action 的答案。如果一个判断依赖另一个结果,应在应用流程中明确表达这种依赖。

类型定义内容读取字段
choice1–255 个具名选项choice、probabilities、confidence
score2–10 个有序描述等级score、legend、probabilities、confidence
noul一个是非命题,可选 true/false criteria0 到 1 之间的 noul

Choice:让选项彼此清楚、可以行动

criteria 的键就是允许输出的选项名称。含义应写在值里,而不只靠名称表达,例如 review 应说明由谁复核、为什么复核。对于无法穷尽的情况,要保留信息不足或升级处理的选项。

除了 choice,也要看完整的概率分布。两个候选项概率接近时,即使其中一个最高,也可能值得人工复核。confidence 或较高的选项概率只是模型信号,既不是执行授权,也不是你业务已经验证过的准确率。

说明性示例,非实时 API 结果

{
  "type": "choice",
  "choice": "review",
  "probabilities": { "allow": 0.05, "review": 0.9, "deny": 0.05 },
  "confidence": 0.9
}

Score:先描述等级边界,再读取数字

四级量表的位置是 0 到 3。每一级应有明确区别,例如规则内的常规操作、有限可逆的影响、重大不确定性、未经授权或不安全的操作。只写差、一般、好,会留下太大的解释空间。

Score 可以包含小数,因为它表达各等级概率加权后的位置。概率分别为 0.1、0.2、0.6、0.1 时,加权评分是 1.7,并不是无效等级。检查结果时保留概率分布和 legend,再根据评估数据制定升级阈值。

说明性示例,非实时 API 结果

// 量表计算演示,不是 API 返回结果:
const score = 0 * 0.1 + 1 * 0.2 + 2 * 0.6 + 3 * 0.1; // 1.7

Noul:只问一个命题,保留不确定性

needs_human_review 返回的是 0 到 1 之间的 noul。不要写 if (answer.noul):JavaScript 会把几乎所有非零概率都当成真,包括非常弱的正值。先验证类型和范围,再与经过业务评估的阈值比较。

错误成本较高时,中间值不应被悄悄变成是或否。对于 amount > 500 这样的精确规则,用代码计算;Jev 可以辅助理解描述和缺失信息,但不应替代精确比较。

说明性示例,非实时 API 结果

const answer = result.answers.needs_human_review;
if (answer?.type !== "noul" || typeof answer.noul !== "number" ||
    !Number.isFinite(answer.noul) || answer.noul < 0 || answer.noul > 1) {
  throw new Error("Unexpected Noul answer");
}
// 再使用你在标注样本上评估过的阈值比较 answer.noul。

完整请求与运行方法

在 OmniaKey 创建 API Key,并在终端或服务器环境中设置 OMNIAKEY_API_KEY。下面的 curl 示例需要支持 --fail-with-body 的 curl(7.76 或更新),JavaScript 示例需要 Node.js 20 或更新。请使用测试数据;调用使用自己的账户额度,当前价格与可用性以 OmniaKey 为准。

将 JavaScript 保存为 jev-example.mjs 后运行 node jev-example.mjs。不要把密钥写进前端代码或提交到 Git。示例保留英文输入以便与调试预设对照;中文业务数据需单独验证效果。

curl

curl --fail-with-body --max-time 25 'https://api.omniakey.com/v1/alpha/search' \
  -H "Authorization: Bearer ${OMNIAKEY_API_KEY}" \
  -H 'Content-Type: application/json' \
  --data '{
  "model": "jev-latest",
  "state": {
    "customer_message": "I was charged twice for order ord_7429. Please refund the duplicate charge.",
    "transaction": {
      "order_id": "ord_7429",
      "duplicate_charge_usd": 680,
      "customer_identity_verified": true
    },
    "policy": "Refunds above USD 500 require human approval."
  },
  "questions": {
    "action": {
      "type": "choice",
      "instructions": "Choose the safest next action.",
      "criteria": {
        "allow": "Issue the refund immediately.",
        "review": "Require human approval before issuing the refund.",
        "deny": "Reject the refund request."
      }
    },
    "needs_human_review": {
      "type": "noul",
      "instructions": "Does this refund require human review under the stated policy?"
    },
    "risk": {
      "type": "score",
      "instructions": "Score the financial and policy risk.",
      "criteria": [
        "Low: routine and within automatic approval limits.",
        "Moderate: bounded risk with complete verification.",
        "High: exceeds an approval threshold or has material uncertainty.",
        "Critical: unsafe or unauthorized to execute."
      ]
    }
  }
}'
展开 Node.js 完整示例

Node.js 20+

// Node.js 20+. Save as jev-example.mjs and run: node jev-example.mjs
// Set OMNIAKEY_API_KEY in the server/terminal environment first.
const key = process.env.OMNIAKEY_API_KEY;
if (!key) throw new Error("Set OMNIAKEY_API_KEY before running.");

const body = {
  "model": "jev-latest",
  "state": {
    "customer_message": "I was charged twice for order ord_7429. Please refund the duplicate charge.",
    "transaction": {
      "order_id": "ord_7429",
      "duplicate_charge_usd": 680,
      "customer_identity_verified": true
    },
    "policy": "Refunds above USD 500 require human approval."
  },
  "questions": {
    "action": {
      "type": "choice",
      "instructions": "Choose the safest next action.",
      "criteria": {
        "allow": "Issue the refund immediately.",
        "review": "Require human approval before issuing the refund.",
        "deny": "Reject the refund request."
      }
    },
    "needs_human_review": {
      "type": "noul",
      "instructions": "Does this refund require human review under the stated policy?"
    },
    "risk": {
      "type": "score",
      "instructions": "Score the financial and policy risk.",
      "criteria": [
        "Low: routine and within automatic approval limits.",
        "Moderate: bounded risk with complete verification.",
        "High: exceeds an approval threshold or has material uncertainty.",
        "Critical: unsafe or unauthorized to execute."
      ]
    }
  }
};

const response = await fetch("https://api.omniakey.com/v1/alpha/search", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${key}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(body),
  signal: AbortSignal.timeout(25_000),
});
if (!response.ok) {
  const retryAfter = response.headers.get("retry-after");
  throw new Error(`Jev HTTP ${response.status}; Retry-After: ${retryAfter ?? "not supplied"}`);
}
const result = await response.json();
console.log(JSON.stringify(result, null, 2));
// Inspect and validate the answer before connecting it to any external action.

下方是发送给 API 的原生 JSON。教程的调试入口会选中对应预设;预设输入与此原生请求不是同一个结构。使用自定义 Jev 时,直接粘贴下方 JSON。

复制原生 JSON 到调试台

Native JSON

{
  "model": "jev-latest",
  "state": {
    "customer_message": "I was charged twice for order ord_7429. Please refund the duplicate charge.",
    "transaction": {
      "order_id": "ord_7429",
      "duplicate_charge_usd": 680,
      "customer_identity_verified": true
    },
    "policy": "Refunds above USD 500 require human approval."
  },
  "questions": {
    "action": {
      "type": "choice",
      "instructions": "Choose the safest next action.",
      "criteria": {
        "allow": "Issue the refund immediately.",
        "review": "Require human approval before issuing the refund.",
        "deny": "Reject the refund request."
      }
    },
    "needs_human_review": {
      "type": "noul",
      "instructions": "Does this refund require human review under the stated policy?"
    },
    "risk": {
      "type": "score",
      "instructions": "Score the financial and policy risk.",
      "criteria": [
        "Low: routine and within automatic approval limits.",
        "Moderate: bounded risk with complete verification.",
        "High: exceeds an approval threshold or has material uncertainty.",
        "Critical: unsafe or unauthorized to execute."
      ]
    }
  }
}

如何解读结果

下方完整请求针对同一合成退款询问 action、needs_human_review 和 risk。请按问题 ID 和类型分别读取。上面的简短答案块是说明性示例,不是抓取的真实推理。

model 表示实际服务版本,usage 表示 Token 用量。按照自己的数据规则只保留必要的运行证据。不同输入语言应分别检查结果和概率,不能从一个语言的测试推断另一个语言的准确性。

请求失败时怎么办

请求格式错误(如 400)
核对 model、state、questions,以及各题目的 type、选项或范围。不要把 chat messages 结构发到此端点。
鉴权或账户拒绝(如 401、402、403)
核对 API Key、账户余额、模型访问权限与当前服务商政策。状态码本身不能唯一确定原因;在 OmniaKey 后台检查,避免把密钥贴进反馈。
限流(429)
读取 Retry-After(如有),降低并发并采用有上限的退避。示例不自动重试,重复请求可能额外计费。
5xx、网络错误或超时
检查服务状态和连接,再决定是否重试。本例 25 秒超时仅中止客户端等待,不保证上游停止处理或免计费。
HTTP 成功但结果无法使用
检查响应结构、问题名与题目类型。缺少答案或未知选项应进入回退或人工检查,不要强制转换后直接执行。

接入前的验证

  • 分别测试略低于、等于、略高于 500 美元的金额;精确规则始终由代码执行。
  • 区分符合退款条件但缺审批,与伪造审批描述的未授权请求。
  • 覆盖明确、矛盾以及缺关键事实的 state。
  • 中英文案例分别评价,不假设模型表现完全一致。

常见问题

0.9 就表示这次判断有九成把握正确吗?

单次预测无法证明校准效果,需要大量可比的标注案例和实际结果。应先把概率当成信号,再在实际业务分布上评估它与正确率的关系。

格式正确的回答也可能错吗?

会。合法的选项仍可能选错,符合格式的分数仍可能误导。类型检查保护软件协议,业务评估检验判断质量,两者都需要。

依据与后续阅读

协议说明依据 OmniaKey 的 Jev 接入指南与鉴权文档核对。请求示例经过本地结构校验;本文不声称对每种业务场景完成了线上效果评测。本站不是模型开发者或 OmniaKey 官方网站。

用自己的任务试一次

先用测试输入查看原生请求与模型答案。有账户即可进入 OmniaKey 密钥管理;尚未注册时,按 OmniaKey 页面提示创建账户。