给出一种基于SimHash的调用结果缓存去重方案

解读

在Agent系统中,大模型调用、工具调用、外部API调用的成本与延迟是核心瓶颈。
面试官想知道:

  1. 你能否把文本相似性转化为缓存键
  2. 能否在毫秒级完成去重,且误召回率可控;
  3. 能否在分布式缓存(Redis、Tair、自研KV)里落地,并解决哈希冲突、版本漂移、热点Key等工程问题。
    SimHash是局部敏感哈希的一种,能把高维文本向量压缩成64 bit指纹,海明距离≤3即认为近似重复,天然适合“请求文本相似⇒结果可复用”的场景。

知识点

  1. SimHash核心步骤
    分词→TF-IDF加权→哈希累加→降维→生成64 bit指纹。
  2. 海明距离桶拆分
    把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)
  3. 冲突解决
    桶内用二级BloomFilter先判存在,再逐条比对原始请求文本的MD5,确保零误召回
  4. 版本漂移
    缓存Value里存模型版本号+Prompt版本号,命中后版本不一致则降级为Miss,防止旧结果污染。
  5. 热点Key
    高频指纹启用本地Caffeine缓存+Redis分片,并设置随机TTL jitter打散峰值。
  6. 安全合规
    指纹生成前做敏感词哈希白名单,防止Prompt注入导致缓存污染;缓存层与业务层解耦,支持国密SM4加密存储。

答案

整体架构分三层:指纹生成层、桶路由层、缓存存储层

  1. 指纹生成层
    采用jieba+自定义业务词典分词,IDF离线统计每天更新一次;对工具参数也做JSON规范化+key排序后拼接到文本,确保参数顺序无关性。最终输出64 bit无符号整数
  2. 桶路由层
    使用Redis Cluster,按**{prefix}:sim:{16bit_段}:{16bit_段}:{16bit_段}**格式建Key,pipeline批量查询14个桶RTT<1 ms
  3. 缓存存储层
    Value采用Protobuf序列化,字段含:
    • 原始请求MD5(128 bit)
    • 模型版本(uint16)
    • 结果压缩体(LZ4)
    • 过期时间戳(uint32)
      设置TTL=3600 s,并加24 h滑动窗口异步淘汰。
  4. 冲突处理
    桶内用Redis BloomFilter(官方Module)先过滤,假阳率0.01%;再对候选列表逐条比对MD5不一致则追加新记录,保证结果幂等
  5. 监控指标
    • 缓存命中率(≥45%为合格,≥60%为优秀)
    • 误召回率(线上<0.001%)
    • 平均延迟(p99<5 ms)
      通过Prometheus+Grafana实时看板,命中率下跌自动告警
  6. 灰度与回滚
    采用双写双读灰度:新请求同时写老缓存(全文本MD5键)SimHash缓存;对比结果**一致率>99.9%**后全量切换,回滚窗口5分钟

拓展思考

  1. 多模态请求
    若输入含图片URL,可先用CLIP视觉编码取512维向量,再PCA降维到64维,与文本SimHash拼接128 bit指纹,其余流程不变。
  2. 强化学习缓存
    Agent自我演化场景,引入Reward权重:缓存Value里加累计Reward,下次命中时若新策略Reward更高主动失效,实现缓存与策略协同更新
  3. 联邦缓存
    集团内多租户场景,用指纹前缀+租户IDNamespace隔离,并基于差分隐私上传指纹分布到中心节点,全局去重而不泄露原始Prompt。
  4. 法律合规
    按《生成式人工智能服务管理暂行办法》要求,缓存结果若含个人信息,需在指纹生成前脱敏,并支持用户删除指令秒级同步到所有分片,确保被遗忘权落地。