用AI批量造测试数据看着省事,可一旦造出来的数据「假得不像真的」或者「真得像真的」,问题就会漏到线上:压测跑不出瓶颈、脱敏字段被反推、边界值全被抹平成正常样本。这篇不聊概念,按场景拆开讲每种造假长什么样、怎么早发现、发现后先做什么,并给出可以直接抄的检查项与排查顺序。
先分清:AI造的测试数据,哪几种算「假出问题」
很多人拿 AI 造测试数据,第一反应是看「像不像真的」——名字像、手机号像、订单号像,就收工了。但「造假」这个事,麻烦不在像不像,而在它悄悄绕过了被测系统本该走到的分支。所以先别急着看数据外观,先给它归类:到底是哪一类失真。三类最典型:分布失真、关系失真、来源失真。判断标准只有一条——这份数据能不能触发被测系统该触发的分支。
| 失真类型 | 典型表现 | 会漏掉什么分支 | 快速判断动作 |
|---|---|---|---|
| 分布失真 | 样本全挤在中间值,没有长尾和极端值 | 边界校验、阈值告警、分页与限流分支 | 统计关键字段的最小/最大/分位分布,跟真实数据比一下形状 |
| 关系失真 | 字段之间对不上,比如状态与时间矛盾、金额与明细不平 | 跨字段校验、状态机流转、对账逻辑 | 挑 3 组有业务约束的字段两两交叉抽查,看有没有互相矛盾 |
| 来源失真 | 真数据被 AI 改写后,仍能反推回具体个人 | 合规审计、脱敏校验、数据出境判断 | 用常见重识别思路回推一遍,看能不能定位到唯一的人 |
分布失真最容易糊弄人。AI 生成数值时天然偏爱「中间值」,看起来合理,实际把边界全避开了。如果你的系统有金额上限、有并发阈值、有超时告警,这些分支在中间值数据下永远不会被触发。判断方法是把关键字段的分布画出来,跟真实数据的形状对一对,重点看尾部和极值有没有。不适用的情况:纯逻辑单测本来就不依赖分布,别拿这条去卡它。
关系失真更隐蔽。单看每个字段都像真的,但字段之间的业务约束被破坏了——创建时间晚于更新时间、订单状态是已完成却没有支付记录、退款金额大于原单金额。这类数据跑接口不会报错,却会让下游的对账和状态机逻辑失去覆盖。判断标准不是字段本身像不像,而是拿业务约束去交叉验证,看数据能不能自然走完一条完整链路。
- 先标出被测系统的关键分支把这次测试要覆盖的分支列出来,比如边界值、异常态、对账不平、权限越界。没有这份清单,后面判断数据真假就没有基准。可以去站内的测试数据相关指南中心页面找现成的分支清单模板。
- 按三类失真逐项对照用上面那张表,把手上这批 AI 数据过一遍:分布有没有尾、关系有没有矛盾、来源能不能回推。哪一类中招,就说明对应分支这次没覆盖到。
- 用真实数据抽一小批做对照从真实环境抽一小批(脱敏后)作为参照,只看分布形状和字段约束,不看具体值。对照完就知道 AI 数据把哪些分支漏了。
- 把漏掉的分支补成用例针对没被触发的分支,手工构造或定向生成极端样本,不要指望通用 AI 生成器自动帮你补。
最后提醒一句:来源失真跟前面两类不是一回事,它伤的是合规不是功能。真数据被 AI 改写一遍,看着脱敏了,但重识别往往还能把人定位出来,这种数据一旦进测试库就是隐患。所以判断顺序建议是——先看来源能不能回推,再看关系对不对得上,最后看分布够不够极端。每一步该看什么、去哪核对,可以在站内的数据合规与脱敏相关页面找到更细的检查项。
场景一:全被抹平的分布,压测和边界测试直接失效
提示词里写「生成合理的用户数据」,模型会把它理解成「生成常见的用户数据」。金额集中在几十到几百、时长集中在几秒到几分钟、并发数集中在几百到几千,两头全被抹平。你拿到手看着挺像真的,实际上是几十行长得差不多的样本,分支覆盖比手写还窄。
| 字段 | AI 常见输出 | 真实系统里一定存在的 |
|---|---|---|
| 金额 | 常规正数区间 | 0、负数、超大额、小数位异常 |
| 时长 | 常见秒级区间 | 0、超时临界值、跨天超长 |
| 并发/条数 | 中等区间 | 0、1、单次超大批量 |
| 文本 | 正常长度字符串 | 空串、超长、特殊字符 |
后果不是数据不好看,而是分支测不到。极端值缺失,唯一索引不命中、超时降级、空值兜底这些逻辑等于从没被跑过。测试环境一路绿灯,上线后第一次真实尖峰才把问题翻出来,这类问题排查起来还特别费劲,因为日志里第一次出现的报错往往就是唯一的线索。
- 先看长尾占比把生成结果按关键字段排序,看最小值、最大值附近有没有样本。如果最小值和最大值都贴着中位数,基本可以判定长尾被抹平。
- 再跑分位数对照拿真实基线或业务上认可的经验分布做分位数对照,看生成数据在各分位上的占比是否和基线接近。差距大的那几个分位,就是需要补造的位置。
- 最后补造长尾样本把零值、极值、超长、临界并发这类样本单独造一批,别混在常规数据里。补完之后再看一遍分支覆盖,确认真实存在的边界都有对应用例。
- 判断依据看的是分布形状,不是样本条数,条数多不等于覆盖全
- 对照基线优先用线上抽样或业务经验,不要用 AI 自己生成的另一批数据
- 长尾样本建议单独标记,方便回归时单独跑
- 什么情况下不适用:纯展示用的假数据、不进任何分支逻辑的场景,没必要纠结长尾
场景二:字段之间对不上,脏数据反而「看起来很干净」
这一类假数据最迷惑人的地方在于:格式全对,字段不缺,类型也匹配,校验脚本跑完一片绿。但只要把几个字段放在一起看,业务上根本说不通。生成模型很容易同时造出「注册时间」和「下单时间」,却不会主动保证后者晚于前者,因为那属于业务约束,不是语法约束。
- 时间顺序穿帮:下单时间早于注册时间,或收货时间早于发货时间
- 金额关系穿帮:退款额大于订单额,优惠后金额反超原价
- 标识归属穿帮:地区编码与手机号号段对不上,或身份证地址与所在城市矛盾
- 状态跳变穿帮:订单从「待付款」直接跳到「已签收」,跳过中间必经状态
- 关联穿帮:订单里引用的商品在下单时还没上架
为什么这类数据能骗过校验脚本?因为脚本通常只检查单字段格式,比如手机号是不是 11 位、时间是不是合法字符串。它不检查字段之间的不等式和引用关系。所以这种脏数据看起来「很干净」,实际上只要业务规则一上,立刻原形毕露。反过来这也说明:它特别适合拿来做数据质量规则的反向测试——你写的每一条断言,都应该能拦住某一类假数据。
| 破绽类型 | 典型表现 | 该补的断言方向 |
|---|---|---|
| 时间序 | 后发生的事件时间早于前序事件 | 前后字段之间的大小关系 |
| 金额 | 退款、折扣、总额之间不闭合 | 加减关系与上下限 |
| 归属 | 编码、号段、地区三者对不上 | 字段映射与枚举表 |
| 状态流转 | 跳过必经状态或出现非法跃迁 | 状态机白名单 |
| 外键引用 | 引用了当时还不存在的对象 | 带时间条件的关联存在性 |
- 把硬约束写成断言从业务流程里逐条抽出「必须成立」的关系,而不是「一般成立」的经验,写成可自动执行的断言集合,一条断言对应一种破绽。
- 每批数据全量过一遍生成一批就跑一遍断言,不要抽样。抽检会漏掉成片的系统性穿帮,而这类假数据往往是批量错同一处。
- 过不了就整批丢弃断言失败的批次直接废弃重新生成,不要手工去改某几条。手工修补会引入人为痕迹,也让造假规模不可控。
- 记录断言命中分布统计哪条断言最常被触发,反过来能看出生成侧最容易漏哪类约束,用来调整你的提示或规则模板。
格式正确的假数据只是通过了语法考试,字段之间的不等式才是业务逻辑的入场券。
场景三:脱敏后还能反推回真人,这是最容易出事的一类
这一类事故最冤:字段看过去都处理过了,名字换成谐音、地址只留到区、证件号中间几位打星,审的时候一列一列看全都「不敏感」。可这几列一旦拼在一条记录里,往往就只剩下一个人。测试数据泄露以后,别人不需要知道你真名,也能顺着这几列把人对上号。
为什么单列没事、拼起来就出事
原理不复杂:姓名、出生年份、地区、职业、入职时间这类字段,单个拎出来覆盖的是成千上万人,但叠到四五列,交集就迅速收敛到个位数甚至一个。这类字段在业内叫准标识符,它们不直接标识身份,却能组合出身份。所以脱敏要看的不是「每列敏不敏感」,而是「这些列放在一起还剩多少人」。哪种情况不适用?如果你的测试数据本来就是凭空生成的、跟真实人群没有任何映射关系,那组合风险自然低,重点就转向别把真实数据混进来。
| 字段类型 | 单独看的观感 | 叠加后的风险 |
|---|---|---|
| 姓名或谐音化姓名 | 常见字,像假的 | 跟地区、年龄一起可大幅收窄 |
| 精确到区县的住址 | 只到区,看着粗 | 配合职业与楼栋信息可锁定 |
| 出生年月日 | 谁都有的字段 | 拼上地区即接近唯一 |
| 证件号打码中段 | 中间星号,像处理过 | 尾号加出生段常可反推完整号 |
| 入职或注册时间 | 业务字段,不像隐私 | 分钟级精度本身接近唯一 |
生成前就该定的抹除清单
- 先列全部字段把要在测试环境用到的每一列写出来,包括你觉得无关的业务字段,比如订单号、设备号、注册时间。
- 逐列打标标成三类:直接标识(必须换掉)、准标识符(要降粒度或做泛化)、普通字段(可保留)。拿不准的先归到准标识符。
- 定组合上限明确规定一条记录里同时保留几个准标识符,以及哪些组合绝对不允许同时出现,写进生成模板而不是靠人记。
- 交给生成环节把清单作为生成任务的输入约束,而不是生成完再靠人工回头看,后者漏的概率很高。
抹除的范围可以到站内 指南中心(/guides/) 看现成的字段分类表,但清单一定要按你自己的业务字段改一遍,直接套用模板很容易漏掉本地特有的字段。
生成完的复核动作
- 按组合而不是按列自查:随机抽若干条记录,把准标识符拼起来,看能不能在原始数据里只命中一条
- 做一次小样本碰撞测试:对同一组字段组合统计重复度,重复率异常低就说明粒度太细
- 检查派生痕迹:谐音姓名、尾号、时间戳这些处理方式本身会留下可逆规律
- 确认测试环境与生产环境之间没有残留映射表或对照文件
- 把复核结果和字段清单一起存档,下次生成直接复用
如果复核时拿不准某个组合到底算不算敏感,不要纠结论证,直接把粒度整体上抬一档:日期从日改成月、地区从区改成市、职业从具体岗位改成大类。粗粒度会让测试场景损失一点真实感,但换来的是不会因为一条测试数据把人认出来。测试数据的价值在于让流程跑通,不在于复刻真实分布。
想要现成的字段分级和复核模板,可以去 工具目录(/tools/) 找对应的检查项,再对照 指南中心(/guides/) 里讲组合标识的那一节把清单补全;落到具体项目上,判断标准始终是那一条——这条记录能不能指向一个真人。
场景四:AI给的标签看起来合理,实际把评估集带偏
这一类问题最阴的地方在于:AI 标的标签单看每一条都说得通,但合在一起就带着它自己的判断口味。你拿这批「标准答案」去评估分类或审核模型,等于让考生的同桌来判卷,线下指标自然好看,一上线上抽样就露馅。
识别特征有三个,凑齐两个以上基本可以定性。一是线下指标异常漂亮,但换一批真实流量抽样,人工看一眼就觉得错得离谱;二是换个人、换个时间重跑同一批评估,结论对不上,差异主要来自标注不一致;三是某些类别的标签高度同质化,同义词、边界样本被整齐地归到一边。
| 观察到的现象 | 大概率原因 | 下一步动作 |
|---|---|---|
| 线下指标好、线上抽样差 | AI 标注带着模型偏好,评估集被污染 | 先冻结结论,回查评估集标签来源 |
| 同一批数据两人复现不一致 | 标签边界模糊,AI 预标注未统一口径 | 补标注规范,按类别抽检复核 |
| 某类别几乎无争议样本 | 该类别被 AI 抄了近道,缺少难例 | 该类整批重做,不补个别样本 |
| 指标随标注批次波动 | 预标注模型换过或提示词变过 | 锁定标注来源版本,重新抽检 |
这里有个容易被忽略的前提:AI 预标注不是不能用,而是不能直接当结论用。只要评估集里有相当比例的标签来自模型自己,评估就失去了「独立裁判」的意义。什么情况下影响小?如果这批标签只用于初筛、最终结论由独立人工从头标注,那问题不大;反过来,只要下游拿它算指标、做上线决策,就必须按污染数据处理。
- 先给评估集做来源标记把每条样本的标签来源标成人工、AI 预标注、混合三类,统计各自占比。占比不用追求精确,能看出量级即可,重点看关键类别是不是 AI 占大头。
- 按类别抽样人工复核不要全量重标,按类别分层抽样,边界类别和争议类别多抽。抽样比例和具体的复核结果分布,可以到站内评测方法页面参考当时的操作口径,别照搬别人的比例。
- 算不一致率,设整批重做线按类别算 AI 标签与人工复核的不一致率。超过你能接受的线,该类整批退回重做;低于线,只补抽中的差异样本。这条线要在动手前定好,事后定容易自我说服。
- 复核完锁定标注版本重做后记录标注人、时间范围、规范版本。下次指标波动时,先比标注版本,别一上来就调模型。
- AI 预标注只能当草稿,任何进入指标计算的标签都要经过人工复核,复核比例按类别风险定
- 不一致率高的类别整批重做,别只改抽到的那几条,抽不到的往往错得更一致
- 评估集和训练集要分开看:评估集混入模型偏好,等于自己给自己出题
- 别用同一个模型既做预标注又做最终评估,裁判和选手要分开
- 留一份随机抽检的「干净子集」,用来给线下指标做交叉验证
场景五:图省事直接把生产数据喂给模型改写
这是最容易被低估的一种翻车方式。很多人觉得「我只是让模型把真数据改个名字、换几个字段」,好像没让模型做坏事。但你把整张表贴进对话框的那一刻,数据边界就已经打开了一次——数据从你的内网跑到了外部服务,剩下的风险不再只体现在最后那份结果文件上。
- 数据边界打开
- 指真实数据离开你可控的环境,进入第三方模型服务的会话上下文,哪怕只是短暂停留
- 先脱敏再进模型
- 在数据进入对话窗口之前就完成替换或泛化,而不是指望模型帮你抹掉敏感字段
- 结果文件之外的风险
- 包括会话留存、日志、被用于后续训练的可能,以及同账号其他人可见的范围
关键顺序不能反。正确姿势是先脱敏、再进模型;一旦是先贴进去、再让模型脱下敏,你就没法验证它到底脱干净没有——模型可能漏改、改写过度、或在解释里复述原值。更麻烦的是,你无法确认中间那一版有没有被留档。所以这条链路上任何「事后补救」都只是心理安慰。
- 先做字段分级把表里的列分成三类:直接标识(姓名、手机号、身份证、订单号)、准标识(地区、生日、邮编)、业务敏感(金额、合同条款)。直接标识一律不出内网。
- 在本地做替换用脚本把直接标识列替换成规则化的假值,保留格式与长度,确保下游关联逻辑还能跑通。替换规则本身也别贴进对话。
- 只把脱敏后的样本贴给模型一次也别贴全量。先给几十行让模型理解结构,确认它按你的要求改写,再决定是否扩充。
- 留一份脱敏前后对照对照表放在本地受控环境,用来回溯哪一列改过、规则是什么,避免下次重复劳动。
- 按站内口径复核把这条链路对着站内安全说明一步步走一遍,确认每一步都没把真数据带出去。
| 做法 | 看起来省事在哪 | 实际风险 |
|---|---|---|
| 整表贴进对话,让模型顺手改名 | 少写一个脱敏脚本 | 真数据进入会话上下文,脱敏结果无法验证 |
| 先本地替换再进模型 | 多花半小时写脚本 | 出网的是假值,模型改坏也只影响假数据 |
| 让模型先脱敏再二次改写 | 对话轮次少 | 模型漏改肉眼难查,且初版已出网 |
| 只贴结构不贴内容 | 模型理解可能慢一点 | 不暴露任何真实取值,最可控 |
- 硬规则:进入模型的数据,必须已经是脱敏后的数据,没有例外。
- 脱敏脚本和替换规则放在本地,不要为了省事把规则也发给模型。
- 如果某列既不能脱敏又必须用,就换合成数据,不要赌模型「不会记住」。
- 复盘时不要只看结果文件对不对,要看数据进出的每一步。
- 拿不准某一列算不算敏感,就按敏感处理。
真出事了按这个顺序排查,别一上来就重造数据
数据被质疑造假之后,最贵的错不是数据本身,而是排查顺序错了。很多人第一反应是赶紧重造一批替换掉,结果新数据一上线,旧数据的流向记录也被覆盖了,再想问「这批到底进过哪些下游」就没人答得上来。所以先定范围、再定性质、最后才动手处置,这个顺序反过来基本等于白干。
- 第一步:定范围把这批数据的生命周期拉一条线:从哪来的、进过哪些环境(本地、测试、预发、演示、生产影子库)、被哪些下游系统或人用过、有没有落盘归档或导出成文件。逐个系统问负责人要使用记录,别只查一个主库就收工。验证方式:能画出一张「环境 × 下游 × 是否落盘」的清单,缺哪格就去补哪格的证据。
- 第二步:定性质按影响面把问题分成三类:分布问题(数值范围、比例明显不合理,但对具体个体没有指向性)、关系问题(表之间对不上、外键悬空、业务链路走不通)、重识别问题(数据能反查到真实个人、真实订单或真实凭证)。判断依据是数据本身能不能指向一个真实对象,而不是数据好不好看。三类问题的处置路径完全不同,混着做就会漏掉最严重的那类。
- 第三步:再处置分布问题通常重造一批就能收口;关系问题要连带修数据生成逻辑和校验规则,否则下一批还会犯;重识别问题不能只靠重造解决,要走数据影响评估,确认已扩散的范围,再按公司流程向上层通报并配合清理。验证方式:处置完回头对一遍第一步的范围清单,逐个确认受影响方已经拿到结论。
| 问题性质 | 典型表现 | 建议处置 | 不建议的做法 |
|---|---|---|---|
| 分布问题 | 数值区间、占比明显不合理,但无个体指向 | 重造数据并补一条生成规则约束 | 直接判定为严重事故,兴师动众 |
| 关系问题 | 表间对不上、外键悬空、链路跑不通 | 同时修生成逻辑与校验环节 | 只换数据不换逻辑,下批复发 |
| 重识别问题 | 能反查到真实个人、订单或凭证 | 走影响评估、定扩散范围、按流程上报 | 内部悄悄重造了事,不留记录 |
- 先重造再定范围:旧数据流向记录可能被覆盖,下游到底谁受了影响说不清
- 只查主库不看导出文件:很多扩散发生在人工导出的表格和演示材料里
- 把三类问题混成一句「数据有问题」:处置粒度对不上,轻的过度反应、重的被漏掉
- 定范围时只问技术不问业务:业务侧自己导过一份的情况很常见
- 处置完没有回头核对范围清单:受影响方以为没事了,其实没收到结论
如果第一步的范围清单拉不全,别急着进第二步。可以先把已知环境跑完,把「尚未确认」的格子明确标出来,作为待办而不是当成没问题。判断标准、分类口径和站内整理过的排查清单,可以到 指南中心(/guides) 对照着看,具体数字和当时的口径以页面上显示的为准。
下次再造数据前,先把这几件事固定下来
造假这事很少是流程里有人故意使坏,多数是「没人说清楚什么叫造对了」。所以先把验收依据写在生成之前,事后再吵就有对错可分。这份依据不用长,一页纸就够,但必须落成文件,不能只停在聊天记录里。
- 写分支清单把这份数据要覆盖的业务分支逐条列出来,比如正常流程、边界取值、非法输入、并发冲突、空值与超长字段。每条后面跟一句「怎么判断这条分支真的被覆盖了」,例如某个状态字段必须出现全部取值组合。写完拿给用这份数据的测试同学过一眼,他认不出哪条分支,就说明写得太抽象。
- 写禁用字段清单把绝对不能出现在测试库里的东西列清楚:真实手机号、身份证、银行卡、内部工单号、真实姓名与邮箱、生产环境的用户主键。同时写上「允许用什么形态替代」,比如统一用固定前缀加序号。清单里出现过一次真实字段名,生成脚本就要硬失败,而不是打日志放过。
- 生成后过三道闸分布对照看关键维度占比是否和预期清单一致,明显偏斜就回炉;约束断言用脚本检查字段格式、枚举取值、外键能不能对上;重识别自查是拿几条记录反查,看能不能顺藤摸瓜还原出真实主体。三道闸任意一道不通过,整批数据不入库,改完重跑,别只挑坏的那几行打补丁。
- 留痕到能复现记录这批数据是哪天、用哪个模型、什么提示词模板、哪一版脱敏规则跑出来的,脚本版本和随机种子也一起存。目的很实在:出问题时能重跑一遍定位,而不是对着结果猜。提示词改了要新开一版记录,不要覆盖旧的。
| 环节 | 要固定下来的东西 | 判定标准 |
|---|---|---|
| 生成前 | 分支清单、禁用字段清单 | 用数据的同学能指着清单说清楚每一条对应哪个用例 |
| 生成后 | 分布对照、约束断言、重识别自查 | 三道闸全过才入库,任一道不过整批退回 |
| 全程 | 模型标识、提示词版本、脱敏规则版本、随机种子 | 换个人按记录能跑出同量级的结果 |
- 清单要作为验收依据提前定稿,生成完再补写清单等于没有标准;
- 三道闸里分布对照最容易被跳过,但它恰好能拦住「字段全对、比例全错」这种隐蔽造假;
- 重识别自查不必全量跑,抽几条做反查就够,重点看能不能拼出真实主体;
- 留痕记录只增不改,提示词或脱敏规则一变就新开一版,否则复现时根本对不上;
- 小团队人手少,可以把清单和留痕合并成一份文件,但分支清单和禁用字段这两块不能省。
常见问题
AI生成的测试数据能不能直接用,还是必须人工过一遍?
看用途。只验证接口通不通、字段能不能解析,通常可以直接用;只要涉及业务规则校验、性能压测、模型评估或对外演示,就必须过人工或自动化闸门。判断标准很简单:这份数据如果错了,会不会让人得出错误结论。会,就不能免检。
怎么快速判断一批AI生成的数据分布是不是失真了?
别只看均值和最大值,看分位数。把生成数据和真实基线的几个关键分位点摆在一起对照,长尾段占比明显偏低基本就是失真了。没有真实基线时,至少检查极值、零值、空值这三类样本是否存在,一个都没有就说明提示词把数据写得太「正常」了。
AI改写过的数据还算不算敏感数据?
取决于能不能被重新识别到个人,而不是取决于改了几个字。同音字替换、删门牌号、打码中间几位,这些手段单独用都挡不住组合推断。稳妥做法是把脱敏当成一个字段组合问题来处理,改完之后做一次重识别自查,拿不准就整体上抬粒度。
造测试数据和用小流量真实数据,哪个风险更小?
两者风险类型不一样。造数据的主要风险是失真,容易让测试结论偏乐观;真实数据的主要风险是合规,稍不注意就把个人信息带进了非生产环境。常见做法是拿真实数据的结构特征去指导生成,但样本本身不进环境,这样两边都避开。
发现造假数据已经流到下游了,最先做什么?
先定范围,别先重造。把数据经过的环境、被谁读过、有没有归档这三件事列清楚,再判断属于分布失真、关系失真还是重识别这三类中的哪一类。重识别类的要立刻走影响评估和通报,分布类的重造并回灌即可,顺序做反了容易漏掉受影响的下游。