KDnuggets

5 Agentic Workflows to Automate Your Data Science Pipeline

8.5内容质量

TL;DR · AI 摘要

自动化数据科学流程的5种代理工作流可节省45%时间,Databricks已集成相关功能,核心依赖ReAct循环与LLM工具。

核心要点

  • 数据科学家45%时间消耗在数据清洗,代理可自动化处理
  • ReAct循环结合LLM实现自动化EDA,生成结构化Markdown报告
  • Databricks Agent框架已实现从问题到洞察的时效压缩

结构提纲

按章节快速跳转。

  1. 揭示数据科学家45%时间消耗在数据准备,代理工作流可自动化处理重复性任务。

  2. 要求Python 3.10+及pandas/scikit-learn/LLM API基础环境。

  3. 通过ReAct循环实现数据集分析、问题标记与Markdown报告生成。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • 自动化数据科学工作流
    • 核心方法
      • ReAct循环
      • LLM工具集成
    • 应用场景
      • EDA自动化
      • 模型监控
    • 实施工具
      • Databricks
      • OpenAI API

金句 / Highlights

值得收藏与分享的关键句。

#AI#数据科学#自动化#MLOps#Python
打开原文

5 种智能代理工作流程,自动化你的数据科学流水线 - KDnuggets

publ: 2026年6月26日

  • 博客热门文章
  • 主题 人工智能 职业建议 计算机视觉 数据工程 数据科学 语言模型 机器学习 MLOps 自然语言处理 编程 Python SQL
  • 数据集
  • 活动
  • 资源 快速参考指南 推荐 技术简报
  • 广告

订阅电子报

#header end

/ad_wrapper

5 种智能代理工作流程,自动化你的数据科学流水线

本文介绍五种具体的应用场景,每种对应数据科学流水线的一个主要阶段。

作者:

Shittu Olumide

,技术内容专家,2026年6月26日发布于

人工智能

<div class="addthis_native_toolbox"></div>

# 引言

普通数据科学家约45%的工作时间都花在数据准备和清洗上,而不是建模、不是洞察生成、不是需要真正判断的工作上。这个估计在行业调查中反复出现,因为它一直成立。消耗这些时间的任务——列特征分析、空值标记、重复运行探索性数据分析(EDA)脚本、网格搜索超参数、编写相同的监控检查——都足够公式化,可以遵循明确的规则。

这正是它们可以通过智能代理实现自动化的关键。智能代理工作流程不会取代数据科学家,而是吸收这些流程性工作,让你专注于评估性工作:判断模型是否有意义、特征是否真正具有信息量、发现是否值得推动业务决策。Databricks等平台已经将智能数据科学功能集成到核心基础设施中,其代理框架明确设计用于"缩短从问题到洞察的时间"。这是生产数据团队正在发展的方向。

本文介绍五种具体的应用场景,每种对应数据科学流水线的一个主要阶段。每个场景都包含实际案例、经过验证的代码模式,以及生产环境中重要的设计决策。

# 先决条件

所有五个工作流程均假设使用 Python 3.10+ 且熟悉 pandas、scikit-learn 和基础大语言模型(LLM)API 使用方法。每个工作流程下会列出具体的包依赖。对于工具调用模式,你需要 OpenAI API 密钥,或者本地服务端点(OllamavLLM)并暴露 OpenAI 兼容 API。

code
# 所有工作流程中使用的核心包
pip install openai pandas numpy scipy scikit-learn lightgbm shap pydantic

# 工作流程 1:自动化探索性数据分析代理

替代方案:手动加载数据、计算汇总统计、可视化分布、检查空值、检测异常值、撰写分析结果。每个数据集每次都要运行相同脚本,只是列名不同。

代理的处理方式:加载数据集、运行完整分析、按严重程度标记问题,并生成结构化 Markdown 报告。人类审核发现后决定如何处理。代理负责完成审核前的所有工作。

#### // 架构

代理使用一个推理与行动(ReAct)循环,包含两个工具:profile_dataset 按列生成汇总统计信息,flag_issues 按严重程度分类问题。代理随后通过单次语言模型调用,将两个输出综合为结构化报告。关键设计决策在于代理如何处理 flag_issues 的输出;它会在报告前推理哪些问题是可操作的,因此输出是优先级列表,而非原始数据转储。

#### // Code Pattern

code
# eda_agent.py
# 先决条件: pip install openai pandas scipy
# 运行方式: python eda_agent.py

import json
import pandas as pd
from scipy import stats
from openai import OpenAI
from dataclasses import dataclass

