关键在于用schema定义输入输出契约并强制校验。需声明字段名、类型、取值范围及空值策略,polars/pandas均支持运行时校验,失败即报错;契约应版本化存为yaml/json,ci中自动校验以阻断问题发布。

关键不是写更多代码,而是让每一步“说什么、听什么、错在哪”都提前白纸黑字写清楚。
用 Schema 做输入输出的硬性合同
清洗模块不能靠“我猜你有这列”,而要声明:我只接受带 customer_id(str)、order_amount(float64)、created_at(datetime[ns]) 的 DataFrame。Polars 2.0 中用 .with_schema() 或读取时设 schema=... 强制校验;Pandas 可用 pd.DataFrame.astype() + 自定义类型检查函数兜底。一旦字段名或类型不符,立刻报错,不进下游。
把业务规则转成可执行断言
契约不只是结构,更是语义。比如“订单金额必须 ≥ 0 且 ≤ 100 万”,不能只写注释,要写成运行时校验:
-
pl.col("order_amount").is_between(0, 1_000_000, closed="both")(Polars) - 或在 Pipeline 的 transformer 中加
assert X["order_amount"].min() >= 0(Python) - 失败时抛出带上下文的异常,如
ValueError: order_amount out of business range [0, 1e6], found -235.7 at row 1289
空值与缺失策略逐列明示
不同列的空值含义不同,契约必须区分对待:
- customer_id 缺失 → 直接丢弃整行(主键不可为空)
- discount_rate 缺失 → 填 0.0(默认无折扣)
- review_text 缺失 → 填 "N/A" 字符串,不填 null(文本字段需保持非空字符串语义)
这些策略写在模块文档头、Schema 注释里,也体现在 .fill_null() 或 .coalesce() 的调用中,避免“全局 fillna(0)”这种模糊操作。
版本化契约文件 + 自动化校验点
把契约单独存为 YAML 或 JSON 文件,例如 cleaning_contract_v2.yaml,包含字段名、类型、必填性、取值范围、空值策略、业务约束描述。CI 流程中加入一步:加载样本数据,跑一遍契约校验脚本,不通过则阻断发布。这样,哪怕上游系统改了导出格式,也会在集成阶段立刻暴露,而不是等模型上线后才发现特征错位。











