作者:来自 Elastic Jeffrey Rengifo 及 Tomás Murúa

使用 LLM 处理图像并将其转换为 Kibana 仪表板。

想获得 Elastic 认证?了解下一次 Elasticsearch Engineer 培训的举办时间!

Elasticsearch 拥有众多新功能,帮助你为你的使用场景构建最佳搜索解决方案。深入我们的示例笔记本了解更多,立即开始免费云试用,或在本地机器上尝试 Elastic。


Kibana Lens 使仪表板创建变得拖放简单,但当你需要几十个面板时,点击次数会累积。如果你可以画一个仪表板草图,截图,然后让 LLM 为你完成整个过程,会怎么样?

在这篇文章中,我们将实现这个目标。我们将创建一个应用程序,接受仪表板图像,分析我们的映射,然后生成一个仪表板,无需我们手动操作 Kibana!

步骤

  • 背景与应用工作流程
  • 准备数据
  • LLM 配置
  • 应用功能

背景与应用工作流程

第一个想法是让 LLM 生成整个 NDJSON 格式的 Kibana 保存对象,然后将其导入到 Kibana。

我们尝试了以下模型:

  • Gemini 2.5 pro
  • GPT o3 / o4-mini-high / 4.1
  • Claude 4 sonnet
  • Grok 3
  • Deepseek ( Deepthink R1 )

至于提示词,我们从最简单的开始:

You are an Elasticsearch Saved-Object generator (Kibana 9.0).
INPUTS
=====
1. PNG screenshot of a 4-panel dashboard (attached).
2. Index mapping (below) – trimmed down to only the fields present in the screenshot.
3. Example NDJSON of *one* metric visualization (below) for reference.TASK
====
Return **only** a valid NDJSON array that recreates the dashboard exactly:
* 2 metric panels (Visits, Unique Visitors)
* 1 pie chart (Most used OS)
* 1 vertical bar chart (State Geo Dest)
* Use index pattern `kibana_sample_data_logs`.
* Preserve roughly the same layout (2×2 grid).
* Use `panelIndex` values 1-4 and random `id` strings.
* Kibana version: 9.0

尽管我们尝试了少样本示例和关于如何构建每个可视化的详细说明,但没有成功。如果你对这个实验感兴趣,可以在这里找到详细信息。

使用这种方法的结果是,在尝试将 LLM 生成的文件上传到 Kibana 时,看到以下消息:

这意味着生成的 JSON 无效或格式错误。最常见的问题是 LLM 生成了不完整的 NDJSON、虚构参数,或者无论我们如何强制要求,都返回常规 JSON 而不是 NDJSON。

受这篇文章的启发 —— 其中搜索模板比 LLM 自由生成效果更好——我们决定为 LLM 提供模板,而不是要求它生成完整的 NDJSON 文件,然后我们在代码中使用 LLM 提供的参数来创建正确的可视化。这种方法没有让人失望,而且是可预测和可扩展的,因为现在代码承担了主要工作,而不是 LLM。

应用工作流程如下:

我们将为了简化省略一些代码,但你可以在这个笔记本中找到完整应用的有效代码。

前提条件

在开始开发之前,你需要以下内容:

  1. Python 3.8 或更高版本
  2. 一个 Venv Python 环境
  3. 一个运行中的 Elasticsearch 实例,以及其端点和 API 密钥
  4. 一个存储在环境变量名 OPENAI_API_KEY 下的 OpenAI API 密钥:
export OPENAI_API_KEY="your-openai-api-key"

准备数据

对于数据,我们将保持简单,使用 Elastic 样本 Web 日志。你可以在这里了解如何将这些数据导入到你的集群。

每个文档包括发出应用程序请求的主机的详细信息,以及请求本身及其响应状态的信息。以下是一个示例文档:

{"agent": "Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24","bytes": 8509,"clientip": "70.133.115.149","extension": "css","geo": {"srcdest": "US:IT","src": "US","dest": "IT","coordinates": {"lat": 38.05134111,"lon": -103.5106908}},"host": "cdn.elastic-elastic-elastic.org","index": "kibana_sample_data_logs","ip": "70.133.115.149","machine": {"ram": 5368709120,"os": "osx"},"memory": null,"message": "70.133.115.149 - - [2018-08-30T23:35:31.492Z] \"GET /styles/semantic-ui.css HTTP/1.1\" 200 8509 \"-\" \"Mozilla/5.0 (X11; Linux i686) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.50 Safari/534.24\"","phpmemory": null,"referer": "http://twitter.com/error/john-phillips","request": "/styles/semantic-ui.css","response": 200,"tags": ["success","info"],"@timestamp": "2025-07-03T23:35:31.492Z","url": "https://cdn.elastic-elastic-elastic.org/styles/semantic-ui.css","utc_time": "2025-07-03T23:35:31.492Z","event": {"dataset": "sample_web_logs"},"bytes_gauge": 8509,"bytes_counter": 51201128
}

现在,让我们获取刚刚加载的索引 kibana_sample_data_logs 的映射:

INDEX_NAME = "kibana_sample_data_logs"es_client = Elasticsearch([os.getenv("ELASTICSEARCH_URL")],api_key=os.getenv("ELASTICSEARCH_API_KEY"),
)result = es_client.indices.get_mapping(index=INDEX_NAME)
index_mappings = result[list(result.keys())[0]]["mappings"]["properties"]

我们将把映射与稍后加载的图像一起传递。

LLM 配置

让我们配置 LLM 使用结构化输出,以输入图像并接收我们需要传递给函数的 JSON,以生成 JSON 对象。

我们安装依赖项:

pip install elasticsearch pydantic langchain langchain-openai -q

Elasticsearch 会帮助我们获取索引映射。Pydantic 允许我们在 Python 中定义 schema,以便要求 LLM 遵循这个结构,而 LangChain 是一个框架,可以更方便地调用 LLMs 和 AI 工具。

我们将创建一个 Pydantic schema 来定义我们希望从 LLM 得到的输出内容。我们需要从图像中识别的信息包括:图表类型、字段、可视化标题,以及仪表板标题:

class Visualization(BaseModel):title: str = Field(description="The dashboard title")type: List[Literal["pie", "bar", "metric"]]field: str = Field(description="The field that this visualization use based on the provided mappings")class Dashboard(BaseModel):title: str = Field(description="The dashboard title")visualizations: List[Visualization]

请上传你刚画的仪表板图片,我会根据图像内容提取图表类型、字段、可视化标题和仪表板标题。

现在我们声明 LLM 模型调用和图像加载。这个函数将接收 Elasticsearch 索引的 mappings 和我们想要生成的仪表板图像。

通过使用 with_structured_output,我们可以将 Pydantic 的 Dashboard schema 作为 LLM 生成的响应对象。使用 Pydantic,我们可以定义带有验证的数据模型,确保 LLM 输出符合预期结构。

要将图像转换为 base64 并作为输入发送,可以使用在线转换工具,或通过代码实现。

prompt = f"""You are an expert in analyzing Kibana dashboards from images for the version 9.0.0 of Kibana.You will be given a dashboard image and an Elasticsearch index mapping.Below are the index mappings for the index that the dashboard is based on.Use this to help you understand the data and the fields that are available.Index Mappings:{index_mappings}Only include the fields that are relevant for each visualization, based on what is visible in the image."""message = [{"role": "user","content": [{"type": "text", "text": prompt},{"type": "image","source_type": "base64","data": image_base64,"mime_type": "image/png",},],}
]try:llm = init_chat_model("gpt-4.1-mini")llm = llm.with_structured_output(Dashboard)dashboard_values = llm.invoke(message)print("Dashboard values generated by the LLM successfully")print(dashboard_values)
except Exception as e:print(f"Failed to analyze image and match fields: {str(e)}")

LLM 已经具备关于 Kibana 仪表板的上下文,因此我们不需要在提示词中解释所有内容,只需添加一些细节,以确保它不会忘记当前处理的是 Elasticsearch 和 Kibana。

让我们来拆解这个提示词:

SectionReason
You are an expert in analyzing Kibana dashboards from images for the version 9.0.0 of Kibana.

通过强调这是 Elasticsearch 以及指定 Elasticsearch 的版本,可以降低 LLM 产生旧的或无效参数的可能性。

You will be given a dashboard image and an Elasticsearch index mapping.

我们说明图像是关于仪表板的,以避免 LLM 产生错误的解读。

Below are the index mappings for the index that the dashboard is based on.Use this to help you understand the data and the fields that are available. Index Mappings: {index_mappings}