client = OpenAI()  # 使用 OPENAI_API_KEY 环境变量

@dataclass
class ColumnIssue:
    column: str
    issue_type: str   # null_rate | skewness | dtype | high_correlation
    severity: str     # low | medium | high
    detail: str

def profile_dataset(df: pd.DataFrame) -> dict:
    """
    生成每列的统计信息。
    在生产环境中,建议使用 ydata-profiling 替代以获得更丰富的输出。
    """
    profile = {}
    for col in df.columns:
        col_stats = {
            "dtype":     str(df[col].dtype),
            "null_rate": df[col].isnull().mean(),
            "n_unique":  df[col].nunique(),
        }
        if pd.api.types.is_numeric_dtype(df[col]):
            col_stats["skewness"] = float(df[col].skew())
            col_stats["mean"]     = float(df[col].mean())
            col_stats["std"]      = float(df[col].std())
        elif df[col].dtype == "object":
            non_null = df[col].dropna()
            numeric_coerced = pd.to_numeric(non_null, errors="coerce")
            col_stats["looks_numeric"] = bool(len(non_null) > 0 and numeric_coerced.notna().mean() > 0.9)
        profile[col] = col_stats
    return profile

def flag_issues(profile: dict) -> list[ColumnIssue]:
    """
    从列统计信息中标记数据质量问题。
    严重程度分级: high = 需要立即处理, medium = 建议检查。
    """
    issues = []
    for col, stats_dict in profile.items():
        null_rate = stats_dict.get("null_rate", 0.0)
        if null_rate > 0.15:
            issues.append(ColumnIssue(col, "null_rate", "high",
                                      f"{null_rate:.0%} of values are missing"))
        elif null_rate > 0.05:
            issues.append(ColumnIssue(col, "null_rate", "medium",
                                      f"{null_rate:.0%} of values are missing"))

        skewness = abs(stats_dict.get("skewness", 0.0))
        if skewness > 5.0:
            issues.append(ColumnIssue(col, "skewness", "high",
                                      f"极端偏度={skewness:.1f} -- 建议使用对数变换"))
        elif skewness > 2.0:
            issues.append(ColumnIssue(col, "skewness", "medium",
                                      f"中等偏度={skewness:.1f}"))

        # 类型为object但实际存储数值的列可能是编码错误
        if stats_dict["dtype"] == "object" and stats_dict.get("looks_numeric", False):
            issues.append(ColumnIssue(col, "dtype", "medium",
                                      "数值以字符串形式存储"))

    return issues

def run_eda_agent(df: pd.DataFrame, dataset_description: str) -> str:
    """
    运行EDA代理循环。
    代理决定调用哪些工具及调用顺序,
    然后生成总结发现的结构化报告。
    """
    profile = profile_dataset(df)
    issues  = flag_issues(profile)

    # 为代理格式化问题列表
    issues_text = "\n".join(
        f"- [{i.severity.upper()}] {i.column}: {i.issue_type} -- {i.detail}"
        for i in issues
    ) or "未检测到问题。"

    prompt = f"""你是一位资深数据科学家,正在为数据科学项目审查数据集。

数据集:{dataset_description}

 /think
python
列概要(摘要统计信息):
{json.dumps(profile, indent=2)}

检测到的问题:
{issues_text}

生成结构化EDA报告,包含以下部分:
1. 数据集概览 -- 形状、数据类型、整体质量评估(1-2句话)
2. 高优先级问题 -- 建模前需要处理的事项
3. 中优先级问题 -- 值得持续监控的事项
4. 建议后续步骤 -- 3-5个具体行动的有序列表

请直接输出。优先考虑可操作性而非完整性。"""

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.2,   # 低温度值确保结构化输出一致性
    )
    return response.choices[0].message.content

# ── 运行示例 ──────────────────────────────────────────────────────────────────
if __name__ == "__main__":
    # 示例:零售交易数据
    import numpy as np
    np.random.seed(42)
    n = 5000
    df = pd.DataFrame({
        "revenue":       np.random.exponential(scale=200, size=n),     # 右偏分布
        "customer_age":  np.random.normal(40, 12, n),
        "created_at":    pd.date_range("2024-01-01", periods=n, freq="h").astype(str),
        "region_code":   np.random.choice(["US", "EU", "APAC", None], size=n, p=[0.5, 0.3, 0.1, 0.1]),
        "session_count": np.where(np.random.rand(n) < 0.2, None, np.random.randint(1, 50, n)),
    })
    report = run_eda_agent(df, "包含客户人口统计信息的零售交易数据")
    print(report)

