多租户 RAG 的过滤条件属于访问控制,不应交给模型决定。服务端必须从登录身份取得 tenant_id,并在每次向量查询中与文档状态和版本条件一起下发。 本文基于 Qdrant Filtering 说明元数据与查询设计,未审计你的认证、数据库和向量集合;真正的隔离还要覆盖写入、更新、删除、缓存、日志和引用回查。
本篇验收要点:tenant_id 由服务端认证上下文提供,向量查询必须附带 tenant_id 相等条件,聊天输入中的租户名不能覆盖它。 片段保存 document_id、version 和 status,查询只选择 active 版本;发布新版本后再原子切换状态并清理缓存。

开始前准备
- 可信的用户到 tenant_id 映射
- 稳定 document_id 与版本规则
- 向量集合 payload 字段定义
- 跨租户和旧版本负面测试数据
按顺序搭建
- 写入时为每个 chunk 保存 tenant_id、document_id、version、status、source_uri 和 chunk_no,字段类型保持一致。
- 从服务端会话解析 tenant_id,构建强制 must 过滤;用户输入只作为查询文本,不允许直接提供过滤 JSON。
- 版本发布采用 staged→active:新版本所有片段写入并校验后再切 active,旧版本改为 archived,避免混合召回。
- 所有读取路径复用同一过滤构造器,包括检索、引用详情、导出和管理员调试接口。
- 创建两个租户的相似文档和同一文档两个版本,运行交叉查询并核对 Top-K、引用与缓存。
可复制的最小示例
过滤结构可表达为下列逻辑,字段名按实际集合调整:
must:
- tenant_id == authenticated_tenant_id
- status == "active"
- doc_type in ["policy", "faq"]
可选:document_id == requested_document
禁止:从聊天文本直接接受 tenant_id 覆盖
怎样验收结果
验证标准是租户 A 的任何查询都无法返回租户 B 的 point、正文或引用,active 版本切换后旧版本不再召回,缓存和详情接口也遵守相同过滤。
- 跨租户相似文档不泄露
- 旧版本从检索和引用中同时消失
- 过滤条件来自认证上下文
- 管理员接口也有明确授权和审计
常见失败与处理
- 过滤无结果:检查 payload 字段类型、索引和实际写入值。
- 新旧版本同时出现:修复状态切换和缓存失效。
- 列表安全但详情泄露:让详情读取复用同一租户过滤。
读者下一步是在测试集合写入两个租户的同名文档,用相同问题验证正文、引用和详情接口都不能跨租户。
相关问答
把每个租户放在独立集合更安全吗?
独立集合可减少误过滤风险,但会增加运维成本;无论哪种方案都要做服务端归属校验。
模型提示词里写“只查当前租户”够吗?
不够。访问边界必须由查询过滤和后端权限强制实现。
官方资料与适用边界
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/32460.html