多租户 RAG 知识库权限怎么隔离

多租户 RAG 知识库权限怎么隔离

先给结论:多租户场景下做 RAG,最致命的不是检索准不准,是 A 公司的人能不能搜到 B 公司的文档。这道权限隔离做漏了,就是数据泄露事故。我踩过一次差点出事的边,把几种隔离方案和选型摆在这。

场景

我做的是一个给多家客户用的合同问答 Agent。每家客户上传自己的合同到知识库,问答时只能检索到自家的文档。早期我图快,所有客户的文档丢一个向量库里,检索时全局召回——直到测试时 A 客户搜出了 B 客户的合同片段,后背一凉。

三种隔离方案对比

我把试过的三种摆一起:

方案

隔离强度

成本

适合规模

主要风险

元数据过滤

中小,几十个租户

过滤条件漏写就穿透

独立 collection

几十到几百租户

collection 多了管理累

独立向量库实例

最高

大客户/强合规

资源浪费、运维重

元数据过滤:所有文档进同一个库,但每条切片打上tenant_id标签,检索时强制带where tenant_id = 当前租户这个过滤条件。成本最低,但有个致命点——只要哪次检索忘了带这个过滤条件,立刻全局穿透。我那次事故就是某条检索分支漏了过滤。

独立 collection:每个租户一个独立的向量集合,检索时按租户路由到对应 collection。物理上分开,不存在"忘了过滤"的穿透问题,隔离强度高一档。代价是租户多了之后,几百个 collection 管起来有点烦。

独立向量库实例:每个大客户单独起一套库。隔离最彻底,合规审计最好交代,但资源和运维成本最高,只对强合规的大客户才值得。

我最后的选型

中小租户用元数据过滤兜底,但加了两道保险:一是把tenant_id过滤写进检索的公共封装里,任何检索调用都自动带上,不给"忘记"的机会;二是上线前专门写了一条越权检索的测试用例,A 租户的请求去搜 B 的关键词,断言必须召回 0 条。

少数强合规的大客户单独切独立 collection。这套混合策略落地下来,既没为小客户上重型方案,又给大客户留了硬隔离。

实现上我是在一个带场景化 RAG 能力的搭智能体平台上做的,它支持按知识库维度建多个独立库,我直接一个租户挂一个知识库,检索时绑定当前租户的库,从源头上就不会跨租户召回——比自己在一个大库里靠过滤条件兜底,心理踏实多了。

一个容易忽略的细节

权限不只是检索那一刻的事。文档删除也要隔离——客户解约后,他那批向量得能干净删掉。我早期是按文档 ID 一条条删,后来发现切片散在库里删不干净,残留的向量还能被搜到。改成按tenant_id批量清,才算彻底。

收尾

多租户 RAG,我的经验是:隔离强度按客户分级别给,别一刀切;同时把越权检索写成自动化测试,每次发版都跑,这比任何人工 review 都靠谱。

模型和向量化那层我用的讯飞星辰现成的服务,大模型 API 直接调,不用自己搭嵌入和推理服务,省下的工夫全花在把权限这道闸做严上了。