关于 ml-ops-engineer
面向 MLOps 工程师的技能,涵盖模型部署、训练流水线、模型注册、漂移监控、特征存储和 ML CI/CD。附带脚本可管理模型版本、检测数据漂移并验证流水线定义。
主要功能
- 01规划和扩展训练流水线
- 02配置实时或批量模型部署
- 03管理模型注册与版本阶段
- 04检测数据漂移并配置监控告警
- 05定义特征存储和实验跟踪模式
- 06验证流水线结构与部署门槛
适用场景
- 01设计模型从训练到部署的流程
- 02比较并晋升模型版本
- 03对比参考数据与生产数据以检测漂移
- 04部署前检查 ML 流水线定义
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ borghei/ claude-skills --skill ml-ops-engineer安装后在 Claude Code 中输入/ml-ops-engineer确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
REFERENCE.mdscripts/drift_detector.pymodel_registry.pypipeline_validator.py详细介绍
MLOps 工程师
该 Agent 以资深 MLOps 工程师的身份工作,负责将模型部署到生产环境、编排训练流水线、监控模型健康状况、管理特征存储,并自动化 ML CI/CD。
先澄清
部署前,请先确认以下输入。若有信息缺失或含糊不清,且会影响结果,请先询问;若不会影响结果,则采用合理的默认值,并说明所用默认值。
- 服务模式 + 延迟 SLA: 实时服务(FastAPI/K8s)或批处理,以及 P99 目标(决定整个部署架构)。
- 当前 MLOps 成熟度: 手动、流水线、CI/CD 或完整 MLOps(用于确定应优先弥补的高影响差距)。
- 模型制品 + 注册表/基础设施: 框架、存储位置和目标平台(MLflow、K8s)(决定服务和注册表配置)。
- 监控阈值: 漂移和准确率下降的限值,以及检查频率(决定告警规则和漂移检测)。
针对当前请求,询问最重要的两到三项输入,而不是把整份清单都问一遍。如果用户希望直接获得结果,请直接提供,并在开头说明所作假设。
工作流
- 评估 ML 成熟度 -- 判断当前级别(手动 Notebook、自动化流水线或完整 CI/CD)。确定应优先弥补的高影响差距。
- 构建或扩展训练流水线 -- 定义获取数据、验证、预处理、训练和评估阶段。使用 Kubeflow、Airflow 或同类工具。设置准确率阈值作为部署门槛(例如,> 0.85)。
- 部署模型以提供服务 -- 根据延迟要求选择实时服务(FastAPI + K8s)或批处理(Spark/Parquet)。配置健康检查、自动扩缩容和资源限制。
- 在模型注册表中注册 -- 在 MLflow 中记录参数、指标和制品。将胜出的版本切换到 Production 阶段;归档之前的版本。
- 添加监控 -- 设置延迟(P50/P95/P99)、错误率、预测分布和特征漂移仪表板。配置告警阈值。
- 端到端验证 -- 对服务端点运行冒烟测试。确认监控仪表板有数据。验证回滚流程是否有效。
MLOps 成熟度模型
| 级别 | 能力 | 关键信号 |
|---|---|---|
| 0 - 手动 | Jupyter Notebook、手动部署 | 模型未进行版本控制 |
| 1 - 流水线 | 自动化训练、模型版本化 | 正在使用 MLflow 跟踪 |
| 2 - CI/CD | 持续训练、自动化测试 | 特征存储已投入运行 |
| 3 - 完整 MLOps | 基于漂移自动重新训练、A/B 测试 | 由 SLA 支持的监控 |
实时服务示例
# model_server.py -- FastAPI model serving
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import mlflow.pyfunc, time
app = FastAPI()
model = mlflow.pyfunc.load_model("models:/fraud_detector/Production")
class PredictionRequest(BaseModel):
features: list[float]
class PredictionResponse(BaseModel):
prediction: float
model_version: str
latency_ms: float
@app.post("/predict", response_model=PredictionResponse)
async def predict(req: PredictionRequest):
start = time.time()
try:
pred = model.predict([req.features])[0]
return PredictionResponse(
prediction=pred,
model_version=model.metadata.run_id,
latency_ms=(time.time() - start) * 1000,
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
async def health():
return {"status": "healthy", "model_loaded": model is not None}
Kubernetes 部署
# k8s/model-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: model-server
spec:
replicas: 3
selector:
matchLabels: {app: model-server}
template:
metadata:
labels: {app: model-server}
spec:
containers:
- name: model-server
image: gcr.io/project/model-server:v1.2.3
ports: [{containerPort: 8080}]
resources:
requests: {memory: "2Gi", cpu: "1000m"}
limits: {memory: "4Gi", cpu: "2000m", nvidia.com/gpu: 1}
env:
- {name: MODEL_URI, value: "s3://models/production/v1.2.3"}
readinessProbe:
httpGet: {path: /health, port: 8080}
initialDelaySeconds: 30
periodSeconds: 10
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: model-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: model-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target: {type: Utilization, averageUtilization: 70}
漂移检测
# monitoring/drift_detector.py
import numpy as np
from scipy import stats
from dataclasses import dataclass
@dataclass
class DriftResult:
feature: str
drift_score: float
is_drifted: bool
p_value: float
def detect_drift(reference: np.ndarray, current: np.ndarray, threshold: float = 0.05) -> DriftResult:
"""Detect distribution drift using Kolmogorov-Smirnov test."""
statistic, p_value = stats.ks_2samp(reference, current)
return DriftResult(feature="", drift_score=statistic, is_drifted=p_value < threshold, p_value=p_value)
def monitor_all_features(reference: dict, current: dict, threshold: float = 0.05) -> list[DriftResult]:
"""Run drift detection across all features; return list of results."""
results = []
for feat in reference:
r = detect_drift(reference[feat], current[feat], threshold)
r.feature = feat
results.append(r)
return results
告警规则
ALERT_RULES = {
"latency_p99": {"threshold": 200, "severity": "warning", "msg": "P99 latency exceeded 200 ms"},
"error_rate": {"threshold": 0.01, "severity": "critical", "msg": "Error rate exceeded 1%"},
"accuracy_drop": {"threshold": 0.05, "severity": "critical", "msg": "Accuracy dropped > 5%"},
"drift_score": {"threshold": 0.15, "severity": "warning", "msg": "Feature drift detected"},
}
特征存储(Feast)
# features/customer_features.py
from feast import Entity, Feature, FeatureView, FileSource, ValueType
from datetime import timedelta
customer = Entity(name="customer_id", value_type=ValueType.INT64)
customer_stats = FeatureView(
name="customer_stats",
entities=["customer_id"],
ttl=timedelta(days=1),
features=[
Feature(name="total_purchases", dtype=ValueType.FLOAT),
Feature(name="avg_order_value", dtype=ValueType.FLOAT),
Feature(name="days_since_last_order", dtype=ValueType.INT32),
Feature(name="lifetime_value", dtype=ValueType.FLOAT),
],
online=True,
source=FileSource(
path="gs://features/customer_stats.parquet",
timestamp_field="event_timestamp",
),
)
服务期间的在线检索:
from feast import FeatureStore
store = FeatureStore(repo_path=".")
features = store.get_online_features(
features=["customer_stats:total_purchases", "customer_stats:avg_order_value"],
entity_rows=[{"customer_id": 1234}],
).to_dict()
实验跟踪(MLflow)
import mlflow
mlflow.set_tracking_uri("http://mlflow.company.com")
mlflow.set_experiment("fraud_detection")
with mlflow.start_run(run_name="xgboost_v2"):
mlflow.log_params({"n_estimators": 100, "max_depth": 6, "learning_rate": 0.1})
model = train_model(X_train, y_train)
mlflow.log_metrics({
"accuracy": accuracy_score(y_test, preds),
"f1": f1_score(y_test, preds),
})
mlflow.sklearn.log_model(model, "model", registered_model_name="fraud_detector")
如需扩展流水线示例(Kubeflow、Airflow DAG、完整 CI/CD 工作流),请参阅 REFERENCE.md。
参考资料
REFERENCE.md-- 扩展模式:Kubeflow 流水线、Airflow DAG、CI/CD 工作流、模型注册表操作
脚本
python scripts/model_registry.py register --name fraud_detector --version v2.3 --metrics '{"f1":0.91,"auc":0.95}' --params '{"n_estimators":200}'
python scripts/model_registry.py promote --name fraud_detector --version v2.3 --stage production
python scripts/model_registry.py list --stage production --json
python scripts/model_registry.py compare --name fraud_detector --versions v2.2 v2.3
python scripts/drift_detector.py --reference train_data.csv --current prod_data.csv
python scripts/drift_detector.py --reference baseline.csv --current latest.csv --threshold 0.1 --json
python scripts/pipeline_validator.py --pipeline pipeline.json --strict
python scripts/pipeline_validator.py --pipeline pipeline.json --json
工具参考
| 工具 | 用途 | 主要标志 |
|---|---|---|
model_registry.py | 使用指标、参数和生命周期阶段注册、晋级、列出并比较模型版本 | register --name --version --metrics --params、promote --stage、list、compare --versions、--json |
drift_detector.py | 使用 KS 统计量、PSI 和卡方检验检测参考数据集与当前数据集之间的数据/模型漂移 | --reference <csv>、--current <csv>、--columns、--threshold、--json |
pipeline_validator.py | 验证 ML 流水线定义的完整性、阶段顺序、评估门槛和回滚配置 | --pipeline <json>、--strict、--json |
故障排查
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 模型延迟超过 P99 SLA(> 200 ms) | 模型过大、输入预处理缓慢,或 Pod 资源不足 | 对服务端点进行性能分析;考虑模型蒸馏、输入缓存,或增加 CPU/内存限制 |
drift_detector.py 将所有特征都标记为漂移 | 阈值过低,或参考数据的时间段与预期不同 | 提高阈值(尝试 0.15-0.2),或使用更具代表性的时间窗口重新生成参考数据集 |
| 流水线未通过评估门禁 | 模型准确率低于配置的阈值 | 检查上游的数据质量问题;使用 drift_detector.py 比较特征分布;使用新数据重新训练 |
| 模型注册表显示“已注册”错误 | 完全相同的名称 + 版本组合之前已注册 | 使用新的版本字符串(例如 v2.3.1),或在旧条目是测试条目时将其删除 |
| Kubernetes Pod 在模型服务中反复崩溃重启 | 模型大小超过内存限制导致 OOM 终止,或健康检查超时时间过短 | 增加 resources.limits.memory;对于大型模型,延长就绪探针的 initialDelaySeconds |
| 特征存储返回过时特征 | 物化任务失败,或运行时间超出 TTL 窗口 | 检查物化日志;重新运行 materialize_features;考虑缩短 TTL 或添加新鲜度告警 |
pipeline_validator.py 报告 STAGE_ORDER 错误 | 流水线阶段的定义顺序不符合预期(data -> transform -> train -> evaluate -> deploy) | 重新排序阶段,使其遵循标准顺序;验证器要求数据阶段位于训练阶段之前 |
成功标准
- 所有生产模型在接收流量前,均已在模型注册表中注册版本、指标和参数。
- 按计划定期运行漂移检测(至少每周一次),并在 PSI > 0.2 或 KS > 0.15 时发出告警。
- ML 流水线在部署前通过
pipeline_validator.py --strict验证,且无任何错误。 - 模型服务延迟保持在 SLA 范围内:P50 < 50 ms、P95 < 100 ms、P99 < 200 ms。
- 每次将模型晋升到生产环境时,都会自动归档之前的生产版本。
- 回滚到之前的模型版本在 5 分钟内完成,且零停机。
- 流水线阶段包含评估门禁,当准确率低于定义的阈值时阻止部署。
范围与限制
范围内: 模型部署(实时和批处理)、ML 流水线编排、模型注册表管理、漂移检测(数据漂移、概念漂移、预测漂移)、特征存储模式、监控与告警、Kubernetes 部署配置,以及 ML 的 CI/CD。
范围外: 模型架构设计和算法选择(参见 data-scientist)、原始数据摄取流水线、BI 仪表板开发,以及业务战略。
限制: Python 工具仅使用 Python 标准库。drift_detector.py 使用近似方法计算 KS 统计量和 PSI,适用于大多数分布,但不支持多变量漂移检测,也不支持 Evidently/Alibi Detect 集成。model_registry.py 将状态存储在本地 JSON 文件中——用于生产环境时,请集成 MLflow Model Registry 或类似平台。pipeline_validator.py 会验证结构和约定,但不会执行流水线阶段。
集成点
- 数据科学家(
data-analytics/data-scientist):接收带有实验元数据的训练模型;将效果最佳的实验晋升至注册表以进行部署。 - 分析工程师(
data-analytics/analytics-engineer):特征工程管道可能依赖 dbt 集市模型;架构变更会触发管道重新验证。 - 工程团队(
engineering/senior-ml-engineer):协作优化模型架构,以满足服务约束(延迟、内存、GPU)。 - 基础设施(
engineering/):Kubernetes 配置、自动扩缩策略和 CI/CD 工作流由平台工程团队共同管理。 - 商业智能(
data-analytics/business-intelligence):模型预测可能会提供给 BI 仪表板;监控指标会显示在运营仪表板中。