mcpField
T
test-ml-pipeline

test-ml-pipeline

github.com/probabl-ai测试与质量144134 次安装1 天前更新
代码仓库

关于 test-ml-pipeline

面向 ML 工作区测试的路由技能。它核对设计说明与实验脚本的配对,选择测试类别、放置空的 pytest 文件,并将测试逻辑交给对应子技能。

主要功能

  1. 01核对已批准说明与实验脚本配对
  2. 02按测试类别分派请求
  3. 03放置空 pytest 脚手架
  4. 04要求已批准实验配备冒烟测试

适用场景

  1. 01为已批准的实验设置冒烟测试
  2. 02将测试请求分派给对应子技能

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/probabl-ai/skills --skill test-ml-pipeline

安装后在 Claude Code 中输入/test-ml-pipeline确认已加载。

附带文件evals/evals.json

详细介绍

测试 ML Pipeline(路由器)

ML 工作区的测试存放在哪里、哪些内容需要配对, 以及每种测试类别的主体由哪个子技能负责。

首要操作(每轮都执行)

在回答任何其他内容之前:

  1. 确认存在已批准的设计说明,对应用户询问的测试。 配对规则是硬性要求: tests/<category>/test_NN_<short_name>.py 仅在 journal/NN_<short_name>.md 至少处于 approved 状态,且 experiments/NN_<short_name>.py 是匹配的脚本时才存在。如果 设计说明不存在,则交由 iterate-ml-experiment 处理。
  2. 输出预检清单(见下文),作为回复中的可见文本, 并标记每个复选框。
  3. 使用分派表选择负责该测试类别的子技能,然后移交处理。

预检 — 开始任何测试工作前,将此清单作为可见文本输出

Pre-flight (test-ml-pipeline):
- [ ] `journal/NN_<short_name>.md` exists and is at least `approved`
      (or confirmed n/a — about to hand off to `iterate-ml-experiment`)
- [ ] `experiments/NN_<short_name>.py` exists with the matching stem
      (or confirmed n/a — about to hand off to `organize-ml-workspace`)
- [ ] Test category picked: smoke | regression | distribution | …
- [ ] Subskill dispatched: `smoke-test-ml-pipeline` | …
- [ ] Test file stem decided: `tests/<category>/test_NN_<short_name>.py`
- [ ] pytest is on the project's dependency manifest (per
      `data-science-python-stack` § Tier 1)

停止条件 — 开始前阅读

  • 没有已批准的设计说明,就不能有测试。 如果匹配的 journal/NN_*.md 不存在于磁盘上,或其状态尚未达到 approved,绝不创建 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 或编写特定于测试的逻辑—— 这些工作属于匹配的子技能(例如 smoke-test-ml-pipeline)。
  • 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 中唯一必需的类别。

测试类别 — 分派表

优先依据用户的具体表述;若无明确线索,则使用表格底部的默认项。

情况子技能
刚刚批准了一个全新实验;需要为其配置 smoke 测试smoke-test-ml-pipeline
用户说“为 02 编写 smoke 测试”、“smoke 测试失败了”或“X 的 smoke 测试应该断言什么?”smoke-test-ml-pipeline
用户说“02 和 03 之间的指标发生了漂移,我们能把这个固定下来吗?”、“针对上周运行结果的回归测试”regression-test-ml-pipeline (未来功能——v1 中尚未实现)
用户说“预测值超出范围了”、“生产环境中的校准似乎不对”或“模式不变量”distribution-test-ml-pipeline (未来功能——v1 中尚未实现)
用户提出开放式问题:“这个实验应该有测试吗?”默认使用 smoke-test-ml-pipeline —— 每次迭代都必须有 smoke 测试;其他测试均为可选。

当前实现仅提供 smoke-test-ml-pipeline。 未来的类别会作为同级子技能加入;分派表规定了添加这些类别时应遵循的契约。

每个实验都必须有测试的规则

