SuperAPI AI 工具集

test-ml-pipeline

测试与质量

查看项目

更新于 10-16 23:42

技能介绍

Test ML Pipeline 是一个面向机器学习工作区的测试路由技能,隶属于 probabl-ai/skills。它不直接编写测试断言,而是负责测试文件的归属划分、实验与测试之间的配对规则,以及按测试类别把工作分派给对应的子技能。

用途

该技能管理 ML 工作区中的 tests/ 文件夹,明确测试应该放在哪里、什么和什么配对,以及每一类测试由哪个子技能负责主体内容。它是一个轻量级路由器:每个测试类别拥有自己的子技能,本技能只做放置与分派。

首要动作与前置检查

每轮响应之前,该技能要求:

  1. 确认用户所询问的测试存在一份已批准的设计笔记。配对规则是硬性的:只有当 journal/NN_<short_name>.md 至少处于 approved 状态,并且 experiments/NN_<short_name>.py 是匹配脚本时,tests/<category>/test_NN_<short_name>.py 才存在。若设计笔记不存在,则交回给 iterate-ml-experiment。
  2. 在响应中以可见文本形式输出 Pre-flight 检查清单,并逐项勾选。
  3. 使用 Dispatch 表选择负责该测试类别的子技能,然后转交。

Pre-flight 清单(test-ml-pipeline)包含以下检查项:

  • journal/NN_<short_name>.md 存在且至少为 approved(或确认不适用——即将转交 iterate-ml-experiment)
  • experiments/NN_<short_name>.py 存在且词干匹配(或确认不适用——即将转交 organize-ml-workspace)
  • 已选定测试类别:smoke | regression | distribution | …
  • 已分派子技能:smoke-test-ml-pipeline | …
  • 已确定测试文件词干:tests/<category>/test_NN_<short_name>.py
  • pytest 已列入项目依赖清单(依据 data-science-python-stack § Tier 1)

停止条件

  • 没有已批准的设计笔记就不写测试。绝不在 matching journal/NN_.md 未落盘且未至少批准的情况下创建 tests/<category>/test_NN_.py。设计笔记是契约,测试断言契约成立,反向顺序不成立。
  • 词干规则是硬性的。测试文件基名为 test_NN_<short_name>.py(带 pytest 期望的 test_ 前缀);NN_<short_name> 部分与实验完全匹配。一个实验 → 每个类别一个测试文件。不允许 test_<NN>v2.py,不允许 test_NN<short_name>_2.py。若测试需演进,原地编辑,配对必须保持 1:1。
  • 每个类别一个子技能。本技能只放置空的测试文件并转交,不写断言体、fixture 构造或测试专属逻辑——这些属于匹配的子技能。
  • pytest 是运行器。测试是 pytest 测试,不是 jupytext 风格的 # %% 脚本。实验脚本位于 experiments/,保持 # %%- 风格用于交互式迭代;测试是二元通过/失败,受益于 pytest 的报告。不要混用两种约定。

布局与配对规则

本技能拥有的布局:

project/ └── tests/ ├── smoke/ │ ├── test_01_baseline.py # ↔ experiments/01_baseline.py │ ├── test_02_short_name.py │ └── ... └── (future: regression/, distribution/, …)

配对规则:

journal/NN_<short_name>.md experiments/NN_<short_name>.py tests/<category>/test_NN_<short_name>.py

三处使用相同的 NN_<short_name> 词干。测试文件基名上的 test_ 前缀是 pytest 命名约定;其后所有内容跟随实验。tests/<category>/ 子文件夹让工作区可以在不重命名任何内容的情况下扩展更多测试类型。tests/smoke/ 是 v1 唯一必需的类别。

测试类别与 Dispatch 表

优先使用用户信号;若无则回退到下方默认值。

情况 子技能
刚批准的全新实验,需要接入其 smoke 测试 smoke-test-ml-pipeline
用户说“为 02 写 smoke 测试”“smoke 测试失败了”“X 的 smoke 测试应断言什么?” smoke-test-ml-pipeline
用户说“02 和 03 之间的指标漂移了,能锁定吗?”“针对上周运行的回归测试” regression-test-ml-pipeline(未来——v1 未实现)
用户说“预测超出范围”“生产中的校准看起来不对”“schema 不变量” distribution-test-ml-pipeline(未来——v1 未实现)
用户问开放式问题“这个实验应该有测试吗?” 默认为 smoke-test-ml-pipeline——smoke 测试在每次迭代都必需;其他为可选

