给出一种基于SimHash的调用结果缓存去重方案
解读
在Agent系统中,大模型调用、工具调用、外部API调用的成本与延迟是核心瓶颈。
面试官想知道:
- 你能否把文本相似性转化为缓存键;
- 能否在毫秒级完成去重,且误召回率可控;
- 能否在分布式缓存(Redis、Tair、自研KV)里落地,并解决哈希冲突、版本漂移、热点Key等工程问题。
SimHash是局部敏感哈希的一种,能把高维文本向量压缩成64 bit指纹,海明距离≤3即认为近似重复,天然适合“请求文本相似⇒结果可复用”的场景。
知识点
- SimHash核心步骤
分词→TF-IDF加权→哈希累加→降维→生成64 bit指纹。 - 海明距离桶拆分
把64 bit指纹拆成4段×16 bit,每段作为Redis Key后缀,形成2^16=65 536个桶;查询时只需扫描与自身指纹海明距离≤3的桶(最多C(4,1)+C(4,2)+C(4,3)=14个),把O(n)比对降到O(1)。 - 冲突解决
桶内用二级BloomFilter先判存在,再逐条比对原始请求文本的MD5,确保零误召回。 - 版本漂移
缓存Value里存模型版本号+Prompt版本号,命中后版本不一致则降级为Miss,防止旧结果污染。 - 热点Key
对高频指纹启用本地Caffeine缓存+Redis分片,并设置随机TTL jitter打散峰值。 - 安全合规
指纹生成前做敏感词哈希白名单,防止Prompt注入导致缓存污染;缓存层与业务层解耦,支持国密SM4加密存储。
答案
整体架构分三层:指纹生成层、桶路由层、缓存存储层。
- 指纹生成层
采用jieba+自定义业务词典分词,IDF离线统计每天更新一次;对工具参数也做JSON规范化+key排序后拼接到文本,确保参数顺序无关性。最终输出64 bit无符号整数。 - 桶路由层
使用Redis Cluster,按**{prefix}:sim:{16bit_段}:{16bit_段}:{16bit_段}**格式建Key,pipeline批量查询14个桶,RTT<1 ms。 - 缓存存储层
Value采用Protobuf序列化,字段含:- 原始请求MD5(128 bit)
- 模型版本(uint16)
- 结果压缩体(LZ4)
- 过期时间戳(uint32)
设置TTL=3600 s,并加24 h滑动窗口异步淘汰。
- 冲突处理
桶内用Redis BloomFilter(官方Module)先过滤,假阳率0.01%;再对候选列表逐条比对MD5,不一致则追加新记录,保证结果幂等。 - 监控指标
- 缓存命中率(≥45%为合格,≥60%为优秀)
- 误召回率(线上<0.001%)
- 平均延迟(p99<5 ms)
通过Prometheus+Grafana实时看板,命中率下跌自动告警。
- 灰度与回滚
采用双写双读灰度:新请求同时写老缓存(全文本MD5键)与SimHash缓存;对比结果**一致率>99.9%**后全量切换,回滚窗口5分钟。
拓展思考
- 多模态请求
若输入含图片URL,可先用CLIP视觉编码取512维向量,再PCA降维到64维,与文本SimHash拼接128 bit指纹,其余流程不变。 - 强化学习缓存
对Agent自我演化场景,引入Reward权重:缓存Value里加累计Reward,下次命中时若新策略Reward更高则主动失效,实现缓存与策略协同更新。 - 联邦缓存
集团内多租户场景,用指纹前缀+租户ID做Namespace隔离,并基于差分隐私上传指纹分布到中心节点,全局去重而不泄露原始Prompt。 - 法律合规
按《生成式人工智能服务管理暂行办法》要求,缓存结果若含个人信息,需在指纹生成前脱敏,并支持用户删除指令秒级同步到所有分片,确保被遗忘权落地。