Skip to content
🔗 分享本题
查看我的学习进度 →
企业 RAG 权限预过滤与隔离图解

🧠 图解记忆: 权限必须进入检索条件,让模型从一开始就看不到无权访问的原文;事后过滤不够安全。

💡 答案要点

核心问题:

普通员工问AI:"高管的平均工资是多少?"
如果RAG没有权限控制 → AI可能从HR文档中检索到 → 信息泄露!

四层权限隔离架构

┌─────────────────────────────────────────────┐
│              权限隔离四层模型                │
├─────────────────────────────────────────────┤
│ Layer 1: 检索前过滤(Query时)               │
│   → 用户问问题时,先判断他能访问哪些文档      │
├─────────────────────────────────────────────┤
│ Layer 2: Chunk级权限标签                      │
│   → 每个Chunk有权限标签(机密/内部/公开)      │
│   → 检索时只返回用户有权限的Chunk             │
├─────────────────────────────────────────────┤
│ Layer 3: 生成时脱敏                          │
│   → LLM回答时再次检查,避免泄露               │
├─────────────────────────────────────────────┤
│ Layer 4: 审计日志                            │
│   → 记录所有检索和回答,用于事后审计          │
└─────────────────────────────────────────────┘

Layer 1: Query时权限预过滤

python
class PermissionPreFilter:
    def filter_query(self, user_query, user_role):
        # 用户角色 → 可访问的文档范围
        accessible_docs = self.role_to_docs.get(user_role, [])

        # 在检索前限制搜索范围
        return {
            "query": user_query,
            "allowed_doc_ids": accessible_docs  # 只检索这些文档
        }

# 示例
role_perms = {
    "普通员工": ["公开文档", "产品手册"],
    "经理": ["公开文档", "产品手册", "内部公告"],
    "HR": ["公开文档", "HR文档"],
    "高管": ["所有文档"]
}

Layer 2: Chunk级权限标签

python
# 给每个Chunk打权限标签
chunk_permissions = [
    {"chunk_id": "c1", "content": "公司产品介绍", "level": "public"},
    {"chunk_id": "c2", "content": "销售数据报表", "level": "internal"},
    {"chunk_id": "c3", "content": "员工工资表", "level": "hr_only"},
    {"chunk_id": "c4", "content": "高管薪酬方案", "level": "executive_only"},
]

# 检索时过滤
def retrieve_with_permission(user_level, query):
    chunks = vectorstore.similarity_search(query, k=10)

    permission_rank = {
        "public": 0,
        "internal": 1,
        "hr_only": 2,
        "executive_only": 3
    }

    # 过滤:只保留用户有权访问的Chunk
    accessible = [
        c for c in chunks
        if permission_rank[c.level] <= permission_rank.get(user_level, 0)
    ]
    return accessible

Layer 3: LLM生成时脱敏

python
# 生成回答时加入权限检查指令
def generate_with_guardrails(context, user_query, user_level):
    permission_instruction = {
        "普通员工": "请只基于公开和内部信息回答,不要提及高管或HR专属信息",
        "经理": "请只基于公开、内部和经理级信息回答",
        "HR": "请只基于公开和HR文档回答",
        "高管": "可以访问所有信息"
    }

    prompt = f"""
    {permission_instruction[user_level]}

    用户问题:{user_query}

    参考信息:{context}

    请谨慎回答。
    """
    return llm.invoke(prompt)

Layer 4: 审计日志

python
# 记录所有检索行为
def log_retrieval(user_id, query, retrieved_chunks, response):
    audit_log = {
        "timestamp": datetime.now(),
        "user_id": user_id,
        "query": query,
        "retrieved_chunk_ids": [c.id for c in retrieved_chunks],
        "chunk_levels": [c.level for c in retrieved_chunks],
        "response_length": len(response),
        "flagged": any(c.level == "restricted" for c in retrieved_chunks)
    }

    # 写入审计表(不可删除)
    audit_table.insert(audit_log)

    # 如果触发了权限边界,告警
    if audit_log["flagged"]:
        security_team.notify(audit_log)

权限隔离vs普通RAG的架构对比

维度普通RAG带权限隔离的RAG
检索范围全量向量数据库按用户权限过滤
Chunk标签每个Chunk有权限级别
LLM指令通用Prompt加权限上下文
审计日志完整记录
数据泄露风险
实现复杂度

面试话术

示例表达(仅在能用本人经历或可复现实验佐证时使用): "企业RAG权限隔离是2026年面试的高频考点。核心是四层防护:检索前过滤(用户能看到哪些文档)、Chunk级标签(每个片段有权限级别)、生成时脱敏(LLM回答时加权限指令)、审计日志(记录所有行为留痕)。实现难点是权限标签的建设——谁来定义、怎么维护、怎么和AD/LDAP集成。我做过一个案例是HR文档保护,普通员工问工资相关问题会被拦截,回答'抱歉您没有权限访问此信息'。"

📚 参考:Milvus:多租户与权限隔离实践


版本: v2.8 | 更新: 2026-04-06 | by 二狗子 🐕