Jev 案例:邮件路由三团队(完整代码)

更新于 适用版本 Jev 1.13 示例数据(example fixture)

TL;DR: 本案例用 Jev 1.13 上的一道选择题给公共邮箱做路由:salesbillingtechnical-support 三选一;置信度低于阈值时不硬分,直接兜底进人工分诊文件夹。完整请求体、示例数据响应和可运行脚本见下文。

场景

我们是一家 12 人的公司,对外只有一个公共邮箱 hello@,邮件全进共享收件箱。三个团队从这里领活:销售、账单、技术支持。每封分错的邮件意味着两次转手、一封莫名其妙的首次回复,通常还要道歉——而”能不能帮忙转给对的人”这类邮件,每周悄悄吃掉我们好几个小时。

我们想要的路由规则说起来很简单、用关键词却很难表达:读这封邮件,选出恰好一个团队。一次 Jev 调用就能做到。

兜底规则不是装饰。一个”自信地分错”的路由模型比没有模型更糟,而一个报出 0.52 的模型等于在告诉你它不知道。Jev 是 TypeSafe AI 发布的 System One 判断模型,2026 年 9 月上线,置信度本来就是它类型化输出的一部分——这让兜底逻辑退化成一次数值比较,不需要再调一次模型。本示例走 OpenRouter 的 OpenAI 兼容端点。

下面的示例邮件是一封续约报价请求。看着像销售线索,但里面出现了”invoice cycle”这类贴着账单的词——正是关键词规则最容易分错的那一类。

请求

{
  "model": "typesafe/jev-1.13",
  "messages": [
    {
      "role": "system",
      "content": "Choice question. Route the email to exactly one team: sales, billing, or technical-support. Reply with JSON only: {\"answer\": <team>, \"confidence\": <0-1>, \"rationale\": <one sentence>}"
    },
    {
      "role": "user",
      "content": "From: dana@example.com\nSubject: License renewal quote for 25 seats\n\nHi, we are expanding from 10 to 25 seats and need a renewal quote with the annual discount before our procurement window closes Friday. Our current invoice cycle renews on the 1st."
    }
  ]
}

响应

示例数据(example fixture)——用于说明格式,不是线上实测抓包:

{
  "answer": "billing",
  "confidence": 0.94,
  "rationale": "The customer asks for a renewal quote tied to their existing subscription and invoice cycle, which is a billing-managed renewal rather than a new-sales conversation."
}

注意模型是怎么处理这封邮件的歧义的:它选了 billing——而且说得通——并把推理过程放在 rationale 里,事后随时可以人工复核。

复现脚本

保存为 route.py,设置环境变量 OPENROUTER_API_KEY 后运行 python3 route.py

import json, os, urllib.request

URL = "https://openrouter.ai/api/v1/chat/completions"
MODEL = "typesafe/jev-1.13"  # confirm exact slug on the OpenRouter model page
FALLBACK_CONFIDENCE = 0.7

SYSTEM = ('Choice question. Route the email to exactly one team: '
          'sales, billing, or technical-support. Reply with JSON only: '
          '{"answer": <team>, "confidence": <0-1>, "rationale": <one sentence>}')

def route(email_text):
    body = {"model": MODEL, "messages": [
        {"role": "system", "content": SYSTEM},
        {"role": "user", "content": email_text}]}
    req = urllib.request.Request(URL, data=json.dumps(body).encode(),
        headers={"Authorization": "Bearer " + os.environ["OPENROUTER_API_KEY"],
                 "Content-Type": "application/json"})
    with urllib.request.urlopen(req) as res:
        payload = json.load(res)
    result = json.loads(payload["choices"][0]["message"]["content"])
    if result["confidence"] < FALLBACK_CONFIDENCE:
        return "human-triage", result
    return result["answer"], result

email = """From: dana@example.com
Subject: License renewal quote for 25 seats

Hi, we are expanding from 10 to 25 seats and need a renewal quote
with the annual discount before our procurement window closes Friday.
Our current invoice cycle renews on the 1st."""

team, detail = route(email)
print(team, "->", detail)

关键参数

字段取值说明
modeltypesafe/jev-1.13固定版本。准确 slug 请以 OpenRouter 模型页为准。
messages[0](system)选择题 + 三个团队 + JSON 结构选项列表就是你的路由表,必须和真实队列保持同步。
messages[1](user)完整邮件(含邮件头)From:Subject: 带着真实的路由信号,不要删。
answer(响应)billing直接映射为目标队列。
confidence(响应)0.94(示例数据)兜底的依据:低于 0.7human-triage
rationale(响应)一句话接收团队能看到”这封邮件为什么落在我这里”。
价格$0.0462 / 1M input tokens每封邮件一次短调用;预算前请在 OpenRouter 核对当前价格。

注意事项

继续阅读