如何运行:

code
export OPENAI_API_KEY=your_key
python eda_agent.py

真实场景:零售交易数据,5000行,8列。该代理将收入标记为高优先级(偏度高达7.3),将会话次数标记为高优先级(22%空值率),将创建时间标记为中优先级(日期以字符串形式存储)。它建议对收入进行对数变换,为会话次数创建空值指示特征,并解析创建时间以提取小时和星期几特征。所有分析在30秒内完成。人工审核报告并执行建议操作,无需手动运行诊断。

# 工作流2:代理驱动的特征工程与选择

替代方案:手动构思交互特征,编写转换代码,用基线模型评估每个候选特征,剔除无效特征,记录保留特征及其原因。

代理的处理方式:基于数据概况和领域上下文提出候选特征,生成转换代码,用快速基线模型评估每个候选特征,并根据可配置的重要性阈值剔除低效特征,每个决策附带书面说明。

两个阶段,一个代理。生成阶段利用LLM根据数据集和预测任务的结构化描述提出候选特征。选择阶段通过5折交叉验证(CV)训练LightGBM分类器,使用SHapley Additive exPlanations(SHAP)计算特征重要性。低于阈值的特征将被剔除。代理在剔除前会分析重要性评分,能识别那些全局表现较弱但对特定细分群体有信号的特征。

code
# feature_agent.py
# 先决条件: pip install openai lightgbm shap scikit-learn pandas numpy
# 运行方式: python feature_agent.py

import json
import numpy as np
import pandas as pd
from openai import OpenAI
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import LabelEncoder
import lightgbm as lgb

client = OpenAI()

def generate_feature_candidates(
    column_descriptions: dict[str, str],
    target: str,
    task_type: str = "classification",
    n_candidates: int = 10,
) -> list[dict]:
    """
    根据列描述和预测任务,让LLM提出候选特征。
    返回包含'name'、'formula'和'rationale'的字典列表。
    """
    prompt = f"""你是一名资深的机器学习工程师,正在为{task_type}任务进行特征工程。

目标变量: {target}

可用列:
{json.dumps(column_descriptions, indent=2)}

提出{n_candidates}个可能提高模型性能的候选工程特征。
每个特征需要提供:
- name: 使用snake_case的特征名称
- formula: 如何从可用列计算该特征(pandas表达式)
- rationale: 一句说明该特征可能起作用的原因

返回一个JSON对象,包含一个"features"键,其值为包含对象的数组,
每个对象包含name、formula、rationale键。
只返回有效的JSON,不要在JSON之外添加任何解释。"""

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        response_format={"type": "json_object"},
        temperature=0.4,
    )
    result = json.loads(response.choices[0].message.content)
    return result.get("features", result.get("candidates", []))

def evaluate_and_prune(
    df: pd.DataFrame,
    candidate_features: list[dict],
    target_col: str,
    importance_threshold: float = 0.01,
) -> tuple[list[str], list[str], dict[str, float]]:
    """
    将候选特征添加到数据框,训练快速LightGBM基线模型,
    提取特征重要性并剪枝低于阈值的特征。

    返回(保留的特征, 剪枝的特征, 重要性分数)
    """
    feature_df = df.copy()
    added = []

    for candidate in candidate_features:
        try:
            # 评估公式字符串 -- 生产环境应使用安全的eval沙箱
            feature_df[candidate["name"]] = feature_df.eval(candidate["formula"])
            added.append(candidate["name"])
        except Exception as e:
            # 公式计算失败 -- 跳过该候选特征
            print(f"  跳过 '{candidate['name']}': {e}")

    if not added:
        return [], [], {}

    X = feature_df[added].fillna(0)
    y = df[target_col]

    model = lgb.LGBMClassifier(n_estimators=100, random_state=42, verbose=-1)
    model.fit(X, y)

    importance_scores = dict(zip(added, model.feature_importances_ / model.feature_importances_.sum()))

    kept   = [f for f in added if importance_scores.get(f, 0) >= importance_threshold]
    pruned = [f for f in added if importance_scores.get(f, 0) < importance_threshold]

    return kept, pruned, importance_scores

def explain_selection(
    kept: list[str],
    pruned: list[str],
    scores: dict[str, float],
) -> str:
    """让代理用自然语言解释其选择决策。"""
    prompt = f"""你正在审查机器学习流水线的特征选择结果。

 /think
python
def explain_selection(kept, pruned, scores):
    prompt = f"""Features KEPT (above importance threshold):
{json.dumps({f: round(scores.get(f, 0), 4) for f in kept}, indent=2)}

