当前位置: 首页 > news >正文

嵌入向量给用户问题做意图分类路由实操

先说结论:一个入口要应付好几类问题,别再堆 if-else 关键词了。把用户那句话先转成嵌入向量,跟你预设的几个意图样本算余弦相似度,谁近就路由到谁的处理链——退款走退款链,查物流走物流链,闲聊扔给兜底。我上个月给一个内部客服机器人这么改完,误分类肉眼可见地少了一截。

我踩到的那个问题

背景是这样。我们组维护一个给运营同学用的小工具,入口就一个输入框,啥都能问。一开始我图省事,用关键词匹配做分流:句子里有"退"就当退款,有"到哪了"就当查物流。

跑了两周,运营群里炸了。

有人问"这单为啥退不了"——里面有"退",路由到退款链,结果人家是想查物流状态卡在哪。还有人打错字把"物流"写成"无流",直接掉进兜底,回了句"没听懂"。关键词这玩意儿对语义一点感知都没有,换个说法就抓瞎。我盯着日志看了半天,决定换嵌入。

分类路由怎么做,分四步

思路不复杂,核心就是把"匹配字面"换成"匹配语义"。

第一步,给每个意图准备几条样本句。别只写一条。比如"查物流"我写了"我的包裹到哪了""快递怎么还没动""单号查一下到哪"这么三四条,覆盖不同说法。

第二步,把这些样本句全部过一遍嵌入模型,存成向量。这步离线做一次就行,结果缓存起来。我直接存内存里了,几十条向量而已,没必要上向量库。

第三步,用户问题进来,实时转成向量,跟每个意图的样本向量算余弦相似度。取每个意图里最高的那条当该意图得分。

第四步,谁分高走谁,但要卡个阈值。最高分低于 0.75 我就判定"没匹配上",扔兜底链让大模型自由发挥,别硬塞。

一段能跑的核心代码

import numpy as np # 意图样本(离线先转成向量缓存好) INTENTS = { "refund": ["我要退款", "这单想退掉", "钱怎么退回来"], "logistics":["包裹到哪了", "快递还没动", "查下物流到哪"], } def cos(a, b): return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)) def route(query_vec, intent_vecs, threshold=0.75): best_intent, best_score = None, -1 for name, vecs in intent_vecs.items(): score = max(cos(query_vec, v) for v in vecs) # 取该意图最近的一条 if score > best_score: best_intent, best_score = name, score return best_intent if best_score >= threshold else "fallback" # route(embed("我这单为啥退不了"), intent_vecs) -> "refund"

embed()就是调嵌入接口拿向量,剩下全是 numpy。真没多少行。

一个真把我坑住的地方

阈值这事我栽过。

一开始我把 threshold 设成 0.6,想着"宽松点别漏"。结果闲聊和正经问题全被归到最近的业务意图去了——有人发了句"在吗",居然被判成查物流,因为跟某条样本沾了点边。后来调到 0.78 又太严,正常的问句被踢进兜底。

来回试了大半天,最后落在 0.75,并且发现一个细节:阈值跟你用的嵌入模型强相关,换个模型这数得重调。不同模型出来的向量分布不一样,余弦值的"高低"刻度根本不通用。所以别抄别人的阈值,自己拿一两百条真实日志跑一遍分布,看错分都卡在哪个值,再定。

另外多嘴一句脏细节:样本句别写得太书面。我最早样本全是"请问我的订单物流信息如何查询"这种端着的句子,结果用户大白话"东西到哪了"反而匹配不上。后来把样本改成跟用户一样的口气,准确率立马上去了。

写在后面

整套搭下来其实最花时间的不是代码,是攒样本句和调阈值。代码两小时,调参两天。

搭这个分类器的时候我没自己撸服务,是在一个零代码就能配智能体的平台上拖出来的——意图分类、知识库、几条处理链拉一拉就连上了,省了我搭框架的功夫。当然它也就帮你把杂活串起来,真正的业务逻辑和样本还是得自己抠,指望它一键生产可用机器人是不现实的,第一版出来照样干巴巴。

你们做多意图路由是怎么定阈值的?还在用关键词的评论区聊聊,我挺好奇有没有更省事的招。

(嵌入和大模型我走的讯飞星辰 MaaS,现成 API 调,没自己部署算力。)

http://www.jsqmd.com/news/1091781/

相关文章:

  • 减肥别再啃水煮菜了!这份中医家常食谱,掉秤还不伤脾胃
  • 当C盘亮起红灯时,你的电脑在告诉你什么?
  • B3930 [GESP202312 五级] 烹饪问题
  • 在单台电脑上实现多人分屏游戏的完整指南:NucleusCoop实战教程
  • 存储引擎内核剖析:B+Tree 与 LSM-Tree 的性能博弈,以及如何做可信的 Benchmark
  • 2026年超好用的钢格栅机构,究竟有何独特之处?
  • 读懂2026年CSP-J 初赛:题型分析、命题规律、备考路线
  • 【STL】iostream 编程:流的定义
  • 这个项目是做什么的
  • Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!
  • 如何在Mac上免费永久备份微信聊天记录:WeChatExporter完整教程
  • [MAF预定义ChatClient中间件-01]LoggingChatClient——在调用LLM前后输出日志
  • 深度解析:ToB销售学AI,最该补的是客户研究和方案表达能力
  • 企业实物资产管理:分类、核心要点与规范管控方案
  • 通用PLM根本撑不住!汽车/芯片/新能源研发的痛,它懂[特殊字符]全星研发项目管理APQP软件系统来救场
  • FDE课程: Codex+AI 编程+ SeedanceAI 视频+ AgentAI 智能体
  • 汉明码编码译码推演与验证(P124302158李晨雨)
  • 评估模块(EVM)使用指南:规避法律风险与安全合规要点
  • BUUCTF [第五空间2019 决赛]PWN5:从格式化字符串到任意地址写的实战通关
  • 深度解析TI PCM/DSD179x评估板:从电源隔离到模拟输出的高性能音频DAC设计实战
  • FanControl终极指南:三步搞定Windows风扇智能控制
  • C#摸鱼实录——IoC与DI案例详解
  • DLSS Swapper:终极游戏性能优化指南,告别卡顿从版本管理开始
  • 瓶盖视觉检测设备 缺陷刮花划伤黑点外观ccd机器视觉检测
  • ChatGPT付费陷阱预警:这5个“默认优势”其实是营销话术,附官方API成本替代方案
  • DeepEval:高效LLM评估框架的完整实战指南
  • PHP 应用 security.txt 漏洞披露实践
  • python爬虫实战项目|第100篇:爬虫技术全景回顾与未来展望
  • 让经典游戏重获新生:dxwrapper全面解决Windows 10/11兼容性问题
  • 强制访问控制的数学基石:深度拆解BLP机密性模型的设计哲学与工程遗产