意图识别三选一:BERT 微调、LLM + Prompt、Jev 到底怎么用
一句话总结 :这三条路不是"谁更先进",而是在"数据、速度、成本、可改性"四个约束下的不同解法 。BERT 微调 是封闭意图集里的性价比之王(毫秒级、近乎零边际成本,但要标注数据、加个新意图就得重训);LLM + Prompt 是零样本时代的瑞士军刀(改个字就能加意图、还能解释理由,但慢且贵);Jev 是专门为"判断"设计的决策模型(70--500ms、输出带校准置信度、永远不给你编标签,但中文偏弱、不能微调)。先问自己三个问题:意图封闭吗?有多少标注数据?QPS 多高? 答案基本就出来了。
📋 目录
- 先给结论:一张决策表
- BERT 微调:封闭集里的性价比之王
- LLM + Prompt:零样本、能改、能解释
- Jev:把"判断"做成一次 API 调用
- 五个维度横向对比
- 决策树:你的场景该选谁
- 更现实的做法:三级瀑布
- 三个容易踩的坑
- 总结
一、先给结论:一张决策表
| 你的情况 | 首选 |
|---|---|
| 意图集合固定 + 标注数据充足 + 延迟要求 < 50ms | BERT 微调 |
| 意图经常变 + 几乎没有标注数据 + 需要解释理由 | LLM + Prompt |
| 意图封闭 + 高频调用(每秒十次级)+ 需要"低置信转人工" | Jev |
| 中文为主 + 要求极致准确 | BERT 或 LLM(Jev 需先验证) |
| 只是做个 demo / 内部工具 | LLM + Prompt(最快) |
🎯 一句话记忆 :
BERT 靠数据,LLM 靠通用能力,Jev 靠结构化的"选择题"。
二、BERT 微调:封闭集里的性价比之王
2.1 它怎么做意图识别
本质是文本分类 :把 [CLS] 位置的向量接一个全连接层,输出 N 个意图的概率。
python
from transformers import AutoTokenizer, AutoModelForSequenceClassification
tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")
model = AutoModelForSequenceClassification.from_pretrained(
"bert-base-chinese",
num_labels=12, # 你的意图数量
)
# 之后用 Trainer 在「文本 → 意图 id」的数据上微调
推理时就是一次前向:输入一句话,输出 12 个概率,取 argmax。
2.2 优势
| 优势 | 说明 |
|---|---|
| 快 | GPU 上几毫秒,CPU 上十几到几十毫秒 |
| 便宜 | 自托管,边际成本几乎为零;一台机器能扛很高 QPS |
| 稳 | 输出永远是 N 个固定标签之一,不存在格式漂移 |
| 准 | 数据充足时,封闭集上的准确率往往高于通用大模型 |
| 可控 | 模型版本、阈值、训练数据全在自己手里,便于审计 |
2.3 适用环境
✅ 适合:
- 意图集合封闭且稳定(比如客服工单的 8 个固定类目)
- 有标注数据(每类几百条起步,上千条更稳)
- 高并发、低延迟(搜索框联想、实时路由)
- 数据敏感,不能出内网
❌ 不适合:
- 意图每周都在变------每次都要重新标注 + 重训 + 上线
- 零标注,且没人愿意标
- 需要处理未登录意图("这句话不属于任何一类")
⚠️ BERT 最大的隐性坑 :它是封闭集分类器 ,永远会从 N 个类里挑一个 。
用户问了个全新意图,它不会说"我不知道",而是自信地分到最像的那一类。加 softmax 阈值能缓解,但效果有限 ------普通分类模型的置信度没有校准过。
三、LLM + Prompt:零样本、能改、能解释
3.1 它怎么做
把意图列表写进提示词,让模型直接输出标签:
python
PROMPT = """你是意图分类器。只能从下面选一个,不要输出别的内容:
- 查订单:查询物流、订单状态
- 退款:要求退款、退货
- 改地址:修改收货信息
- 其他:以上都不符合
用户:{query}
只输出标签名。"""
没有训练,没有模型文件,改一行字就多一个意图。
3.2 优势
| 优势 | 说明 |
|---|---|
| 零样本可用 | 不用标注数据,当天就能上线 |
| 改起来极快 | 加意图 = 改 prompt,不用重训 |
| 开放集友好 | 可以让它回答"其他/无法判断",不会硬猜 |
| 能解释 | 可以让它顺带输出理由,方便排查 badcase |
| 跨语言 | 中英日韩通常一个 prompt 搞定 |
3.3 适用环境
✅ 适合:
- 项目早期,意图还没定型
- 长尾意图多,且经常新增
- QPS 不高(几十到几百),能接受秒级延迟
- 需要可解释性(给运营看"为什么分到这一类")
❌ 不适合:
- 高并发 + 低延迟(每次 1--5 秒,成本也高)
- 要求输出 100% 稳定(模型可能多输出一句解释、字段名写错)
- 有严格成本预算的百万级调用
💡 LLM 做意图识别的两个必备工程手段 :
① 约束输出 ------用 JSON Schema / structured output,不要靠正则去抠。
② 给"其他"选项------否则它同样会硬猜。
四、Jev:把"判断"做成一次 API 调用
4.1 它是什么
Jev 是 TypeSafe AI 的 System One 决策模型 ------不生成文字 ,只从你给的选项里选一个,并返回校准过的概率。
python
from typesafe_sdk import Choice, TypeSafeClient
client = TypeSafeClient()
resp = client.system_one(
state=user_query, # 用户原话
questions={
"intent": Choice(
instructions="用户这句话的意图是什么",
criteria={
"query_order": "查询订单或物流状态",
"refund": "要求退款或退货",
"change_addr": "修改收货信息",
"other": "以上都不符合",
},
)
},
)
ans = resp.answers["intent"]
print(ans.choice, ans.confidence) # refund 0.91
4.2 优势
| 优势 | 说明 |
|---|---|
| 快 | 端到端 70--500ms,远快于通用大模型 |
| 便宜 | 输入 $0.042/百万 Token,输出免费 |
| 不会编标签 | 答案只能从你给的选项里选,不存在"生造一个类名" |
| 有校准置信度 | 可以直接做「高置信自动执行 / 低置信转人工」 |
| 零标注 | 用 criteria 描述选项即可,改选项就能加意图 |
4.3 适用环境
✅ 适合:
- 意图封闭但选项很多 (Choice 最多支持 255 个选项)
- 高频决策循环(Agent 路由、工单分流)
- 需要置信度分流------这是它最强的地方
- 输入以英文为主
❌ 不适合:
- 中文为主 ------官方明确说 CJK 准确率偏低,需要先小范围验证
- 需要解释理由(它只给选项和概率,不给推理链)
- 需要多轮推理或长上下文理解
- 需要微调(不提供)
⚠️ 两个必须做的事 :
① 一定要加
other选项 ,否则它会挑一个"最不坏"的错误标签。② 生产环境锁定版本号 (如
jev-1.13.0),别用jev-latest------模型一更新,你调好的置信度阈值就漂了。
五、五个维度横向对比
| 维度 | BERT 微调 | LLM + Prompt | Jev |
|---|---|---|---|
| 需要标注数据 | ✅ 每类几百~上千条 | ❌ 0(few-shot 几十条也行) | ❌ 0(用选项描述) |
| 新增意图成本 | 高(重标 + 重训 + 部署) | 极低(改 prompt) | 低(加一个选项) |
| 延迟 | 5--50ms | 1--5s | 70--500ms |
| 单次成本 | 近乎为 0(自托管) | 高(按 token) | 极低 |
| 封闭集准确率 | 最高(数据充足时) | 中高 | 中(略低于通用大模型) |
| 未登录意图 | ❌ 差(会硬分) | ✅ 好(能说"其他") | ⚠️ 中(靠 other 选项) |
| 输出稳定性 | ✅ 100% 固定标签 | ⚠️ 需约束,可能漂移 | ✅ 100% 类型化 |
| 可解释性 | ❌ 低 | ✅ 高(能说理由) | ❌ 无 |
| 中文能力 | ✅ 好 | ✅ 好 | ⚠️ 偏弱 |
| 运维负担 | 重(训练管线) | 轻 | 轻 |
🎯 看这张表的方法 :
BERT 赢在"延迟 + 成本 + 封闭集准确率";LLM 赢在"零数据 + 可改性 + 可解释";Jev 赢在"延迟与成本接近 BERT、但零标注 + 有校准置信度"。
六、决策树:你的场景该选谁
#mermaid-svg-gHWNCqwQHQloJTGF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gHWNCqwQHQloJTGF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gHWNCqwQHQloJTGF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gHWNCqwQHQloJTGF .error-icon{fill:#552222;}#mermaid-svg-gHWNCqwQHQloJTGF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gHWNCqwQHQloJTGF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gHWNCqwQHQloJTGF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gHWNCqwQHQloJTGF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gHWNCqwQHQloJTGF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gHWNCqwQHQloJTGF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gHWNCqwQHQloJTGF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gHWNCqwQHQloJTGF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gHWNCqwQHQloJTGF .marker.cross{stroke:#333333;}#mermaid-svg-gHWNCqwQHQloJTGF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gHWNCqwQHQloJTGF p{margin:0;}#mermaid-svg-gHWNCqwQHQloJTGF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gHWNCqwQHQloJTGF .cluster-label text{fill:#333;}#mermaid-svg-gHWNCqwQHQloJTGF .cluster-label span{color:#333;}#mermaid-svg-gHWNCqwQHQloJTGF .cluster-label span p{background-color:transparent;}#mermaid-svg-gHWNCqwQHQloJTGF .label text,#mermaid-svg-gHWNCqwQHQloJTGF span{fill:#333;color:#333;}#mermaid-svg-gHWNCqwQHQloJTGF .node rect,#mermaid-svg-gHWNCqwQHQloJTGF .node circle,#mermaid-svg-gHWNCqwQHQloJTGF .node ellipse,#mermaid-svg-gHWNCqwQHQloJTGF .node polygon,#mermaid-svg-gHWNCqwQHQloJTGF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gHWNCqwQHQloJTGF .rough-node .label text,#mermaid-svg-gHWNCqwQHQloJTGF .node .label text,#mermaid-svg-gHWNCqwQHQloJTGF .image-shape .label,#mermaid-svg-gHWNCqwQHQloJTGF .icon-shape .label{text-anchor:middle;}#mermaid-svg-gHWNCqwQHQloJTGF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gHWNCqwQHQloJTGF .rough-node .label,#mermaid-svg-gHWNCqwQHQloJTGF .node .label,#mermaid-svg-gHWNCqwQHQloJTGF .image-shape .label,#mermaid-svg-gHWNCqwQHQloJTGF .icon-shape .label{text-align:center;}#mermaid-svg-gHWNCqwQHQloJTGF .node.clickable{cursor:pointer;}#mermaid-svg-gHWNCqwQHQloJTGF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gHWNCqwQHQloJTGF .arrowheadPath{fill:#333333;}#mermaid-svg-gHWNCqwQHQloJTGF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gHWNCqwQHQloJTGF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gHWNCqwQHQloJTGF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gHWNCqwQHQloJTGF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gHWNCqwQHQloJTGF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gHWNCqwQHQloJTGF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gHWNCqwQHQloJTGF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gHWNCqwQHQloJTGF .cluster text{fill:#333;}#mermaid-svg-gHWNCqwQHQloJTGF .cluster span{color:#333;}#mermaid-svg-gHWNCqwQHQloJTGF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gHWNCqwQHQloJTGF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gHWNCqwQHQloJTGF rect.text{fill:none;stroke-width:0;}#mermaid-svg-gHWNCqwQHQloJTGF .icon-shape,#mermaid-svg-gHWNCqwQHQloJTGF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gHWNCqwQHQloJTGF .icon-shape p,#mermaid-svg-gHWNCqwQHQloJTGF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gHWNCqwQHQloJTGF .icon-shape .label rect,#mermaid-svg-gHWNCqwQHQloJTGF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gHWNCqwQHQloJTGF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gHWNCqwQHQloJTGF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gHWNCqwQHQloJTGF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否,经常变
是
没有
有,且充足
是
否,500ms 可接受
需要
不需要
是
否,英文为主
要做意图识别
意图集合
封闭且稳定?
LLM + Prompt
有标注数据吗?
中文为主?
延迟要求 < 50ms?
BERT 微调
需要置信度分流?
Jev
BERT 或 LLM 都行
LLM + Prompt
(Jev 先小样本验证)
Jev
三个关键判断点:
- 意图会不会变? 会变 → 直接 LLM,别碰 BERT。
- 有没有标注数据? 没有 → 排除 BERT。
- 延迟卡在多少? <50ms → 只能 BERT;500ms 能接受 → Jev 也进了候选。
七、更现实的做法:三级瀑布
线上系统很少只用一种方案。 更常见的是分层:
#mermaid-svg-4nmb6NzY9COmrM9L{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4nmb6NzY9COmrM9L .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4nmb6NzY9COmrM9L .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4nmb6NzY9COmrM9L .error-icon{fill:#552222;}#mermaid-svg-4nmb6NzY9COmrM9L .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4nmb6NzY9COmrM9L .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4nmb6NzY9COmrM9L .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4nmb6NzY9COmrM9L .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4nmb6NzY9COmrM9L .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4nmb6NzY9COmrM9L .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4nmb6NzY9COmrM9L .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4nmb6NzY9COmrM9L .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4nmb6NzY9COmrM9L .marker.cross{stroke:#333333;}#mermaid-svg-4nmb6NzY9COmrM9L svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4nmb6NzY9COmrM9L p{margin:0;}#mermaid-svg-4nmb6NzY9COmrM9L .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-4nmb6NzY9COmrM9L .cluster-label text{fill:#333;}#mermaid-svg-4nmb6NzY9COmrM9L .cluster-label span{color:#333;}#mermaid-svg-4nmb6NzY9COmrM9L .cluster-label span p{background-color:transparent;}#mermaid-svg-4nmb6NzY9COmrM9L .label text,#mermaid-svg-4nmb6NzY9COmrM9L span{fill:#333;color:#333;}#mermaid-svg-4nmb6NzY9COmrM9L .node rect,#mermaid-svg-4nmb6NzY9COmrM9L .node circle,#mermaid-svg-4nmb6NzY9COmrM9L .node ellipse,#mermaid-svg-4nmb6NzY9COmrM9L .node polygon,#mermaid-svg-4nmb6NzY9COmrM9L .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4nmb6NzY9COmrM9L .rough-node .label text,#mermaid-svg-4nmb6NzY9COmrM9L .node .label text,#mermaid-svg-4nmb6NzY9COmrM9L .image-shape .label,#mermaid-svg-4nmb6NzY9COmrM9L .icon-shape .label{text-anchor:middle;}#mermaid-svg-4nmb6NzY9COmrM9L .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4nmb6NzY9COmrM9L .rough-node .label,#mermaid-svg-4nmb6NzY9COmrM9L .node .label,#mermaid-svg-4nmb6NzY9COmrM9L .image-shape .label,#mermaid-svg-4nmb6NzY9COmrM9L .icon-shape .label{text-align:center;}#mermaid-svg-4nmb6NzY9COmrM9L .node.clickable{cursor:pointer;}#mermaid-svg-4nmb6NzY9COmrM9L .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4nmb6NzY9COmrM9L .arrowheadPath{fill:#333333;}#mermaid-svg-4nmb6NzY9COmrM9L .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4nmb6NzY9COmrM9L .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4nmb6NzY9COmrM9L .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4nmb6NzY9COmrM9L .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4nmb6NzY9COmrM9L .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4nmb6NzY9COmrM9L .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4nmb6NzY9COmrM9L .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4nmb6NzY9COmrM9L .cluster text{fill:#333;}#mermaid-svg-4nmb6NzY9COmrM9L .cluster span{color:#333;}#mermaid-svg-4nmb6NzY9COmrM9L div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4nmb6NzY9COmrM9L .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4nmb6NzY9COmrM9L rect.text{fill:none;stroke-width:0;}#mermaid-svg-4nmb6NzY9COmrM9L .icon-shape,#mermaid-svg-4nmb6NzY9COmrM9L .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4nmb6NzY9COmrM9L .icon-shape p,#mermaid-svg-4nmb6NzY9COmrM9L .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4nmb6NzY9COmrM9L .icon-shape .label rect,#mermaid-svg-4nmb6NzY9COmrM9L .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4nmb6NzY9COmrM9L .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4nmb6NzY9COmrM9L .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4nmb6NzY9COmrM9L :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 高置信
低置信
仍不确定
确定
用户输入
第一层
BERT 或 Jev
覆盖 80% 头部意图
毫秒级
✅ 直接路由
第二层
LLM + Prompt
兜底 + 长尾 + 新意图
👤 人工
这样分层的理由:
| 层 | 承担 | 为什么 |
|---|---|---|
| 第一层 | 80% 的头部高频意图 | 用最便宜的方案扛最大流量 |
| 第二层 | 20% 的长尾 + 低置信 | 用最贵的模型处理最难的部分 |
| 第三层 | 极少数 | 人工兜底,顺便产标注数据 |
🎯 这个结构的精髓是"钱花在刀刃上" :
不要让 100 万次调用都走 LLM,也不要让 100 个新意图都去重训 BERT。
八、三个容易踩的坑
坑 1:以为 BERT 会告诉你"我不知道"
它不会。 封闭集分类器永远输出 N 个类之一,遇到新意图会自信地分错。
解法 :加一个"其他"类进训练集,或者用 softmax 阈值 + 人工兜底。但要知道,普通分类模型的置信度没校准过,阈值很难定。
坑 2:用 LLM 却不约束输出格式
python
# ❌ 指望模型"只输出标签"
"这句话的意图是什么?"
# ✅ 明确约束 + 给兜底选项
"只输出以下之一:查订单 / 退款 / 改地址 / 其他。不要解释。"
更稳的做法是用 structured output(JSON Schema),而不是靠正则去抠。
坑 3:中文场景直接上 Jev
官方明确说 CJK 准确率偏低 。中文为主的业务,先用几百条真实数据做对照实验(拿同一个测试集,跑 Jev 和 LLM 比一比),再决定要不要用。
别拿英文榜单的成绩去推中文效果。
九、总结
三句话概括三个方案
- BERT 微调 :"我知道就那么几类,而且我有数据。" ------ 最快、最便宜、最稳,但改不动。
- LLM + Prompt :"我还不确定要分几类,先跑起来再说。" ------ 最灵活、能解释,但慢且贵。
- Jev :"类目我定好了,我要毫秒级 + 一个能决策的置信度。" ------ 位置卡在两者之间,但中文是短板。
✅ 应该做的
- 先问三个问题:意图封闭吗、有数据吗、延迟多少
- BERT 训练集里加一个"其他"类
- LLM 一定要用 structured output,别靠正则
- Jev 必加
other选项 + 锁定版本号 - 中文场景对 Jev 先做小样本对照验证
- 流量大的系统用三级瀑布,别用一种方案硬扛
❌ 不要做的
- ❌ 认为"大模型时代 BERT 没用了"(封闭集 + 高并发下它仍然最能打)
- ❌ 意图天天变还硬上 BERT
- ❌ 零标注还非要微调
- ❌ 让 100 万次调用全走 LLM
- ❌ 用 Jev 做需要解释理由的场景(它不给推理链)
🎯 最后一句
意图识别没有"最好的模型",只有"最合适的约束组合"。
数据多、意图稳 → BERT;数据少、意图活 → LLM;要毫秒级又要置信度 → Jev。
而真正上线时,往往是三个一起用------便宜的打头阵,贵的兜底,人工收尾。
📚 参考资料
- BERT 原论文:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
- HuggingFace Transformers 文本分类文档:https://huggingface.co/docs/transformers/tasks/sequence_classification
- OpenAI Function Calling / Structured Outputs:https://platform.openai.com/docs/guides/structured-outputs
- Jev 官方文档(TypeSafe AI):https://docs.typesafe.ai
- Jev 规格与限制(含 CJK 说明):https://docs.typesafe.ai/introduction/quickstart
说明 :本文中 BERT 与 LLM 的延迟、数据量、成本为工程经验区间 ,实际取决于硬件、模型尺寸和供应商,请以自己压测为准。Jev 的规格(70--500ms、$0.042/百万 Token 输入、输出免费、Choice 最多 255 个选项、CJK 准确率偏低、不支持微调)取自 TypeSafe 官方文档,其性能数据为官方自测、未经第三方复现;Jev 处于早期访问阶段,速率限制与定价可能调整。
如果这篇对你有帮助,欢迎点赞 + 收藏。下一篇可以写 三级瀑布的具体实现 ,或者 BERT 意图分类的完整微调代码------评论区告诉我。