RAG 元数据过滤设计:先收窄再向量检索
向量相似解决「长得像」,元数据过滤解决「该不该看」。 多租户、多产品线知识库里,不做过滤就容易把 A 客户的合同段落塞进 B 客户的答案。
常见过滤维度
tenant_id/ 工作空间product/localedoc_type(政策 / FAQ / 工单)effective_from/expires_ataccess_level
过滤应在检索前或混合检索的硬约束阶段生效,而不是只靠提示词说「请忽略无关文档」。
设计步骤
- 列出业务上「绝不能串」的边界(通常是租户与密级)。
- 为每份入库文档强制写入这些字段,缺字段则拒收。
- 查询侧从会话上下文注入同等过滤(勿让终端用户随意改租户)。
- 评测:构造「语义很像但租户不同」的对抗集。
与关键词检索
时效、编号、SKU 等精确字段往往更适合关键词或结构化过滤,再叠加向量。参见 何时加关键词检索;过期文档策略见 文档过期。
反模式
- 只用
filename模糊匹配当权限。 - 把过滤条件写进 Prompt 却不在检索引擎执行。
- 元数据枚举无限膨胀,导致几乎总是滤空。
示意查询伪代码
retrieve(
query,
filters={tenant: T, doc_type in [FAQ, POLICY], expires_at > now},
top_k=8
)
滤空与回退
过滤过严会导致零命中。策略可以是:硬过滤(租户、密级)不可放宽;软过滤(语言、产品线)可在零命中时有限度回退并提示用户。回退必须写进产品逻辑与审计,不能靠模型「偷偷用别的租户文档」。
元数据治理比调向量维度更先:没有字段质量,后面的混合检索都是空中楼阁。对抗评测集应定期加新串租案例。字段枚举变更要有迁移脚本,避免旧文档成为漏网之鱼。
字段写入责任
入库管道校验失败要告警到文档所有者,而不是静默丢字段。查询侧过滤来自会话身份,不来自模型自由发挥。管理员「跨租户检索」应是独立特权工具,带审计,不与普通问答共用。
评测报告里单独列「串租率」指标,目标是零。和过期策略联动:过期文档可以保留向量但默认硬过滤掉,除非查询显式要历史版本。元数据设计一次做好,后续少救命。
调试技巧
命中结果页同时显示元数据,便于判断是过滤错还是向量差。临时关闭软过滤做对比实验,硬过滤保持开启。文档修复后重建索引的延迟要告知运营。示意伪代码不可直接当生产实现。 先过滤、再相似,是多业务知识库的默认姿势。字段质量决定上限。示意维度请映射到你们的权限模型。