提供 mappings 至关重要,这样 LLM 才能动态选择有效字段。否则我们只能在这里写死 mappings,太死板,或者依赖图像中包含正确的字段名,但这种方式不可靠。

Only include the fields that are relevant for each visualization, based on what is visible in the image.

我们必须添加这个强化说明,因为有时它会尝试添加与图像无关的字段。

这将返回一个包含可显示可视化数组的对象:

"Dashboard values generated by the LLM successfully
title=""Client, Extension, OS, and Response Keyword Analysis""visualizations="["Visualization(title=""Count of Client IP","type="["metric"],"field=""clientip"")","Visualization(title=""Extension Keyword Distribution","type="["pie"],"field=""extension.keyword"")","Visualization(title=""Most Used OS","type="["bar"],"field=""machine.os.keyword"")","Visualization(title=""Response Keyword Distribution","type="["bar"],"field=""response.keyword"")"
]

处理 LLM 响应

我们创建了一个示例的 2x2 面板仪表板,然后使用 Get a dashboard API 导出为 JSON,再将面板存储为可视化模板(饼图、条形图、指标),可以根据问题替换部分参数以创建不同字段的新可视化。

你可以在这里看到模板 JSON 文件。注意我们如何用 {variable_name} 替换想要后续替换的对象值。

根据 LLM 提供的信息,我们可以决定使用哪个模板以及替换哪些值。

fill_template_with_analysis 函数将接收单个面板的参数,包括可视化的 JSON 模板、标题、字段,以及可视化在网格上的坐标。

然后,它会替换模板中的值,返回最终的 JSON 可视化结果。

def fill_template_with_analysis(template: Dict[str, Any],visualization: Visualization,grid_data: Dict[str, Any],
):template_str = json.dumps(template)replacements = {"{visualization_id}": str(uuid.uuid4()),"{title}": visualization.title,"{x}": grid_data["x"],"{y}": grid_data["y"],}if visualization.field:replacements["{field}"] = visualization.fieldfor placeholder, value in replacements.items():template_str = template_str.replace(placeholder, str(value))return json.loads(template_str)

为了简化,我们会使用固定坐标分配给 LLM 决定创建的面板,生成如上图所示的 2x2 网格仪表板。

# Filling templates fields
panels = []    
grid_data = [{"x": 0, "y": 0},{"x": 12, "y": 0},{"x": 0, "y": 12},{"x": 12, "y": 12},
]i = 0for vis in dashboard_values.visualizations:for vis_type in vis.type:template = templates.get(vis_type, templates.get("bar", {}))filled_panel = fill_template_with_analysis(template, vis, grid_data[i])panels.append(filled_panel)i += 1

根据 LLM 决定的可视化类型,我们会选择对应的 JSON 模板文件,使用 fill_template_with_analysis 替换相关信息,然后将新面板添加到数组,稍后用来创建仪表板。

当仪表板准备好后,我们会使用 Create a dashboard API 将新的 JSON 文件推送到 Kibana,生成仪表板:

try:dashboard_id = str(uuid.uuid4())# post request to create the dashboard endpointurl = f"{os.getenv('KIBANA_URL')}/api/dashboards/dashboard/{dashboard_id}"dashboard_config = {"attributes": {"title": dashboard_values.title,"description": "Generated by AI","timeRestore": True,"panels": panels,  # Visualizations with the values generated by the LLM"timeFrom": "now-7d/d","timeTo": "now",},}headers = {"Content-Type": "application/json","kbn-xsrf": "true","Authorization": f"ApiKey {os.getenv('ELASTICSEARCH_API_KEY')}",}requests.post(url,headers=headers,json=dashboard_config,)# Url to the generated dashboarddashboard_url = f"{os.getenv('KIBANA_URL')}/app/dashboards#/view/{dashboard_id}"print("Dashboard URL: ", dashboard_url)print("Dashboard ID: ", dashboard_id)except Exception as e:print(f"Failed to create dashboard: {str(e)}")

要执行脚本并生成仪表板,请在控制台运行以下命令:

python <file_name>.py

最终结果将如下所示:

Dashboard URL: https://your-kibana-url/app/dashboards#/view/generated-dashboard-id
Dashboard ID: generated-dashboard-id

结论

