news 2026/10/4 19:10:10

45.多租户知识库怎么做用户团队文档和向量数据隔离

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
45.多租户知识库怎么做用户团队文档和向量数据隔离

多租户知识库怎么做?用户、团队、文档和向量数据隔离

码海寻道 · 大模型、智能体与 RAG 工程组件系列第 45 篇

多租户知识库最危险的错误,不是页面显示错了,而是用户在检索结果、引用或 Agent 工具中看到了另一个租户的数据。隔离设计必须贯穿身份、API、数据库、对象存储、向量检索、缓存和日志。

一、先定义租户模型

Tenant ├── Users ├── Teams ├── Roles └── KnowledgeBases └── Documents

常见关系:

  • 用户属于一个或多个团队;
  • 团队拥有或共享知识库;
  • 文档属于知识库和租户;
  • 权限可以继承,也可以针对文档单独配置。

不要只在用户表里增加一个tenant_id就认为完成了多租户设计。真实系统还要处理跨团队协作、离职、邀请、转移和审计。

二、隔离的四个层次

认证隔离

Token 或会话中记录用户身份,但不要完全信任客户端提交的租户 ID。

授权隔离

服务端根据用户、角色、团队和资源关系计算可访问范围。

数据隔离

PostgreSQL 行级策略、对象 Key 前缀和向量过滤共同限制数据范围。

运行隔离

缓存 Key、任务队列、日志、限流和模型调用预算都要带租户维度。

三、PostgreSQL 中的租户字段

业务表通常显式保存tenant_id:

CREATETABLEdocuments(id uuidPRIMARYKEY,tenant_id uuidNOTNULL,titletextNOTNULL,statustextNOTNULL,created_at timestamptzNOTNULLDEFAULTnow());CREATEINDEXidx_documents_tenant_statusONdocuments(tenant_id,status);

所有 Repository 查询都应带租户范围。可以使用 PostgreSQL Row-Level Security 增加数据库层保护,但应用层仍要正确设置当前租户上下文。

身份服务应把“用户属于哪些租户、在租户内拥有什么角色、能访问哪些知识库”作为授权事实源。请求进入业务层后生成不可由客户端覆盖的AuthContext,数据库连接、对象存储 Key、向量过滤和缓存 Key 都从这个上下文派生。

四、向量数据如何隔离?

常见方案:

同一 Collection + tenant_id

成本低、租户数量扩展容易,但每次搜索必须带可信过滤条件。

每个租户独立 Collection

隔离强,但集合、索引和运维数量随租户增加,适合少数大型租户或强隔离场景。

分区或分区键

适合稳定且数量可控的数据域。不要为每个用户随意创建 Partition。

无论采用哪种方案,向量库都不能成为唯一授权层。检索命中后仍应进行业务回查和权限确认。

同时要测试空过滤、错误字段和召回不足时的行为,确保任何检索路径都不会因为过滤条件缺失而退化为全库搜索。最终返回前仍应按chunk_id重新确认资源可见性。

五、对象存储路径隔离

tenants/{tenant_id}/knowledge-bases/{kb_id}/documents/{document_id}/v3/source.pdf

服务端生成对象 Key,客户端不能自定义跨租户路径。下载使用短时预签名 URL,并在生成前检查用户权限。

六、缓存 Key 必须带租户

错误:

rag:answer:{query_hash}

正确:

rag:answer:{tenant_id}:{kb_version}:{model_version}:{query_hash}

会话、限流、权限范围、检索结果和任务状态都要避免跨租户复用。Redis 共享集群时尤其需要做 Key 规范和访问审计。

仅加入tenant_id还不够,问答缓存通常还要包含user_id或权限版本、知识库serving_version、模型版本、检索参数和查询哈希。角色变化、文档下线和权限回收时,应提升权限版本或主动失效,避免旧缓存绕过新授权。

七、API 权限检查流程

请求 Token ↓ 解析 user_id ↓ 服务端确定 tenant_id 和 team_scope ↓ 检查资源所属关系 ↓ 生成数据库和向量过滤条件 ↓ 执行查询 ↓ 结果再次脱敏与校验

不要让前端直接控制tenant_id、team_id、document_ids或向量过滤表达式。前端可以提出目标,权限范围必须由服务端裁决。