Features PRUNED (below threshold):
{json.dumps({f: round(scores.get(f, 0), 4) for f in pruned}, indent=2)}

撰写一个3-5句的摘要,总结选择结果。
注意任何令人意外的剪枝或重要性异常高的特征。
基于保留的特征,建议一个值得进一步测试的额外特征。"""

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.3,
    )
    return response.choices[0].message.content

if __name__ == "__main__":
    column_descriptions = {
        "days_since_login":    "客户上次登录以来的天数",
        "plan_tier":           "订阅层级:basic、pro 或 enterprise",
        "support_tickets_90d": "过去90天内提交的支持工单数量",
        "monthly_spend":       "客户平均月消费金额(美元)",
    }

    candidates = generate_feature_candidates(
        column_descriptions, target="churned", task_type="classification", n_candidates=10
    )

    # 生产环境中此处应加载真实客户数据
    np.random.seed(42)
    n = 3000
    df = pd.DataFrame({
        "days_since_login":    np.random.randint(0, 90, n),
        "plan_tier":           np.random.choice(["basic", "pro", "enterprise"], n),
        "support_tickets_90d": np.random.poisson(1.5, n),
        "monthly_spend":       np.random.exponential(80, n),
        "churned":             np.random.binomial(1, 0.15, n),
    })

    kept, pruned, scores = evaluate_and_prune(df, candidates, target_col="churned")
    summary = explain_selection(kept, pruned, scores)
    print(summary)
code
python feature_agent.py

真实场景 客户流失预测,包含12个输入列,如days_since_login(自登录天数)、plan_tier(计划层级)、support_tickets_90d(90天内支持工单数)和monthly_spend(月支出)。代理提出了15个候选特征,包括spend_per_day(日均支出)、tickets_per_spend_ratio(工单/支出比值)和login_recency_x_plan(登录近期性与计划层级的交互项)。经过评估后,有9个特征通过了重要性阈值。解释指出tickets_per_spend_ratio具有最高重要性得分(0.18):"支出较高且同时提出支持工单的客户,具有特别高的流失风险",这一发现值得与产品团队分享。

# 工作流3:智能代理超参数优化

替代方案:网格搜索(穷举但低效)、随机搜索(高效但盲目)和手动贝叶斯优化设置(强大但需要大量模板代码)。所有这些方法都将超参数调优视为搜索问题。而代理将其视为推理问题。

代理的处理方式:提出超参数配置方案,通过训练模型进行评估,分析迭代过程中的指标趋势,识别推动性能提升的关键参数,并据此自主调整搜索方向。与传统方法相比,代理能在远少于网格搜索或随机搜索的迭代次数内收敛到优质配置。

单一代理,单一工具:train_and_evaluate。该工具接收经过Pydantic验证的超参数配置,使用5折交叉验证训练模型,返回曲线下面积(AUC)、训练耗时以及训练/验证过拟合差距。代理在每一步都能获取完整的试验历史记录,并据此推理下一步尝试方向。当最近三次AUC得分差异小于0.005时判定收敛。这种模式直接借鉴了已发表的智能代理超参数调优研究,该研究表明在中等规模分类任务中,LLM引导的搜索比贝叶斯优化在更少迭代次数内实现了5%-12%的性能提升。

code

hp_agent.py

前提条件:pip install openai scikit-learn pydantic pandas

运行方式:python hp_agent.py

import json from dataclasses import dataclass, field from pydantic import BaseModel, Field, field_validator from openai import OpenAI from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score from sklearn.metrics import roc_auc_score from sklearn.datasets import make_classification import numpy as np

client = OpenAI()

── 用于结构化工具输入的Pydantic模式 ─────────────────────────────

模型必须返回有效的超参数 -- Pydantic在训练任务开始前会捕获无效值

从而避免在不良配置上浪费计算资源。

class HyperparamConfig(BaseModel): n_estimators: int = Field(..., ge=10, le=1000, description="树的数量") max_depth: int = Field(..., ge=1, le=50, description="最大树深度") min_samples_split: int = Field(..., ge=2, le=50, description="分割所需的最小样本数") max_features: float = Field(..., gt=0, le=1.0, description="每次分割的特征比例")

@dataclass class TrialResult: iteration: int config: dict val_auc: float train_auc: float train_time_s: float

@property def overfit_gap(self) -> float: return round(self.train_auc - self.val_auc, 4)

def train_and_evaluate(config: dict, X, y) -> TrialResult: """ 使用给定配置训练随机森林并返回交叉验证指标。 这是代理在每次迭代中调用的工具。 """ import time params = HyperparamConfig(**config) # 在训练前验证参数 clf = RandomForestClassifier( n_estimators=params.n_estimators, max_depth=params.max_depth, min_samples_split=params.min_samples_split, max_features=params.max_features, random_state=42, n_jobs=-1, ) t0 = time.time() val_scores = cross_val_score(clf, X, y, cv=5, scoring="roc_auc") clf.fit(X, y) train_auc = roc_auc_score(y, clf.predict_proba(X)[:, 1]) return TrialResult( iteration=0, config=config, val_auc=round(float(val_scores.mean()), 4), train_auc=round(float(train_auc), 4), train_time_s=round(time.time() - t0, 2), )

def detect_convergence(results: list[TrialResult], window: int = 3, tol: float = 0.005) -> bool: """当最后 window 个AUC分数的范围小于 tol 时停止。""" if len(results) < window: return False recent = [r.val_auc for r in results[-window:]] return (max(recent) - min(recent)) < tol

def propose_next_config(trial_history: list[TrialResult]) -> dict: """ 要求代理根据完整的试验历史提出下一个超参数配置, 并进行推理。 """ history_text = "\n".join( f"Trial {r.iteration}: config={r.config}, val_AUC={r.val_auc}, " f"overfit_gap={r.overfit_gap}, time={r.train_time_s}s" for r in trial_history ) prompt = f"""你正在优化一个随机森林分类器。你的目标是最大化val_AUC。

