Jev 案例:工单分诊与情绪判断(完整代码)
更新于 适用版本 Jev 1.13 示例数据(example fixture)
TL;DR: 本案例演示一条两次调用的工单分诊流水线:第一次是选择题,把工单分进
billing、technical-support、sales三个队列之一;第二次是判断题,决定这张工单是否要加急。完整请求体、示例数据(example fixture)格式的响应,以及可直接复制的 Python 脚本都在下文。
场景
我们团队为一款 B2B SaaS 产品做客服支持,每月大约 4 万张工单。过去分诊靠值班客服”人工过第一遍”:读工单、选队列、判断紧不紧急。这样做有三个问题:慢;交接班时标准会漂移;规则引擎根本接不住这类活——工单很少直接写”我是账单问题”,它们只会写”你们好像扣了我两次钱,今天必须给我解决”,语气从客客气气到火冒三丈都有。
我们把第一遍分诊换成了每张工单两次 Jev 调用:
- 选择题——把工单分进且只分进一个队列:
billing(账单)、technical-support(技术支持)、sales(销售); - 判断题——这张工单是否应该加急?回答
yes、no或unclear。
Jev 是 TypeSafe AI 在 2026 年 9 月发布的 System One 判断模型,专做这类判断题、选择题、打分题,而不是开放式聊天。它返回带置信度的类型化 JSON——这正是分诊门禁真正需要的东西:高置信度的直接路由,其余全部转人工。
下文的示例工单是刻意挑的典型票:重复扣款、当天必须解决、威胁找银行拒付。这种消息应该既进账单队列,又触发加急。
请求
第一次调用——队列分配(选择题):
{
"model": "typesafe/jev-1.13",
"messages": [
{
"role": "system",
"content": "Choice question. Assign the ticket to exactly one queue: billing, technical-support, or sales. Reply with JSON only: {\"answer\": <queue>, \"confidence\": <0-1>, \"rationale\": <one sentence>}"
},
{
"role": "user",
"content": "Subject: Card charged twice for the September invoice\n\nBody: Hi, I see two charges of $49 on my card from your billing page this morning. Please refund the duplicate charge today, otherwise I will ask my bank to reverse the payment."
}
]
}
第二次调用——加急检查(判断题):
{
"model": "typesafe/jev-1.13",
"messages": [
{
"role": "system",
"content": "Judgment question. Answer yes, no, or unclear. Reply with JSON only: {\"answer\": <yes|no|unclear>, \"confidence\": <0-1>, \"rationale\": <one sentence>}"
},
{
"role": "user",
"content": "Ticket: Card charged twice for the September invoice. The customer reports a duplicate $49 charge, asks for a same-day refund, and says they will contact their bank otherwise. Should this ticket be escalated?"
}
]
}
响应
以下两个响应均为示例数据(example fixture),用于说明格式,不是线上实测抓包。
第一次调用:
{
"answer": "billing",
"confidence": 0.94,
"rationale": "The customer reports a duplicate charge on an invoice, which is a billing dispute rather than a product defect or a purchase request."
}
第二次调用:
{
"answer": "yes",
"confidence": 0.97,
"rationale": "The customer names a same-day deadline and a bank-dispute escalation path, which matches the urgent-financial-impact escalation rule."
}
复现脚本
保存为 triage.py,设置环境变量 OPENROUTER_API_KEY 后运行 python3 triage.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
def ask(system, user):
body = {"model": MODEL, "messages": [
{"role": "system", "content": system},
{"role": "user", "content": user}]}
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)
return json.loads(payload["choices"][0]["message"]["content"])
CHOICE = ('Choice question. Assign the ticket to exactly one queue: '
'billing, technical-support, or sales. Reply with JSON only: '
'{"answer": <queue>, "confidence": <0-1>, "rationale": <one sentence>}')
JUDGE = ('Judgment question. Answer yes, no, or unclear. Reply with JSON only: '
'{"answer": <yes|no|unclear>, "confidence": <0-1>, "rationale": <one sentence>}')
ticket = """Subject: Card charged twice for the September invoice
Body: Hi, I see two charges of $49 on my card from your billing page this
morning. Please refund the duplicate charge today, otherwise I will ask my
bank to reverse the payment."""
queue = ask(CHOICE, ticket)
escalate = ask(JUDGE, "Ticket:\n" + ticket + "\n\nShould this ticket be escalated?")
print(queue)
print(escalate)
关键参数
| 字段 | 取值 | 说明 |
|---|---|---|
model | typesafe/jev-1.13 | 固定版本号,避免新版本发布后悄悄改变分诊行为。准确 slug 请以 OpenRouter 模型页为准。 |
messages[0](system) | 题型 + 选项列表 + JSON 结构 | Jev 做判断题、选择题、打分题。明确写出题型和全部选项,能让类型化输出保持稳定。 |
messages[1](user) | 工单原文 | 一次调用只放一张工单,置信度才有横向可比性。 |
answer(响应) | billing / yes | 决策本身——直接映射成队列名或加急标记。 |
confidence(响应) | 0.94 / 0.97(示例数据) | 兜底逻辑就看它:低于阈值就转人工,不要硬路由。 |
rationale(响应) | 一句话 | 足够写审计日志,不用再调一次模型去解释。 |
| 价格 | $0.0462 / 1M input tokens | 每天几千次分诊调用,单次成本很关键。预算前请在 OpenRouter 核对当前价格。 |
注意事项
- 上面的响应均为示例数据(example fixture);字段名请与官方文档核对后再依赖。官方 API 细节在 typesafe.ai,入口是System One 模型发布公告。
- 原始 HTTP 响应是 OpenAI 兼容的 chat completion 结构;本文展示的 JSON 是从 message content 里解析出来的模型类型化输出。
- 上线前请在 OpenRouter 模型页确认准确的模型 slug(
typesafe/jev-1.13),版本迭代时 slug 可能变化。 - 每张工单两次调用意味着输入 token 翻倍。按 $0.0462 / 1M input tokens 算仍然很便宜,但如果第一次调用返回的置信度很低,可以直接跳过第二次调用——低置信度的路由决策本来就该转人工。
- 加急逻辑里要保留
unclear:把它当成”加急”处理,而不是当成”不加急”。 - 适用于 Jev 1.13(2026 年 9 月发布),演示渠道为 OpenRouter。