swe-workflow-skills 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +144 -0
- package/VERSION +1 -0
- package/bin/cli.mjs +44 -0
- package/catalog.json +225 -0
- package/commands/role.md +34 -0
- package/hooks/session-start.mjs +118 -0
- package/install.mjs +318 -0
- package/package.json +47 -0
- package/roles.json +194 -0
- package/scripts/resolve.mjs +296 -0
- package/skills/accessibility-design/SKILL.md +128 -0
- package/skills/accessibility-design/evals/evals.json +51 -0
- package/skills/accessibility-design/references/accessibility-patterns.md +321 -0
- package/skills/api-design/SKILL.md +144 -0
- package/skills/api-design/evals/evals.json +48 -0
- package/skills/api-design/references/rest-conventions.md +147 -0
- package/skills/api-design/templates/api-spec.md +156 -0
- package/skills/architecture-design/SKILL.md +86 -0
- package/skills/architecture-design/evals/evals.json +44 -0
- package/skills/architecture-design/references/clean-architecture.md +147 -0
- package/skills/architecture-design/references/component-principles.md +129 -0
- package/skills/architecture-design/references/principles.md +81 -0
- package/skills/architecture-design/references/solid-principles.md +106 -0
- package/skills/architecture-design/templates/adr.md +63 -0
- package/skills/architecture-documentation/SKILL.md +126 -0
- package/skills/architecture-documentation/evals/evals.json +44 -0
- package/skills/architecture-documentation/references/abstraction-levels.md +91 -0
- package/skills/architecture-documentation/references/diagram-tooling.md +141 -0
- package/skills/architecture-documentation/templates/architecture-doc.md +171 -0
- package/skills/bug-investigating/SKILL.md +133 -0
- package/skills/bug-investigating/evals/evals.json +56 -0
- package/skills/bug-investigating/references/common-bugs.md +62 -0
- package/skills/bug-investigating/references/debugging-patterns.md +94 -0
- package/skills/cicd-pipeline/SKILL.md +87 -0
- package/skills/cicd-pipeline/evals/evals.json +34 -0
- package/skills/cicd-pipeline/references/pipeline-patterns.md +206 -0
- package/skills/cicd-pipeline/templates/github-actions.md +206 -0
- package/skills/code-reviewing/SKILL.md +92 -0
- package/skills/code-reviewing/evals/evals.json +62 -0
- package/skills/code-reviewing/references/error-handling.md +108 -0
- package/skills/code-reviewing/references/review-checklist.md +144 -0
- package/skills/configuration-strategy/SKILL.md +109 -0
- package/skills/configuration-strategy/evals/evals.json +41 -0
- package/skills/configuration-strategy/references/config-patterns.md +161 -0
- package/skills/containerization/SKILL.md +90 -0
- package/skills/containerization/evals/evals.json +36 -0
- package/skills/containerization/references/dockerfile-patterns.md +168 -0
- package/skills/containerization/templates/dockerfile.md +154 -0
- package/skills/data-modeling/SKILL.md +83 -0
- package/skills/data-modeling/evals/evals.json +43 -0
- package/skills/data-modeling/references/conventions.md +57 -0
- package/skills/data-modeling/templates/schema.md +120 -0
- package/skills/dependency-impact-analysis/SKILL.md +113 -0
- package/skills/dependency-impact-analysis/evals/evals.json +41 -0
- package/skills/dependency-impact-analysis/references/impact-patterns.md +150 -0
- package/skills/dependency-management/SKILL.md +161 -0
- package/skills/dependency-management/evals/evals.json +48 -0
- package/skills/dependency-management/references/evaluation-checklist.md +127 -0
- package/skills/deployment-checklist/SKILL.md +132 -0
- package/skills/deployment-checklist/evals/evals.json +58 -0
- package/skills/deployment-checklist/references/pre-deploy-gates.md +91 -0
- package/skills/deployment-repo/SKILL.md +190 -0
- package/skills/deployment-repo/evals/evals.json +44 -0
- package/skills/deployment-repo/references/deployment-repo-patterns.md +258 -0
- package/skills/deployment-repo/references/version-compatibility.md +227 -0
- package/skills/deployment-repo/templates/deployment-repo-structure.md +226 -0
- package/skills/effort-estimation/SKILL.md +95 -0
- package/skills/effort-estimation/evals/evals.json +32 -0
- package/skills/effort-estimation/references/estimation-methods.md +154 -0
- package/skills/feature-planning/SKILL.md +84 -0
- package/skills/feature-planning/evals/evals.json +44 -0
- package/skills/feature-planning/templates/plan.md +55 -0
- package/skills/feature-planning/templates/task.md +26 -0
- package/skills/frontend-architecture/SKILL.md +154 -0
- package/skills/frontend-architecture/evals/evals.json +34 -0
- package/skills/frontend-architecture/references/component-patterns.md +264 -0
- package/skills/frontend-architecture/templates/folder-structure.md +203 -0
- package/skills/git-workflow/SKILL.md +127 -0
- package/skills/git-workflow/evals/evals.json +44 -0
- package/skills/git-workflow/references/conventions.md +142 -0
- package/skills/git-workflow/templates/pull-request.md +57 -0
- package/skills/gitops-delivery/SKILL.md +319 -0
- package/skills/gitops-delivery/evals/evals.json +44 -0
- package/skills/gitops-delivery/references/gitops-patterns.md +478 -0
- package/skills/gitops-delivery/templates/gitops-config.md +196 -0
- package/skills/incident-response/SKILL.md +130 -0
- package/skills/incident-response/evals/evals.json +55 -0
- package/skills/incident-response/references/communication-templates.md +134 -0
- package/skills/incident-response/references/severity-levels.md +77 -0
- package/skills/incident-response/templates/incident-timeline.md +57 -0
- package/skills/infrastructure-as-code/SKILL.md +86 -0
- package/skills/infrastructure-as-code/evals/evals.json +33 -0
- package/skills/infrastructure-as-code/references/iac-patterns.md +179 -0
- package/skills/infrastructure-as-code/templates/terraform-module.md +158 -0
- package/skills/metrics-and-okrs/SKILL.md +113 -0
- package/skills/metrics-and-okrs/evals/evals.json +33 -0
- package/skills/metrics-and-okrs/references/metric-catalog.md +90 -0
- package/skills/metrics-and-okrs/templates/okr-document.md +61 -0
- package/skills/ml-experiment-tracking/SKILL.md +96 -0
- package/skills/ml-experiment-tracking/evals/evals.json +32 -0
- package/skills/ml-experiment-tracking/references/tracking-tools.md +127 -0
- package/skills/ml-model-deployment/SKILL.md +106 -0
- package/skills/ml-model-deployment/evals/evals.json +34 -0
- package/skills/ml-model-deployment/references/serving-patterns.md +162 -0
- package/skills/ml-pipeline-design/SKILL.md +162 -0
- package/skills/ml-pipeline-design/evals/evals.json +34 -0
- package/skills/ml-pipeline-design/references/pipeline-components.md +174 -0
- package/skills/observability-design/SKILL.md +162 -0
- package/skills/observability-design/evals/evals.json +52 -0
- package/skills/observability-design/references/logging-patterns.md +229 -0
- package/skills/observability-design/references/slo-framework.md +151 -0
- package/skills/observability-design/templates/slo-document.md +80 -0
- package/skills/performance-optimization/SKILL.md +83 -0
- package/skills/performance-optimization/evals/evals.json +47 -0
- package/skills/performance-optimization/references/bottleneck-patterns.md +256 -0
- package/skills/performance-optimization/references/concurrency.md +101 -0
- package/skills/prd-writing/SKILL.md +109 -0
- package/skills/prd-writing/evals/evals.json +33 -0
- package/skills/prd-writing/references/prd-examples.md +132 -0
- package/skills/prd-writing/templates/prd.md +71 -0
- package/skills/prd-writing/templates/rfc.md +79 -0
- package/skills/project-documentation/SKILL.md +104 -0
- package/skills/project-documentation/evals/evals.json +48 -0
- package/skills/project-documentation/references/contributing-guide.md +100 -0
- package/skills/project-documentation/templates/changelog.md +59 -0
- package/skills/project-documentation/templates/readme.md +121 -0
- package/skills/project-proposal/SKILL.md +90 -0
- package/skills/project-proposal/evals/evals.json +31 -0
- package/skills/project-proposal/references/proposal-examples.md +140 -0
- package/skills/project-proposal/templates/proposal.md +76 -0
- package/skills/project-review/SKILL.md +111 -0
- package/skills/project-review/evals/evals.json +42 -0
- package/skills/refactoring/SKILL.md +90 -0
- package/skills/refactoring/evals/evals.json +44 -0
- package/skills/refactoring/references/transformations.md +132 -0
- package/skills/retrospective/SKILL.md +157 -0
- package/skills/retrospective/evals/evals.json +34 -0
- package/skills/retrospective/references/facilitation-guide.md +130 -0
- package/skills/retrospective/templates/post-mortem.md +121 -0
- package/skills/rollback-strategy/SKILL.md +116 -0
- package/skills/rollback-strategy/evals/evals.json +55 -0
- package/skills/rollback-strategy/references/rollback-patterns.md +125 -0
- package/skills/rollback-strategy/templates/rollback-plan.md +69 -0
- package/skills/security-audit/SKILL.md +146 -0
- package/skills/security-audit/evals/evals.json +66 -0
- package/skills/security-audit/references/owasp-top-10.md +167 -0
- package/skills/security-audit/templates/security-report.md +79 -0
- package/skills/skill-router/SKILL.md +171 -0
- package/skills/skill-router/evals/evals.json +39 -0
- package/skills/strategic-review/SKILL.md +106 -0
- package/skills/strategic-review/evals/evals.json +42 -0
- package/skills/strategic-review/templates/full-review-prompt.md +84 -0
- package/skills/tdd-workflow/SKILL.md +147 -0
- package/skills/tdd-workflow/evals/evals.json +58 -0
- package/skills/tdd-workflow/references/test-quality.md +71 -0
- package/skills/technical-debt-review/SKILL.md +113 -0
- package/skills/technical-debt-review/evals/evals.json +41 -0
- package/skills/technical-debt-review/references/debt-taxonomy.md +124 -0
- package/skills/technical-debt-review/templates/debt-audit.md +85 -0
- package/skills/test-data-strategy/SKILL.md +129 -0
- package/skills/test-data-strategy/evals/evals.json +49 -0
- package/skills/test-data-strategy/references/data-generation-patterns.md +341 -0
- package/skills/test-suite-design/SKILL.md +137 -0
- package/skills/test-suite-design/evals/evals.json +69 -0
- package/skills/test-suite-design/references/test-infrastructure.md +175 -0
- package/skills/test-suite-design/references/testing-pyramid.md +140 -0
- package/skills/ui-ux-design/SKILL.md +117 -0
- package/skills/ui-ux-design/evals/evals.json +35 -0
- package/skills/ui-ux-design/references/interaction-patterns.md +145 -0
- package/skills/ui-ux-design/templates/screen-spec.md +97 -0
- package/skills/verification-before-completion/SKILL.md +85 -0
- package/skills/verification-before-completion/evals/evals.json +53 -0
- package/skills/writing-skills/SKILL.md +87 -0
- package/skills/writing-skills/evals/evals.json +41 -0
- package/skills/writing-skills/references/pressure-testing.md +69 -0
- package/uninstall.mjs +182 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ml-experiment-tracking
|
|
3
|
+
description: "Design reproducible ML experiments — tracking, versioning, run comparison with MLflow, W&B, or DVC. Triggers: experiment tracking, MLflow, wandb, weights and biases, DVC, track experiments, compare models, hyperparameter, reproducibility, model registry, which model is better, experiment results, log metrics."
|
|
4
|
+
model: sonnet
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ML Experiment Tracking
|
|
9
|
+
|
|
10
|
+
Establish disciplined experiment tracking that makes ML development reproducible, comparable, and auditable. Without tracking, ML work degenerates into "which notebook had the good results?"
|
|
11
|
+
|
|
12
|
+
## Why This Matters
|
|
13
|
+
|
|
14
|
+
ML experiments differ from traditional software in critical ways:
|
|
15
|
+
- **Non-deterministic**: Same code + same data can produce different results (random seeds, GPU nondeterminism)
|
|
16
|
+
- **Multi-dimensional**: Performance depends on code, data, hyperparameters, and environment simultaneously
|
|
17
|
+
- **Retrospective**: You often realize a past experiment was better only after running new ones
|
|
18
|
+
|
|
19
|
+
Without systematic tracking, reproducing results becomes archaeology.
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
### Step 1: Set Up Tracking Infrastructure
|
|
24
|
+
|
|
25
|
+
Before running experiments, establish:
|
|
26
|
+
|
|
27
|
+
- **Experiment tracker**: MLflow, Weights & Biases, Neptune, or even a structured CSV/JSON approach
|
|
28
|
+
- **Data versioning**: DVC, Delta Lake, or immutable dataset snapshots in object storage
|
|
29
|
+
- **Code versioning**: Git (this should already exist)
|
|
30
|
+
- **Environment capture**: Docker image hash, conda environment export, pip freeze
|
|
31
|
+
|
|
32
|
+
Recommend MLflow for open-source simplicity, W&B for rich visualization needs. See [references/tracking-tools.md](references/tracking-tools.md) for setup patterns.
|
|
33
|
+
|
|
34
|
+
### Step 2: Define What to Track
|
|
35
|
+
|
|
36
|
+
For every experiment run, log:
|
|
37
|
+
|
|
38
|
+
**Inputs:**
|
|
39
|
+
- Dataset version or hash (not just "training_data.csv" — the specific version)
|
|
40
|
+
- Git commit hash of the code
|
|
41
|
+
- All hyperparameters (learning rate, batch size, epochs, model architecture choices)
|
|
42
|
+
- Random seed
|
|
43
|
+
- Environment (Python version, key library versions, GPU type)
|
|
44
|
+
|
|
45
|
+
**Outputs:**
|
|
46
|
+
- Primary metric (what you're optimizing: accuracy, F1, RMSE, etc.)
|
|
47
|
+
- Secondary metrics (latency, model size, memory usage)
|
|
48
|
+
- Training curves (loss per epoch)
|
|
49
|
+
- Evaluation on held-out test set
|
|
50
|
+
- Model artifacts (serialized model, weights)
|
|
51
|
+
- Confusion matrix, ROC curves, or other diagnostic plots
|
|
52
|
+
|
|
53
|
+
**Metadata:**
|
|
54
|
+
- Experiment name and description (what hypothesis is being tested)
|
|
55
|
+
- Run duration and compute cost
|
|
56
|
+
- Tags for filtering (e.g., "baseline", "feature_engineering", "architecture_search")
|
|
57
|
+
|
|
58
|
+
### Step 3: Design the Experiment
|
|
59
|
+
|
|
60
|
+
Before running anything, define:
|
|
61
|
+
|
|
62
|
+
1. **Hypothesis**: What do you expect to happen and why?
|
|
63
|
+
2. **Baseline**: What's the current best result to beat?
|
|
64
|
+
3. **Variable**: What exactly are you changing? (Change one thing at a time)
|
|
65
|
+
4. **Metric**: What defines "better"? Set this before seeing results to avoid cherry-picking.
|
|
66
|
+
5. **Stopping criteria**: When do you stop iterating? (Target metric reached, diminishing returns, time budget exhausted)
|
|
67
|
+
|
|
68
|
+
Document this as the experiment description in your tracker.
|
|
69
|
+
|
|
70
|
+
### Step 4: Run and Compare
|
|
71
|
+
|
|
72
|
+
Run experiments with full tracking. After a batch of runs:
|
|
73
|
+
|
|
74
|
+
1. **Compare metrics** across runs in a table or parallel coordinates plot
|
|
75
|
+
2. **Identify the best run** by the pre-defined primary metric
|
|
76
|
+
3. **Verify reproducibility** — can you re-run the best experiment and get similar results?
|
|
77
|
+
4. **Check for data leakage** — is the test set truly held out? No information from test in training?
|
|
78
|
+
5. **Assess overfitting** — compare train vs validation metrics
|
|
79
|
+
|
|
80
|
+
### Step 5: Register the Best Model
|
|
81
|
+
|
|
82
|
+
When a model is ready for staging or production:
|
|
83
|
+
|
|
84
|
+
1. Register it in a model registry (MLflow Model Registry, or equivalent)
|
|
85
|
+
2. Tag it with a stage: `staging`, `production`, `archived`
|
|
86
|
+
3. Link it to the experiment run that produced it (full lineage)
|
|
87
|
+
4. Document what makes this model better than the previous version
|
|
88
|
+
|
|
89
|
+
This creates an auditable trail from "model in production" back to "exact data + code + params that created it."
|
|
90
|
+
|
|
91
|
+
## Principles Applied
|
|
92
|
+
|
|
93
|
+
- **DRY**: Track once, query many times. Don't reconstruct experiment details from memory or notebooks.
|
|
94
|
+
- **YAGNI**: Start with simple tracking (parameters + metrics + artifacts). Add complexity (feature stores, automated comparisons) when the number of experiments justifies it.
|
|
95
|
+
- **Reproducibility over speed**: A fast experiment you can't reproduce has zero long-term value.
|
|
96
|
+
- **KISS**: One experiment changes one variable. Multi-variable changes make it impossible to attribute improvement.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "ml-experiment-tracking",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "I'm training a text classification model using scikit-learn. I want to compare TF-IDF + Logistic Regression vs TF-IDF + Random Forest vs sentence-transformers + XGBoost. Set up experiment tracking so I can compare them properly.",
|
|
7
|
+
"expected_output": "Should set up MLflow or W&B tracking, define what to log for each run, ensure all three experiments are comparable, and provide the tracking code.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Sets up experiment tracking infrastructure (MLflow or W&B)",
|
|
10
|
+
"Defines consistent metrics across all three approaches",
|
|
11
|
+
"Logs hyperparameters, dataset version, and git commit for each run",
|
|
12
|
+
"Logs model artifacts for later loading",
|
|
13
|
+
"Shows how to compare runs after completion",
|
|
14
|
+
"Emphasizes changing one variable at a time where possible",
|
|
15
|
+
"Includes reproducibility measures (random seed, environment capture)"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": 2,
|
|
20
|
+
"prompt": "I've been training models in Jupyter notebooks for 3 months and I have results scattered across 40+ notebooks. How do I get organized?",
|
|
21
|
+
"expected_output": "Should recommend setting up tracking infrastructure, then systematically re-running or cataloging key experiments. Should be practical about not re-running everything.",
|
|
22
|
+
"assertions": [
|
|
23
|
+
"Does NOT suggest re-running all 40 notebooks",
|
|
24
|
+
"Recommends setting up tracking for all future experiments",
|
|
25
|
+
"Suggests cataloging the best results from notebooks into the tracker manually",
|
|
26
|
+
"Recommends extracting reusable training code from notebooks into scripts",
|
|
27
|
+
"Suggests data versioning to prevent future dataset ambiguity",
|
|
28
|
+
"Provides a practical migration path, not an all-or-nothing approach"
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Experiment Tracking Tools
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- MLflow setup and patterns
|
|
5
|
+
- Weights & Biases patterns
|
|
6
|
+
- DVC for data versioning
|
|
7
|
+
- Comparison matrix
|
|
8
|
+
|
|
9
|
+
## MLflow Setup
|
|
10
|
+
|
|
11
|
+
### Basic tracking
|
|
12
|
+
```python
|
|
13
|
+
import mlflow
|
|
14
|
+
|
|
15
|
+
mlflow.set_tracking_uri("http://localhost:5000") # Or remote server
|
|
16
|
+
mlflow.set_experiment("my-classification-project")
|
|
17
|
+
|
|
18
|
+
with mlflow.start_run(run_name="baseline-logistic-regression"):
|
|
19
|
+
# Log parameters
|
|
20
|
+
mlflow.log_param("model_type", "logistic_regression")
|
|
21
|
+
mlflow.log_param("C", 1.0)
|
|
22
|
+
mlflow.log_param("max_iter", 100)
|
|
23
|
+
mlflow.log_param("dataset_version", "v2.3")
|
|
24
|
+
mlflow.log_param("git_commit", subprocess.check_output(["git", "rev-parse", "HEAD"]).strip())
|
|
25
|
+
|
|
26
|
+
# Train model
|
|
27
|
+
model = LogisticRegression(C=1.0, max_iter=100)
|
|
28
|
+
model.fit(X_train, y_train)
|
|
29
|
+
|
|
30
|
+
# Log metrics
|
|
31
|
+
y_pred = model.predict(X_test)
|
|
32
|
+
mlflow.log_metric("accuracy", accuracy_score(y_test, y_pred))
|
|
33
|
+
mlflow.log_metric("f1_score", f1_score(y_test, y_pred, average="weighted"))
|
|
34
|
+
mlflow.log_metric("precision", precision_score(y_test, y_pred, average="weighted"))
|
|
35
|
+
|
|
36
|
+
# Log model artifact
|
|
37
|
+
mlflow.sklearn.log_model(model, "model")
|
|
38
|
+
|
|
39
|
+
# Log additional artifacts
|
|
40
|
+
mlflow.log_artifact("confusion_matrix.png")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Model Registry
|
|
44
|
+
```python
|
|
45
|
+
# Register a model from a run
|
|
46
|
+
model_uri = f"runs:/{run_id}/model"
|
|
47
|
+
mlflow.register_model(model_uri, "my-classifier")
|
|
48
|
+
|
|
49
|
+
# Transition model stage
|
|
50
|
+
client = mlflow.tracking.MlflowClient()
|
|
51
|
+
client.transition_model_version_stage(
|
|
52
|
+
name="my-classifier",
|
|
53
|
+
version=3,
|
|
54
|
+
stage="Production"
|
|
55
|
+
)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Weights & Biases Patterns
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
import wandb
|
|
62
|
+
|
|
63
|
+
wandb.init(
|
|
64
|
+
project="my-classification-project",
|
|
65
|
+
name="baseline-logistic-regression",
|
|
66
|
+
config={
|
|
67
|
+
"model_type": "logistic_regression",
|
|
68
|
+
"C": 1.0,
|
|
69
|
+
"max_iter": 100,
|
|
70
|
+
"dataset_version": "v2.3",
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Training loop with automatic metric logging
|
|
75
|
+
for epoch in range(config.epochs):
|
|
76
|
+
train_loss = train_one_epoch(model, train_loader)
|
|
77
|
+
val_loss, val_acc = evaluate(model, val_loader)
|
|
78
|
+
wandb.log({
|
|
79
|
+
"train_loss": train_loss,
|
|
80
|
+
"val_loss": val_loss,
|
|
81
|
+
"val_accuracy": val_acc,
|
|
82
|
+
"epoch": epoch
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
# Log final artifacts
|
|
86
|
+
wandb.log({"confusion_matrix": wandb.plot.confusion_matrix(
|
|
87
|
+
y_true=y_test, preds=y_pred, class_names=class_names
|
|
88
|
+
)})
|
|
89
|
+
|
|
90
|
+
wandb.finish()
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## DVC for Data Versioning
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Initialize DVC in a git repo
|
|
97
|
+
dvc init
|
|
98
|
+
|
|
99
|
+
# Track a dataset
|
|
100
|
+
dvc add data/training_data.csv
|
|
101
|
+
git add data/training_data.csv.dvc data/.gitignore
|
|
102
|
+
git commit -m "track training data v1"
|
|
103
|
+
|
|
104
|
+
# Push data to remote storage
|
|
105
|
+
dvc remote add -d myremote s3://my-bucket/dvc-store
|
|
106
|
+
dvc push
|
|
107
|
+
|
|
108
|
+
# Switch to a different data version
|
|
109
|
+
git checkout v2.0 # Checkout the git tag
|
|
110
|
+
dvc checkout # Pull the matching data version
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
DVC tracks large files (datasets, model weights) alongside git without storing them in git. The `.dvc` file in git points to the actual data in remote storage.
|
|
114
|
+
|
|
115
|
+
## Comparison Matrix
|
|
116
|
+
|
|
117
|
+
| Feature | MLflow | W&B | Neptune | DVC |
|
|
118
|
+
|---------|--------|-----|---------|-----|
|
|
119
|
+
| Experiment tracking | ✓ | ✓ | ✓ | Partial |
|
|
120
|
+
| Model registry | ✓ | ✓ | ✓ | ✗ |
|
|
121
|
+
| Data versioning | ✗ | ✓ (Artifacts) | ✗ | ✓ |
|
|
122
|
+
| Visualization | Basic | Rich | Rich | ✗ |
|
|
123
|
+
| Self-hosted | ✓ | Enterprise | ✗ | ✓ |
|
|
124
|
+
| Free tier | Open source | Free (limits) | Free (limits) | Open source |
|
|
125
|
+
| Best for | Teams wanting open-source control | Rich visualization and collaboration | Team collaboration | Data and pipeline versioning |
|
|
126
|
+
|
|
127
|
+
**Recommendation**: MLflow + DVC for open-source, self-hosted workflows. W&B for teams that value visualization and can use SaaS.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ml-model-deployment
|
|
3
|
+
description: "Deploy ML models to production — serving infrastructure, monitoring, drift detection, safe rollouts. Triggers: deploy model, serve model, model API, model monitoring, data drift, concept drift, model degradation, A/B test model, canary model, inference endpoint, prediction API, retrain trigger."
|
|
4
|
+
model: sonnet
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ML Model Deployment
|
|
9
|
+
|
|
10
|
+
Deploy models to production with serving infrastructure that is reliable, observable, and safely updatable. Deploying a model is not the finish line — it's the beginning of the operational lifecycle.
|
|
11
|
+
|
|
12
|
+
## Key Difference from Software Deployment
|
|
13
|
+
|
|
14
|
+
Software deployment is primarily concerned with "does the code work?" Model deployment adds: "does the model still work *well* on real-world data that changes over time?" Models degrade silently — they keep returning predictions, just increasingly wrong ones.
|
|
15
|
+
|
|
16
|
+
## Workflow
|
|
17
|
+
|
|
18
|
+
### Step 1: Package the Model
|
|
19
|
+
|
|
20
|
+
Before deployment, the model must be a self-contained, versioned artifact:
|
|
21
|
+
|
|
22
|
+
- **Serialize the model**: Use framework-native formats (joblib/pickle for sklearn, SavedModel for TF, TorchScript for PyTorch, ONNX for cross-framework)
|
|
23
|
+
- **Pin dependencies**: Exact versions of libraries used during training
|
|
24
|
+
- **Include preprocessing**: The serving pipeline must apply the same feature transformations as training. Feature skew (different preprocessing in training vs serving) is the #1 cause of silent model failure
|
|
25
|
+
- **Version it**: Tag with model registry version, git commit, training data version, and training metrics
|
|
26
|
+
|
|
27
|
+
### Step 2: Choose the Serving Pattern
|
|
28
|
+
|
|
29
|
+
| Pattern | When to Use | Latency | Complexity |
|
|
30
|
+
|---------|-------------|---------|------------|
|
|
31
|
+
| **REST API** (Flask/FastAPI + model) | Low traffic, simple models | Medium (50-200ms) | Low |
|
|
32
|
+
| **Dedicated serving** (TF Serving, Triton, Seldon) | High traffic, GPU inference | Low (5-50ms) | Medium |
|
|
33
|
+
| **Batch prediction** (scheduled job) | High volume, latency-tolerant | N/A (scheduled) | Low |
|
|
34
|
+
| **Streaming** (Kafka + model) | Real-time event processing | Low | High |
|
|
35
|
+
| **Edge / embedded** | Offline, privacy-sensitive | Very low | High |
|
|
36
|
+
|
|
37
|
+
For most teams starting out: REST API with FastAPI is the right default. Optimize for lower latency only when measured need justifies complexity.
|
|
38
|
+
|
|
39
|
+
### Step 3: Build the Serving Application
|
|
40
|
+
|
|
41
|
+
The serving app needs:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Request → Validate input → Preprocess → Predict → Postprocess → Response
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Key requirements:
|
|
48
|
+
- **Input validation**: Reject malformed requests before they reach the model
|
|
49
|
+
- **Feature preprocessing**: Apply the same transformations used in training
|
|
50
|
+
- **Error handling**: Model errors should return 500 with diagnostic info, not crash the service
|
|
51
|
+
- **Logging**: Log every prediction request/response for monitoring and debugging
|
|
52
|
+
- **Health check**: Endpoint that verifies the model is loaded and responsive
|
|
53
|
+
|
|
54
|
+
See [references/serving-patterns.md](references/serving-patterns.md) for implementation templates.
|
|
55
|
+
|
|
56
|
+
### Step 4: Deploy Safely
|
|
57
|
+
|
|
58
|
+
Models should be deployed with the same caution as any production service — more, given their non-deterministic nature:
|
|
59
|
+
|
|
60
|
+
**Shadow mode**: Deploy the new model alongside the current one. Both receive traffic, but only the current model's predictions are used. Compare predictions to evaluate the new model on real data.
|
|
61
|
+
|
|
62
|
+
**Canary deployment**: Route a small percentage of traffic (5-10%) to the new model. Monitor metrics. Gradually increase if performance is acceptable.
|
|
63
|
+
|
|
64
|
+
**A/B testing**: Split traffic between model versions to measure business impact (conversion rate, click-through, etc.), not just ML metrics.
|
|
65
|
+
|
|
66
|
+
**Blue-green**: Deploy new model to a separate environment, switch all traffic at once after validation. Fastest rollback.
|
|
67
|
+
|
|
68
|
+
### Step 5: Monitor in Production
|
|
69
|
+
|
|
70
|
+
After deployment, monitor continuously. See [references/serving-patterns.md](references/serving-patterns.md) for implementation details.
|
|
71
|
+
|
|
72
|
+
**Model performance monitoring:**
|
|
73
|
+
- Track prediction accuracy against ground truth (when available)
|
|
74
|
+
- Monitor prediction distribution (are predictions shifting?)
|
|
75
|
+
- Track business KPIs that the model influences
|
|
76
|
+
|
|
77
|
+
**Data drift detection:**
|
|
78
|
+
- Compare input feature distributions against the training data baseline
|
|
79
|
+
- Use statistical tests: Population Stability Index (PSI), Kolmogorov-Smirnov (KS) test, Jensen-Shannon divergence
|
|
80
|
+
- Alert when drift exceeds thresholds
|
|
81
|
+
|
|
82
|
+
**System monitoring:**
|
|
83
|
+
- Prediction latency (P50, P95, P99)
|
|
84
|
+
- Request throughput and error rates
|
|
85
|
+
- Resource utilization (CPU, memory, GPU)
|
|
86
|
+
- Model loading time
|
|
87
|
+
|
|
88
|
+
**Retraining triggers:**
|
|
89
|
+
- Accuracy drops below threshold
|
|
90
|
+
- Data drift exceeds threshold
|
|
91
|
+
- Scheduled retraining (weekly/monthly depending on domain)
|
|
92
|
+
- New labeled data becomes available
|
|
93
|
+
|
|
94
|
+
### Step 6: Plan Rollback
|
|
95
|
+
|
|
96
|
+
Every model deployment needs a rollback plan:
|
|
97
|
+
- Previous model version tagged and ready in the registry
|
|
98
|
+
- One-command rollback through CI/CD or model registry stage transition
|
|
99
|
+
- Automated rollback on monitoring alert (if confidence is high)
|
|
100
|
+
|
|
101
|
+
## Principles Applied
|
|
102
|
+
|
|
103
|
+
- **KISS**: Start with REST API + batch monitoring. Add real-time drift detection when scale justifies it.
|
|
104
|
+
- **YAGNI**: Don't build an A/B testing framework for your first model. Shadow mode is enough.
|
|
105
|
+
- **Defense in depth**: Validate inputs, monitor outputs, detect drift, and have rollback ready.
|
|
106
|
+
- **Functional Independence**: Serving, monitoring, and retraining should be independent components, not monolithic.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "ml-model-deployment",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "I have a scikit-learn fraud detection model that's performing well in our test environment. I need to deploy it as a real-time API that our payment service calls for every transaction. We process about 1000 transactions per second. What's the best approach?",
|
|
7
|
+
"expected_output": "Should design a serving architecture considering the 1000 TPS requirement, recommend appropriate serving pattern, address preprocessing consistency, and set up monitoring with drift detection.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Considers the 1000 TPS requirement in architecture choice",
|
|
10
|
+
"Addresses feature preprocessing consistency (training-serving skew)",
|
|
11
|
+
"Recommends containerized serving with horizontal scaling",
|
|
12
|
+
"Sets up input validation for the prediction endpoint",
|
|
13
|
+
"Designs drift detection (fraud patterns change over time)",
|
|
14
|
+
"Plans a safe rollout strategy (shadow mode or canary)",
|
|
15
|
+
"Includes latency monitoring (fraud checks must be fast)",
|
|
16
|
+
"Plans for rollback"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": 2,
|
|
21
|
+
"prompt": "Our recommendation model has been in production for 6 months and click-through rates are declining. The data science team says the model metrics look fine on their test set. What's going on and how do we fix it?",
|
|
22
|
+
"expected_output": "Should identify this as likely data drift or concept drift, recommend checking production data distributions against training baseline, and suggest monitoring and retraining infrastructure.",
|
|
23
|
+
"assertions": [
|
|
24
|
+
"Identifies data/concept drift as the likely cause",
|
|
25
|
+
"Explains why test set metrics can look fine while production degrades",
|
|
26
|
+
"Recommends comparing production feature distributions against training baseline",
|
|
27
|
+
"Suggests PSI or KS tests for drift detection",
|
|
28
|
+
"Recommends setting up continuous monitoring to prevent recurrence",
|
|
29
|
+
"Suggests a retraining pipeline with fresh data",
|
|
30
|
+
"Does NOT just say 'retrain the model' without diagnosing the cause"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Serving and Monitoring Patterns
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- FastAPI serving template
|
|
5
|
+
- Drift detection patterns
|
|
6
|
+
- Monitoring dashboard design
|
|
7
|
+
- Retraining pipeline triggers
|
|
8
|
+
|
|
9
|
+
## FastAPI Model Serving Template
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from fastapi import FastAPI, HTTPException
|
|
13
|
+
from pydantic import BaseModel, validator
|
|
14
|
+
import mlflow
|
|
15
|
+
import numpy as np
|
|
16
|
+
import logging
|
|
17
|
+
import time
|
|
18
|
+
|
|
19
|
+
app = FastAPI(title="Model Serving API")
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
# Load model at startup (not per-request)
|
|
23
|
+
model = None
|
|
24
|
+
|
|
25
|
+
@app.on_event("startup")
|
|
26
|
+
async def load_model():
|
|
27
|
+
global model
|
|
28
|
+
model = mlflow.pyfunc.load_model("models:/my-classifier/Production")
|
|
29
|
+
logger.info("Model loaded successfully")
|
|
30
|
+
|
|
31
|
+
class PredictionRequest(BaseModel):
|
|
32
|
+
features: list[float]
|
|
33
|
+
|
|
34
|
+
@validator("features")
|
|
35
|
+
def validate_features(cls, v):
|
|
36
|
+
if len(v) != EXPECTED_FEATURE_COUNT:
|
|
37
|
+
raise ValueError(f"Expected {EXPECTED_FEATURE_COUNT} features, got {len(v)}")
|
|
38
|
+
return v
|
|
39
|
+
|
|
40
|
+
class PredictionResponse(BaseModel):
|
|
41
|
+
prediction: int
|
|
42
|
+
probability: float
|
|
43
|
+
model_version: str
|
|
44
|
+
latency_ms: float
|
|
45
|
+
|
|
46
|
+
@app.post("/predict", response_model=PredictionResponse)
|
|
47
|
+
async def predict(request: PredictionRequest):
|
|
48
|
+
start = time.time()
|
|
49
|
+
try:
|
|
50
|
+
features = np.array(request.features).reshape(1, -1)
|
|
51
|
+
prediction = model.predict(features)
|
|
52
|
+
probability = model.predict_proba(features).max()
|
|
53
|
+
|
|
54
|
+
latency_ms = (time.time() - start) * 1000
|
|
55
|
+
|
|
56
|
+
# Log for monitoring
|
|
57
|
+
logger.info(f"prediction={prediction[0]} prob={probability:.4f} latency={latency_ms:.1f}ms")
|
|
58
|
+
|
|
59
|
+
return PredictionResponse(
|
|
60
|
+
prediction=int(prediction[0]),
|
|
61
|
+
probability=float(probability),
|
|
62
|
+
model_version=model.metadata.run_id,
|
|
63
|
+
latency_ms=latency_ms,
|
|
64
|
+
)
|
|
65
|
+
except Exception as e:
|
|
66
|
+
logger.error(f"Prediction failed: {e}")
|
|
67
|
+
raise HTTPException(status_code=500, detail="Prediction failed")
|
|
68
|
+
|
|
69
|
+
@app.get("/health")
|
|
70
|
+
async def health():
|
|
71
|
+
return {"status": "healthy", "model_loaded": model is not None}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Drift Detection Patterns
|
|
75
|
+
|
|
76
|
+
### Population Stability Index (PSI)
|
|
77
|
+
|
|
78
|
+
PSI measures how much a feature distribution has shifted from a baseline.
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
import numpy as np
|
|
82
|
+
|
|
83
|
+
def calculate_psi(baseline, current, bins=10):
|
|
84
|
+
"""Calculate Population Stability Index between two distributions."""
|
|
85
|
+
# Bin the data
|
|
86
|
+
breakpoints = np.quantile(baseline, np.linspace(0, 1, bins + 1))
|
|
87
|
+
breakpoints[0] = -np.inf
|
|
88
|
+
breakpoints[-1] = np.inf
|
|
89
|
+
|
|
90
|
+
baseline_counts = np.histogram(baseline, bins=breakpoints)[0] / len(baseline)
|
|
91
|
+
current_counts = np.histogram(current, bins=breakpoints)[0] / len(current)
|
|
92
|
+
|
|
93
|
+
# Avoid division by zero
|
|
94
|
+
baseline_counts = np.clip(baseline_counts, 1e-6, None)
|
|
95
|
+
current_counts = np.clip(current_counts, 1e-6, None)
|
|
96
|
+
|
|
97
|
+
psi = np.sum((current_counts - baseline_counts) * np.log(current_counts / baseline_counts))
|
|
98
|
+
return psi
|
|
99
|
+
|
|
100
|
+
# Interpretation:
|
|
101
|
+
# PSI < 0.1: No significant drift
|
|
102
|
+
# PSI 0.1-0.2: Moderate drift — investigate
|
|
103
|
+
# PSI > 0.2: Significant drift — retrain
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Monitoring with Evidently AI
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from evidently.report import Report
|
|
110
|
+
from evidently.metric_preset import DataDriftPreset, TargetDriftPreset
|
|
111
|
+
|
|
112
|
+
# Compare current production data against training baseline
|
|
113
|
+
report = Report(metrics=[
|
|
114
|
+
DataDriftPreset(),
|
|
115
|
+
TargetDriftPreset(),
|
|
116
|
+
])
|
|
117
|
+
|
|
118
|
+
report.run(reference_data=training_df, current_data=production_df)
|
|
119
|
+
report.save_html("drift_report.html")
|
|
120
|
+
|
|
121
|
+
# Programmatic access to results
|
|
122
|
+
results = report.as_dict()
|
|
123
|
+
drift_detected = results["metrics"][0]["result"]["dataset_drift"]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Monitoring Dashboard Design
|
|
127
|
+
|
|
128
|
+
A model monitoring dashboard should show:
|
|
129
|
+
|
|
130
|
+
**Real-time panel:**
|
|
131
|
+
- Prediction throughput (requests/sec)
|
|
132
|
+
- Latency percentiles (P50, P95, P99)
|
|
133
|
+
- Error rate
|
|
134
|
+
- Prediction distribution (histogram updated hourly)
|
|
135
|
+
|
|
136
|
+
**Drift panel (updated daily/hourly):**
|
|
137
|
+
- PSI per feature over time (line chart)
|
|
138
|
+
- Drift alert threshold line
|
|
139
|
+
- Feature importance × drift magnitude (which drifted features matter most?)
|
|
140
|
+
|
|
141
|
+
**Performance panel (updated as ground truth arrives):**
|
|
142
|
+
- Primary metric (accuracy, F1, RMSE) over time
|
|
143
|
+
- Comparison against baseline model
|
|
144
|
+
- Performance by segment (if applicable)
|
|
145
|
+
|
|
146
|
+
**Operational panel:**
|
|
147
|
+
- Model version currently serving
|
|
148
|
+
- Last retrain date
|
|
149
|
+
- Resource utilization (CPU, memory, GPU)
|
|
150
|
+
- Cost per prediction
|
|
151
|
+
|
|
152
|
+
## Retraining Pipeline Triggers
|
|
153
|
+
|
|
154
|
+
| Trigger | When to Use | Implementation |
|
|
155
|
+
|---------|-------------|---------------|
|
|
156
|
+
| **Scheduled** | Stable domains (weekly/monthly) | Cron job or orchestrator schedule |
|
|
157
|
+
| **Performance-based** | When ground truth is available | Monitor metric, trigger when below threshold |
|
|
158
|
+
| **Drift-based** | When data changes are detectable | Monitor PSI/KS, trigger when above threshold |
|
|
159
|
+
| **Data-volume** | When new labeled data accumulates | Count new labels, trigger at threshold |
|
|
160
|
+
| **Manual** | Regulatory or business-driven | Human approval in model registry |
|
|
161
|
+
|
|
162
|
+
Start with scheduled + drift-based triggers. Add performance-based when ground truth labeling is established.
|