后过滤召回塌陷:Redis 先召回 → ES 再过滤,如果全部被过滤掉怎么办?

真正做过企业级 RAG / 向量检索的人一定会遇到双引擎架构的核心难点:

Redis 先召回 → ES 再过滤,如果全部被过滤掉怎么办?

这叫:

Post-filter Recall Collapse(后过滤召回塌陷)

也是 Redis + ES 架构必须解决的问题。

下面我按 问题本质 → 为什么会发生 → 解决方案→兜底策略 讲清楚。


一、问题本质(发生了什么)

流程:

复制代码
RedisSearch KNN Top50
↓
ES 权限过滤
↓
0 条结果 ❌

原因不是 Redis 搜错。

而是:

复制代码
Top50 ≠ Top50 可访问文档

换句话说:

👉 语义最近 ≠ 用户有权限


举个真实例子

系统里:

文档 相似度 部门
A 0.99 CEO
B 0.98 CEO
C 0.97 CEO
... ... ...
Z 0.80 Finance

用户是 Finance。

Redis 返回:

复制代码
Top50 = 全是 CEO 文档

ES 一过滤:

复制代码

二、为什么这是 ANN 系统天然问题

ANN(HNSW)目标只有一个:

复制代码
最相似

不知道权限

所以:

权限分布越不均匀,问题越严重。

企业知识库里非常常见:

  • 高层文档语义集中
  • 普通员工权限少

三、工业界标准解法(⭐重点)

解决思路只有一个核心:

不要一次只召回固定 TopK

而是:

复制代码
动态扩大召回范围

方案 1⭐:Oversampling + 回填机制 ✅

这是最常见方案。


Step 1:Redis 多召回

不要:

复制代码
Top50

而是:

复制代码
Top200 / Top500

因为你知道会被过滤。


Step 2:ES 过滤

假设:

复制代码
200 → 只剩 8 条

Step 3:检测数量

如果:

复制代码
result < target_k

触发:

复制代码
二次召回

Step 4:扩大搜索范围

例如:

复制代码
第一次 ef_runtime = 100
第二次 ef_runtime = 300
TopK = 500

再过滤一次。

在 HNSW 算法中,从 ef_runtime = 100 增加到 300,查询耗时通常不会线性增加 3 倍,但会表现出明显的延迟增长。根据在 RedisSearch 环境下的实测经验,增加比例通常在 1.5倍 到 2.5倍 之间。
TopK 仅决定返回数量,而 ef_runtime 决定 HNSW 的搜索深度。后过滤召回塌陷的根因是搜索空间不足,因此扩大 ef_runtime 比单纯增加 TopK 更有效。


伪代码

java 复制代码
k = 50
recall = 200

while(true){
   candidates = redis.knn(recall)
   results = es.filter(candidates)

   if(results.size >= k)
       break

   recall *= 2
}

✅ 优点:

  • 简单
  • 稳定
  • 工业标准

方案 2⭐:权限感知 Oversampling

观察:

不同用户过滤比例不同。

例如:

用户 过滤率
admin 5%
普通员工 80%
外包 95%

于是:

动态计算:

复制代码
recall_k = target_k / (1 - filter_ratio)

例:

复制代码
目标50
预计过滤80%

→ 50 / 0.2 = 250

Redis 直接召回 250。

必须同时保证:ef_runtime ≥ recall_k


方案 3⭐:权限预分桶(工业优化)

核心思想:

不要让 Redis 完全不知道权限。

但又不能破坏 HNSW。

怎么办?


做"软隔离"索引

例如:

Redis 建多个索引:

复制代码
doc_idx_public
doc_idx_finance
doc_idx_hr

查询时:

复制代码
finance 用户 → 优先搜 finance index

必要时 fallback 全局索引。


好处:

✅ 不破坏图结构

✅ 召回稳定

✅ ES过滤压力下降


方案 4⭐:Filter-aware ANN(权限感知向量空间)

在 embedding 中加入权限特征:(1.向量拼接;2.训练模型)

复制代码
embedding = semantic + access embedding

通过将权限信息编码进向量空间,使可访问文档在语义空间中天然更接近查询,从而减少后过滤带来的召回浪费,本质是将"过滤问题"转化为空间几何问题。

让:

复制代码
无权限文档在向量空间更远

等于:

ANN 自然避开。

但实现复杂,有向量污染风险,权限维度过强,会导致语义被破坏,搜索质量下降。


四、Safety Fallback(安全兜底策略)

Fallback 1:降低 keyword 约束(放宽条件)

原查询

复制代码
部门=财务
AND
关键词=报销流程2024新版

可能太严格:

复制代码
0结果

fallback 做什么?

逐步放松条件:

复制代码
部门=财务
AND
关键词=报销流程

再不行:

复制代码
关键词=报销

本质:

复制代码
Precision ↓
Recall ↑

先保证有结果。


✅ 类似 Google:

你搜错字时:

"Showing results for ..."


Fallback 2:返回"权限允许的次优语义"

这是向量检索里的核心兜底。


情况:

复制代码
最相似文档 → 无权限

过滤后:

复制代码

fallback 做法:

扩大语义范围:

复制代码
Top50 → Top300 → Top1000

只要:

复制代码
语义还算相关 + 有权限

就返回。


例子:

用户问:

复制代码
差旅报销标准

最相关文档是总部制度(无权限)。

fallback 返回:

复制代码
部门差旅制度(相似但次优)

目标:

复制代码
有用 > 完美

Fallback 3(RAG ⭐)

不是只靠检索。

而是改变 LLM回答策略


当系统检测:

复制代码
高置信文档不存在

不要让 AI 硬答。

而是生成:

复制代码
未找到完全匹配内容,
但以下相关制度可能有帮助:

然后引用次相关文档。


这叫:Graceful Degradation(优雅降级)


用户体验从:

没找到。

变成:

没完全匹配,但这些可能相关。

相关推荐
木易士心11 分钟前
MyBatis数据源切换全面解析
数据库
新中地GIS开发老师20 分钟前
地信职业百科④:GIS开发工程师
前端·数据库·gis·webgis·三维gis开发
云和恩墨28 分钟前
从“第二存储”到多智能体协作,云和恩墨充实数据基础设施产品矩阵
数据库
ClouGence35 分钟前
SAP HANA 到 Doris 数据迁移:4 种方案对比与迁移教程
数据库·后端·dba
霸道流氓气质36 分钟前
ApiPost 中配置自动获取 Token 并调用业务接口完整指南
java·服务器·数据库
我不想名字重复39 分钟前
redis缓存和数据库数据保持一致
数据库·redis·缓存
宇宙第一小趴菜1 小时前
三、Oracle 核心原理
数据库·oracle
码出钞能力2 小时前
apache-shardingsphere-5.5.3自定义分片算法
数据库
兜有米啦2 小时前
数据库第二次作业
数据库
nVisual3 小时前
机柜PDU安装位置与空间建模方案
大数据·网络·数据库·信息可视化·数据中心基础设施管理