测评大模型的PromQL能力
OpsPilot 项目实践:构建 PromQL 生成能力 Benchmark,并完成大模型选型
这篇博客记录的是我们在 OpsPilot 创新实训项目中的一次阶段性工作:围绕“让大模型自动生成 PromQL”这个能力,搭建了一套 benchmark,扩充测试集,设计 prompt,完成自动评分,并基于真实评测结果做了一轮模型选型。
这不是一篇单纯的 PromQL 教程,而是一次比较完整的工程实践记录。我们并不是简单地“调用一个大模型写 PromQL”,而是尝试把 PromQL 生成这件事做成一个可评测、可复现、可接入后端的模块。
1. 项目背景:OpsPilot 为什么需要 PromQL 生成能力
OpsPilot 是一个面向智能运维场景的 Agent 平台。它的目标不是只回答“哪里可能有问题”,而是能够结合告警、指标、日志、服务状态等上下文,辅助用户完成故障排查。
在真实运维流程中,Prometheus 是非常常见的指标系统,而 PromQL 是查询指标的核心语言。例如:
- 服务是否存活?
- 最近 5 分钟 QPS 是否升高?
- 5xx 错误率是多少?
- 哪个接口 P95 / P99 延迟最高?
- 数据库是否不可用?
- 服务是否刚刚重启?
- 是否存在日志风暴?
这些问题都可以通过 PromQL 查询 Prometheus 得到答案。
但是 PromQL 对普通用户并不友好。写对一个查询,需要知道指标名是什么、label 有哪些、counter 类型指标是否应该用 rate 或 increase、histogram 分位数是否应该用 histogram_quantile、聚合时是否保留了正确 label、错误率分母是否需要保护除零等。
因此,我们希望 OpsPilot 能够根据用户问题、告警场景和可用指标上下文,自动生成可靠的 PromQL 查询。
2. 为什么要专门评测 PromQL 生成能力
一开始很容易有一个误区:既然大模型看起来会写 PromQL,那是不是直接接进去就行?
实际测试后发现,不能这么简单。
PromQL 生成和普通文本生成不一样,它有很强的工程约束。一个查询看起来像是对的,但可能存在很多隐蔽问题:
- 使用了当前系统里不存在的指标名;
- 使用了 metric context 中没有声明的 label;
- 对 counter 指标直接求平均,没有使用
rate或increase; - 错误率分母没有使用
clamp_min保护,可能出现除零; - 使用 histogram 计算 P95 / P99 时没有保留
lelabel; - 用户问题里没有相关指标时,模型却编造了一个指标;
- 输出中混入 Markdown、解释文字或推理过程,导致后端无法稳定解析。
所以我们决定不只“凭感觉”选模型,而是先构建一套 PromQL 生成能力 benchmark,用统一测试集、统一 prompt、统一评分逻辑去比较不同模型。
3. Benchmark 模块设计
本次新增的模块位于:
benchmarks/promql_llm_eval/
核心结构如下:
benchmarks/promql_llm_eval/
README.md
.env.example
requirements.txt
config/
models.yaml
data/
promql_cases.yaml
metric_catalog.yaml
prompts/
zero_shot.md
few_shot.md
structured_output.md
structured_fewshot.md
src/
dataset.py
llm_client.py
run_benchmark.py
evaluate.py
scoring.py
prometheus_validator.py
report.py
docs/
promql_llm_eval_final_summary.md
promql_integration_recommendation.md
几个关键文件的作用如下:
promql_cases.yaml:PromQL 测试集,目前包含 50 条 case;metric_catalog.yaml:指标目录,记录指标名、类型、label、用途和常见 PromQL 模式;structured_fewshot.md:当前推荐的默认 prompt;run_benchmark.py:批量调用不同大模型;scoring.py:自动评分逻辑;prometheus_validator.py:后续可用于连接 Prometheus 做实际查询验证;docs/:保存可提交、可复用的最终报告和接入建议。
这套结构的目标是让 PromQL 生成能力不只是一个临时测试脚本,而是后续可以继续维护和扩展的子模块。
4. 测试集设计:从简单查询到边界反例
本次我们将 PromQL 测试集扩展到了 50 条 case,覆盖了 OpsPilot 后续可能遇到的主要运维场景。
覆盖类别包括:
-
基础查询
- 服务存活
up; - 按
job、instance、service过滤; - 当前 gauge 值查询;
- 故障开关状态查询。
- 服务存活
-
QPS / Counter 类查询
rate;increase;- counter 不能直接
avg; - 过去 5 分钟每秒速率;
- 过去 10 分钟新增请求数;
- 按
path、method、status聚合请求量。
-
错误率查询
- 全局 5xx 错误率;
- 按接口计算 5xx 错误率;
- 按服务计算错误率;
- 按状态码聚合;
- 使用
clamp_min(..., 1e-9)保护分母; - 区分 4xx 和 5xx;
- success rate 成功率。
-
延迟查询
- P50 / P95 / P99;
histogram_quantile;- 按 path 计算 P95;
- 按 service 计算 P99;
- histogram 聚合时必须保留
lelabel; - 缺少 bucket 指标时拒绝编造查询。
-
时间窗口与对比
offset 10m;- 当前 QPS 与 10 分钟前对比;
avg_over_time;max_over_time;min_over_time;- 最近 30 分钟最大错误率。
-
故障场景
- 数据库不可用;
- 数据库错误率升高;
- 日志风暴;
- 日志文件过大;
- 磁盘使用率升高;
- 接口高延迟告警;
- 接口 5xx 告警;
- 服务重启检测
changes(process_start_time_seconds)。
-
资源类指标
- CPU 使用率;
- 内存使用率;
- 磁盘使用率;
- 容器 CPU;
- 容器内存;
- Node Exporter 风格指标;
- cAdvisor 风格指标。
-
边界与反例
- 用户要求查询不存在 CPU 指标,但上下文中没有,应返回空 PromQL;
- 用户要求使用不存在 label,应避免使用该 label;
- 用户要求“平均 counter”,应改写为
rate或increase; - 用户要求 histogram 延迟,但没有 bucket 指标,应返回空 PromQL;
- metric context 中有多个相似指标时,选择最合适的指标;
- 不得编造指标或 label。
这一步很重要。只有测试集中包含“容易出错”的场景,才能真正区分模型能力,而不是只测几个简单查询。
5. Prompt 演进:从 zero-shot 到 structured_fewshot
在这次实验中,我们尝试了多种 prompt 策略。
5.1 zero-shot
zero-shot 的方式很直接:给模型自然语言问题和指标上下文,让它直接输出 PromQL。
优点是输入短、token 少、速度快。缺点是复杂 PromQL 不够稳定,例如错误率分母保护、increase 与 rate 的区分、histogram 聚合等细节容易漏掉。
5.2 few-shot
few-shot 会在 prompt 中加入几个 PromQL 示例,例如:
- counter 查询速率用
rate; - 查询一段时间新增数量用
increase; - 错误率分母使用
clamp_min; - P95 / P99 延迟用
histogram_quantile。
few-shot 的正确率明显提升,但它通常只输出 PromQL 字符串,不方便后端拿到 used_metrics、confidence 等结构化字段。
5.3 structured
structured prompt 要求模型输出 JSON,例如:
{"promql":"...","used_metrics":["..."],"confidence":0.0}
这种方式对后端非常友好,但早期测试中,纯 structured prompt 在复杂 PromQL 上仍有一些扣分点,例如缺少 clamp_min 或错误使用 rate/increase。
5.4 structured_fewshot
最后我们把 few-shot 示例和 structured JSON 输出结合起来,形成 structured_fewshot。
它要求模型最终只输出一行 JSON:
{"promql":"...","used_metrics":["..."],"confidence":0.0}
同时在 prompt 中加入关键规则:
- 只能使用
metric_context中出现的指标; - 只能使用声明过的 label;
- 没有合适指标时返回空 PromQL;
- counter 查询速率使用
rate; - 查询时间段内新增数量使用
increase; - 错误率分母使用
clamp_min(..., 1e-9); histogram_quantile必须使用*_bucket指标;- histogram 聚合时必须保留
le; - 不输出 Markdown、代码块、推理过程或多余字段。
从实验结果看,structured_fewshot 同时兼顾了 PromQL 正确性和后端解析稳定性,因此成为当前默认 prompt。
6. API 调试和工程问题
这次工作中也遇到了一些典型工程问题。
6.1 API Key 预算问题
一开始真实调用 API 时,平台返回了类似 “Budget has been exceeded” 的错误。后来确认是 API Key 预算为 0,而不是请求格式问题。重新创建并分配额度后,请求才正常进入模型调用。
这个问题提醒我们:调用大模型 API 时,需要区分几类错误:
- Key 无效;
- 权限不足;
- 预算不足;
- 模型不存在;
- 请求格式错误;
- 平台限流;
- 模型响应超时。
不同错误不能简单混为“模型不可用”。
6.2 平台响应较慢
测试中发现,有些请求本地等待超时,但平台后台可能仍然继续生成并计费。因此我们加入了几个安全策略:
timeout-seconds=300,给慢模型足够等待时间;retries=0,避免本地超时后自动重试造成重复扣费;- 每条结果写入 JSONL 后立即 flush,避免中途中断导致结果丢失;
- 单模型连续 2 条 timeout 后跳过该模型后续 case。
这样做以后,benchmark 的稳定性明显提高。
6.3 GLM-5 的输出格式问题
GLM-5 在前期测试中容易输出较长 reasoning、Markdown code fence 或非标准 JSON,并且响应较慢。这不一定说明它不会 PromQL,但对自动化系统来说,格式不稳定和延迟过高本身就是问题。
因此在最终推荐中,我们没有把 GLM-5 作为默认模型候选。
7. 全模型评测结果
最终,我们在 structured_fewshot 条件下,对平台上的 15 个模型、50 条 case 进行了完整评测。
理论请求数为:
15 个模型 × 50 条 case = 750 次请求
实际写入记录数为 542 条。原因是部分模型连续 timeout 或 API error 后按照规则被跳过,避免无限等待。
完整跑完 50 条 case 的模型包括:
Ali-dashscope/DeepSeek-V3.2Ali-dashscope/Kimi-K2.5Ali-dashscope/Qwen3-Coder-NextAli-dashscope/Qwen3-MaxByteDance-volcengine/Doubao-Seed-2.0-CodeByteDance-volcengine/Doubao-Seed-2.0-liteSDU-AI/DeepSeek-V4-FlashSDU-AI/Qwen3-235B-A22B-Instruct-2507SDU-AI/Qwen3-Coder-30B-A3B-InstructSDU-AI/Qwen3-Coder-Next
被跳过的模型主要包括:
Ali-dashscope/MiniMax-M2.5:连续 timeout;Ali-dashscope/Qwen3.5-Flash:连续 timeout;Ali-dashscope/Qwen3.5-Plus:连续 timeout;SDU-AI/GLM-5:连续 timeout;Ali-dashscope/Qwen3.6-Plus:HTTP 429 quota / concurrency error。
Top 5 结果如下:
| 排名 | 模型 | 平均分 | JSON 可解析率 | 备注 |
|---|---|---|---|---|
| 1 | SDU-AI/Qwen3-235B-A22B-Instruct-2507 |
99.24 | 50/50 | 高分,适合作高精度备用 |
| 2 | ByteDance-volcengine/Doubao-Seed-2.0-Code |
99.24 | 50/50 | 高分,代码类任务能力强 |
| 3 | Ali-dashscope/Kimi-K2.5 |
99.16 | 50/50 | 质量稳定 |
| 4 | Ali-dashscope/Qwen3-Max |
99.10 | 50/50 | 综合能力较强 |
| 5 | Ali-dashscope/Qwen3-Coder-Next |
99.00 | 50/50 | 平均耗时约 3424ms,综合最均衡 |
从结果上看,最高分模型不一定就是默认模型。在线系统还需要考虑延迟、稳定性、输出格式、token 成本和后端接入复杂度。
8. 模型选型结论
最终我们给出当前阶段的模型选型建议。
默认模型
Ali-dashscope/Qwen3-Coder-Next
选择它的原因是:
- 完整跑完 50 条 case;
- 平均分 99.00,已经足够高;
- JSON 可解析率 50/50;
- 平均耗时约 3424ms;
- 没有 timeout 或 API error;
- 在准确性和响应速度之间最均衡。
虽然 SDU-AI/Qwen3-235B-A22B-Instruct-2507 和 Doubao-Seed-2.0-Code 分数略高,但它们不一定比 Qwen3-Coder-Next 更适合作为在线默认模型。OpsPilot 是运维场景,响应速度和稳定性非常重要。
备用模型
备用模型建议选择:
SDU-AI/Qwen3-Coder-NextSDU-AI/Qwen3-235B-A22B-Instruct-2507Ali-dashscope/Kimi-K2.5
它们可以用于默认模型失败、复杂场景复核或后续多模型投票。
暂不推荐默认使用
暂不推荐作为默认模型的有:
SDU-AI/GLM-5Ali-dashscope/MiniMax-M2.5Ali-dashscope/Qwen3.5-FlashAli-dashscope/Qwen3.5-PlusAli-dashscope/Qwen3.6-Plus
主要原因是 timeout、API error、输出 reasoning / Markdown 或格式不稳定风险较高。
9. 对 OpsPilot 后续接入的意义
这次工作之后,PromQL 生成模块已经有了比较清晰的接入方案。
后续 OpsPilot 可以按下面的流程接入:
-
生成 metric context
- 从
metric_catalog.yaml、Prometheus metadata、告警规则和当前故障上下文中整理可用指标; - 只把必要的指标名、label、类型和说明传给模型。
- 从
-
调用默认模型和默认 prompt
- 默认模型:
Ali-dashscope/Qwen3-Coder-Next; - 默认 prompt:
structured_fewshot。
- 默认模型:
-
解析 JSON 输出
- 读取
promql、used_metrics、confidence; - 如果 JSON 解析失败,最多要求模型修复一次;
- 如果仍失败,交给人工确认。
- 读取
-
做安全校验
used_metrics必须都来自metric_context;- PromQL 中不能出现未声明指标或 label;
confidence过低时不自动查询;promql为空时直接返回“当前上下文没有合适指标”。
-
查询 Prometheus
- PromQL 查询是只读操作;
- 调用
/api/v1/query; - 查询失败时把错误结构化返回给 Agent。
-
交给 Agent 做根因分析
- Agent 根据查询结果、日志线索、告警信息和知识库内容继续判断故障原因。
这个流程比“让大模型自由发挥”要安全很多,也更容易解释和调试。
10. 本次工作的收获
这次工作让我对“大模型接入工程系统”有了更具体的认识。
之前我可能会觉得,只要模型会写 PromQL,就可以直接接入 OpsPilot。但实际做下来发现,真正重要的是一整套工程闭环:
- 要有测试集,不能只凭几个例子判断;
- 要有指标目录,不能让模型乱猜指标;
- 要有 prompt 约束,不能让模型自由输出;
- 要有自动评分,才能比较不同模型;
- 要有 timeout 和错误处理,否则 benchmark 本身不稳定;
- 要有后端校验,不能完全相信模型输出;
- 要有最终报告和接入建议,实验结果才不会停留在临时文件里。
这次我们最终沉淀出了:
- 50 条 PromQL benchmark case;
- 一份 metric catalog;
- 一个默认 prompt:
structured_fewshot; - 一套批量评测、评分和报告生成脚本;
- 一轮 15 模型横向评测结果;
- 一份 OpsPilot PromQL 生成模块接入建议。
这些内容后续可以直接服务于 OpsPilot 的智能运维工作流。
11. 总结
本次工作不是简单地“测试哪个模型会写 PromQL”,而是围绕 OpsPilot 的实际需求,构建了一套可复用的 PromQL 生成能力评测和选型流程。
当前阶段结论如下:
- 默认 prompt:
structured_fewshot; - 默认模型:
Ali-dashscope/Qwen3-Coder-Next; - 备用模型:
SDU-AI/Qwen3-Coder-Next、SDU-AI/Qwen3-235B-A22B-Instruct-2507、Ali-dashscope/Kimi-K2.5; - 暂不推荐默认使用:
SDU-AI/GLM-5、MiniMax-M2.5、Qwen3.5-Flash、Qwen3.5-Plus、Qwen3.6-Plus。
接下来,OpsPilot 可以在这个基础上继续推进 PromQL 生成服务的后端接入,把“自然语言问题 → PromQL 查询 → Prometheus 指标结果 → Agent 根因分析”这条链路真正打通。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)