用 Redis 7.2 的向量检索做问答缓存,embedding 用 text-embedding-3-small,相似度阈值设 0.92,上线后“怎么退运费”命中了“怎么退会员费”的旧答案,客诉集中在退费类问题。
这类报错背后常见的原因有几处,逐个排除就行。短问句的向量区分度低,0.92 对它们不算高;缓存键没有带业务域,跨场景互相命中;向量没有归一化,内积与余弦混用;命中的是同义但答案不同的问法。
上来先打印命中对的相似度分布
python -c "import numpy as np;print(np.percentile([0.93,0.91,0.95],[10,50,90]))"
然后按业务域做键前缀再检索
python -c "print({'key':'qa:refund:'+ 'qhash'})"
接着对短问句提高阈值到 0.97
python -c "print({'threshold':0.97,'min_len':8})"
末了用真实日志回放一遍误命中样本
redis-cli --scan --pattern 'qa:refund:*' | head -20
这次没动代码,只在配置和运行环境上找原因。
改完先别撤,确认这几项。退费与会员费两类问题不再互相命中,抽样 200 条误命中率降到 2% 以下,平均响应时间仍在 300ms 内。
提醒一点。语义缓存的风险从来不是没命中,而是错命中,短句和金额类问题最好直接跳过缓存。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
