我们上个月把客服工单的分流环节从"规则 + 大模型生成 JSON"换成了判断型模型。它不是纯技术问题,换完之后运维面变了:以前盯的是"解析成功率"和"超时率",现在盯的是"置信度分档的实际准确率"。前者是系统指标,后者是业务指标。
这篇按落地顺序写:怎么接、哪些东西必须做成配置、线上会出什么事、监控埋什么、怎么验收、谁来签字。不讲模型原理。
原来的链路是这样的:
这条链路里有一半的工程成本花在了"让模型说出结构"上,而不是"判断对不对"上。重试、兜底解析、字段缺失处理,这些代码在判断任务里其实都是额外开销。
判断型模型的返回值域是封闭的——选项由你给,刻度由你给,布尔问题只返回概率。没有自由文本,就没有解析层。 接进来之后,我们那条链路的解析模块直接删掉了,重试策略也简化成一个兜底分支。
代价是:判断能力变窄了。它写不了摘要、编不了回复草稿。所以我把生成相关的活儿留在原来那层,判别相关的活儿搬到新的一层。分层之后,两边的 SLA 和告警规则终于能分开配。
它对外只有三类问题:
这三类问题可以在同一次请求里并行求值,互相隔离,多挂几个几乎不增加响应时间。所以工程上要按批设计,别一个问题一次调用。
resp = judge(
evidence=ticket_text,
questions=[
{"id": "dept", "type": "choice",
"options": ["售前", "售后", "财务", "unknown"],
"text": "该工单应路由到哪个部门?"},
{"id": "severity", "type": "score", "range": [0, 9],
"text": "该工单的紧急程度?"},
{"id": "refund", "type": "bool",
"text": "该工单涉及退款诉求"},
],
)
result = {q.id: (q.answer, q.probability) for q in resp.questions}返回值可以直接拿去做分支,中间不需要任何解析。
接入前我犯过一个低级错误——把阈值写成了常量。
正确做法是每个动作一条阈值,放在配置中心,并且和模型版本绑定:
dept_routing:
model_id: judge-v3.2-20250910 # 必须钉死版本号,不能用浮动别名
t_auto: 0.90 # 以上直接自动化
t_review: 0.65 # 之间转人工复核
measured_on: cs_tickets_202508 # 阈值是在哪批数据上量的
refund_detection:
model_id: judge-v3.2-20250910
t_auto: 0.98 # 涉及钱的,门槛必须更严
t_review: 0.85
measured_on: cs_tickets_202508理由很直接:路由一个咨询工单和判断一笔退款诉求,误判代价差几个数量级,不该共用同一个门槛。 把阈值写成常量,等于把两个完全不同的风险等级压成了一个。
顺手加一个出口类目也很重要——unknown 或 needs_review 必须由你自己定义。它不会弃权。 强制二选一的时候它不说"不知道",只会挑一个相对最不坏的。这个坑我们第一版就踩了,选项里没有出口,于是所有拿不准的工单都被硬塞进了"售后",第二天工单群里直接炸了。
这个最容易被忽略。同一个模型、同一批题,只把选项顺序换一下,准确率能从 72% 掉到 21%。小参数模型上尤其明显。
动作:选项顺序写进配置并纳入版本管理,任何一次调整都要重新跑校准。我们现在的规则是"顺序变更视同模型变更"。
模型一升级,校准跟着漂,所有阈值同时失效。麻烦在于它不是系统级报错——各分档的比例悄悄变了,接口不报错也不告警,你只能在业务指标上慢慢看出来。
两条硬要求:
log.info("judge_call",
extra={"model_id": resp.model_id, # 实际生效的版本
"question": q.id,
"answer": q.answer,
"prob": round(q.probability, 4)})加了这两条之后,我们才第一次发现"昨天指标抖动"其实是发版导致的,而不是数据变了。
在自己的标注样本上画一条"置信度 → 准确率"的曲线,再决定门槛压在哪。先拍阈值再找数据支持它,是这个环节最常见的自欺。
它不给出任何理由。审计、客诉、合规场景必须再叠一个生成模型专门写说明,别指望判别层自己交代。这也再次说明两层要分开:判别层出决策,生成层出解释。
换了判别层之后,我们删掉了解析成功率的看板,加了三个新指标。
还有一个容易被忽略的:噪声地板。在公开测评里我看到过一份自己给出的噪声地板是 0.024,意思是低于这个量级的误差差异没有意义。你自己的数据集也要先估一个下限,否则会为 0.01 的波动开复盘会。
判断型模型不生成 token,端到端通常在几十到两百毫秒,输入单价也比生成式低一两个数量级。这些数字是报价,不是成本——自建的话要把显存、并发、排队算进去。
我们这边是自托管。目前已有 Apache-2.0 的完整实现,四亿参数级别、单张 T4 上三十毫秒一次、数据不出网,这几个条件刚好卡在合规要求上。
但有个前提必须说清楚:能力来自微调,不来自权重。 有两个互不相干的复现都验证了同一句话——直接用基座权重,准确率低到接近"永远输出最常见那一类"。所以别以为拿到权重就能跑。
好在跑校准很便宜。单卡把一批数据过一遍,几分钟、不到一块钱。这个成本远低于接错一次的成本,所以校准应该做成例行动作,而不是上线前做一次。
验收报告里只写一个准确率是没有意义的。要看的是这样一条曲线:
举个例子。有个从公开脱敏客服历史里抽出来的数据集,整体命中率只有 0.598,很平庸。但门槛提到 0.8 之后,能自动处理掉 34% 的样本,这批里精度是 0.92。
整体平庸,不妨碍切出一块可靠的自动化区间。 反过来也一样:在可接受的风险下它能替你干掉多少活,这才是验收要回答的问题。
顺带提醒样本量。我曾见过两份测评,一份 60 条、一份 2000 条,结论完全相反,而且 60 条那份里有 50 条落在 0.9~1.0 这一档。这种分布本身就不正常。样本量差三十倍的数字不能放一起比。
"这个判断做错一次要赔多少",这是业务授权,不是技术参数。它该由承担这个后果的人来画,不是由调参的人顺手定。划下去就等于说"这类事以后不用每次都问人了"。
配套要留的记录三样,缺一样半年后就说不清:
换完之后最大的变化不是省钱,是风险变得可度量了。
以前的链路里,模型答错的概率是个黑盒;现在每个决策都带一个概率值,阈值是我自己定的,代价是我自己算的。这个概率值到底靠不靠谱,文档里不会写,只能在自己的数据上量出来——而且数据分布一换,就得重新量。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。