元数据过滤是什么
元数据过滤把权限、时效与范围约束下沉到检索层:给每个块带上部门、密级、生效日期、文档类型、版本等字段,查询时先按条件过滤再做近邻计算。过滤与检索的先后顺序差别很大:先过滤再检索(pre-filter)能在允许集合内取满 top-k;先检索再过滤(post-filter)会让结果被无效数据稀释,过滤后可能只剩一两条。权限过滤属于硬约束,条件必须由后端从登录态推导,绝不能接受前端传入的部门或密级参数。
基本信息
| 常用字段 | 部门、密级、生效日期、文档类型、版本 |
|---|---|
| 过滤时机 | pre-filter 优于 post-filter |
| post-filter 风险 | top-k 被无效结果稀释,结果数量不足 |
| 权限来源 | 由后端从登录态推导,不信客户端参数 |
| 维护要求 | 元数据随文档更新同步刷新,支持失效标记 |
| 缺失处理 | 元数据缺失的块要有明确默认策略 |
典型使用场景
- 多租户知识库:按租户或部门隔离检索范围
- 权限分级:不同密级文档对不同角色可见
- 时效控制:只检索现行有效版本,自动排除已废止文件
- 范围收敛:按产品线或地区限定检索集合
- 多版本共存:按版本号过滤,避免新旧制度混答
- 评测区分:按来源类型分组统计召回效果
过滤检索请求示例
过滤检索请求示例
POST /collections/kb/points/search
{
"vector": [0.12, 0.98, 0.31],
"limit": 10,
"filter": {
"must": [
{ "key": "dept", "match": { "value": "finance" } },
{ "key": "status", "match": { "value": "effective" } },
{ "key": "level", "range": { "lte": 2 } }
]
}
}
# must 内的条件由后端从登录态与会话上下文拼装
# 不要直接使用客户端传来的 dept 或 level 字段过滤顺序对比
| 顺序 | 行为 | 后果 |
|---|---|---|
| 先过滤再检索 | 在允许集合内做近邻搜索 | 结果数量稳定,推荐做法 |
| 先检索再过滤 | 取完 top-k 再剔除不合格项 | 剔除后可能剩不到几条,需要放大 k 补救 |
| 客户端传参过滤 | 过滤条件来自请求体 | 越权读取他人数据的直接入口 |
| 元数据缺失 | 块没有部门或密级字段 | 要么被全部过滤,要么全部放开 |
过滤条件必须在后端由身份信息推导,并且只作为查询的硬约束;把它交给模型判断或加进提示词,等于把越权入口写进系统。
元数据缺失的块要有明确默认策略:建议默认拒绝入库并在导入阶段就补全字段,避免事后靠人工比对补齐。