用 Jev 做工单路由:显著减少错派单
TL;DR: 工单路由本质是一道选择题(choice)——“这单该进哪个队列”。Jev 是 TypeSafe AI(typesafe.ai)2026 年 9 月发布的 System One 判断模型(judgment model),专做判断题(judgment)、选择题(choice)、打分题(scoring),不做聊天。一次调用直接返回结构化的
{answer, confidence, rationale}:置信度 0.85 以上自动派单,以下进人工队列。本文给出输入输出定义、架构图和 50 行以内的端到端实现。
路由决策长什么样
写代码之前,先把任务定义收窄:
- 输入:工单主题 + 截断后的正文。够分类即可,不必喂整个会话线程。
- 任务类型:
choice——从固定队列列表里选一个,例如billing(账单)、technical(技术)、account(账号)、other(其他)。 - 输出:结构化结果,不是一段散文。示例数据(example fixture):
{"answer":"billing","confidence":0.94,"rationale":"客户反映被重复扣款并要求退款。"}
三个字段各司其职:answer 决定分支走向,confidence 决定能不能自动化,rationale 是客服接手时直接能读的判据。
为什么判断模型更合适
聊天模型为开放式生成优化,拿它做路由就得解析自由文本、祈祷格式不跑偏。Jev 的任务形态和路由天然对齐。
| 对比维度 | 聊天模型 | Jev(choice 调用) |
|---|---|---|
| 输出形态 | 自由文本,需要自己解析 | 结构化 answer / confidence / rationale |
| 任务框定 | 靠提示词压制闲聊 | 原生选择题 |
| 自动化信号 | 默认没有 | confidence 可直接设阈值 |
| 可解释性 | 不稳定 | 每次决策都附带 rationale |
| 失败方式 | 格式跑偏、答非所问 | 低置信度结果,可转人工 |
架构图
工单到达(主题 + 正文)
|
v
预处理(截断、脱敏、拼接主题与正文)
|
v
Jev choice 调用(经 OpenRouter,typesafe/jev-1.13)
|
v
解析结构化结果 {answer, confidence, rationale}
|
+--> confidence >= 0.85 --> 自动派单到对应队列
|
+--> confidence < 0.85 --> 人工队列,rationale 展示给客服
整条流水线就是四步逻辑加一个阈值分支,没有任何魔法。
最小端到端实现
import os, json, requests
URL = "https://openrouter.ai/api/v1/chat/completions"
# Confirm the exact model slug on the OpenRouter model page.
MODEL = "typesafe/jev-1.13"
QUEUES = ["billing", "technical", "account", "other"]
SYSTEM = ("You are a ticket router. Choose exactly one queue from: "
+ ", ".join(QUEUES) + ".")
def route(subject: str, body: str) -> dict:
resp = requests.post(
URL,
headers={"Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}"},
json={
"model": MODEL,
"messages": [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": f"Subject: {subject}\n\n{body[:4000]}"},
],
"temperature": 0,
},
timeout=30,
)
resp.raise_for_status()
# 示例数据(example fixture):
# {"answer":"billing","confidence":0.94,"rationale":"..."}
return json.loads(resp.json()["choices"][0]["message"]["content"])
result = route("Refund not received", "I was charged twice this month...")
if result["confidence"] < 0.85 or result["answer"] not in QUEUES:
print("ACTION=human-review", result)
else:
print("ACTION=route queue=", result["answer"], "conf=", result["confidence"])
核心就三步:调用、解析、分支。任何支持 OpenAI 兼容端点的 SDK(JavaScript、Go 等)写法一致,只是 HTTP 客户端不同。官方 API 的端点与字段请以 typesafe.ai 官方文档为准。
参数与阈值建议
| 配置项 | 建议 | 理由 |
|---|---|---|
| 任务类型 | choice | 路由是单选决策,不是 yes/no 也不是打分 |
| 自动派单阈值 | confidence >= 0.85 | 保守起点,用自有误派样本回调 |
| 低置信度路径 | 人工队列 + rationale | 客服能看到模型犹豫的原因 |
| 未知标签 | 按低置信度处理 | answer 不在队列列表里就进人工队列 |
| 正文截断 | 约 4000 字符 | 信号足够,延迟可控 |
三种任务类型的详细区别见 Jev 三原语(three primitives)指南,阈值设计见置信度与兜底(confidence and fallback)指南;邮件路由三团队的实际案例展示了同款配置的生产运行方式。
本文适用版本:Jev 1.13。
路由规则与低置信度回退
路由逻辑本身只有两条主干分支:置信度达标则自动派单,不达标则转人工。但在生产环境里,还需要处理几类边界情况。
规则优先级顺序
收到结构化结果
|
v
answer 不在已知队列列表? --> YES --> 进人工队列(未知标签)
|
NO
v
confidence < 阈值? --> YES --> 进人工队列(低置信度)
|
NO
v
自动派单到对应队列
按以上顺序执行可确保:未知标签绝不会静默派单,低置信度结果不会绕过人工审核。
回退信息的设计原则
进人工队列时,rationale 字段对客服的价值取决于它的可读性。建议按以下方式呈现,而非原样丢给客服:
| 展示位置 | 内容 | 备注 |
|---|---|---|
| 工单侧边栏 | answer 与 confidence | 客服一眼能看到模型的倾向 |
| 折叠详情 | rationale 原文 | 供需要追溯的场景 |
| 派单备注 | “AI 置信度低,需人工确认” | 说明为什么没有自动派 |
这样客服既不会对模型产生过度依赖,也能快速理解为什么这张工单来到了人工队列。关于阈值设计的更多内容,参见 置信度与兜底指南。
阈值调整节奏
不建议在初始部署就把阈值压到 0.7 以下来”减少人工工作量”。合理的调整路径是:先以 0.85 上线,跑满 300 张真实工单,按照误派率和人工介入率决定是否下调。每次调整幅度不超过 0.05,并在调整后至少观察一周。
新增队列时的回归验证
业务增长时往往需要新增队列,例如把 technical 拆分成 technical-hardware 与 technical-software,或新增 returns(退货)队列。新增队列会改变模型在所有工单上的概率分布,需要在上线前做回归验证。
最小回归集构成
示例数据(example fixture)——构建回归集时,建议覆盖以下三类样本:
1. 明确属于新队列的工单 × 20 张(新业务代表性样本)
2. 与新队列最容易混淆的旧队列工单 × 20 张
3. 原有队列的随机样本 × 60 张(监控原有派单是否漂移)
总共约 100 张,人工标注好预期队列,跑一遍新 prompt 配置,对比输出与标注的吻合率。若旧队列的准确率相对基线下降超过 5 个百分点,需要重新调整 system prompt 中的队列描述,直到回归集通过再上线。
prompt 变更与版本锁
每次修改 QUEUES 列表或 system prompt,都应该同步更新版本标记(例如 ROUTER_VERSION=v2),并在日志里记录每张工单路由时使用的版本。这样当出现误派率上升时,可以快速按版本切片排查,而不是在整个历史日志里大海捞针。
监控指标
路由上线之后,监控是保证长期效果的唯一手段。以下是值得持续跟踪的核心指标,可接入任何支持时序存储的监控系统。
| 指标名 | 计算方式 | 关注阈值 | 含义 |
|---|---|---|---|
| 自动派单率 | 自动派单数 / 总工单数 | 低于 70% 需排查 | 反映整体置信度水位 |
| 人工修正率 | 客服改派数 / 自动派单数 | 高于 8% 需复查阈值 | 直接衡量错派率 |
| 平均置信度 | 所有结果的 confidence 均值 | 周环比下降 >3% 需关注 | 输入分布变化的早期信号 |
| 低置信度队列积压 | 人工队列未处理数量 | 视团队 SLA 而定 | 反映人工处理能力是否跟上 |
| answer 分布 | 各队列占比 | 骤变超 10% 需排查 | 可能是输入脏数据或队列定义漂移 |
平均置信度下降通常先于误派率上升出现,是最值得优先设置告警的指标。如果某一天的平均置信度出现明显下降,先检查:当天工单的语言分布是否变化、是否有大批相似工单(刷单或系统异常)、队列定义是否被人修改。
三原语的底层工作方式见 Jev 三原语指南;若需了解置信度与人工兜底的完整设计,参见 置信度与兜底指南。
FAQ
- 工单路由为什么用 Jev 而不是聊天模型? 路由是选择题,不是对话。Jev 是 System One 判断模型,专做判断、选择、打分,直接返回带置信度的结构化结果,不用从自由文本里抠答案。
- 自动派单的置信度阈值设多少? 建议 0.85 起步:达到就自动派单,低于就连同 rationale 一起进人工队列,再按实际误派样本微调。
- 在 OpenRouter 上调用哪个模型 id? 示例用
typesafe/jev-1.13,端点为https://openrouter.ai/api/v1/chat/completions;上线前在 OpenRouter 模型页确认确切 slug。