跳到正文
Jev | typesafeAPI & Playground
…

开发方法

Jev 做判断,代码做决策

一个动作问题会把规则藏起来

客户要求退款。应用已经知道金额、退款资格和操作员权限。真正需要模型理解的部分更小:客户在表达什么诉求?

「退款、升级还是继续?」把意图、资格、金额、授权和规则优先级混在一起。把所有例外写进一个 Choice 描述后,很难区分错误路由来自模型判断还是业务规则。

拆开模型要理解的内容与应用能精确计算的事实。模型判断消息是否要求退款、是否要求人工。应用从可信服务读取资格,用整数分比较金额。实际退款仍需独立授权。

TypeSafe 在 2026 年 11 月 3 日的文章说明这一分工:Don't Call It a Decision Model。

只问两个具体问题

宿主请求使用 POST /api/v1/decide,模型选择器为 jev,包含两个 Noul 问题。state.message 是合成文本,请求没有让模型批准退款。

示意响应包含 answers.wants_refund.noul 与 answers.requests_human.noul。所有概率、模型标签、token 数和余额都是假设值,不是实测。Noul 是概率,不是额外置信度字段,也不是解释文字。

本站使用 jv_live_ 密钥。TypeSafe 官方使用另一套 endpoint 和模型 ID。集成前阅读本站 API 文档,不要把密钥放到前端代码。

契约说明:本站 API 文档。

用代码选复核队列

先校验两个概率,再按规则路由。明确的人工诉求优先。只有可信应用事实表明申请符合资格,退款诉求才进入退款复核队列。代码用 amount_cents 与示意性的 2,500 分界线比较。

没有任何分支执行退款,返回值只是 human_review 或 small_refund_review 等队列标签。0.8 与 0.2 用来演示策略应写在哪里,未经生产数据校准,不是推荐阈值。

缺字段、类型错误、无效概率和无效金额都进入人工复核。真实集成还要先处理超时和 HTTP 错误,再把响应交给路由函数。接口失败不能变成执行许可。

区分判断记录与事实记录

记录服务返回的模型标识、问题模板版本、已校验的判断、策略版本、命中规则和复核队列。证据引用来自应用输入的材料记录,不是虚构的 Jev evidence 响应字段。

不要记录密钥或不必要的客户原文。最终授权与实际动作单独记日志,便于检查错误来自语义理解、过期事实还是规则。

自动化前先验证

固定问题模板,用带标签的数据覆盖歧义诉求、不支持的输入和失败场景。使用独立验证集调阈值,跟踪真实业务数据中的错误与人工复核覆盖率。类型化答案不保证每类任务都准确或校准良好。

打开已有 Playground 查看请求模式(不会自动导入本例)。更高风险场景见欺诈信号与 KYB 复核;已发表结果及限制见第三方评测。

完整离线示例:请求

合成输入与假设响应,仅用于演示。以下代码不联网,不执行任何业务动作。

POST /api/v1/decide(示意)
{
  "model": "jev",
  "state": {
    "message": "I want the duplicate charge refunded. Please have a person check it."
  },
  "questions": {
    "wants_refund": {
      "type": "noul",
      "instructions": "Does the message request money back?"
    },
    "requests_human": {
      "type": "noul",
      "instructions": "Does the message explicitly ask for a person to review the issue?"
    }
  }
}

示意响应

响应(假设值)
{
  "model": "jev-1.14.0",
  "answers": {
    "wants_refund": {
      "type": "noul",
      "noul": 0.92
    },
    "requests_human": {
      "type": "noul",
      "noul": 0.87
    }
  },
  "usage": {
    "input_tokens": 180,
    "billed_tokens": 180,
    "output_tokens": 0,
    "remaining_tokens": 11999820
  },
  "meta": {
    "decide_model": "jev",
    "credit_multiplier": 1
  }
}

离线路由

support_route
import math

def probability(response, name):
    try:
        answer = response["answers"][name]
        value = answer["noul"]
        if answer["type"] != "noul":
            return None
        if type(value) not in (int, float):
            return None
        if not math.isfinite(value) or not 0 <= value <= 1:
            return None
        return value
    except (KeyError, TypeError):
        return None

def support_route(response, facts):
    """Return a review queue label, never execute a refund."""
    refund = probability(response, "wants_refund")
    human = probability(response, "requests_human")
    if refund is None or human is None:
        return "human_review"
    if human >= 0.2:
        return "human_review"
    if not isinstance(facts, dict):
        return "human_review"
    amount = facts.get("amount_cents")
    if type(amount) is not int or amount < 0:
        return "human_review"
    if refund >= 0.8 and facts.get("refund_eligible") is True:
        return "small_refund_review" if amount <= 2500 else "refund_specialist_review"
    return "general_support_review"

在 Playground 里查看请求形态

本站 Playground 不会自动导入本例,但便于对照 Noul 问题模板。