试验历史记录: {history_text}

参数范围:

  • n_estimators: 10-1000
  • max_depth: 1-50
  • min_samples_split: 2-50
  • max_features: 0.1-1.0

分析趋势。识别哪些参数似乎最有影响力。

code

def propose_next_config(results): """ 提出下一个要尝试的配置,并用一句话解释你的理由。

返回一个包含以下键的JSON对象:n_estimators, max_depth, min_samples_split, max_features, reasoning """ prompt = f"""基于以下历史试验结果,提出下一个要尝试的配置: {results}

请用一句话解释你的理由。

返回一个包含以下键的JSON对象:n_estimators, max_depth, min_samples_split, max_features, reasoning"""

response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"}, temperature=0.3, ) result = json.loads(response.choices[0].message.content) print(f" 代理推理: {result.get('reasoning', '')}") return {k: v for k, v in result.items() if k != "reasoning"}

def run_hp_agent(X, y, max_iterations: int = 15) -> TrialResult: """ 运行代理式超参数优化循环。 从合理的默认值开始,然后让代理引导搜索过程。 """

合理的初始配置 -- 不要从随机开始

initial_config = {"n_estimators": 100, "max_depth": 10, "min_samples_split": 5, "max_features": 0.5} results = []

for i in range(max_iterations): config = initial_config if i == 0 else propose_next_config(results) try: result = train_and_evaluate(config, X, y) except Exception as e: print(f" 第 {i+1} 次试验失败: {e} -- 跳过") continue

result.iteration = i + 1 results.append(result) best = max(results, key=lambda r: r.val_auc) print(f"试验 {i+1:02d}: AUC={result.val_auc:.4f} (最佳={best.val_auc:.4f})")

if detect_convergence(results, window=3, tol=0.005): print(f"经过 {i+1} 次迭代后收敛。") break

return max(results, key=lambda r: r.val_auc)

if __name__ == "__main__": X, y = make_classification(n_samples=5000, n_features=20, n_informative=10, random_state=42) best = run_hp_agent(X, y, max_iterations=15) print(f"\n最佳配置: {best.config}") print(f"最佳验证AUC: {best.val_auc}")

code

python hp_agent.py

code

实际场景

人口普查收入分类数据集(UCI,48,842行)。默认随机森林AUC:0.87。经过15次代理指导的迭代后,代理收敛到max_depth=12、n_estimators=350、min_samples_split=8、max_features=0.4,实现AUC 0.91。在第7次迭代时,代理的推理日志显示:"max_depth似乎是主要驱动因素,将其从8增加到12使AUC提升了0.019,而n_estimators超过200后收益递减。" 这种推理过程在输出中可追溯,而不是隐藏在黑盒优化器中。

## # 工作流程4:自动化模型监控与漂移检测代理

替代方案:手动按计划检查特征分布,为每列编写阈值规则,维护会过时的仪表板警报,并在业务指标显示模型退化后才发现问题。