八、跨租户操作要单独设计

平台管理员、客服和数据分析任务可能需要跨租户访问,但不能让普通业务接口自动获得这种能力。

跨租户操作建议使用独立接口、独立角色和短时授权,并要求填写工单或审批单。操作结果要带目标租户列表、原因、操作者和审批链;禁止通过修改请求头、查询参数或模型工具参数临时扩大范围。

应使用:

  • 独立角色和权限;
  • 明确的操作原因;
  • 限定的租户范围;
  • 更详细的审计;
  • 必要时双人审批;
  • 导出数据的脱敏和水印。

九、租户删除和数据生命周期

删除或注销租户时,需要清理:

PostgreSQL 记录 对象存储文件 Milvus / pgvector 向量 Redis 缓存和会话 消息队列中的任务 搜索和监控中的敏感副本 备份中的合规数据

大规模删除应异步执行,并向管理员展示进度、失败项目和最终审计结果。不要因为界面显示“租户已删除”就假设所有副本已经同步清理。

删除任务应先写入租户级 tombstone,阻止新请求和新任务继续写入,再按依赖顺序清理 PostgreSQL、对象存储、向量索引、Redis、队列消息、日志和备份副本。清理任务要可重试、可审计,并能报告仍未删除的副本。

十、隔离测试不能只测正常请求

至少测试:

  • 用户修改请求中的 tenant_id;
  • 猜测其他租户 document_id;
  • 通过搜索结果获取跨租户引用;
  • 通过缓存命中得到其他租户答案;
  • 旧任务完成后覆盖新租户状态;
  • 对象存储预签名 URL 越权;
  • Agent 工具调用绕过前端权限;
  • 批量导出和管理员接口越权。

十一、上线检查清单

  • 身份和租户范围由服务端确定;
  • PostgreSQL 查询包含租户约束或 RLS;
  • Milvus 检索包含可信过滤;
  • 对象存储 Key 按租户隔离;
  • Redis Key 包含租户和版本;
  • 任务、日志和审计带租户上下文;
  • 跨租户管理员操作独立授权;
  • 删除、备份和恢复有明确策略;
  • 已完成越权和缓存串租户测试。

结语

多租户隔离不是某个组件的单一功能,而是一条贯穿身份、权限、数据库、对象存储、向量库、缓存、任务和日志的系统边界。任何一层遗漏,都可能让前面的隔离失效。

至此,第八篇章“后端、前端与系统集成”全部完成。下一篇章将进入评估、监控与安全,从大模型应用如何评估开始。

参考资料

  1. PostgreSQL 官方文档:Row Security Policies
  2. Milvus 官方文档:Filtered Search
  3. OWASP:Authorization Cheat Sheet

本文为“码海寻道”原创技术文章。多租户系统涉及权限和数据合规,正式上线前应进行独立安全评审与恢复演练。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 19:04:20

Agent的state注入

Agent 的记忆里藏一句话,就能带偏它这不是黑客炫技,是 TypeSafe 官方文档自己承认的缺陷 查证日期:2026-10-01 | 官方引文来自 TypeSafe AI 文档 jaggedness 页(jev-1.13,2026-09-17 复核)一、官…

作者头像 李华
网站建设 2026/10/4 19:00:22

VSCode插件实战:用TaoToken统一管理注释修改时间的自动更新

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/4 18:54:23

隔离内网下AI Agent工程化落地:MCP与Skills实战

1. 隔离内网下的 AI Agent 工程化落地:从零搭建到稳定运行很多做企业级交付的朋友都遇到过这种场景:客户现场只有一台跳板机能连外网,业务服务器全部在隔离内网里,没有公网出口,没有外部镜像源,甚至连 pip …

作者头像 李华
网站建设 2026/10/4 18:53:50

基因组重复序列注释全流程:RepeatModeler建库与RepeatMasker屏蔽实操

基因组组装完成后,跑完三代组装、Hi-C挂载、纠错这些大工程,很多人会下意识松一口气——但如果你直接把基因组丢给BRAKER或者Augustus做基因结构预测,接下来大概率会收获一堆结构错乱的基因模型。这不是组装的问题,而是绕过了重复…

作者头像 李华