LLM 在文本转代码或将图像转为代码时展现出强大的视觉能力。仪表板 API 也使得将 JSON 文件转换为仪表板成为可能,结合 LLM 和一些代码,我们可以将图像转成 Kibana 仪表板。

下一步是通过使用不同的网格设置、仪表板尺寸和位置,提升仪表板视觉的灵活性。同时,支持更复杂的可视化和更多类型的可视化,将是该应用的有益补充。

原文:AI-powered dashboards: From a vision to Kibana - Elasticsearch Labs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89450.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89450.shtml
英文地址,请注明出处:http://en.pswp.cn/web/89450.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI产品经理面试宝典第17天:AI时代敏捷开发与MVP构建面试题与答法

机器学习MVP构建问题怎么答? 面试官:请举例说明如何将业务问题转化为机器学习可解的问题? 你的回答:以电商供应商评价为例,传统方法用人工设定的低维度指标评分,而机器学习能利用大数据构建高维模型。比如通过供应商历史交易数据、物流时效、售后投诉率等数百个特征,训…

HBase2.5.4单机模式与伪分布式的安装与配置(Ubuntu系统)

HBase的安装也分为三种&#xff0c;单机模式、伪分布式模式、完全分布式模式&#xff1b;我们先来安装单机版。 一、环境准备 1. 系统要求 Ubuntu 20.04/22.04 LTS Java 8&#xff08;必须&#xff0c;HBase不兼容更高版本&#xff09; Hadoop&#xff08;单机模式不需要&a…

Honeywell霍尼韦尔DV-10 变速器放大器 输入 15-28 VDC,输出 +/- 10VDC 060-6881-02

Honeywell霍尼韦尔DV-10 变速器放大器 输入 15-28 VDC,输出 /- 10VDC 060-6881-02

腾讯位置商业授权鸿蒙地图SDK工程配置

工程配置 安装 DevEco Studio 开发环境 手机HarmonyOS系统&#xff1a;OpenHarmony-5.0.0.71及以上DevEco Studio版本&#xff1a;DevEco Studio NEXT Release(Build Version: 5.0.3.900)及以上 获取key与生成秘钥 获取key 登录腾讯位置服务控制台&#xff0c;未注册过账号可…

RocketMQ源码级实现原理-Commitlog刷盘机制

刷盘机制 同步刷盘 代码实现 写入线程 写入线程可能同时有多个&#xff0c;但是刷盘线程至始至终就是一个单线程 刷盘线程&#xff0c;始终是操作双缓冲区域&#xff0c;一个用来刷盘&#xff0c;另一个用来接收多个写入线程同时写入刷盘请求 刷盘线程 通过这种方式&#xff0…

Java与Vue技术搭建的SRM招标采购管理系统,提供源码,涵盖招标、投标、评标全流程,助力企业高效规范采购管理

前言&#xff1a;在当今竞争激烈的商业环境中&#xff0c;高效、透明、规范的招标采购流程对于企业的成本控制、供应链稳定以及整体运营效率至关重要。SRM招标采购管理系统应运而生&#xff0c;它借助先进的信息技术&#xff0c;整合了招标采购的各个环节&#xff0c;实现了采购…

Kotlin集合分组

集合的分组&#xff08;Grouping&#xff09; 在之前的学习中&#xff0c;我们已经学会了如何对集合进行过滤、排序或执行聚合操作。 在本节中&#xff0c;我们将学习如何对集合元素进行分组&#xff0c;以便以最适合我们任务的方式呈现信息。分组&#xff08;Grouping&#xf…

阿里云ssh证书过期,如果更换并上传到服务器

登录阿里云平台&#xff0c;在控制台中找到“数字证书管理服务”进入频道后&#xff0c;选择“SSL证书管理”点击“创建证书”&#xff0c;创建成功后&#xff0c;进入证书详情页选择“下载”板块&#xff0c;根据自身服务器类型&#xff0c;下载相应的证书即可服务器更新证书登…

【软件系统架构】系列七:系统性能——计算机性能深入解析

目录 一、什么是计算机性能&#xff1f; 二、计算机性能核心指标 1. CPU性能指标 2. 内存性能指标 3. 存储子系统性能 4. 网络性能指标 5. 系统资源使用与并发能力 三、性能瓶颈分析方法 四、计算机性能评测与对比 常见性能测试指标与工具&#xff1a; 五、计算机性…

