如果你正在搞 n8n 智能体开发,想给 AI Agent 接上监控数据能力,那 Grafana 这个节点几乎是绕不开的。我最近把一个告警自动处理项目从想法跑通到落地,核心就是让智能体能随时查询 Grafana 里的指标和告警状态。这篇记录一下整个实践过程,包括我为什么这么设计、具体怎么接、以及踩过的坑,给同样在做 n8n + Grafana 集成的朋友一个可复现的参考。
先声明一下,我这里说的“Grafana 节点”,不一定特指 n8n 节点库里现成的官方节点。因为实际用下来,官方节点的封装偏“管理对象”,比如拉仪表盘、拉数据源列表;而我要的“查指标”能力,用 HTTP Request 节点自己签一条请求反而更直白。后面我会把两种方式都讲清楚,你可以按需选择。
1. 为什么要把Grafana塞进n8n智能体
1.1 监控数据是智能体决策的“传感器”
智能体的本质是大模型加工具调用。大模型再聪明,也没有办法直接知道你现在线上服务是绿的还是红的。想要让它回答“当前系统压力大不大”“最近十分钟错误率有没有上升”,就必须给它一个获取监控数据的入口。Grafana 就是那个入口的集合地,它聚合了 Prometheus、Loki、InfluxDB 等一堆数据源,对外提供了统一的 HTTP API。接上 Grafana 节点,等于给智能体装了一个“仪表盘眼睛”。
我之前看过不少团队做智能体,只接知识库和搜索引擎,完全不接监控数据。结果智能体只能聊概念,没法回答任何关于线上状态的问题。一旦遇到“帮我看看刚才告警发生时 CPU 是不是打满了”这种请求,就直接宕机。所以如果你在做运维或架构方向的智能体,Grafana 节点不是一个锦上添花的插件,而是一个刚需。
1.2 从被动告警到主动排查的转变
传统的告警链路是:Grafana 触发告警 -> 钉钉/邮件通知 -> 值班人爬起来查面板。这个过程有几个痛点,一是告警内容往往只有缩略信息和标签,不够直白;二是排查结论完全依赖人的经验,新人很难快速上手。接入 n8n 智能体之后,链路变成:Grafana 触发告警 -> Webhook 进 n8n -> 智能体自动调用 Grafana 节点拉取相关指标 -> 生成一份结构化排查报告 -> 推给值班群。
我试着跑通了这条链路之后,最直观的感受是“人越来越少的操作重复动作”。告警来了,不再是先慌着找面板,而是先看智能体给出的摘要,再去验证细节。这个过程不是我凭空想象的,某运维团队实际落地后,每周至少省出十几个小时的重复查询时间。别看这个数字不大,遇到大促或者故障演练,价值会成倍放大。
2. 摸清Grafana API的底细再动手
2.1 先列一张常用接口清单
做任何集成,第一件事不是写代码,而是搞清楚对方提供哪些接口、认证方式是什么。Grafana 的 HTTP API 非常完整,但文档分散。我用得比较多的接口整理如下:
| 用途 | 接口 | 请求方式 |
|---|---|---|
| 获取数据源列表 | /api/datasources | GET |
| 通过数据源代理查询 PromQL | /api/datasources/proxy/{dataSourceId}/api/v1/query | GET |
| 范围查询:某个时间段内的指标 | /api/datasources/proxy/{dataSourceId}/api/v1/query_range | GET |
| 搜索仪表盘 | /api/search?type=dash-db | GET |
| 告警规则列表 | /api/v1/provisioning/alert-rules | GET |
其中使用频率最高的是 query 和 query_range。query 适合查当前值,比如“现在 CPU 多少”;query_range 适合看趋势,比如“过去15分钟的错误率曲线”。在 n8n 里,我通常把它们封成两个独立的工具节点,而不是塞进一个大节点里。原因是 Agent 调用时,描述越单一,调用越不容易出错。
有一点要注意,Grafana 的接口版本不同,路径细节会有差异。比如 9.x 和 10.x 在告警接口上区别就挺大。我的建议是先去浏览器开发者工具里抓一下 Grafana 界面发起的请求,以实际请求为准。
2.2 认证选型:服务账号Token最省心
Grafana 提供三种常见认证方式:Basic Auth(用户名密码)、API Key、服务账号 Token(Service Account Token)。早期 API Key 用得比较多,但它和用户账号绑定,不太好收敛权限和轮换密钥。现在新建项目我统一用服务账号 Token。
具体操作:进入 Grafana 的 Administration -> Service accounts -> Add service account,给它起个名字比如“n8n-readonly”,角色选 Viewer 就够了。创建之后点 Add token,生成一段以glsa_开头的 token,复制保存好,关闭页面之后不会再看到第二次。
我用 Viewer 角色不是因为够用就行,而是刻意限制风险:n8n 工作流如果被恶意触发,最多只能读到监控数据,改不了面板、删不了数据源。你永远不知道某个工作流里的表达式会不会有意外副作用,权限做小一点,出事了也能兜底。
2.3 为什么我后来放弃了现成的 Grafana 节点
n8n 节点库里有一个 Grafana 节点,它封面确实写着 Grafana。但我上手一用,发现它的操作列表主要围绕对象管理,比如创建仪表盘、更新数据源、获取组织信息。而我最关心的“执行 PromQL 查询”却没有直接暴露。也可能是我用的版本还没更新,不管怎么说,用 HTTP Request 去调 Grafana API,反而是最灵活、最不会受节点版本限制的方案。
所以我的策略是:把“通过 HTTP Request 调 Grafana API”这件事封装成一个正经的 Grafana 节点,挂在 n8n 的子工作流里。这样既保留节点化的使用体验,又不受官方节点封装限制,还能让 AI Agent 把它当工具调用。
3. 从零搭一个能查指标的Grafana节点工作流
3.1 测试数据源列表请求
在 n8n 里新建一个工作流,先拖一个“HTTP Request”节点,方法选 GET,URL 填:
{{YOUR_GRAFANA_URL}}/api/datasourcesAuthentication 选择 “Generic Credential Type” 或自定义 Header。我用的是自定义 Header,直接加一行:
Authorization: Bearer {{serviceAccountToken}}之所以不把 token 直接写在 URL 或 Body 里,是因为日志和错误信息里可能会泄露。n8n 有 Credential 机制,建议把 baseUrl 和 token 都存到 Credential 或环境变量里,节点里只写{{$credentials.grafanaToken}}这种引用。
跑一次,应该能看到一个 JSON 数组,里面是当前 Grafana 里所有的数据源信息。重点关注两个字段:id和type。比如 Prometheus 数据源 type 就是prometheus,id 可能是数字。这一步能跑通,说明认证和网络都没问题。
3.2 用数据源ID拼出指标查询
接下来把 URL 拼成全的:
{{YOUR_GRAFANA_URL}}/api/datasources/proxy/{{dataSourceId}}/api/v1/query?query=up这里{{dataSourceId}}用上一节返回结果里的某个 id。query=up是 PromQL 最简单的一句,表示每个实例是否在线。如果返回 JSON 里有 result 数组,说明代理查询也通了。
如果需要查时间范围,使用 query_range,并带上 start、end、step 三个参数。start 和 end 要用 Unix 时间戳(秒),step 是采样间隔,比如60表示每分钟一个点。我一般用 n8n 的表达式动态生成:start 填{{ Math.floor(Date.now() / 1000) - 900 }},end 填{{ Math.floor(Date.now() / 1000) }},这样刚好是过去 15 分钟。
注意这里有个 n8n 的小坑:Date.now()返回的是毫秒,直接传进去会超出 Prometheus 能接受的合理范围,导致查询结果为空。所以必须除以 1000,再取整。我第一次就是忘了取整,得到的是小数时间戳,Prometheus 居然也接受了,但查询范围完全不对,一度以为是数据源问题。
3.3 把两步串成子工作流
如果你想省事,每次手动填数据源 ID 也能跑,但不优雅。我把第一步“拿数据源列表”和第二步“查指标”拆成两个节点,用 n8n 的表达式把第一个节点的输出传给第二个节点。第二个节点的 URL 可以这样写:
{{YOUR_GRAFANA_URL}}/api/datasources/proxy/{{$json[0]['id']}}/api/v1/query?query=up这里$json[0]取的是第一个数据源。生产环境数据源数量有限,我更常做的是把数据源 ID 存到 n8n 静态变量里,因为除非数据源被重建,这个 ID 一般不会变。手动填 ID 反而更稳定,少一次请求。
工作流跑通之后,我建议在节点上右键 Test workflow,把各种输入参数都测一遍,确保 n8n 表达式对数组取值的路径正确。这个阶段多花几分钟,后面接 Agent 时能省一大把时间。
4. 把Grafana工具交给AI Agent的正确姿势
4.1 Agent节点里注册一个子工作流工具
在 n8n 中新建一个 AI Agent 节点,选择你常用的模型(我本地跑的是开源模型,线上用的大模型都行),然后在 Tools 区域添加工具。工具来源选择“Sub-workflow Tool”,然后选择你刚才做好的那个 Grafana 查询子工作流。
这里有一件很关键的事:工具的描述。Agent 不会看你的节点连接,它只靠描述来理解工具。所以我给工具写的名称是get_grafana_metric,描述是:
获取Grafana中的监控指标。输入promql是PromQL查询表达式,startTime和endTime是Unix时间戳(秒)。返回result数组,其中value是[时间戳, 数值]。你可以看到,我明确写了输入字段名、类型、返回结构。这一点对 Agent 正确处理数据至关重要。描述写得太含糊,比如“获取监控数据”,模型就会乱猜参数名,传成字符串而不是数字,导致请求直接 400。
4.2 设计输入参数,让模型替你拼PromQL
子工作流接收的参数,需要映射到 HTTP Request 节点的 Query Parameters 上。具体做法是:在子工作流设置里定义输入参数名promql、startTime、endTime、step,然后在 HTTP Request 节点的 Query Parameters 里引用它们:
query:{{ $json.promql }}start:{{ $json.startTime }}end:{{ $json.endTime }}step:{{ $json.step || '60' }}
真正跑起来之后,你会发现模型拼 PromQL 的能力比预想中强。比如你问它“看看最近5分钟的平均CPU使用率”,它可能会生成:
100 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100这个查询在大多数 Prometheus 环境下都能正常返回。但也有翻车的时候,比如某个指标名称在环境里根本不存在,模型会凭借训练数据瞎编。我建议在工具描述里附上几个可用指标的示例,或者在系统提示词里给一份“指标白名单”。没有白名单兜底,第一次演示很容易拉回来一张空图。
4.3 别让模型在不需要时乱调工具
还有一个容易被忽略的问题:Agent 可能会过度调用。比如用户只是问“今天天气怎么样”,Agent 判断系统里有个 Grafana 工具,就顺手调一下,造成无意义的开销。解决方法是系统提示词里写明“仅在问题涉及当前系统运行状态、监控指标、告警信息时,才调用 Grafana 工具”。
经验之谈,工具函数的门槛设高一点,宁可偶尔漏调,也不要频繁误调。监控查询虽然不贵,但每次调用都会增加几十秒延迟和 token 消耗,在高频群里体验很差。
5. 告警自动处理场景:从Webhook到排查报告
5.1 完整链路设计
现在把 Grafana 节点放进一个更贴近生产的场景:Grafana 告警触发后,自动让智能体产出排查报告。整体链路如下:
- Grafana 的告警规则配置 Contact point,类型为 Webhook,地址指向 n8n 的 Webhook 节点。
- n8n Webhook 节点收到告警 payload,包含 alertName、status、labels、annotations。
- 经过一个简单的条件判断:status 是否为 firing,避免 resolved 也触发全流程。
- 调用 AI Agent 节点,把告警原始内容塞进系统提示词,并让 Agent 决定是否需要继续查 Grafana。
- Agent 调用 Grafana 工具获取相关指标,生成结构化排查报告。
- 将报告通过 IM Webhook(比如钉钉、飞书、Slack)发送,同时也可以写入到一个自定义的记录表里。
我在实际搭建时,把第 4 步和第 5 步写在一个 Agent 节点里,没有拆开。原因是 Agent 需要根据告警的内容动态判断查询哪些指标,如果预先设定好固定查询,就失去“智能”的意义了。
5.2 系统提示词的一个可复用模板
下面这段提示词我一直在改,目前的版本效果还可以:
你是值班助理。收到告警后,你必须: 1. 先调用 get_grafana_metric 工具获取相关指标,不要凭经验猜测; 2. 根据告警标签和指标趋势给出可能原因; 3. 输出格式固定为:影响范围、关键指标、可能原因、建议操作; 4. 如果数据不足,明确说明“数据不足”,不要编造。这段提示词里最重要的是第 1 条:先查数据再下结论。大模型天然有“脑补”倾向,不给这个约束,它会在没拿到任何数据的情况下写出一篇看起来很有道理的报告,那还不如不接 Grafana。
另外,很多人会忽略一点:给 Agent 提供上下文不只是告警 JSON,还可以把我们环境里常见的几个业务面板 URL 放进去。这样它在查完指标后,如果怀疑某个面板相关,可以直接把面板链接附在报告里,方便值班人快速跳转。
5.3 防止告警风暴打爆智能体
告警风暴是运维里最常见的问题,一条大故障往往触发几十条类似告警。如果每个 Webhook 都进入 Agent 流程,不仅费用失控,IM 群也会被刷屏。我用的去重逻辑很简单:
- 以 label 里的
alertname+startsAt作为去重键; - n8n 里加一个 Wait 节点,或者用 Redis 节点存一个标记;
- 如果同一告警在 15 分钟内重复触发,直接丢弃,只有首次和状态变化才进入 Agent。
这算不上什么高深技巧,但如果不在开始设计,后患无穷。我自己第一个版本没加去重,测试时连续触发了三次告警,结果群里一下子塞满了三份几乎一样的报告。
6. 实测中踩过的五个坑和解决方案
6.1 403 权限:Token角色和API Key的坑
第一次用 API Key 时,我明明创建了,但查询接口还是 403。检查后发现,旧版 API Key 的权限模型和现在的服务账号不一样,某些新接口就是不认旧 Key。后来换成服务账号 Token,并在创建时勾选需要的权限范围,问题就消失了。
这里补充一点:如果 Grafana 版本较老,服务账号概念还没普及,可能只能用 API Key。遇到这种情况,至少给 API Key 选一个只读角色,并在 n8n Credential 里把 token 标记为 Restricted,避免其他工作流误用。
6.2 时间戳精度和格式:查询结果莫名为空
前面提到过,Date.now()是毫秒级,而 Prometheus 的 start/end 需要秒级时间戳。另一个坑是,某些 API 接受字符串形式的 RFC3339,比如2025-04-01T10:00:00Z,但代理接口不一定兼容。
稳妥的做法是:统一在 n8n 表达式里传秒级时间戳,并且用Math.floor()而不是parseInt(),因为parseInt(Date.now()/1000)在 n8n 表达式引擎里偶尔会因为参数类型问题报错。我怀疑是类型推断的锅,但用Math.floor从来没出过问题。
6.3 PromQL 返回的数组结构解析
Grafana 通过 query_range 返回的数据,结构大概长这样:
{ "data": { "result": [ { "metric": { "__name__": "node_load1" }, "values": [[1700000000, "1.23"], [1700000060, "1.35"]] } ] } }n8n 的表达式里,要从这样一串嵌套 JSON 里取出最新值,很多人会写错。正确路径是:
{{ $json['data']['result'][0]['values'][$json['data']['result'][0]['values'].length - 1][1] }}写这类表达式时,建议先用{{ JSON.stringify($json) }}把整个日志打出来,手动确认层级。我看到太多小伙伴一上来直接猜路径,结果取到[object Object],还以为是 n8n 不支持 JSON。
6.4 数据源ID写死导致查不到指标
我曾经图省事,把数据源 ID 直接写死在 URL 里。后来某次 Grafana 从备份迁移恢复,数据源 ID 全变了,所有工作流一下子都查不到数据,排查了半天才发现。从那以后,我每次部署至少会去/api/datasources验证一遍当前 ID。如果能接受额外一次请求,最好还是设计成动态获取。
6.5 Agent 乱调用工具导致的高延迟和消耗
这个坑可能不算 Grafana 特有,但对本文场景特别常见。当工具描述不当,Agent 即使是在闲聊中也会去调用 Grafana 查询,导致响应从 1 秒变成 15 秒。我的缓解办法是在系统提示词里加一句“如果用户没有明确提到当前系统、服务、监控相关概念,不要调用 get_grafana_metric,直接回答”。类似的约束对每个工具都适用。
一路跑下来,我最大的体会是:n8n 智能体开发中的 Grafana 节点,核心价值不是把“查面板”这个动作变成 API 调用,而是把监控数据从“给人看的仪表盘”变成“给机器用的上下文”。这中间真正花时间的部分,不是节点怎么连,而是怎么让智能体在正确的时候、用正确的方式、拿正确的数据。我建议所有刚开始做这个方向的朋友,先手工用 HTTP Request 把 Grafana API 跑通,再考虑封装成 Agent 工具。这样每一步的结果都可预测,后续排查问题也会简单很多。
后续我打算在这个基础上接入知识库和故障历史,让智能体在报告里不仅给出指标,还能引用同类故障的处理方案。等实践更成熟了,再回来继续分享其中的细节。