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

大模型系列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中,可以通过以下步骤设置端口: 打开SQL Server配置管理器。可以在开始菜单中搜索“SQL Server配置管理器”来找到它。 在左侧导航窗格中,展开“SQL Server网络配置”节点。 选择你要配置的实例,如“SQL Server Netw…...

调整网络安全策略以适应不断升级的威胁形势
关键网络安全统计数据和趋势 当今数字时代网络安全的重要性...
(leetcode学习)9. 回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数 是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 例如,121 是回文,而…...

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” 模式,它允许你编写看起来是同步的异步代码。 特性: 暂停执行:当 Generator 函数遇到 yield 表达式时,它会暂停执行,等待 …...

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

Python和C++全球导航卫星系统和机器人姿态触觉感知二分图算法
🎯要点 🎯马尔可夫随机场网格推理学习 | 🎯二维伊辛模型四连网格模型推理 | 🎯统计物理学模型扰动与最大乘积二值反卷积 | 🎯受限玻尔兹曼机扰动和最大乘积采样 | 🎯视觉概率生成模型测试图像 dz…...

Unity 优化合集
1️⃣ 贴图优化 1. Read/Write Enable 这个属性勾选后允许你在运行时读取和写入纹理数据,这对于需要实时生成内容或者需要动态修改纹理的场合非常有用但在大部分情况下这是不必要的。如果打开这个属性,会使运行时贴图大小翻倍,内存中会额外…...
第九届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 操作符,具有 map(Function<T,R>) 签名的方法可用于逐个处理元素。 当操作符将元素的类型从 T 转变为 R 时…...

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

海事无人机解决方案
海事巡察 海事巡察现状 巡查效率低下,存在视野盲区,耗时长,人力成本高。 海事的职能 统一管理水上交通安全和防治船舶污染。 管理通航秩序、通航环境。负责水域的划定和监督管理,维护水 上交通秩序;核定船舶靠泊安…...
Docker--在linux安装软件
Docker 引用Docker原因是在linux中安装软件 以前在linux中安装软件,是直接安装在linux操作系统上,软件和操作系统耦合度很高,不方便管理,因为linux版本不同,环境也就改变了 docker是一种容器技术,提供标…...

知识库与RAG
认识知识库的技术原理 第一步:📖➡️📈将文档的文本转换为向量,向量存储到向量数据库。第二步:🗨️➡️🔍将用户的提问内容转换成向量,在向量数据库中检索相似的文本内容࿰…...
【2024最新】C++扫描线算法介绍+实战例题
扫描线介绍:OI-Wiki 【简单】一维扫描线(差分优化) 网上一维扫描线很少有人讲,可能认为它太简单了吧,也可能认为这应该算在差分里(事实上讲差分的文章里也几乎没有扫描线的影子)。但我认为&am…...

语言主要是一种交流工具,而不是思维工具?GPT5何去何从?
引言 在人工智能领域,特别是大语言模型(LLM)的发展中,语言和思维的关系一直是一个备受关注的话题。近期,麻省理工学院(MIT)在《Nature》杂志上发表了一篇题为《Language is primarily a tool f…...

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

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

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...