Appearance
6.3.1 Metadata Filter 在检索阶段怎么用?
先给结论:Metadata Filter 在检索阶段的作用,是先把“哪些对象有资格参与本次召回”这件事收紧。它不只是结果展示的附加条件,而是召回质量和边界控制的一部分。
所以更稳的系统通常不会等候选都召回完再说,而是会尽量在检索阶段就先做过滤。
它到底在过滤什么
最常见的 metadata filter 往往在过滤这些边界:
- 版本
- 状态
- 租户
- 权限范围
- 文档类型
- 时间范围
- 业务域
也就是说,它解决的不是“语义像不像”,而是:
- 这些对象本来该不该参加当前检索
为什么这一步应该尽量前置
如果不前置,而是等召回完再处理,常见问题包括:
- 候选池先被无关内容污染
- selective filter 下容易错过真正该召回的对象
- 后续排序、重排都在噪声上浪费资源
- 权限和版本边界更容易串
更稳的做法通常是:
- 能在召回前缩边界,就尽量在召回前缩
一个最小示意
python
filters = {
"tenant_id": "tenant-a",
"status": "active",
"doc_type": "policy"
}
results = vector_search(
query_vector,
top_k=20,
metadata_filter=filters
)这段代码想说明的是:
- 检索不是先全库找,再最后挑
- 而是最好一开始就限制参与范围
检索阶段常见的两种过滤位置
更粗略地说,常见有两种思路:
1. 先过滤,再召回
优点是:
- 候选更干净
- 边界更稳
代价通常是:
- 某些实现里计算成本可能会上升
2. 先召回,再过滤
优点是:
- 实现有时更简单
风险是:
- highly selective filter 场景更容易漏真正结果
- 候选池先被噪声占位
所以很多生产系统会更偏向:
- 能 pre-filter 时尽量 pre-filter
什么场景尤其必须把 filter 放进检索阶段
下面这些场景,特别不适合把过滤拖到检索后再说:
- 多租户隔离
- 严格权限控制
- 当前有效版本必须唯一
- 业务域非常明确,比如只查 FAQ、只查政策库
这些场景里,filter 不只是“优化”,而是边界本身。
一个常见误区
很多人会觉得:
- 先搜回来,再在展示时挑一下就行
这在低风险场景里有时能凑合,但更稳的系统不会这么做。
因为一旦错误候选已经进入后续链路,它就可能:
- 抢掉真正相关候选的位置
- 被 rerank 继续放大
- 进入生成上下文
所以 metadata filter 最好不要只当展示层筛选器。
一句话总结
Metadata Filter 在检索阶段的作用,是先决定哪些对象有资格参与本次召回。它解决的是边界控制,不是语义匹配。能前置的过滤尽量前置,通常会比“先全找回来再过滤”更稳。