园区场景的用户输入高度口语化,渠道还混杂:微信里是打字,大屏前是语音转写。要在 100 毫秒内判断"这句话想干什么",纯用大模型既慢又贵,纯规则又覆盖不住长尾。
不是二选一,而是五级瀑布
每一级都比上一级更贵、更准,能拦住的就不往下走:
-
L0 预处理:emoji 过滤、口语归一(「咋」→「怎么」),以及一份 Prompt 注入黑名单(8 类正则,覆盖「ignore previous instructions」、模板占位符这类常见攻击串)
-
L1 关键词(<50ms):不是简单命中,而是按命中词的长度计分——「打开 A 栋监控」比「打开」更精确所以得分更高;再加语义前缀加分(「怎么/如何」指向知识库、「打开/查询」指向设备控制),以及否定短语降权(「不是想查」直接打对折)
-
L1.5 语义匹配(<100ms):向量检索标准问句,用 TopK + Margin 双阈值——不仅要求最相似的 ≥0.85,还要求它比第二名高出 0.10。只卡绝对相似度的话,语义模糊时会把两个相近意图来回误判;加一道「领先幅度」就稳了。底层组件挂了会自动降级成内存扫描,不让一个依赖拖垮整条链路
-
L1.6 接口语义通道:把每个业务接口的名称、描述、参数结构预先向量化。运营在后台配好一个新接口,不用改一行代码就能被识别出来
-
L2 大模型兜底:动态 Few-Shot(从缓存读,可热更新)+ 动态接口列表注入 + 上一轮意图偏置
分层的意义不只是快,而是让每一层的问题都变得可解释:命中了哪一层、分是怎么算出来的,都能复盘。
让阈值被数据驱动
多层阈值最容易出的问题是「拍脑袋定完就没人敢动」。所以做了一个影子模式:每次分类同时记录关键词、向量、大模型三路的结果,连同用户的隐式反馈(触发澄清 = 一次负反馈)一起落库,离线对比三路准确率,再回来调阈值。
阈值不该是魔数,应该是可以被数据推翻的假设。
上下文不是简单「带上一轮」
多轮对话里,「那边呢」这种省略句要继承上一轮的意图;但继承得太激进,又会把话题锁死。最终只在「槽位不完整 + 当前输入被判定为参数补充」时才启用继承,并配套三件事:槽位锁定(已收集的实体不再重新分类)、待完成意图恢复、意图漂移检测(发现用户已经换话题就标记出来,交给澄清节点)。
另一层是抗退化:输入先过口语归一和注入黑名单,避免规则被两句话绕过去。