基于现代R语言【Tidyverse、Tidymodel】的机器学习方法

机器学习已经成为继理论、实验和数值计算之后的科研“第四范式”&#xff0c;是发现新规律&#xff0c;总结和分析实验结果的利器。机器学习涉及的理论和方法繁多&#xff0c;编程相当复杂&#xff0c;一直是阻碍机器学习大范围应用的主要困难之一&#xff0c;由此诞生了Python…

Python暑期学习笔记5

时间&#xff1a;2025.7.18学习内容&#xff1a;【语法基础】while循环与循环嵌套一、循环语句循环流程图二、while循环基本格式&#xff1a;while条件&#xff1a;循环体&#xff08;条件满足时段做的事情&#xff09;改变变量死循环while True:循环体&#xff08;要循环做的事…

world models and Human–Object Interaction (HOI)

Author: Chatgpt Here are several key research papers that explore the intersection of world models and Human–Object Interaction (HOI)—especially ones that build structured, object-centric representations from videos or use world-model-based learning to p…

无人值守共享自习室物联系统安全防线:从设备到数据的全面防护策略!

在“全民学习”浪潮的推动下&#xff0c;无人值守共享自习室凭借24小时开放、灵活预约和沉浸式体验&#xff0c;已成为城市学习空间的新形态。而当人力值守被物联网设备替代后&#xff0c;安全风险却从物理世界延伸到了数字世界。一套完整的自习室物联网系统包含门禁、传感器、…

【27】MFC入门到精通——MFC 修改用户界面登录IP IP Address Control

界面搭建 将【IP Address Control】控件&#xff0c;【Edit Control】控件和两个【button】控件分别拖入主界面 将ID分别修改为&#xff1a;IDC_IP_ADDRESS IDC_IPADDRESS_EDIT IDC_GET_BUTTON IDC_CLEAN_BUTTON添加变量 为【IP Address Control】控件添加变量【m_IPaddress】&…

MacOS安装linux虚拟机

在学习docker时用的云环境本身就是一个容器&#xff0c;启动docker总是各种问题&#xff0c;所以直接在本机上装一个虚拟机。 当前系统环境&#xff1a; 安装虚拟机软件 安装UTM 下载官网&#xff1a;https://mac.getutm.app/ uname -m查看一下指令架构&#xff0c;下载…

TimSort:论Java Arrays.sort的稳定性

TimSort 是一种混合的、稳定的排序算法&#xff0c;结合了归并排序&#xff08;Merge Sort&#xff09;和二分插入排序&#xff08;Binary Insertion Sort&#xff09;的优点&#xff0c;尤其适用于部分有序的数据。在 Java 中&#xff0c;Arrays.sort() 对对象数组排序时内部使…

企业数据生命周期安全架构设计

数据是企业的生命线&#xff0c;而安全则是这条生命线的保护神。今天我们就来聊聊如何为企业数据的一生一世构建一套坚不可摧的安全防护体系。 &#x1f4da; 文章目录 为什么需要数据生命周期安全架构数据生命周期全景图安全架构设计的核心原则各阶段安全防护策略整体安全架构…

【Java】字符串常量池

文章目录一.字符串常量池(StringTable)1.1 定义1.2 演示示例1.3 intern方法一.字符串常量池(StringTable) 1.1 定义 字符串常量词本质是一个固定大小的HashTable。当用一个字符串构造String对象时&#xff0c;首先会去StringTable中查看是否存在在字符串&#xff0c;如果存在…

数据通信与计算机网络——模拟传输

主要内容数字到模拟转换幅移键控ASK频移键控FSK相移键控PSK正交振幅调制QAM模拟信号调制调幅AM调频FM调相PM一、数字到模拟转换数字信号需要低通通道&#xff0c;如果现实应用中只有带通通道&#xff0c;只能选择模拟信号进行传输。将数字数据转换为带通模拟信号&#xff0c;传…

如何用Python并发下载?深入解析concurrent.futures 与期物机制

concurrent.futures模块的核心价值 Python的concurrent.futures模块提供了线程池&#xff08;ThreadPoolExecutor&#xff09;和进程池&#xff08;ProcessPoolExecutor&#xff09;两种并发模型&#xff0c;通过高层接口简化并发编程。其核心优势在于&#xff1a; 自动管理资源…