返回 S01~S90 教材库
S02 · 总 Day 092教材已备 ≠ 学习已完成

S02:JSONL 数据管线、Schema 验证与可重复变换

Schema 验证是在数据进入下一状态前,用显式契约检查其结构与语义前提;可重复变换则保证同一输入版本和同一规则产生可解释的一致输出。

2026-11-24JSONL、datacontract、validation、deterministictransform

内容类型:预习教材(不代表已完成)
日期:2026-11-24
阶段:P2 · AI Systems Engineering 90
总路线:Day 092 / 360
周次 / 节奏:W1 · 周二最小实现
状态:教材已备;学习未完成
主题:JSONL、data contract、validation、deterministic transform

一句话定义

Schema 验证是在数据进入下一状态前,用显式契约检查其结构与语义前提;可重复变换则保证同一输入版本和同一规则产生可解释的一致输出。

学习目标

  1. 能用 Node/TS 流式读取少量 JSONL,并区分解析失败、结构失败和业务规则失败。
  2. 能为一个合成事件定义最小契约,包括必填字段、类型、允许值和版本。
  3. 能设计 accepted / quarantined 两条路径,而不是静默丢弃坏记录。
  4. 能解释幂等、确定性与输入顺序对重跑结果的影响。

核心知识

JSONL 每行一个 JSON 对象,适合小型事件流和增量处理,但“能 parse”不代表“符合契约”。验证通常至少包含四层:语法层检查 JSON;结构层检查字段与类型;语义层检查金额、时间、枚举等约束;跨记录层检查重复、引用和时序。初学实现只需前 3 层并记录第 4 层需求。

契约不只是 TypeScript interface。静态类型只约束编译期代码,外部文件在运行时仍是不可信输入。契约应明确 schema version、兼容策略和失败处理。对金额等字段,不要用宽松的 truthy 判断;0 可能合法,空字符串、NaN 和负数则需按业务语义分别决定。

一个学习级转换可以把输入事件标准化为统一字段,增加 validation_statustransform_version。错误记录进入 quarantine,并保留原始行号、错误码和最少必要的原文;在真实系统中还要考虑敏感字段脱敏,本日不处理真实数据。

机制与推导

把验证器看成状态函数:

[ V(e,c_v)\rightarrow {accepted(e'), quarantined(e,errors)} ]

c_v 是契约版本。确定性要求在输入字节、契约和变换配置固定时,输出集合及错误分类固定。若转换依赖当前时间、随机数或外部 API,就需显式注入并记录这些依赖,否则同一数据重跑可能不同。

幂等意味着重复处理同一事件不会产生额外业务效果。可用稳定 event_id 与输出键实现近似:key = hash(source_id, event_id, transform_version)。这并不自动带来 exactly-once;文件重复写入、写到一半崩溃、下游重复消费仍需另外处理。

最小练习或观察步骤

  1. 准备 6~10 行合成 JSONL,包含合法、缺字段、错类型、未知版本与一行非法 JSON。
  2. 写一个逐行读取脚本,先捕获 parse error,再调用显式 validateEvent
  3. 输出两个小文件或两个内存数组:accepted 与 quarantined;每条错误有稳定 error code。
  4. 对 accepted 记录增加 transform version,但不覆盖 raw payload。
  5. 连续运行两次,比较记录数、排序与 hash;只记录观察,不宣称生产级幂等。
  6. 改一个契约规则,说明哪些旧记录会改变分类,以及为何必须版本化。

常见误区与边界

  • as Event 强制类型转换,误以为运行时已经验证。
  • 遇到坏行直接 continue,没有错误计数和隔离证据。
  • 一次性把整个大文件读入内存;本日虽是小数据,也应理解流式边界。
  • 修复坏数据时覆盖 raw,失去重建和审计能力。
  • 把重跑输出相同等同 exactly-once;后者涉及存储提交和下游副作用。

系统场景连接

金融交易事件可能来自多个渠道,字段名称、币种、小数位和时间格式不同。契约能阻止错误单位悄悄进入特征与评测集。对于链上索引数据,缺失区块号、链 ID 或交易哈希会破坏去重和回放。轻量 JSONL 练习直接连接后续的数据 lineage、artifact hash 和 replay,而不需要先建数据平台。

自检问题

  1. JSON parse 成功后还需要哪几层验证?
  2. 为什么 TypeScript interface 不能替代外部输入契约?
  3. 确定性变换最容易被哪些隐式依赖破坏?
  4. quarantine 至少需要保存哪些信息,哪些敏感信息不应照搬?

专业课程对齐

  • 阅读 Full Stack Deep Learning 2022 的 data management 内容,重点看数据版本和训练/服务数据路径如何影响可重复性,将其映射到 accepted/quarantine 两条支路。
  • 阅读 Stanford CS329S 的 data collection、validation 与 production data 主题,提取“静态类型之外还要验证什么”的问题清单。
  • 阅读 OpenLineage 官方文档 的 dataset 与 run 概念,把本日输入 JSONL、验证运行和两个输出看成一条最小 lineage,但不要求接入服务。

深入学习提示

先写失败分类,再写 happy path。观察代码中字节→字符串→JSON→unknown→validated event 的类型收窄过程,并标注每一步可能丢失什么。进一步思考 schema evolution:新增可选字段通常可向后兼容,改变金额单位即使类型不变也可能语义不兼容。练习的评价标准不是代码行数,而是你能否解释每个错误去哪、能否重跑、哪些保证仍未提供。

学后填写区

  • 实际使用的合成字段:
  • 发现的三类失败:
  • 两次运行是否一致及证据:
  • 契约变化后的影响:
  • 尚未实现的系统保证:
重点主线 · H01 · 任务契约与上下文架构本周配套机制实验 · W1 · 历史数据:当时发生,不等于当时已知 →详细讲义、离线示例与源码;按需要选读,不新增必交任务。
本页是未来 P2 的预习教材。等 P1 完成并正式进入 P2 后,再填写真实理解、练习结果和不确定项;现在阅读不会改变P1 唯一进度账本