代理的解决方案:按计划运行于新批次数据,使用人口稳定性指数(PSI)和科莫洛夫-斯米尔诺夫(KS)检验计算每个特征的漂移统计量,分类漂移严重程度,并根据严重程度采取不同响应:轻度漂移触发警报,重度漂移触发重新训练流水线调用。

基于单一工具compute_drift_stats构建的定时代理,该工具为每列计算PSI和KS检验并按严重程度分类结果。单个语言模型调用决定响应方式:通过检查仅记录日志,轻度漂移为数据科学团队起草警报,重度漂移则生成警报并触发重新训练有向无环图(DAG),通过Slack或Airflow表示性状态转移(REST)API发送。关键设计决策是分支响应本身;代理处理路由,而不是硬编码的if/else层级。

PSI解释:低于0.1表示稳定,0.1-0.25为值得监控的轻度漂移,高于0.25为应触发重新训练的显著漂移。PSI是生产机器学习系统中衡量人口迁移的标准指标,在LLM出现前的数十年间已广泛用于金融风险建模。

drift_agent.py

先决条件: pip install openai pandas scipy numpy

运行: python drift_agent.py

import json import math import numpy as np import pandas as pd from dataclasses import dataclass from openai import OpenAI

client = OpenAI()

@dataclass class FeatureDrift: feature: str psi: float ks_stat: float ks_pvalue: float severity: str # stable | mild_drift | severe_drift

def compute_psi(baseline: np.ndarray, current: np.ndarray, buckets: int = 10) -> float: """ 基准分布与当前分布之间的人口稳定性指数(PSI)。 PSI = sum((current_% - baseline_%) * ln(current_% / baseline_%))

评估标准: <0.1 稳定 | 0.1-0.25 轻度漂移 | >0.25 严重漂移 """ min_val = min(baseline.min(), current.min()) max_val = max(baseline.max(), current.max()) bucket_width = (max_val - min_val) / buckets

def bucket_freqs(data: np.ndarray) -> list[float]: counts = np.zeros(buckets) for v in data: idx = min(int((v - min_val) / bucket_width), buckets - 1) counts[idx] += 1 freqs = counts / len(data) return [max(f, 1e-6) for f in freqs] # 避免对数运算中的零值

b_freq = bucket_freqs(baseline) c_freq = bucket_freqs(current) return round(sum((c - b) * math.log(c / b) for b, c in zip(b_freq, c_freq)), 4)

def classify_drift(psi: float) -> str: if psi < 0.10: return "stable" if psi < 0.25: return "mild_drift" return "severe_drift"

def compute_drift_stats( baseline_df: pd.DataFrame, current_df: pd.DataFrame, numeric_cols: list[str], ) -> list[FeatureDrift]: """为每个数值型特征计算PSI和KS检验统计量。""" from scipy.stats import ks_2samp results = [] for col in numeric_cols: b = baseline_df[col].dropna().values c = current_df[col].dropna().values psi = compute_psi(b, c) ks_stat, ks_pvalue = ks_2samp(b, c) results.append(FeatureDrift( feature=col, psi=psi, ks_stat=round(float(ks_stat), 4), ks_pvalue=round(float(ks_pvalue), 6), severity=classify_drift(psi), )) return results

def run_monitoring_agent( baseline_df: pd.DataFrame, current_df: pd.DataFrame, numeric_cols: list[str], model_name: str = "churn_model_v3", ) -> str: """ 启动监控代理程序。 它会计算漂移统计量,并根据严重程度决定响应方式。 """ drift_results = compute_drift_stats(baseline_df, current_df, numeric_cols)

drift_summary = [ {"feature": d.feature, "psi": d.psi, "ks_pvalue": d.ks_pvalue, "severity": d.severity} for d in drift_results ]

severe_features = [d.feature for d in drift_results if d.severity == "severe_drift"] mild_features = [d.feature for d in drift_results if d.severity == "mild_drift"]

