当前位置: 首页 > news >正文

LLM代理应用实战:构建Plotly数据可视化代理

如果你尝试过像ChatGPT这样的LLM,就会知道它们几乎可以为任何语言或包生成代码。但是仅仅依靠LLM是有局限的。对于数据可视化的问题我们需要提供一下的内容

描述数据:模型本身并不知道数据集的细节,比如列名和行细节。手动提供这些信息可能很麻烦,特别是当数据集变得更大时。如果没有这个上下文,LLM可能会产生幻觉或虚构列名,从而导致数据可视化中的错误。

样式和偏好:数据可视化是一种艺术形式,每个人都有独特的审美偏好,这些偏好因图表类型和信息而异。不断地为每个可视化提供不同的风格和偏好是很麻烦的。而配备了风格信息的代理可以简化这一过程,确保一致和个性化的视觉输出。

如果每次于LLM进行交互都附带这些内容会导致请求过于复杂,不利于用户的输入,所以这次我们构建一个数据可视化的代理,通过代理我们只需提供很少的信息就能够让LLM生成我们定制化的图表。

可视化库的选择

在构建一个数据可视化的AI代理时,选择合适的可视化工具是至关重要的。虽然存在多种工具可以用于数据可视化,但Plotly和Matplotlib是最为常用的两种。为了构建一个既功能丰富又用户友好的可视化界面,我们决定使用Plotly作为主要的可视化库。

与Matplotlib相比,Plotly提供了更加丰富的交互性功能。它支持直接在Web浏览器中的动态渲染,使得用户能够通过缩放、平移、悬停来互动式地探索数据。这种高度的交互性是Plotly的一大优势,尤其是在需要展示复杂数据集或进行深入数据分析的应用场景中。

虽然Matplotlib在科学研究和学术出版物中有广泛的应用,特别是在生成高质量的静态图像方面具有极高的灵活性和精确度,但其在交互性和Web集成方面的限制使得它在构建现代、交互式的数据可视化解决方案时可能不如Plotly那么吸引人。

所以我们选择Plotly作为构建数据可视化AI代理的工具,不仅能够满足用户对交互性的需求,还能够提供强大的数据处理能力和优秀的用户体验。这将极大地提高数据可视化的效率和效果,使得数据分析更加直观和易于理解。

下面是我使用Llama3 70B构建可视化基线。

我们执行上面的代码将得到如下的结果

要构建这个应用程序,我们需要为LLM代理配备两个工具:一个工具提供关于数据集的信息,另一个工具包含关于样式的信息。

代理提供的信息

1、DataFrame信息

这个工具目的是分析DataFrame并将其内容信息存储到索引中。要索引的数据包括列名、数据类型以及值的最小值、最大值和平均值范围。这有助于代理理解它们正在处理的变量类型。

这里我们使用layoff.fyi 的数据来进行分析。

我们这里还做了一些预处理的工作,包括将数据转换为适当的类型(例如,将数字字符串转换为整数或浮点数)并删除空值。

 #Optional pre-processingimport pandas as pdimport numpy as npdf = pd.read_csv('WARN Notices California_Omer Arain - Sheet1.csv')#Changes date like column into datetime df['Received Date'] = [pd.to_datetime(x) for x in df['Received Date']]df['Effective Date'] = [pd.to_datetime(x) for x in df['Effective Date']]#Converts numbers stored as strings into intsdf['Number of Workers'] = [int(str(x).replace(',','')) if str(x)!='nan' else np.nan for x in df['Number of Workers']]# Replacing NULL valuesdf = df.replace(np.nan,0)

将数据集信息存储到索引中

 from llama_index.core.readers.json import JSONReaderfrom llama_index.core import VectorStoreIndeximport json# Function that stores the max,min & mean for numerical valuesdef return_vals(df,c):if isinstance(df[c].iloc[0], (int, float, complex)):return [max(df[c]), min(df[c]), np.mean(df[c])]# For datetime we need to store that information as stringelif(isinstance(df[c].iloc[0],datetime.datetime)):return [str(max(df[c])), str(min(df[c])), str(np.mean(df[c]))]else:# For categorical variables you can store the top 10 most frequent items and their frequencyreturn list(df[c].value_counts()[:10])# declare a dictionary dict_ = {}for c in df.columns:# storing the column name, data type and contentdict_[c] = {'column_name':c,'type':str(type(df[c].iloc[0])), 'variable_information':return_vals(df,c)}# After looping storing the information as a json dump that can be loaded # into a llama-index Document# Writing the information into dataframe.json with open("dataframe.json", "w") as fp:json.dump(dict_ ,fp) reader = JSONReader()# Load data from JSON filedocuments = reader.load_data(input_file='dataframe.json')# Creating an Indexdataframe_index =  VectorStoreIndex.from_documents(documents)