每个获批的实验都必须先通过冒烟测试,才能在 JOURNAL.md 中标记为 done。 iterate-ml-experiment § 3(设计说明获批后、创建脚本前)和 § 4(记录结果前)强制执行此规则:测试是迭代循环的一部分,而不是事后补充。如果冒烟测试失败,后续迭代应针对流水线(重新进入 build-ml-pipeline),而非模型——冒烟测试失败几乎总是 DataOps 图布局的结构性问题,而不是预测器的指标问题。

工作区中的每个实验都必须进行冒烟测试。其他测试类别(回归、分布等)为可选项,可根据工作区的需要添加。

决策流程

  1. 是否存在获批的 journal/NN_<short_name>.md,以及对应的 experiments/NN_<short_name>.py?
    • 否 → 移交给 iterate-ml-experiment(先写设计说明)或 organize-ml-workspace(先写脚本)。停止。
    • 是 → 继续。
  2. 根据用户的信号确定测试类别(见分派表)。默认值:smoke。
    • 如果分派表中标记该子技能为*(未来功能——v1 中尚未实现)*(regression-test-ml-pipeline、distribution-test-ml-pipeline 等):停止。不要创建 tests/<category>/。不要假装该子技能存在并进行分派。不要编写 def test_、断言代码片段或冒烟测试主体。用一句话说明:该类别已识别,但尚未实现;可选补充“该功能尚未随子技能发布,存在此缺口。”
  3. 使用 pytest 脚手架在 tests/<category>/test_NN_<short_name>.py 创建空测试文件(包含一个 def test_*(): 函数、空函数体,以及 # TODO: filled in by <subskill> 标记)。如果文件已存在,不要覆盖。若步骤 2 因类别尚未实现而停止,则跳过此步骤。
  4. 移交给子技能(例如 smoke-test-ml-pipeline)。子技能负责编写断言、构造夹具,以及编写所需的辅助工具。
  5. 运行测试前,向用户确认子技能提供的草稿是否正确(此循环由子技能负责;此技能只负责放置文件和分派)。

此技能不会做什么

  • 运行 pytest。是否执行测试由用户(或 CI)决定。
  • 编写断言主体。各子技能负责其类别的断言。
  • 决定是否需要测试。每个实验都必须有测试的规则(每次迭代都进行冒烟测试)由此技能固定;是否添加可选类别属于工作区级别的决策,由用户而非此技能作出。
  • 修改 tests/ 以外的文件。配套技能对 iterate-ml-experiment / organize-ml-workspace / build-ml-pipeline / evaluate-ml-pipeline 的修改应在这些技能中进行,而不是在此技能中。

配套技能

  • smoke-test-ml-pipeline — 负责冒烟测试契约 (夹具构建、通过构造实现诊断的特性、断言、失败语义)。在 v1 中,这是唯一必需的测试类别。
  • organize-ml-workspace — 在创建工作区时,在 journal/ / experiments/ 旁搭建 tests/<category>/。 占位测试文件由此技能放置,而非由 organize-ml-workspace 放置。
  • iterate-ml-experiment — 推进迭代循环。设计说明获批后,会分派给此技能(再由此技能分派给 smoke-test-ml-pipeline)来起草相应测试。实验运行后,要求冒烟测试通过,实验才能切换为 done。
  • build-ml-pipeline — 声明流水线。冒烟测试是可执行证据,证明遵循了 build-ml-pipeline 的 X 标记规则(提前标记 X,之后进行特征工程,通过上游节点引用历史记录)。冒烟测试失败通常意味着流水线结构有误;请回到此处处理。
  • evaluate-ml-pipeline — 负责交叉验证(CV)协议。当流水线包含依赖历史记录的特征时,CV 是必要条件,但并非充分条件;smoke-test-ml-pipeline 可弥补 CV 未覆盖的部分。
  • data-science-python-stack — 声明 pytest 是任何使用此技能的工作区都必须具备的 Tier 1 依赖项。

评论

支持 Markdown