人工智能驱动的仪表盘:从设想到 Kibana
使用 LLM 生成仪表盘,处理图像并将其转化为 Kibana 仪表盘。
Kibana Lens让仪表盘的拖放变得非常简单,但当你需要几十个面板时,点击次数就会增加。如果你能勾画出一个仪表盘,截图后让法律硕士为你完成整个过程,那会怎么样?
在本文中,我们将实现这一目标。我们将创建一个应用程序,它可以获取仪表盘的图像,分析映射,然后生成仪表盘,而无需接触 Kibana!
步骤:
后台& 应用程序工作流程
我首先想到的是让 LLM 生成整个 NDJSON 格式的 Kibana保存对象,然后将它们导入 Kibana。
我们尝试了几种型号:
双子座 2.5 pro
GPT o3 / o4-mini-high / 4.1
克劳德 4 号十四行诗
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 给出的参数来创建适当的可视化。
申请工作流程如下:

为简单起见,我们将省略一些代码,但您可以在 本 笔记本上找到完整应用程序的工作代码 。
准备工作
在开始开发之前,您需要具备以下条件:
Python 3.8 或更高版本
VenvPython 环境
运行的 Elasticsearch 实例及其端点和 API 密钥
存储在环境变量 OPENAI_API_KEY 下的 OpenAI API 密钥:
export OPENAI_API_KEY="your-openai-api-key"准备数据
在数据方面,我们将保持简单,使用 Elastic 样本网络日志。您可以在此了解如何将这些数据导入群集。
每份文档都包含向应用程序发出请求的主机的详细信息,以及请求本身及其响应状态的信息。下面是一个文件示例:
{
"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 -qElasticsearch 将帮助我们检索索引映射。Pydantic 允许我们在 Python 中定义模式,然后要求 LLM 遵循这些模式,而LangChain框架则有助于更轻松地调用 LLM 和人工智能工具。
我们将创建一个 Pydantic 模式,以定义我们希望从 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 索引的映射和我们要生成的仪表盘图像。
通过with_structured_output ,我们可以使用 PydanticDashboard 模式作为 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。
让我们来分析一下提示:
部门 | 原因 |
|---|---|
您是根据 Kibana 9.0.0 版本的图像分析 Kibana 仪表板的专家。 | 通过强化 Elasticsearch 和 Elasticsearch 版本,我们降低了 LLM 产生旧参数/无效参数的可能性。 |
您将获得一个仪表盘图像和一个 Elasticsearch 索引映射。 | 我们解释说,图片是关于仪表盘的,以避免法律硕士做出任何错误的解释。 |
下面是仪表盘所基于的索引的索引映射,使用它可以帮助你理解数据和可用字段。索引映射: {index_mappings} | 提供映射至关重要,这样 LLM 才能动态选择有效字段。否则,我们就可能在这里硬编码映射,这太死板了,或者依靠图像包含正确的字段名,这也不可靠。 |
根据图像中可见的内容,只包含与每个可视化相关的字段。 | 我们必须添加这一增强功能,因为有时它会尝试添加与图像无关的字段。 |
这将返回一个包含要显示的可视化数组的对象:
"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 面板仪表盘示例,然后使用 "获取仪表盘 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.field
for 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 = 0
for 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 替换相关信息,然后将新面板追加到稍后用于创建仪表盘的数组中。
仪表盘准备就绪后,我们将使用 创建 仪表盘 API 将新的 JSON 文件推送到 Kibana 以生成仪表盘:
try:
dashboard_id = str(uuid.uuid4())
# post request to create the dashboard endpoint
url = 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 dashboard
dashboard_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最终结果将是这样的

仪表板 URL: https://your-kibana-url/app/dashboards#/view/generated-dashboard-id 仪表板 ID: generated-dashboard-id
结论
在将文本转化为代码或将图像转化为代码时,LLM 展示了其强大的视觉能力。仪表盘 API 还能将 JSON 文件转化为仪表盘,而通过 LLM 和一些代码,我们就能将图片转化为 Kibana 仪表盘。
下一步是通过使用不同的网格设置、仪表盘大小和位置来提高仪表盘视觉效果的灵活性。此外,为更复杂的可视化和可视化类型提供支持也是对该应用程序的有益补充。




