AI 数据分类分级自动识别敏感字段不只是正则匹配公司要做数据安全合规老板让给所有表里的字段分级。传统做法是写几百条正则规则但还是有名字叫remark的字段里存了身份证号漏网了。AI 加持下的分类分级真的能从语义层面理解这片数据是什么。一、正则匹配的边界它只认识格式不认识含义先看传统做法的标准操作。给字段名和字段值各配一套正则规则import re # 典型的正则规则集长得像身份证的就认为是身份证 SENSITIVE_RULES [ (r身份证号|身份证|id_card|idcard, C3), # 字段名匹配 (r\b\d{6}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]\b, C3), # 值匹配 (r手机号|手机|phone|mobile, C2), (r\b1[3-9]\d{9}\b, C2), (r银行卡|银行账号|bank_card|bankcard, C3), ]这套规则的问题非常典型它识别的是格式像敏感数据的数据而不是语义上是敏感数据的数据。反过来真正该拦截的反倒漏了漏报场景原因字段名叫remark但内容里存了身份证号字段名不匹配任何规则字段名叫user_ident非标准缩写正则覆盖不到所有变体字段值是320106 19900101 1234空格分隔格式稍有偏差就匹配不上字段值已经脱敏但被误判为真实数据正则只看格式不了解上下文正则更像一个格式嗅探器它能准确抓到标准身份证号但对变体、缩写、上下文依赖重的场景就力不从心了。二、AI 分类分级的双层判断架构AI 做数据分类分级不是简单地把正则规则替换成模型调用。真正有效的做法是正则当哨兵AI 当审判官。graph TD A[输入: 表名 字段名 字段值样本] -- B{正则规则集: 快速初筛} B --|命中已知规则| C[高置信度: 直接分级] B --|未命中| D[AI 语义推断: 字段名样本值联合判断] B --|规则冲突/异常| D D -- E[模型返回: 敏感类型 置信度] E -- F{置信度 ≥ 0.8?} F --|是| G[自动打标] F --|否| H[推人工审核队列] C -- G style D fill:#f9f,stroke:#333,stroke-width:2px style H fill:#ff9,stroke:#333第一层正则处理告警的格式匹配快速放行常见模式手机号、身份证、银行卡等标准格式这部分效率高、误报低。第二层 AI处理正则搞不定的语义盲区。用字段名 字段值样本拼接成一个自然语言推理NLI任务扔给模型。from openai import OpenAI client OpenAI() def classify_field_with_ai(table_name: str, field_name: str, sample_values: list[str]) - dict: 用 AI 做字段级别的敏感分类 设计意图不给模型看全量数据只传字段名脱敏后的样本值。 样本值取前 5 条并做脱敏处理保留前2后2字符 既给模型足够的语义信息又避免泄露真实敏感数据。 # 样本值脱敏保留少量特征供 AI 判断类型 masked_samples [] for v in sample_values[:5]: v_str str(v) if len(v_str) 4: masked_samples.append(v_str[:2] *** v_str[-2:]) else: masked_samples.append(***) prompt f 请判断以下数据库字段是否包含敏感信息 表名: {table_name} 字段名: {field_name} 字段值样本: {masked_samples} 返回 JSON 格式 {{ is_sensitive: true/false, sensitive_type: 身份证/手机号/银行卡/姓名/地址/邮箱/无, confidence: 0.0-1.0, reason: 判断依据 }} response client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: prompt}], response_format{type: json_object} ) return eval(response.choices[0].message.content)这个 Prompt 设计有三层精妙之处一是传脱敏样本而非原始数据保护隐私二是同时输入字段名和字段值模型能从在user_profile表里、名为remark、值是510***01综合判断这是身份证号三是要求返回置信度低置信度自动转入工审核不用所有兜底规则都写死在代码里。三、AI 分类的三个优势场景场景一非标准字段名。正则规则写id_card能匹配但userIdentifier、CustID、uin就全漏了。AI 模型知道uin是腾讯体系的用户标识能根据值的格式18位数字推断出是身份证号。场景二关系型敏感数据。一张表里provincecitystreethouse_number四个字段分开看哪个都不算敏感但组合在一起就是家庭住址。正则规则没法做这种跨字段关联判断AI 能def assess_field_group(table_name: str, fields: list[dict]) - list[dict]: 用 AI 评估一组字段的组合敏感性 设计意图单字段不敏感但组合后敏感的典型场景是地址信息。 模型需要同时看到多个字段名才能做出正确的关联判断。 fields_desc \n.join( f- {f[name]}: 样本{f[samples][:3]} for f in fields ) prompt f表 {table_name} 包含以下字段请判断是否存在组合敏感风险 {fields_desc} 考虑以下风险类型 - 字段组合是否构成完整地址 - 是否包含姓名身份证或姓名手机号的关联 - 是否有多个半标识符组合可重识别个人身份 # 调用 LLM 返回评估结果...场景三跨系统一致性。公司有 3000 张表、5 万个字段不同团队可能对敏感的定义不同。AI 做分类可以保持一致的判断标准不会出现 DBA 团队觉得这个字段不敏感、安全团队觉得敏感的矛盾。四、工程落地的三道防线防线一AI 不过原始数据。绝对不能把真实数据扔给外部 API。上面代码里已经做了脱敏处理更严格的方案是只传字段名统计特征长度分布、字符集分布、唯一值数量完全绕过原始值def compute_field_profile(values: list) - dict: 计算字段的统计画像不包含任何原始值 lengths [len(str(v)) for v in values] return { min_len: min(lengths), max_len: max(lengths), avg_len: sum(lengths) / len(lengths), unique_ratio: len(set(values)) / len(values), contains_chinese: any(\u4e00 c \u9fff for v in values[:100] for c in str(v)), digit_ratio: sum(1 for v in values[:100] for c in str(v) if c.isdigit()) / max(1, sum(len(str(v)) for v in values[:100])), }防线二置信度分层处理。不是每个字段都需要推到人审。将模型输出按置信度分级置信度策略≥ 0.95自动打标0.8 ~ 0.95自动打标 审计日志0.5 ~ 0.8推人工审核队列 0.5标记未分类防线三增量更新而非全量重跑。用元数据变更事件驱动只在表结构变更时重新评估而不是每天凌晨全量扫一遍。五、总结AI 数据分类分级不是要干掉正则而是补正则的盲区。正则负责格式匹配的高效层AI 负责语义理解的推断层 —- 两层协作才是务实方案。落地时记住三点AI 不过原始数据脱敏或只传特征置信度做分层处理而非全自动字段组合敏感性检查和单字段检查一样重要。最后一条很多人忽略但地址信息的泄露往往就出在组合字段上。
AI 数据分类分级:自动识别敏感字段,不只是正则匹配
AI 数据分类分级自动识别敏感字段不只是正则匹配公司要做数据安全合规老板让给所有表里的字段分级。传统做法是写几百条正则规则但还是有名字叫remark的字段里存了身份证号漏网了。AI 加持下的分类分级真的能从语义层面理解这片数据是什么。一、正则匹配的边界它只认识格式不认识含义先看传统做法的标准操作。给字段名和字段值各配一套正则规则import re # 典型的正则规则集长得像身份证的就认为是身份证 SENSITIVE_RULES [ (r身份证号|身份证|id_card|idcard, C3), # 字段名匹配 (r\b\d{6}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]\b, C3), # 值匹配 (r手机号|手机|phone|mobile, C2), (r\b1[3-9]\d{9}\b, C2), (r银行卡|银行账号|bank_card|bankcard, C3), ]这套规则的问题非常典型它识别的是格式像敏感数据的数据而不是语义上是敏感数据的数据。反过来真正该拦截的反倒漏了漏报场景原因字段名叫remark但内容里存了身份证号字段名不匹配任何规则字段名叫user_ident非标准缩写正则覆盖不到所有变体字段值是320106 19900101 1234空格分隔格式稍有偏差就匹配不上字段值已经脱敏但被误判为真实数据正则只看格式不了解上下文正则更像一个格式嗅探器它能准确抓到标准身份证号但对变体、缩写、上下文依赖重的场景就力不从心了。二、AI 分类分级的双层判断架构AI 做数据分类分级不是简单地把正则规则替换成模型调用。真正有效的做法是正则当哨兵AI 当审判官。graph TD A[输入: 表名 字段名 字段值样本] -- B{正则规则集: 快速初筛} B --|命中已知规则| C[高置信度: 直接分级] B --|未命中| D[AI 语义推断: 字段名样本值联合判断] B --|规则冲突/异常| D D -- E[模型返回: 敏感类型 置信度] E -- F{置信度 ≥ 0.8?} F --|是| G[自动打标] F --|否| H[推人工审核队列] C -- G style D fill:#f9f,stroke:#333,stroke-width:2px style H fill:#ff9,stroke:#333第一层正则处理告警的格式匹配快速放行常见模式手机号、身份证、银行卡等标准格式这部分效率高、误报低。第二层 AI处理正则搞不定的语义盲区。用字段名 字段值样本拼接成一个自然语言推理NLI任务扔给模型。from openai import OpenAI client OpenAI() def classify_field_with_ai(table_name: str, field_name: str, sample_values: list[str]) - dict: 用 AI 做字段级别的敏感分类 设计意图不给模型看全量数据只传字段名脱敏后的样本值。 样本值取前 5 条并做脱敏处理保留前2后2字符 既给模型足够的语义信息又避免泄露真实敏感数据。 # 样本值脱敏保留少量特征供 AI 判断类型 masked_samples [] for v in sample_values[:5]: v_str str(v) if len(v_str) 4: masked_samples.append(v_str[:2] *** v_str[-2:]) else: masked_samples.append(***) prompt f 请判断以下数据库字段是否包含敏感信息 表名: {table_name} 字段名: {field_name} 字段值样本: {masked_samples} 返回 JSON 格式 {{ is_sensitive: true/false, sensitive_type: 身份证/手机号/银行卡/姓名/地址/邮箱/无, confidence: 0.0-1.0, reason: 判断依据 }} response client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: prompt}], response_format{type: json_object} ) return eval(response.choices[0].message.content)这个 Prompt 设计有三层精妙之处一是传脱敏样本而非原始数据保护隐私二是同时输入字段名和字段值模型能从在user_profile表里、名为remark、值是510***01综合判断这是身份证号三是要求返回置信度低置信度自动转入工审核不用所有兜底规则都写死在代码里。三、AI 分类的三个优势场景场景一非标准字段名。正则规则写id_card能匹配但userIdentifier、CustID、uin就全漏了。AI 模型知道uin是腾讯体系的用户标识能根据值的格式18位数字推断出是身份证号。场景二关系型敏感数据。一张表里provincecitystreethouse_number四个字段分开看哪个都不算敏感但组合在一起就是家庭住址。正则规则没法做这种跨字段关联判断AI 能def assess_field_group(table_name: str, fields: list[dict]) - list[dict]: 用 AI 评估一组字段的组合敏感性 设计意图单字段不敏感但组合后敏感的典型场景是地址信息。 模型需要同时看到多个字段名才能做出正确的关联判断。 fields_desc \n.join( f- {f[name]}: 样本{f[samples][:3]} for f in fields ) prompt f表 {table_name} 包含以下字段请判断是否存在组合敏感风险 {fields_desc} 考虑以下风险类型 - 字段组合是否构成完整地址 - 是否包含姓名身份证或姓名手机号的关联 - 是否有多个半标识符组合可重识别个人身份 # 调用 LLM 返回评估结果...场景三跨系统一致性。公司有 3000 张表、5 万个字段不同团队可能对敏感的定义不同。AI 做分类可以保持一致的判断标准不会出现 DBA 团队觉得这个字段不敏感、安全团队觉得敏感的矛盾。四、工程落地的三道防线防线一AI 不过原始数据。绝对不能把真实数据扔给外部 API。上面代码里已经做了脱敏处理更严格的方案是只传字段名统计特征长度分布、字符集分布、唯一值数量完全绕过原始值def compute_field_profile(values: list) - dict: 计算字段的统计画像不包含任何原始值 lengths [len(str(v)) for v in values] return { min_len: min(lengths), max_len: max(lengths), avg_len: sum(lengths) / len(lengths), unique_ratio: len(set(values)) / len(values), contains_chinese: any(\u4e00 c \u9fff for v in values[:100] for c in str(v)), digit_ratio: sum(1 for v in values[:100] for c in str(v) if c.isdigit()) / max(1, sum(len(str(v)) for v in values[:100])), }防线二置信度分层处理。不是每个字段都需要推到人审。将模型输出按置信度分级置信度策略≥ 0.95自动打标0.8 ~ 0.95自动打标 审计日志0.5 ~ 0.8推人工审核队列 0.5标记未分类防线三增量更新而非全量重跑。用元数据变更事件驱动只在表结构变更时重新评估而不是每天凌晨全量扫一遍。五、总结AI 数据分类分级不是要干掉正则而是补正则的盲区。正则负责格式匹配的高效层AI 负责语义理解的推断层 —- 两层协作才是务实方案。落地时记住三点AI 不过原始数据脱敏或只传特征置信度做分层处理而非全自动字段组合敏感性检查和单字段检查一样重要。最后一条很多人忽略但地址信息的泄露往往就出在组合字段上。