"""客服会话落库前的敏感凭据最小化处理。 来源:同事 `ZSY_develop` 分支(`app/core/conversation_privacy.py`),整文件移植,未改语义。 纯正则、无外部依赖,供记忆投影(`MilvusProfileProjection`)在写入向量前做最后一道脱敏。 为什么要单独抽一层:记忆内容最终会进入 Milvus 与 Neo4j,一旦写入就脱离了会话事务的 管控范围。把脱敏放在**写入适配器内部**(而不是依赖调用方记得做),是为了让"未经脱敏的 文本不得落外部存储"成为代码保证,而不是流程约定。 """ import re # 替换顺序从带业务语义的凭据开始,避免通用数字规则先破坏上下文。 _SENSITIVE_PATTERNS: tuple[tuple[re.Pattern[str], str], ...] = ( ( re.compile(r"(?i)((?:登录|交易)?密码)\s*(?:[::=]|是)\s*[^\s,。;,;]{1,64}"), r"\1[已隐藏]", ), (re.compile(r"(?i)((?:登录|交易)?密码)\s*\d{4,32}"), r"\1[已隐藏]"), (re.compile(r"(?i)(验证码|短信码|校验码)\s*(?:[::=]|是)?\s*\d{4,8}"), r"\1[已隐藏]"), (re.compile(r"(? str: """保留风险关键词,移除不应进入会话、Outbox 或后续 Redis 的凭据值。""" sanitized = message for pattern, replacement in _SENSITIVE_PATTERNS: sanitized = pattern.sub(replacement, sanitized) return sanitized