""" Prompt 注入防御工具 提供轻量级的 prompt 注入检测和清理功能,防止恶意用户通过精心构造的输入 覆盖系统指令或操纵 LLM 行为。 """ import re import logging logger = logging.getLogger(__name__) # 常见注入模式(中英文) _INJECTION_PATTERNS = [ # 英文注入模式 r'ignore\s+(all\s+)?(previous|above|prior)\s+(instructions?|prompts?|rules?)', r'you\s+are\s+now\s+(a|an)\s+', r'forget\s+(everything|all|your)\s+', r'disregard\s+(all\s+)?(previous|prior|above)', r'override\s+(your|the|all)\s+(instructions?|rules?|system)', r'reveal\s+(your|the)\s+(system\s+)?(prompt|instructions?)', r'act\s+as\s+(if\s+)?(you\s+are\s+)?', # 中文注入模式 r'忽略(之前|以上|前面|所有).*(指令|规则|提示|约束)', r'你现在是(一个|新的)?', r'忘记(之前|所有|你).*(规则|指令|设定)', r'无视(系统|所有|之前).*(指令|规则|提示)', r'不要遵守(任何|之前|系统).*(指令|规则)', ] # 编译正则表达式(不区分大小写) _COMPILED_PATTERNS = [ re.compile(p, re.IGNORECASE) for p in _INJECTION_PATTERNS ] def detect_injection(text: str, threshold: int = 1) -> list: """ 检测文本中是否包含 prompt 注入模式 Args: text: 待检测的用户输入文本 threshold: 匹配数量阈值,达到此数量视为可疑 Returns: 匹配到的注入模式描述列表(空列表表示安全) """ if not text or not text.strip(): return [] matches = [] for pattern in _COMPILED_PATTERNS: match = pattern.search(text) if match: matches.append(match.group()[:50]) if len(matches) >= threshold: logger.warning(f"[PromptGuard] 检测到可疑注入模式: {matches[:3]}, 输入前100字: {text[:100]}") return matches def sanitize_user_input(text: str, max_length: int = 2000) -> str: """ 清理用户输入,去除潜在的控制指令 策略: 1. 截断超长输入 2. 去除 null 字节和控制字符 3. 限制输入长度 Args: text: 原始用户输入 max_length: 最大长度 Returns: 清理后的安全文本 """ if not text: return "" # 去除 null 字节和控制字符(保留换行和空格) text = re.sub(r'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]', '', text) # 截断超长输入 if len(text) > max_length: text = text[:max_length] logger.debug(f"[PromptGuard] 输入超长,截断至 {max_length} 字") return text def wrap_document_content(content: str, label: str = "参考资料") -> str: """ 将文档内容包装在明确的标记内,降低文档内容被当作指令执行的风险 Args: content: 文档原始内容 label: 标签名称 Returns: 包装后的内容 """ return f"[以下为{label},非系统指令]\n---\n{content}\n---\n[{label}结束]"