当前实现只提供 smoke-test-ml-pipeline。未来类别将作为同级子技能落地;Dispatch 表是添加它们的契约。

每实验必需测试规则

每个已批准的实验在 JOURNAL.md 中标记为完成之前,必须有一个通过的 smoke 测试。这由 iterate-ml-experiment § 3(设计笔记批准后、脚本创建前)和 § 4(记录结果前)强制执行:测试是迭代循环的一部分,不是事后补充。若 smoke 测试失败,后续迭代针对的是管线(重新进入 build-ml-pipeline),而非模型——smoke 测试失败几乎总是 DataOps 图布局的结构问题,而非预测器的指标问题。

smoke 测试对工作区中每个实验都是非可选的。其他测试类别(regression、distribution 等)为可选,在工作区需要时添加。

决策流程

  1. 是否存在已批准的 journal/NN_<short_name>.md 和匹配的 experiments/NN_<short_name>.py?
    • 否 → 转交 iterate-ml-experiment(先设计笔记)或 organize-ml-workspace(先脚本)。停止。
    • 是 → 继续。
  2. 从用户信号识别测试类别(Dispatch 表)。默认:smoke。
  3. 若 Dispatch 表将该子技能标记为(未来——v1 未实现)(regression-test-ml-pipeline、distribution-test-ml-pipeline 等):停止。不要创建 tests/<category>/。不要当作子技能存在来分派。不要编写 def test_、断言片段或 smoke 测试体。用一句话说明:该类别已被识别但未实现;可选“在子技能发布前的缺口”。
  4. 在 tests/<category>/test_NN_<short_name>.py 放置空测试文件,带 pytest 脚手架(一个 def test_*(): 函数、空主体、一个 # TODO: filled in by <subskill> 标记)。若文件已存在,不要覆盖。当第 2 步因未来类别而停止时跳过此步。
  5. 转交子技能(smoke-test-ml-pipeline 等)。子技能编写断言、fixture 构造及其所需辅助函数。
  6. 在运行测试前,与用户确认子技能的草稿是否正确(子技能拥有此循环;本技能只做放置 + 分派)。

不做什么

  • 不运行 pytest。测试执行由用户(或 CI)决定。
  • 不编写断言体。每个子技能拥有其类别的断言。
  • 不决定测试是否必需。每实验必需测试规则(每次迭代 smoke)由本技能固定;添加可选类别是用户做出的工作区级决策,不是本技能。
  • 不触碰 tests/ 之外的文件。对 iterate-ml-experiment / organize-ml-workspace / build-ml-pipeline / evaluate-ml-pipeline 的 companion-skill 编辑属于那些技能,不属于本技能。

配套技能

  • smoke-test-ml-pipeline:拥有 smoke 测试契约(fixture 构造、construction 诊断属性、断言、失败语义)。v1 唯一必需的测试类别。
  • organize-ml-workspace:在工作区创建时与 journal/、experiments/ 一同脚手架化 tests/<category>/。占位测试文件由本技能放置,而非 organize-ml-workspace。
  • iterate-ml-experiment:驱动迭代循环。设计笔记批准后,分派到本技能(进而分派到 smoke-test-ml-pipeline)以起草匹配测试。实验运行后,要求 smoke 测试通过,实验才能翻转为完成。
  • build-ml-pipeline:管线声明。smoke 测试是可执行证明,证明遵循了 build-ml-pipeline 的 X-marker 规则(早标记 X、之后 featurize、通过上游节点引用历史)。smoke 测试失败通常意味着管线形状错误;路由回此处。
  • evaluate-ml-pipeline:拥有 CV 协议。当管线具有历史依赖特征时,CV 必要但不充分;smoke-test-ml-pipeline 填补 CV 未覆盖的缺口。
  • data-science-python-stack:声明 pytest 为任何使用本技能的工作区的 Tier 1 强制依赖。