![[Bug]: `redis-semantic` cache never produces semantic hits, `_get_cache_key_filter_expression` uses full request hash as RediSearch pre-filt](https://www.chat-gpts.plus/wp-content/uploads/2026/06/29086-12748e58.jpg)
[Bug]: `redis-semantic` cache never produces semantic hits, `_get_cache_key_filter_expression` uses full request hash as RediSearch pre-filt
快速结论:该 Bug 发生在使用 LiteLLM 的 `redis-semantic` 缓存类型时,语义相似缓存查询永远返回 miss,原因是 `_get_cache_key_filter_expression` 将完整请求哈希作为 RediSearch 预过滤器,导致 KNN 向量搜索无法执行。优先排查 `redis_semantic_cache.py` 中 `_get_cache_key_filter_expression` 是否返回了正确的预过滤器表达式。
问题场景
用户在 LiteLLM 代理中配置了 cache_params.type: redis-semantic,期望基于语义相似性(向量距离)命中缓存。但实际上,即使两个请求的语义高度相似(余弦距离约 0.008),缓存查找仍然返回 miss,请求被转发到模型并再次写入缓存。该问题在 LiteLLM 版本 1.85.1 至 1.86.2 中复现,最早由 Redis 语义缓存隔离功能合并引入。
报错原文
Traceback (most recent call last):
No errors are raised. The failure is silent — the cache appears to function but never produces a semantic hit.
With --detailed_debug you can observe the embedding call succeeding and the Redis lookup returning empty on every request.
原因分析
根本原因在 litellm/caching/redis_semantic_cache.py 中:
async_get_cache调用_get_cache_key_filter_expression(key),其中key是模型、消息、温度等参数的 SHA256 哈希。- 该哈希被用作 RediSearch 的
Tag预过滤器(pre-filter),要求检索的文档哈希必须完全匹配。 - RediSearch 索引在 KNN 向量搜索前先执行该预过滤器,对于任何非逐字节相同的请求,预过滤器返回空候选集,KNN 相似度计算和距离阈值判断永远不会执行。
- 即使预过滤器通过(极少见),
_is_cache_hit也会拒绝命中,因为存储的哈希与当前请求哈希不同。
可能原因:开发者意图通过哈希预过滤器实现缓存隔离(如按用户、应用隔离),但哈希粒度太细,导致语义缓存完全失效。
环境排查
- LiteLLM 版本:1.85.1 至 1.86.2(该区间内均受影响)
- Redis 版本:Redis Stack Server(需 RediSearch 模块)
- 缓存类型:
redis-semantic - Embedding 模型:ollama/mxbai-embed-large:335m(1024 维)
- 部署方式:Docker / Docker Compose
- Python 版本:3.13
解决步骤
- 确认 Bug 代码路径:检查
litellm/caching/redis_semantic_cache.py中_get_cache_key_filter_expression的实现,确认其返回包含完整请求哈希的Tag过滤器。 - 应用修复(已验证):移除请求哈希预过滤器。在
async_get_cache和sync_get_cache中,将预过滤器参数设为None或空表达式,让 KNN 搜索作用于整个索引:- 同步路径(约第 256 行):将
_get_cache_key_filter_expression(key)改为None - 异步路径(约第 370 行):同样改为
None
这样 redisvl 会执行全索引 KNN 搜索,相似度和距离阈值生效。
- 同步路径(约第 256 行):将
- 注意保留写入逻辑:
set_cache和async_set_cache中写入文档时仍设置哈希标签(用于索引 schema),读取时不使用即可。 - 可优先尝试:如果需保留多租户隔离能力,可在
_get_cache_key_filter_expression中使用caller_id或api_key代替完整请求哈希,但需同步修改set_cache调用方以传递身份信息。
验证方法
- 发送两个语义相似但措辞不同的请求(如 “What is the capital of France?” 和 “Which city is the capital of France?”),确认第二个请求命中缓存,不触发模型调用。
- 检查 Redis 中的缓存文档,确认 KNN 搜索返回正确结果,距离阈值
similarity_threshold(如 0.75)生效。 - 使用
--detailed_debug日志确认 embedding 调用后 Redis 查找返回有效候选集。 - 运行回归测试:相同请求仍能命中缓存(同一哈希),完全不同的请求(距离 > 阈值)不命中。

![[BUG]: Desktop on Windows-ARM (Snapdragon) ships x64 Prisma query engine → "could not locate the Query Engine", all DB ops fail](https://www.chat-gpts.plus/wp-content/uploads/2026/06/5881-651d8865-768x403.jpg)

