项目:离线合成评测数据流水线
项目目标
在 Windows 11、PowerShell 7 与 Python 3 标准库环境中,完成一条不联网、不调用模型、不使用真实数据或密钥的合成评测数据流水线:
- 严格解析并验证版本化 JSON spec,拒绝重复 key、
NaN、未知字段和布尔冒充数字; - 从“语言 × 场景”条件矩阵生成带稳定 ID、family、标签与 provenance 的候选;
- 隔离 schema/来源错误、疑似个人信息和规范化精确重复,并保留拒绝原因;
- 按 family 做 development/test 划分,验证条件覆盖与完整性;
- 用冻结质量门输出
PASS、REVIEW或BLOCK,用独立退出码区分契约错误; - 生成内容指纹、manifest、限制清单,并以 43 项测试验证关键边界。
解释边界
所有文本都是作者设计的虚构模板。
contains_real_data: false是来源声明,不是对任意外部语料的相似性证明;正则扫描和精确去重也不是匿名化。本项目没有真实留出集、生成模型、近重复模型或差分隐私机制,因此不能声称生产效用、分布代表性、无版权风险或隐私保证。
项目文件
- build_synthetic_evalset.py:严格契约、生成、过滤、去重、划分、质量门和 CLI;
- synthesis_spec.json:正常数据契约与条件矩阵;
- synthesis_spec_quality_regression.json:契约有效但条件覆盖门过严,演示
BLOCK; - synthesis_spec_contract_error.json:故意含未知字段,演示契约错误;
- test_build_synthetic_evalset.py:43 项标准库
unittest。
环境准备
项目没有第三方依赖。若需要练习隔离环境,把 venv 建在 vault 之外:
$venvDir = Join-Path $env:TEMP "ai-agent-engineer-synthetic-data-venv"
python -m venv $venvDir
& (Join-Path $venvDir "Scripts\Activate.ps1")
# 本项目无需 pip install。从同时包含 docs/ 与 .website/ 的项目根目录进入示例目录:
$projectDir = (Resolve-Path -LiteralPath 'docs\数据合成\03-项目与自测\examples').Path
Push-Location -LiteralPath $projectDir后续命令全部使用 -B,避免在知识库产生 __pycache__ 或 .pyc。
严格 spec 契约
spec 把数据工程中的隐含决定变成可审计输入:
| 区域 | 说明 | 不能替代什么 |
|---|---|---|
| dataset ID/version/schema | 标识发布与兼容边界 | 内容质量 |
| purpose/non-goals | 限定支持的用途与非目标 | 真实效用测试 |
| generator | 类型、版本、核对日期、是否接触真实数据 | 授权或匿名性证明 |
| split | seed 与 development family 数 | 随机逐行划分 |
| quality gates | 每格/总量/重复率/覆盖门 | 人工标签与真实留出 |
| teaching faults | 是否注入可追踪坏样本 | 真实故障分布 |
| conditions | 语言、场景、oracle、关键性与模板 | 生产发生频率 |
加载器拒绝重复 JSON key 和非标准 NaN/Infinity;每层字段必须精确匹配。数值 gate 不接受 true/false,因为 Python 中布尔值是整数子类,若不显式拒绝可能把 true 静默当成 1。
生成、隔离与去重
正常 spec 定义 2 种语言 × 3 个场景 × 每格 2 个模板,共 12 个有效候选。脚本额外注入:
- 一个内容完全相同但 ID 不同的候选,用于验证规范化精确去重;
- 一个缺少
expected_action的候选,用于验证契约隔离。
候选包含 candidate_id、family_id、条件、输入、oracle、critical 标记、synthetic: true 与 provenance。provenance 不只检查字段存在:其 generator type/version、真实数据声明、模板 ID 的条件前缀与变量映射必须与冻结 spec 一致,防止旧生成器或另一条件的模板伪装成当前批次。它仍是技术 trace,不是授权、版权或匿名性证明。过滤顺序是:
- 精确字段/schema 与 oracle 一致性;
- provenance 字段和真实数据声明一致性;
- 演示用邮箱/电话模式扫描;
- candidate ID 唯一性;
- 语言、场景与规范化输入的精确去重。
拒绝项进入 rejection_log,包含阶段和原因。扫描未命中只能说明这组规则未发现问题,不能推出“无个人信息”;近重复和语义复制仍需额外工具与人工审查。
Family 划分与质量门
同一语言/场景模板 family 的变体整体进入 development 或 test,防止近似改写跨集。发布后验证:ID 唯一、规范化输入唯一、family 不跨 split、两个 split 都存在、全部条件格覆盖、所有记录标记 synthetic,且 provenance 完整。
质量门按以下顺序解释:
- 条件缺失、每格数量不足、总量不足或真实来源声明未审查 →
BLOCK; - 重复比例超过软门 →
REVIEW; - 所有冻结门通过 →
PASS; - 文件、JSON 或 schema 不合法 → 契约错误,不生成数据报告。
BLOCK 表示流水线成功执行但不允许发布;契约错误表示连比较/生成前提都不成立。两者不能混成“脚本失败”。
运行正常 spec
python -B .\build_synthetic_evalset.py --spec .\synthesis_spec.json
if ($LASTEXITCODE -ne 0) { throw "PASS fixture exit code mismatch" }预期:
action=PASS,退出码0;raw=14、contract_rejected=1、duplicate_rejected=1、released=12;- 6 个条件格均保留 2 条;
- development 有 2 个 family/4 条,test 有 4 个 family/8 条;
- manifest 含
sha256:内容指纹; - stdout 是 JSON,不写任何输出文件。
运行质量回归
python -B .\build_synthetic_evalset.py `
--spec .\synthesis_spec_quality_regression.json
if ($LASTEXITCODE -ne 1) { throw "quality regression exit code mismatch" }该 spec 的结构和生成逻辑都合法,但把 min_records_per_cell 冻结为 3,而每格只有 2 条,预期 action=BLOCK、退出码 1。这证明“成功生成很多行”不等于达到发布门。
运行契约错误
python -B .\build_synthetic_evalset.py `
--spec .\synthesis_spec_contract_error.json
if ($LASTEXITCODE -ne 2) { throw "contract error exit code mismatch" }该 fixture 故意包含未知顶层字段,预期 stderr 说明字段不匹配,stdout 为空,退出码 2。
CLI 约定:
0:PASS;1:REVIEW或BLOCK;2:文件、JSON、字段、类型或取值契约错误。
三模式测试与语法检查
python -B -m unittest -v test_build_synthetic_evalset
if ($LASTEXITCODE -ne 0) { throw "normal tests failed" }
python -B -O -m unittest -v test_build_synthetic_evalset
if ($LASTEXITCODE -ne 0) { throw "optimized tests failed" }
python -B -W error -m unittest -v test_build_synthetic_evalset
if ($LASTEXITCODE -ne 0) { throw "warnings-as-errors tests failed" }
python -B -c "from pathlib import Path; [compile(p.read_text(encoding='utf-8'), str(p), 'exec') for p in map(Path, ('build_synthetic_evalset.py', 'test_build_synthetic_evalset.py'))]"
if ($LASTEXITCODE -ne 0) { throw "syntax check failed" }
Pop-Location测试覆盖重复 key、NaN、未知/缺失字段、布尔数值、非法 gate、空模板、候选/来源错误、生成器版本/模板 lineage/变量映射不一致、疑似个人信息、重复 ID、family 划分、覆盖、PASS/REVIEW/BLOCK、真实来源硬门、指纹和三类 CLI 退出码。生产代码不使用 assert,因此 -O 不会移除关键验证。
动手练习
- 把
max_duplicate_fraction调为0.01,验证结果变成REVIEW而非BLOCK; - 增加
tool-timeout条件,同时写 oracle、critical 标记和两条模板,再解释它与哪些场景组合有业务意义; - 新增一个 candidate 的邮箱样式内容,验证进入拒绝日志,并解释为何仍不能称 PII 扫描完整;
- 设计 n-gram/Embedding 候选对报告,但把最终合并交给有证据的规则或人工;
- 准备一个不参与生成或调参的授权真实小留出,设计合成数据对系统错误模式的效用实验;
- 若要使用真实日志,先画授权、最小化、保留、访问、删除和发布审批流程,再改
contains_real_data,不要为了跑通直接关闭硬门。
自测题
- 为什么
contains_real_data: false不是匿名性证明? - 为什么重复率可设软门,而缺失关键条件通常应设硬门?
- 固定 seed 能保证什么,不能保证什么?
- 为什么同一 family 的改写不能跨 development/test?
- fingerprint 变化能说明什么,不能说明什么?
- 43 项测试通过后,为什么仍不能声称数据对真实模型训练有效?
掌握检查
- 能解释 spec、候选、发布记录、拒绝日志与 manifest 的职责;
- 能区分样本契约错误、数据集质量 BLOCK 和软门 REVIEW;
- 能证明 family 划分与条件覆盖由代码实际检查;
- 能运行 43 项测试和三类 CLI 场景,并解释退出码;
- 能列出近重复、真实效用、隐私、许可与人工审核的剩余边界;
- 不会把 synthetic、哈希、扫描或无真实输入声明写成形式隐私保证。
项目边界与下一步
本项目建立的是透明、可重复的模板合成基线。接入模型生成时,沿用同一契约、provenance、拒绝日志和独立验证,并回到 模型生成与条件覆盖。正式发布前按 质量、效用与真实数据校准 使用独立真实证据,再按 隐私、记忆、偏差与版权 与 版本、评测与发布 完成风险和维护审批。
参考资料
- SELF-INSTRUCT 原始论文(获取日期:2026-07-22)
- NIST SDNist Synthetic Data Report Tool(v1.4 多维 utility/privacy 报告案例;获取日期:2026-07-22)
- NIST SP 800-226(差分隐私声明与实现风险边界;2025-03 最终版)
- Google Data Cards 官方论文页面(获取日期:2026-07-22)