使用LangGraph构建数据清洗代理
可悲的是,你太熟悉这个故事了...
数据科学家花费了不成比例的时间来清洗数据,而不是分析数据和提取见解
幸运的是,这正是AI实际上可以非常有用的领域,帮助自动化并提供巨大的生产力提升。
这就是为什么这是我今年早些时候开始使用AI工作流和代理时首先着手构建的事情之一。我构建了一个代理来处理修复数据类型、移除异常值、处理缺失值等重复性的苦差事,这样我可以将更多时间集中在重要的分析上。
今天,我将向你展示如何使用LangGraph构建这个系统的轻量级版本,这样你就可以开始将自动化引入你自己的分析工作流。
但在那之前,让我向你展示这个代理的实际运行:
现在,让我们开始实现...
1、数据清洗工作流
在我们开始代码之前,让我们使用LangSmith Studio在高层次上可视化我们的工作流。
如你所见,图本身实际上非常简单。它只包含3个功能节点和一个条件边。以下是每个节点处理内容的概述:
- create_data_cleaner_code:调用LLM并指示它基于一系列要求和数据集预览生成数据清洗Python代码。
- execute_data_cleaner_code:安全执行前一个节点生成的Python代码。
- fix_data_cleaner_code:使用LLM反馈循环提供自动错误纠正。
💡 这是我们工作流的最小功能版本。它作为基线表现良好,但这只是起点。你可以用额外的元素扩展它,比如人工干预阶段或更高级的规划节点。
好的,让我们看看核心逻辑是如何工作的 👇
2、LLM驱动的代码生成节点
就我们的目的而言,这是"推理"节点,决定最合适的数据清洗方式的组件。在幕后,它调用LLM基于指令和数据集特征生成Python代码。
提示使用LangChain的PromptTemplate方法处理,这对于定义带有占位符的提示并在发送给LLM之前填充它们非常有用。以下是提示的主要部分:
- 主要指令:定义模型应遵循的清洗策略,描述如何处理数据集中出现的常见问题,如缺失值或重复值。
- 用户指令:用户提供的自由形式指令,允许代理根据特定需求或偏好自定义清洗逻辑。
- 数据集摘要:数据框的结构化概述,包括列名、数据类型和缺失值计数,帮助模型生成上下文感知的代码。
- Python代码格式:强制模型返回有效的、可执行的Python代码并包装在单个函数中的模板,以便工作流可以端到端可靠地运行。
现在,让我们看看生成代码后会发生什么!
3、执行LLM生成的代码
一旦我们从LLM获取数据清洗Python代码,我们需要在隔离的命名空间中执行它并捕获任何错误,以便我们可以利用重试逻辑。
以下是这段代码的关键部分:
- 定义函数:我们使用Python内置函数
exec()来解析LLM生成的代码字符串并在隔离的命名空间中创建函数定义。 - 检索函数:使用
local_vars.get(),我们从命名空间中提取新定义的函数对象,以便可以调用它。 - 执行函数:
agent_function(df)在实际数据上运行生成的清洗函数,返回清洗后的数据框或抛出错误。
让我们看看如果函数调用抛出错误会发生什么...
4、使用错误反馈进行自我纠正
如果生成的代码失败,代理会自动将错误消息反馈给LLM。这允许模型诊断失败并产生修正版本的函数,无需人工干预。
修复代码。作者图片。
- 定义提示:
prompt_template.format()创建提示,将损坏的代码和错误消息插入到指示LLM修复问题的模板中。 - 修复代码:
llm.invoke()将提示发送给LLM以生成修正的代码,然后解析响应以提取干净的Python代码。
这个反馈循环赋予代理迭代地从常见错误中恢复并继续改进生成的代码的能力。
5、使用示例
这是一个简单的示例,展示如何以编程方式运行代理。
如果你想将工作流直接集成到现有代码库中或将其自动化作为更大管道的一部分,这种模式很有效。
你也可以在此基础上构建一个界面,例如使用Streamlit,如前面的演示所示。但最佳方法取决于你计划如何使用代理。
例如,如果你的目标是在探索性数据分析或迭代分析期间调用它,你可以将代理打包为模块并直接导入到笔记本中。这允许你在不离开分析环境的情况下生成清洗函数、检查它们并在不同的数据集上重用它们。
如果你想试用代码,这里是GitHub仓库。
6、结束语
这个代理展示的不仅仅是更快的数据清洗方式,而是一种不同工作方式的一瞥。我们正在从手动编写每个转换转向设计为我们生成、修复和执行代码的系统。
即使是一个轻量级代理也能消除数小时的摩擦,这清楚地表明我们可以为工作中真正需要判断、分析和创造力的部分回收多少时间。
不过,这只是开始。我们可以利用AI做的远不止清洗混乱的数据!
原文链接: Building a Data Cleaning Agent with LangGraph
汇智网翻译整理,转载请标明出处