prompt = f"""您是{model_name}模型的监控代理程序。

漂移分析结果: {json.dumps(drift_summary, indent=2)}

严重漂移(PSI > 0.25): {severe_features} 轻度漂移(PSI 0.10-0.25): {mild_features}

根据严重程度确定响应方案:

  • 稳定:记录通过状态,无需操作
  • 轻度漂移:为数据科学团队起草警报信息
  • 严重漂移:起草警报信息并触发重新训练流水线
code

""" SEVERITY_LEVEL: ACTION: MESSAGE: """

response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}], temperature=0.1, # 非常低 -- 这是决策性调用,而非创造性任务 ) return response.choices[0].message.content

if __name__ == "__main__": np.random.seed(42) n = 2000

基线:正常电商浏览模式

baseline = pd.DataFrame({ "session_duration_s": np.random.normal(180, 60, n), "pages_per_session": np.random.normal(4.2, 1.5, n), "cart_add_rate": np.clip(np.random.normal(0.12, 0.04, n), 0, 1), })

当前情况:促销活动使所有特征显著变化

current = pd.DataFrame({ "session_duration_s": np.random.normal(310, 90, n), # 会话时间显著延长 "pages_per_session": np.random.normal(6.8, 2.1, n), # 浏览更多页面 "cart_add_rate": np.clip(np.random.normal(0.31, 0.08, n), 0, 1), # 加购率大幅提升 })

result = run_monitoring_agent(baseline, current, list(baseline.columns), model_name="recommendation_engine_v2") print(result)

code

python drift_agent.py

code

真实场景:电商推荐模型。促销活动导致浏览行为分布突然变化,会话时长均值从180秒跃升至310秒,加购率几乎翻倍。监控代理在午夜运行当天数据时,检测到三个特征的PSI均超过0.25,判定严重程度为严重,并通过Slack触发重训练流水线并发送告警。数据团队收到包含变化原因和处理措施的说明消息,而非需要凌晨6点解读的原始仪表盘。

## # 工作流5:智能管道编排与自愈机制

替代方案:盯着Airflow的失败通知,打开日志,手动阅读堆栈跟踪,判断修复是否需要代码修改、配置调整或重试,执行修复后重新运行任务,并希望下游任务不会因相同原因失败。

代理的处理方式:读取失败日志,分类错误类型,判断是否可自动修复,若可修复则直接处理,否则生成完整结构化事件报告并升级给人类处理。

一个封装现有编排层的元代理。当Airflow任务失败时,编排器将任务ID、错误日志和任务定义发送给代理。代理使用parse_pipeline_error工具对故障进行确定性分类。随后,单次语言模型调用将决定错误是否可自动修复,并根据分类结果生成修复方案描述或结构化事件报告供人工审核。

pipeline_healer.py

先决条件: pip install openai pandas

运行方式: python pipeline_healer.py

import json import re from dataclasses import dataclass from typing import Optional from openai import OpenAI

client = OpenAI()

@dataclass class PipelineError: task_id: str error_type: str # schema_mismatch | null_violation | timeout | unknown column: Optional[str] detail: str auto_fixable: bool

def parse_pipeline_error(log_line: str, task_id: str) -> PipelineError: """ 将任务失败日志分类为结构化错误类型。 可自动修复的错误无需人工干预即可修复。 """ if "KeyError" in log_line or ("column" in log_line.lower() and "not found" in log_line.lower()): col_match = re.search(r"['\"](\w+)['\"]", log_line) col = col_match.group(1) if col_match else None return PipelineError(task_id, "schema_mismatch", col, log_line.strip(), auto_fixable=True)

if "IntegrityError" in log_line or ("null" in log_line.lower() and "violate" in log_line.lower()): return PipelineError(task_id, "null_violation", None, log_line.strip(), auto_fixable=True)

if "TimeoutError" in log_line or "timed out" in log_line.lower(): return PipelineError(task_id, "timeout", None, log_line.strip(), auto_fixable=False)

return PipelineError(task_id, "unknown", None, log_line.strip(), auto_fixable=False)

def run_self_healing_agent( task_id: str, error_log: str, task_definition: str, ) -> str: """ 对失败的管道任务运行自愈代理。 它会分类错误,决定补救措施,并生成 自动修复描述或结构化升级报告。 """ error = parse_pipeline_error(error_log, task_id)

prompt = f"""你是一名数据管道可靠性工程师。 一个管道任务已失败,你必须决定如何应对。

任务: {task_id} 任务定义: {task_definition} 错误类型: {error.error_type} 受影响列: {error.column or 'N/A'} 可自动修复: {error.auto_fixable} 完整错误: {error.detail}

{"你可以为这种错误类型应用自动修复。" if error.auto_fixable else "此错误需要人工审核——你无法自动修复它。"}

