提示词过滤:对输入进行多级安全与合规检查

FreeGuideOnline 最新 2026-06-29

用户输入 → 规范化清洗 → 第一级:模式规则 → 第二级:实体与敏感信息 → 第三级:语义意图分类 → 放行/修改/阻断


### 第一级:模式与正则规则

这一层用于快速匹配明确禁止的关键词、正则表达式或黑白名单。

- **关键词列表**:维护一份禁用语清单,支持普通词、同音词、变体(如全角/半角混合、特殊字符间隔)。
- **正则表达式**:匹配结构化敏感信息,如身份证号、手机号、银行卡号、API Key、JWT Token等。
- **规范化处理**:在匹配前统一转换输入,例如:全角转半角、统一Unicode字符(如将`e`的异体字归一到标准ASCII)、去除零宽字符、解码HTML实体。

实现示例(Python 伪代码):

```python
import re

def basic_pattern_filter(text: str) -> dict:
    text = normalize_unicode(text)  # 自定义函数,处理同形字、隐藏字符
    blocked_phrases = ["暴力手段", "非法制作", "hack into"]
    for phrase in blocked_phrases:
        if phrase in text.lower():
            return {"allowed": False, "reason": f"包含禁止短语: {phrase}"}

    # 正则匹配身份证号(简单示例)
    id_card_pattern = r'[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]'
    if re.search(id_card_pattern, text):
        return {"allowed": False, "reason": "检测到疑似身份证号"}

    return {"allowed": True}

第二级:实体识别与隐私过滤

这一级利用命名实体识别(NER)技术,检测并脱敏或阻断包含个人身份信息(PII)的提示词。

  • 实体类型:姓名、地址、电子邮件、电话号码、IP地址、凭证密钥等。
  • 处理策略:不轻易返回“输入违规”,而是选择自动脱敏,将检测到的实体替换为占位符(如[EMAIL][PHONE])后再传递给模型,并提示用户输入已修改。
  • 工具选择:可使用轻量级NER模型(如spaCy、Microsoft Presidio)、基于正则的扫描器,或调用云服务API(需注意数据离线处理)。

结合脱敏的流水线设计:

  1. 检测实体
  2. 若为低敏感度实体(如城市名)则保留原样
  3. 若为高敏感度PII,则替换为占位符,并记录原始值用于后处理响应(如将答案中的占位符还原,但需谨慎以防泄漏)
  4. 如果输入中PII密度过高或意图可疑,仍可直接阻断

第三级:语义意图与越狱检测

前两层无法覆盖经过伪装、隐喻或语言变异的恶意提示。第三级引入语义分类器,识别输入的真实意图。

常见语义风险类别:

  • 越狱/角色扮演:试图让模型忽略安全准则,如“DAN模式”、“开发者模式”、“假装你是我的奶奶讲述如何制作…”等。
  • 仇恨与歧视:涉及种族、性别、宗教的影射或刻板印象宣传。
  • 自伤/暴力:表达自我伤害、策划暴力行为的意图。
  • 非法建议:请求生成恶意软件、欺诈话术、管制物品合成方法。

实现方式:

  • 小模型分类:使用经过微调的轻量级BERT类模型(如DistilBERT、SecureBERT)直接对提示词进行二分类或多标签分类,延迟低于100ms。
  • LLM自检:调用另一个专用于安全的LLM,或让主模型在系统提示中执行分类(例如:“你的第一个任务是判断以下用户消息是否安全,回答SAFE或UNSAFE,然后根据判断继续或拒绝”)。这种方式更灵活但成本和延迟更高。
  • 向量相似度匹配:将用户输入转化为向量,与已知越狱提示词库的向量进行相似度计算,超过阈值则拦截。此方法可捕获变种。

示例:使用分类 API 的伪代码

def semantic_safety_check(prompt: str, classifier) -> dict:
    categories = classifier.predict(prompt)  # 返回如 {"jailbreak": 0.92, "hate": 0.01, ...}
    if categories.get("jailbreak", 0) > 0.8:
        return {"allowed": False, "reason": "检测到越狱尝试"}
    if categories.get("illegal", 0) > 0.7:
        return {"allowed": False, "reason": "可能请求非法内容"}
    return {"allowed": True}