你这套 RAG 部署到银行,一个普通的大堂经理,他问系统'公司薪酬结构是什么',系统会不会把副行长的薪资文件检索出来给他
P1 · rag · 🏢 蚂蚁
🏷 标签:rag, permission, security, banking
1️⃣ 考察意图
面试官真正想看你是否具备生产级 RAG 系统的安全设计意识,而非仅会调 API 搭 demo。这是典型的系统设计 + 安全审计类问题,刁钻点在于:向量检索默认无权限隔离,语义相似度会直接绕过传统 ACL(访问控制列表)。答好了能展示你对 RAG 落地中“数据泄露”这一核心风险的深度理解,以及从检索层到应用层构建权限控制架构的工程能力。
2️⃣ 标准答
会,而且概率极高。 原因在于标准 RAG 流程(Embedding → 向量库 → 相似度检索)只关心语义匹配,不关心文档的访问权限。当“薪酬结构”与“副行长薪资文件”在语义空间接近时,系统会无差别返回。
核心问题:向量数据库默认无行级权限
- 传统数据库有行级安全(RLS),但向量库(如 Pinecone、Milvus、FAISS)的索引是全局的,检索时只返回 Top-K 相似结果,不检查用户身份。
- 即使文档元数据中标注了“权限等级=机密”,若检索时不加过滤,机密文档仍会进入候选集。
解决方案:三层权限控制架构
- 文档级权限标注(预处理层) - 在文档入库时,为每个 chunk 附加元数据字段:
{ "doc_id": "xxx", "permission_level": "confidential", "allowed_roles": ["admin", "hr_director"] }。 - 坑:银行文档常有多级权限(如“仅副行长可见”),需统一映射到角色-权限矩阵,避免硬编码。 - 检索时权限过滤(检索层) - 使用支持元数据过滤的向量库(如 Milvus 的
expr过滤、Pinecone 的filter参数)。查询时,将当前用户角色(如role="teller")作为过滤条件,只检索allowed_roles包含该角色的 chunk。 - 工程取舍:过滤会降低检索效率(尤其当权限条件复杂时),需在索引设计时对权限字段建倒排索引,或使用分区(Partition)按权限等级物理隔离文档。 - 实际落地坑:权限字段若为数组类型(如allowed_roles: ["admin","hr"]),部分向量库不支持数组过滤,需拆成多值字段或改用布尔组合。 - 结果后置脱敏(应用层) - 即使检索层漏过,LLM 生成前需二次校验:对返回的 chunk 做正则/规则匹配,若包含“薪资”“机密”等敏感词,直接丢弃或替换为“无权限访问”。 - 注意:不能完全依赖 LLM 做权限判断,因为 LLM 可能被 prompt injection 绕过。
为什么不能只靠 LLM 做权限?
- LLM 的上下文窗口有限,且对权限规则的理解不稳定。例如,用户问“公司薪酬结构”,LLM 可能认为“副行长薪资”是合理答案,而不会意识到权限越界。
- 必须从检索源头掐断,遵循最小权限原则。
总结:不加权限控制的 RAG 在银行场景就是数据泄露事故。核心是元数据过滤 + 角色映射 + 后置校验三层兜底。
3️⃣ 答题模板(30 秒电梯版)
“这个问题我从三个层面回答:第一,检索层——向量库默认无行级权限,语义相似度会直接泄露敏感文档;第二,解决方案——在文档入库时标注权限元数据,检索时用角色过滤(如 Milvus 的
expr过滤),生成前再做后置脱敏;第三,工程取舍——过滤会牺牲检索速度,需对权限字段建索引或分区隔离。总结一句:银行 RAG 必须把权限控制嵌入检索链路,不能依赖 LLM 事后判断。”
4️⃣ 高频追问 & 应对
追问 1:如果用户通过改写问题(如“公司高层福利”)绕过权限过滤怎么办?
应对策略:这是典型的语义绕过攻击。解法是双保险:① 检索层用权限白名单而非黑名单——只允许用户访问
allowed_roles包含其角色的文档,不依赖问题语义判断;② 应用层加敏感词检测,对返回内容做正则匹配(如“薪资”“奖金”),匹配到则触发二次确认或直接拒绝。注意:白名单策略会误伤跨部门协作场景,需配合临时授权机制(如管理员手动放行)。
追问 2:银行有几十万份文档,权限粒度到段落级,元数据过滤性能扛不住怎么办?
应对策略:这是典型的大规模权限过滤性能问题。解法:① 分区隔离——按权限等级(公开/内部/机密)将文档分到不同物理分区,查询时只扫描用户有权限的分区,减少过滤数据量;② 倒排索引加速——对
allowed_roles字段建倒排索引,将 O(n) 扫描降为 O(log n);③ 缓存热点权限——对高频角色(如大堂经理)的权限列表做本地缓存,避免每次查询都读数据库。工程取舍:分区会增加维护成本(如跨分区查询需合并结果),需根据业务场景权衡。
追问 3:如果副行长的薪资文件被误标为“公开”怎么办?
应对策略:这是数据治理问题,非纯技术能解决。解法:① 入库前做自动化权限校验——用规则引擎(如 Drools)检查文档标题/内容是否含敏感关键词,自动标记或拒绝入库;② 定期做权限审计——扫描所有文档的元数据,对“公开”但内容含敏感词的文档报警;③ 引入人工审核流程——对高权限文档(如机密级)的入库操作需双人确认。注意:自动化校验有误报率,需设置阈值(如敏感词命中率 > 80% 才拦截)。
5️⃣ 避坑 · 常见错误答法
- ❌ 回答“不会,因为向量检索只找语义相似的,副行长薪资文件语义不匹配” → ✅ 正确切入:语义相似度是连续的,“薪酬结构”和“副行长薪资”在 embedding 空间距离很近,必须假设所有敏感文档都可能被检索到,从权限过滤入手。
- ❌ 回答“用 LLM 判断权限,在 prompt 里加‘不要返回敏感内容’” → ✅ 正确切入:LLM 对权限规则的理解不稳定,且易被 prompt injection 绕过,必须从检索层做硬性过滤,LLM 只能做辅助校验。
- ❌ 回答“把敏感文档单独存一个向量库,用户查询时先判断权限再决定查哪个库” → ✅ 正确切入:这本质是分区隔离,但没说清楚如何动态判断用户权限。需补充角色映射和查询时路由逻辑,否则用户仍可能通过跨库查询绕过。
6️⃣ 简历呼应
- 如果你有 RAG 项目:从“我在项目中遇到过数据泄露问题”切入,描述如何用元数据过滤解决,并量化效果(如“将敏感文档泄露率从 15% 降到 0.1%”)。
- 如果你只做过传统 NLP:用“传统搜索中的 ACL 控制”类比,说明 RAG 的权限控制本质是“在向量检索中嵌入行级安全”,并强调 embedding 的语义连续性让问题更复杂。
- 如果你是校招无项目:聚焦“论文复现”——引用《RAG vs Fine-tuning》中关于数据安全的讨论,或复现 Milvus 官方文档中的权限过滤 demo,展示对生产级问题的思考。
- 《RAG vs Fine-tuning: Pipelines, Tradeoffs, and a Case Study on Agriculture》(讨论 RAG 数据安全)
- Milvus 官方文档:
Metadata Filtering与Partition Key设计 - Pinecone 博客:
Securing Your Vector Database: Row-Level Access Control - 《Access Control in Vector Databases: A Survey》(2024,arXiv)
- 蚂蚁集团技术博客:
金融级 RAG 系统的权限控制实践(内部资料,可搜索公开版本)