回复格式: ACTION: FIX_DESCRIPTION: ESCALATION_REPORT: NEXT_STEP: """

response = client.chat.completions.create( model="gpt-4o-mini", messages=[{"role": "user", "content": prompt}], temperature=0.1, ) return response.choices[0].message.content

if __name__ == "__main__":

场景: CRM导出新增了列并更改了日期格式

result = run_self_healing_agent( task_id="ingest_crm_daily", error_log="KeyError: 'transaction_date' column not found in source dataframe. " "Available columns: ['txn_date_utc', 'customer_id', 'amount_usd', 'product_sku']", task_definition="读取每日CRM导出,提取transaction_date和customer_id, " "与产品目录连接,写入特征存储。", ) print(result)

code

python pipeline_healer.py

code

真实场景 每天凌晨2点,一个日常特征流水线因上游CRM系统更新了导出模式而失败,将transaction_date字段重命名为txn_date_utc,并新增了三列。代理读取错误日志,识别出transaction_date字段的模式不匹配问题,生成自动修复方案:在数据摄入步骤中重命名该字段,并将新增的三列以可为空的方式添加到模式定义中。它记录修复过程,重新触发失败任务,并向值班工程师发送摘要信息:“模式修复已自动应用。源已将transaction_date → txn_date_utc。模式中新增了三列可为空字段。任务已于02:14重新触发。”工程师在早晨查看更改内容,而无需被叫醒。

## # 总结

这五个工作流并非独立工具,而是构成一个完整流程的环节:

EDA代理理解数据,特征工程代理优化数据,超参数代理优化基于这些特征构建的模型,监控代理观察生产环境中的模型,自愈代理保护整个流水线,为所有环节提供数据支持。

请按以下顺序部署:首先部署监控代理,它无需修改建模代码即可立即为现有流水线带来价值。随后添加EDA代理以处理新引入的数据集。在建立值得改进的基线模型后,再部署特征工程代理和超参数代理。

这些工作流均需人工审核关键决策。EDA代理标记问题,你决定如何处理;特征工程代理提出候选特征,你决定重要性阈值;超参数代理进行搜索,你决定参数边界和收敛条件;监控代理检测数据漂移,你决定触发重新训练的严重性阈值;自愈代理应用修复,你审核确认后再合并到生产环境。

这种分工正是设计初衷。代理处理流程性工作,你保留评估权。结果是一个更快、更一致且更易于维护的流水线,因为现在许多故障点在你查看之前就被检测并修复。

Shittu Olumide 是一位软件工程师和技术作家,热衷于利用前沿技术创作引人入胜的叙事,以细致入微的洞察力和将复杂概念简化的天赋著称。你也可以在Twitter上关注Shittu。

### 更多相关内容

- 使用n8n自动化SQL工作流:通过电子邮件发送定时数据库报告

- 7个ChatGPT技巧自动化你的数据任务

- 使用Python和Docker构建自己的简单数据流水线

- 在机器学习流水线中匿名化和保护用户数据的三种方法

- 使用Bash构建你的第一个ETL流水线

- 你的机器学习流水线效率能提升到极限吗?

<hr class="grey-line"><br> <div><h3>我们推荐的5门顶级免费课程</h3><br> </div>

Mailchimp for WordPress v4.13.0 - https://wordpress.org/plugins/mailchimp-for-wp/

/ Mailchimp for WordPress插件

你可以从此处开始编辑。

如果评论已关闭。

<= 上一篇

下一篇 =>

#content end

<script type="text/javascript">kda_sid_write(kda_sid_n);</script>

### 最新文章

- 在 Apple Silicon 上使用 MLX 微调语言模型 5 个智能工作流实现数据科学流水线自动化 使用 Gemini 创建 Google Sheets 5 个开源全能 AI 模型处理文本、图像、音频和视频 2026 年成为 AI 架构师的发展路线图 2026 年可本地运行的顶级 7 款编程模型

## 热门文章

- 2026 年可本地运行的顶级 7 款编程模型

- 每位有志成为数据科学家者在编写第一行代码前必须掌握的数学技能

- 2026 年成为 AI 架构师的发展路线图

- 5 个使用 OpenAI Codex 的趣味项目

- 为什么 WebMCP 非常令人兴奋

- 2026 年成为大语言模型工程师的发展路线图

- 5 个智能工作流实现数据科学流水线自动化

- 我是如何(以及为何)构建 AI 助手的

- 关于智能 AI 的常见误解

- 在 Apple Silicon 上使用 MLX 微调语言模型

#content_wrapper end

© 2026

Guiding Tech Media

|

关于

联系我们

广告合作

隐私政策

服务条款

2026年6月26日由 Olumide Shittu 发布

blank

不,谢谢!

/.main_wrapper

<script defer type="text/javascript" src="https://s7.addthis.com/js/300/addthis_widget.js#pubid=gpsaddthis"></script>

noptimize

/noptimize