这样第一步就完成了。

2、自定义样式信息

表样式主要包括关于如何在plot中设置不同图表样式的自然语言说明。这里需要使用自然语言描述样式,所以可能需要进行尝试,下面是我如何创建折线图和条形图的说明!

 from llama_index.core import Documentfrom llama_index.core import VectorStoreIndexstyling_instructions =[Document(text="""Dont ignore any of these instructions.For a line chart always use plotly_white template, reduce x axes & y axes line to 0.2 & x & y grid width to 1. Always give a title and make bold using html tag axis label and try to use multiple colors if more than one lineAnnotate the min and max of the lineDisplay numbers in thousand(K) or Million(M) if larger than 1000/100000 Show percentages in 2 decimal points with '%' sign"""), Document(text="""Dont ignore any of these instructions.For a bar chart always use plotly_white template, reduce x axes & y axes line to 0.2 & x & y grid width to 1. Always give a title and make bold using html tag axis label and try to use multiple colors if more than one lineAlways display numbers in thousand(K) or Million(M) if larger than 1000/100000. Add annotations x valuesAnnotate the values on the y variableIf variable is a percentage show in 2 decimal points with '%' sign.""")# You should fill in instructions for other charts and play around with these instructions, Document(text=""" General chart instructionsDo not ignore any of these instructionsalways use plotly_white template, reduce x & y axes line to 0.2 & x & y grid width to 1. Always give a title and make bold using html tag axis label Always display numbers in thousand(K) or Million(M) if larger than 1000/100000. Add annotations x valuesIf variable is a percentage show in 2 decimal points with '%'""")]# Creating an Indexstyle_index =  VectorStoreIndex.from_documents(styling_instructions)

或者直接将部分样式的代码作为示例输入给模型,这样对于固定的样式是非常好的一个方式

构建AI代理

我们上面已经构建了2个索引:DataFrame信息(元数据),表格自定义样式信息

下面就可以使用lama- index从索引构建查询引擎并将其用作代理工具使用。

 #All imports for this sectionfrom llama_index.core.agent import ReActAgentfrom llama_index.core.tools import QueryEngineToolfrom llama_index.core.tools import  ToolMetadatafrom llama_index.llms.groq import Groq# Build query engines over your indexes# It makes sense to only retrieve one document per query # However, you may play around with this if you need multiple charts# Or have two or more dataframes with similar column namesdataframe_engine = dataframe_index.as_query_engine(similarity_top_k=1)styling_engine = style_index.as_query_engine(similarity_top_k=1)# Builds the toolsquery_engine_tools = [QueryEngineTool(query_engine=dataframe_engine,# Provides the description which helps the agent decide which tool to use metadata=ToolMetadata(name="dataframe_index",description="Provides information about the data in the data frame. Only use column names in this tool",),\),QueryEngineTool(# Play around with the description to see if it leads to better resultsquery_engine=styling_engine,metadata=ToolMetadata(name="Styling",description="Provides instructions on how to style your Plotly plots""Use a detailed plain text question as input to the tool.",),),]# I used open-source models via Groq but you can use OpenAI/Google/Mistral models as wellllm = Groq(model="llama3-70b-8192", api_key="<your_api_key>")# initialize ReAct agentagent = ReActAgent.from_tools(query_engine_tools, llm=llm, verbose=True)

为了防止幻觉,我这里稍微调整了一下提示,这步不是必须的

这里是ReAct的默认提示

修改为:

 from llama_index.core import PromptTemplatenew_prompt_txt= """You are designed to help with building data visualizations in Plotly. You may do all sorts of analyses and actions using Python## ToolsYou have access to a wide variety of tools. You are responsible for using the tools in any sequence you deem appropriate to complete the task at hand.This may require breaking the task into subtasks and using different tools to complete each subtask.You have access to the following tools, use these tools to find information about the data and styling:{tool_desc}## Output FormatPlease answer in the same language as the question and use the following format:

Thought: The current language of the user is: (user’s language). I need to use a tool to help me answer the question.
Action: tool name (one of {tool_names}) if using a tool.
Action Input: the input to the tool, in a JSON format representing the kwargs (e.g. {{“input”: “hello world”, “num_beams”: 5}})


Please ALWAYS start with a Thought.Please use a valid JSON format for the Action Input. Do NOT do this {{'input': 'hello world', 'num_beams': 5}}.If this format is used, the user will respond in the following format:

Observation: tool response


You should keep repeating the above format till you have enough information to answer the question without using any more tools. At that point, you MUST respond in the one of the following two formats:

Thought: I can answer without using any more tools. I’ll use the user’s language to answer
Answer: [your answer here (In the same language as the user’s question)]


Thought: I cannot answer the question with the provided tools.
Answer: [your answer here (In the same language as the user’s question)]


## Current ConversationBelow is the current conversation consisting of interleaving human and assistant messages."""# Adding the prompt text into PromptTemplate object
new_prompt = PromptTemplate(new_prompt_txt)# Updating the prompt
agent.update_prompts({'agent_worker:system_prompt':new_prompt})

可视化

现在让就可以向我们构建的代理发起请求了

 response = agent.chat("Give Plotly code for a line chart for Number of Workers get information from the dataframe about the correct column names and make sure to style the plot properly and also give a title")

从输出中可以看到代理如何分解请求并最终使用Python代码进行响应(可以直接构建输出解析器或复制过去并运行)。

通过运行以代码创建的图表,将注释、标签/标题和轴格式与样式信息完全一致。因为已经有了数据信息,所以我们直接提出要求就可以,不需要输入任何的数据信息

在试一试其他的图表,生成一个柱状图

结果如下:

总结

AI代理可以自动化从多个数据源收集、清洗和整合数据的过程。这意味着可以减少手动处理错误,提高数据处理速度,让分析师有更多时间专注于解读数据而不是处理数据。使用AI代理进行数据可视化能够显著提升数据分析的深度和广度,同时提高效率和用户体验,帮助企业和组织更好地利用他们的数据资产。

我们这里只是做了第一步,如果要制作一套代理工具还需要很多步骤,比如可视化代码的自动执行,优化提示和处理常见故障等等,如果你对这方面感兴趣,可以留言,如果人多的话我们会在后续的文章中一一介绍。

https://avoid.overfit.cn/post/b7250a6a029d46adb2c5948eb71b5d28

作者:Arslan Shahid

相关文章:

LLM代理应用实战:构建Plotly数据可视化代理

如果你尝试过像ChatGPT这样的LLM&#xff0c;就会知道它们几乎可以为任何语言或包生成代码。但是仅仅依靠LLM是有局限的。对于数据可视化的问题我们需要提供一下的内容 描述数据:模型本身并不知道数据集的细节&#xff0c;比如列名和行细节。手动提供这些信息可能很麻烦&#…...

大模型系列3--pytorch dataloader的原理

pytorch dataloader运行原理 1. 背景2. 环境搭建2.1. 安装WSL & vscode2.2. 安装conda & pytorch_gpu环境 & pytorch 2.112.3 命令行验证python环境2.4. vscode启用pytorch_cpu虚拟环境 3. 调试工具3.1. vscode 断点调试3.2. py-spy代码栈探测3.3. gdb attach3.4. …...

SQLServer 如何设置端口

在SQL Server中&#xff0c;可以通过以下步骤设置端口&#xff1a; 打开SQL Server配置管理器。可以在开始菜单中搜索“SQL Server配置管理器”来找到它。 在左侧导航窗格中&#xff0c;展开“SQL Server网络配置”节点。 选择你要配置的实例&#xff0c;如“SQL Server Netw…...

调整网络安全策略以适应不断升级的威胁形势

关键网络安全统计数据和趋势 当今数字时代网络安全的重要性...

(leetcode学习)9. 回文数

给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数 是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 是回文&#xff0c;而…...

QT VTK 简单测试工程

目录 1 目录结构 2 文件源码 3 运行结果 4 报错及处理 使用编译好的VTK库进行测试 1 目录结构 2 文件源码 Pro文件 QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c17# You can make your code fail to compile if it uses deprecated APIs. #…...

ES6 Generator函数的异步应用 (八)

ES6 Generator 函数的异步应用主要通过与 Promise 配合使用来实现。这种模式被称为 “thunk” 模式&#xff0c;它允许你编写看起来是同步的异步代码。 特性&#xff1a; 暂停执行&#xff1a;当 Generator 函数遇到 yield 表达式时&#xff0c;它会暂停执行&#xff0c;等待 …...

Navicat:打造高效数据库管理之道

1. 导言 1.1 介绍Navicat Navicat是一款功能强大的数据库管理工具,旨在帮助用户高效地管理多种类型的数据库,包括MySQL、PostgreSQL、Oracle、SQL Server等。通过Navicat,用户可以轻松地进行数据库的创建、编辑、备份、同步和调试等操作,极大地简化了数据库管理的复杂性。…...

Python和C++全球导航卫星系统和机器人姿态触觉感知二分图算法

&#x1f3af;要点 &#x1f3af;马尔可夫随机场网格推理学习 | &#x1f3af;二维伊辛模型四连网格模型推理 | &#x1f3af;统计物理学模型扰动与最大乘积二值反卷积 | &#x1f3af;受限玻尔兹曼机扰动和最大乘积采样 | &#x1f3af;视觉概率生成模型测试图像 &#x1f3…...

Unity 优化合集

1️⃣ 贴图优化 1. Read/Write Enable 这个属性勾选后允许你在运行时读取和写入纹理数据&#xff0c;这对于需要实时生成内容或者需要动态修改纹理的场合非常有用但在大部分情况下这是不必要的。如果打开这个属性&#xff0c;会使运行时贴图大小翻倍&#xff0c;内存中会额外…...

第九届MathorCup高校数学建模挑战赛-A题:基于数据驱动的城市轨道交通网络优化研究

目录 摘 要 一、 问题的提出 二、 基本假设 三、 符号说明 四、 问题分析 4.1 问题 1 的分析 4.2 问题 2 的分析 4.3 问题 3 的分析 4.4 问题 4 的分析 五、 问题 1 的模型建立与求解 5.1 问题分析 5.2 数据处理 5.2.1 数据统计 5.2.2 异常数据处理方法 5.2.3 剔除异常数据值 5…...

Spring webflux基础核心技术

一、 用操作符转换响应式流 1 、 映射响应式流元素 转换序列的最自然方式是将每个元素映射到一个新值。 Flux 和 Mono 给出了 map 操作符&#xff0c;具有 map(Function<T&#xff0c;R>) 签名的方法可用于逐个处理元素。 当操作符将元素的类型从 T 转变为 R 时&#xf…...

关闭Ubuntu烦人的apport

先来看让人绷不住的&#xff08;恼&#xff09; 我查半天apport是啥玩意发现就一错误报告弹窗&#xff0c;十秒钟给我弹一次一天给我内存弹爆了 就算我程序就算真的不停崩溃&#xff0c;也没你这傻比apport杀伤性强啊&#xff1f;&#xff1f;&#xff1f; 原则上是不建议关闭…...

海事无人机解决方案

海事巡察 海事巡察现状 巡查效率低下&#xff0c;存在视野盲区&#xff0c;耗时长&#xff0c;人力成本高。 海事的职能 统一管理水上交通安全和防治船舶污染。 管理通航秩序、通航环境。负责水域的划定和监督管理&#xff0c;维护水 上交通秩序&#xff1b;核定船舶靠泊安…...

Docker--在linux安装软件

Docker 引用Docker原因是在linux中安装软件 以前在linux中安装软件&#xff0c;是直接安装在linux操作系统上&#xff0c;软件和操作系统耦合度很高&#xff0c;不方便管理&#xff0c;因为linux版本不同&#xff0c;环境也就改变了 docker是一种容器技术&#xff0c;提供标…...

知识库与RAG

认识知识库的技术原理 第一步&#xff1a;&#x1f4d6;➡️&#x1f4c8;将文档的文本转换为向量&#xff0c;向量存储到向量数据库。第二步&#xff1a;&#x1f5e8;️➡️&#x1f50d;将用户的提问内容转换成向量&#xff0c;在向量数据库中检索相似的文本内容&#xff0…...

【2024最新】C++扫描线算法介绍+实战例题

扫描线介绍&#xff1a;OI-Wiki 【简单】一维扫描线&#xff08;差分优化&#xff09; 网上一维扫描线很少有人讲&#xff0c;可能认为它太简单了吧&#xff0c;也可能认为这应该算在差分里&#xff08;事实上讲差分的文章里也几乎没有扫描线的影子&#xff09;。但我认为&am…...

语言主要是一种交流工具,而不是思维工具?GPT5何去何从?

引言 在人工智能领域&#xff0c;特别是大语言模型&#xff08;LLM&#xff09;的发展中&#xff0c;语言和思维的关系一直是一个备受关注的话题。近期&#xff0c;麻省理工学院&#xff08;MIT&#xff09;在《Nature》杂志上发表了一篇题为《Language is primarily a tool f…...

传感器标定(三)激光雷达外参标定(lidar2ins)

一、数据采集 1、LiDAR 传感器的 LiDAR PCD 数据 2、来自 IMU 传感器的姿势文件 3、手动测量传感器之间外部参数初始值并写入的 JSON 文件 二、下载标定工具 //总的git地址&#xff1a; https://github.com/PJLab-ADG/SensorsCalibration git地址&#xff1a; https://githu…...

【漏洞复现】Crocus系统—Download 文件读取

声明&#xff1a;本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动&#xff0c;将与本文档的作者或发布者无关。 一、漏洞描述 Crocus系统中的Download文件读取漏洞允许未经身份验证的攻击者通过特定请求读取系统上的任意文件。Crocu…...

游戏开发面试题1

说说对单例模式的了解 单例模式&#xff08;Singleton Pattern&#xff09;是一种设计模式&#xff0c;其目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。这在某些情况下非常有用&#xff0c;比如需要一个唯一的配置管理器、日志记录器、或资源管…...

线程池笔记

笔记梳理 前言.PHONYC标准库头文件C/C通用或C特有头文件mkdirc_str()snprintfvsnprintfumaskopen函数可变参数列表va_startva_endfunctionalstatic_castpthread_cond_init_threads.emplace_backstd::bindstd::placeholdersThreadPool(const ThreadPool<T> &tp) dele…...

Go语言基础数据类型、变量及自增语法

本文内容为Go语言的基础数据类型、变量定义和赋值及自增语法介绍。 目录 基础数据类型 变量 先定义后赋值 定义时直接赋值 自动推导定义赋值 平行赋值 自增语法 总结 基础数据类型 int,int8 intl6, int32, int64 uint8... uint64 float32,float64 true/false 变量 …...

ES6-ES13符号:单双引号、变量的解构赋值、占位符 、字符串模版`${} `、扩展运算符...、?,??,_,||=,=,in

原型、this、闭包&#xff0c;for四类循环&#xff0c;ES6-14&#xff08;2023&#xff09;_es6-es14-CSDN博客 目录 查看ES版本 单双引号&#xff1a;无区别 变量的解构赋值&#xff1a;声明变量被数组/对象中的元素赋值 推荐用const&#xff0c;因为是从其他地方获取值 …...

【远景能源25届校招PI测评】题型深度解析与应试策略

摘要&#xff1a; 远景能源作为新能源行业的领军企业&#xff0c;其校园招聘备受瞩目。本文将深入分析25届远景能源校招的PI测评题型&#xff0c;为求职者提供全面的备考指南。 正文&#xff1a; 尊敬的求职者们&#xff0c;您是否正准备迎接远景能源的校招挑战&#xff1f;P…...

关于Qt Creator 使用Qt Quick的Design模式设置

关于使用Qt Quick的Design模式设置&#xff1a; 如描述所言&#xff1a; 如果使用Design模式打开qml文件失败显示如下&#xff1a; 首先确认自己是否安装了Qt Design Studio 如果安装了仍然不显示&#xff0c;则需要勾选下面三个地方才能用Design模式打开.ui.qml文件&#…...

Spring常见问题一:IOC和DI

IOC和DI IOC和DI之间到底是什么关系&#xff1f; 什么是依赖关系&#xff1f;依赖关系会带来什么问题&#xff1f;Spring是怎么来支持依赖注入的&#xff1f; 引言 在现代软件开发中&#xff0c;面向对象编程&#xff08;OOP&#xff09;已经成为主流编程范式。然而&#xff0…...

LabVIEW红外热波图像缺陷检

开发使用LabVIEW开发的红外热波图像缺陷检测系统。该系统结合红外热像仪、工业相机和高效的数据采集硬件&#xff0c;实现对工件表面缺陷的自动检测和分析。通过LabVIEW的强大功能&#xff0c;系统能够实时采集、处理和显示红外热波图像&#xff0c;有效提高了检测的精度和效率…...

c#与欧姆龙PLC通信——如何更改PLC的IP地址

前言 我们有时候需要改变欧姆龙Plc的ip地址,下图有两种更改方式,一种是已知之前Plc设置的Ip地址,还有一种是之前不知道Pl的Ip地址是多少,下面分别做介绍。 1、已知PLC的IP地址的情况下更改地址 假设已知PLC的Ip地址,比如本文中PLC的IP为192.168.1.2,我首先将电脑的IP地…...

[Spring Boot]定时任务因系统时间修改之后无法执行

问题描述 当Spring Boot启动时&#xff0c;当前时间为2024-01-01 00:00:00。 此时你创建了任务&#xff1a; 每10秒钟触发一次定时任务 Scheduled(cron "0/10 * * * * ? ") public void scheduledTask() { }此时你手动修改了系统时间&#xff0c;修改为2023-12-0…...