关于 elasticsearch-anomaly-detection-explainer
elasticsearch-anomaly-detection-explainer 是面向 Elasticsearch ML 异常检测使用者的解释技能,可分析异常分数、模型行为和影响因素。它读取作业配置与异常记录,并特别说明分数重归一化及模型上下文。
主要功能
- 01读取 ML 作业配置与统计信息
- 02解释初始分数和当前分数差异
- 03依据 actual 与 typical 判断异常方向
- 04检查分数解释因素与影响实体
- 05查询模型边界和日志类别
适用场景
- 01解释单条异常记录的分数
- 02调查分数偏低或偏高的原因
- 03衡量作业中的分数重归一化
- 04查看异常影响实体或模型边界
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ elastic/ agent-skills --skill elasticsearch-anomaly-detection-explainer安装后在 Claude Code 中输入/elasticsearch-anomaly-detection-explainer确认已加载。
附带文件references/explainer-reference.md
详细介绍
异常检测分数解读器
解释异常分数、模型行为,以及结果呈现出这种样子的原因。使用 ML REST API 获取作业配置,并使用针对 .ml-anomalies-* 的 标准 _search API 获取结果——不使用 ES|QL,完全兼容 Elastic Serverless。对于作业生命周期操作(创建、启动、停止),请使用 elasticsearch-anomaly-detection skill。
环境配置
此 skill 通过 elastic CLI 执行 Elasticsearch 操作。如果未安装
elastic CLI,请告知用户安装它的用途。不要猜测凭据、直接调用 HTTP API,也不要尝试其他变通方法。
此 skill 以 HTTP 简写形式引用操作(例如,GET /、GET /_cat/indices、GET /{index}/_mapping、
GET /{index}/_settings/index.mode、POST /_query)。本文档末尾的 操作 表列出了每种简写对应的 elastic CLI 命令——请始终使用 CLI,而不要直接调用 HTTP API。
前提条件: 自管理集群上的 ML 异常检测需要 Platinum 等效许可证。Serverless 项目包含 ML。调用方需要
monitor_ml权限才能读取作业配置和异常结果。Serverless 说明: 在 Elastic Serverless 中,
_ml/.../results/*REST 端点会返回 HTTP 410。查询结果时请始终使用POST /.ml-anomalies-*/_search——此方法在此 skill 运行的所有环境中均受支持。
流程
-
判断是获取数据还是解读用户提供的内容。 如果用户在提示词中嵌入了异常记录(或作业配置),请直接使用下方的领域知识进行解读——不要调用 API 重新获取已有字段。如果缺少作业 ID、时间范围或记录,请从集群中检索。
判断标准:当记录包含
record_score、initial_record_score、actual、typical和function时,仅凭判断进行解释;否则,请先获取缺少的信息再进行解释。 -
调用集群时验证连接。 调用
GET /。如果调用失败,请停止操作并报告连接错误——不要猜测端点或凭据。 -
确定作业 ID 并加载配置。 如果未知作业 ID,请调用
GET /_ml/anomaly_detectors列出候选项。调用GET /_ml/anomaly_detectors/{job_id}获取完整的analysis_config(bucket_span、detectors、custom_rules、use_null、model_plot_config),并调用GET /_ml/anomaly_detectors/{job_id}/_stats获取state、model_size_stats.memory_status和数据计数。判断标准:解读分数前,确认检测器函数和方向与用户的问题相符。
low_count作业确实会因数量下降而触发;high_count作业则不会。 -
检索指定时间范围内的异常记录。 调用
POST /.ml-anomalies-*/_search,并提供result_type: record、作业 ID、时间戳范围,以及可选的record_score筛选条件。读取initial_record_score、record_score、actual、typical、function、multi_bucket_impact和anomaly_score_explanation。始终同时显示
initial_record_score和record_score。两者的差距体现了重新归一化过程。 -
先对分数模式分类,再推测原因。
initial_record_score>>record_score— 重新归一化。 后续出现的、更极端的异常对该记录的分数进行了下调。这是预期的、健康的模型行为,并不意味着模型损坏,也不构成怀疑检测结果的理由。使用initial_record_score确定告警严重程度;同时显示两个分数,并明确说明分差。initial_record_score==record_score— 检测后尚未发生重新归一化。actual<<typical,且存在low_count、count或low_mean— 缺失/下降异常。 高分是合理的——任务检测到了服务中断、流水线停滞或服务故障。这不是误报。建议调查事件,而不是调整分数。actual>>typical,且存在high_count或high_mean— 峰值异常;使用single_bucket_impact进行确认。
仅引用记录中存在的
anomaly_score_explanation因子。 如果high_variance_penalty为false,不要将原因归咎于方差。如果某个因子不存在,请说明系统未返回该因子,不要凭空编造。 -
量化整个任务中的重新归一化情况(可选)。 重新查询
POST /.ml-anomalies-*/_search,获取时间范围内的记录,并按timestamp升序排序。为每条记录计算score_drift = initial_record_score − record_score,并筛选|score_drift| ≥ 20。较大的负向漂移(initial >> record)可确认后续出现了更极端的异常,导致分数重新归一化。 -
用户询问“是什么导致了这个结果?”或“为什么这么低/高?”时,补充上下文。
- 模型边界 — 如果
model_plot_config.enabled为 true,则对同一任务和时间范围调用POST /.ml-anomalies-*/_search,并指定result_type: model_plot。比较actual与model_lower/model_upper。 - 影响因素 — 对相应的桶时间范围调用
POST /.ml-anomalies-*/_search,并指定result_type: influencer;按influencer_score降序排序。 - 分类任务 — 调用
POST /.ml-anomalies-*/_search,并指定result_type: category_definition,以列出已学习的日志模式(每个category_id对应terms、regex、examples)。
有关聚合、跨任务查询、桶级结果或超出分数和时间范围的自定义筛选条件,请参阅 references/explainer-reference.md。
- 模型边界 — 如果
常见多步骤工作流
| 任务 | 步骤(按顺序) |
|---|---|
| 解释特定异常 | 任务配置 → 记录(任务 + 精确时间)→ 显示 initial_record_score 与 record_score,并说明分数因子。 |
| 为什么我的分数这么低? | 任务配置 → 记录 → 检查重新归一化 → 模型图(如果已启用)→ 说明分数因子。 |
| 为什么我的分数这么高? | 任务配置 → 记录 → 检查函数方向、历史数据不足、use_null 和基数。 |
| 重新归一化漂移 | 记录(按时间戳排序)→ 计算 score_drift → 列出 initial >> record 的记录。 |
| 哪些实体产生了影响? | 影响因素(任务 + 时间范围)→ 按 influencer_score 排序。 |
| 可视化模型边界 | 模型图(任务 + 时间范围)→ 比较 model_lower/model_upper 与 actual。 |
| 分类任务模式 | category_definition(job_id)→ 查看每个类别对应的 terms、regex、examples。 |
关键原则
- 先检索记录(或使用用户提供的记录)。没有
initial_record_score、record_score、actual、typical和function时,绝不解释分数。 - 重新归一化是正常的。 当
initial_record_score >> record_score时,说明之后出现了更极端的异常,导致该分数降低——这是预期行为,并非模型故障。 - 方向很重要。
low_count在数值下降时触发;high_count在数值激增时触发。在交通停止事件中,low_count得分高属于正确检测,并非误报。 - 先解释影响因素,再做推测。 阅读记录中的
anomaly_score_explanation。只讨论其中存在且相关的因素。 - 作业配置至关重要。
bucket_span、检测器函数、custom_rules、use_null和内存状态都会影响分数。若分数令人意外,请检查作业配置。 - 模型图是最直观的解释。 启用后,显示模型边界,以说明实际值相对于预期范围的位置。
- 对于作业运行状况问题(“缺少文档”“内存限制”“数据馈送未运行”),请使用
elasticsearch-anomaly-detection技能。
领域知识
分数类型
| 术语 | 含义 |
|---|---|
| record_score | 单条异常记录的归一化分数,范围为 0–100;会通过重新归一化更新。>75 为严重。 |
| initial_record_score | 检测时分配的分数,尚未经过重新归一化。用于告警。 |
| anomaly_score | 作业中所有检测器汇总的桶级严重程度。 |
| influencer_score | 桶中某个特定实体(主机、用户、服务)的异常程度;分数越高,越可能是原因。 |
| multi_bucket_impact | 0–5;持续多个桶的行为对分数的影响程度。≥3 表示行为发生转变。 |
anomaly_score_explanation 影响因素
每条记录中的 anomaly_score_explanation 字段会将分数拆解为多个组成部分:
| 因素 | 方向 | 含义 |
|---|---|---|
| anomaly_length | 提高 | 异常持续的连续桶数。持续时间越长,分数越高。 |
| single_bucket_impact | 提高 | 单个桶的异常程度。概率越低,影响越大。 |
| multi_bucket_impact | 提高 | 持续多桶模式的影响。 |
| anomaly_characteristics_impact | 提高 | 异常属于均值偏移还是方差变化。 |
| high_variance_penalty | 降低 | 数据嘈杂或处于训练初期时,置信区间会变宽,从而降低分数。 |
| incomplete_bucket_penalty | 降低 | 桶中的数据少于预期(数据延迟、事件稀疏)。 |
分数可能意外偏低的原因
- high_variance_penalty: 指标的历史数据噪声较大,较宽的置信区间会吸收激增值。
- 重新归一化: 之后出现了更极端的异常,导致该分数降低(
initial_record_score>>record_score)。 - 训练历史不足: 周期性季节性至少需要 3 周的数据;检测任何周期至少需要 2 个完整周期。
bucket_span过大: 短时激增会被平滑处理。对于高频事件,请使用较小的bucket_span。- 检测器函数不匹配:
mean与high_mean、count与high_count只能检测一个方向。 - incomplete_bucket_penalty: 桶接收的数据少于预期(摄取延迟或数据缺口)。
custom_rules: 检测器筛选条件可能会抑制异常。
分数可能意外偏高的原因
- 历史数据不足: 模型尚未学会正常模式,因此早期异常不可靠。
- 模型划分过细: 高基数的
partition_field或by_field→ 每个实体的点数很少 → 概率不可靠。 - use_null: 如果
use_null: true,缺失实体会产生可能没有意义的“null”异常。 - 缺失/下降检测: 使用
low_count或low_mean时,actual << typical会产生合理的高分——应将其视为真实事件,而非误报。
模型行为概念
| 概念 | 含义 |
|---|---|
| actual | 观测值。typical 是模型的预期值。方向很重要。 |
| 缺失异常 | 使用 count、low_count 或 low_mean 时,actual << typical → 服务中断、管道停止、服务故障。 |
| by_field | 按实体建立独立基线(例如,每台主机)。每个实体都与自身的历史数据进行比较。 |
| over_field | 群体分析——将实体与同一时间桶中的同类实体比较,而非与自身的历史数据比较。 |
| partition_field | 完全独立的子模型,每个分区分别进行分数归一化。 |
模型图表和类别
- 模型图表: 显示模型在每个时间点学到的上限和下限。如果
actual在界限内,则无异常;如果超出界限,分数取决于超出界限的距离。只有在作业上启用model_plot_config后才可用。使用result_type: model_plot查询POST /.ml-anomalies-*/_search。 - 类别: 对于设置了
categorization_field_name的作业,查询result_type: category_definition以显示日志消息模式(每个category_id对应的术语、正则表达式和示例)。异常记录使用by_field_value = <category_id>。
分数故障排查流程
- 列出作业——作业 ID 未知时,调用
GET /_ml/anomaly_detectors。 - 获取作业配置和统计信息——调用
GET /_ml/anomaly_detectors/{job_id}和GET /_ml/anomaly_detectors/{job_id}/_stats。检查bucket_span、检测器函数、custom_rules、use_null、 作业状态(已打开/已关闭/失败)以及model_size_stats.memory_status。 - 检索记录——调用
POST /.ml-anomalies-*/_search,并指定result_type: record、作业 ID、时间范围, 以及可选的最低record_score。检查initial_record_score、record_score、actual、typical、function、multi_bucket_impact和anomaly_score_explanation。 - 检查重新归一化——比较
initial_record_score和record_score。如果初始分数远高于记录分数,则按时间戳排序重新查询记录,并计算score_drift,以量化整个作业中的重新归一化情况。 - 可视化模型界限——如果启用了
model_plot_config,则查询result_type: model_plot,并显示实际值相对于model_lower和model_upper的位置。 - 影响因素——查询异常时间桶范围内的
result_type: influencer;按influencer_score排序。 - 解释因素——根据记录中的
anomaly_score_explanation,说明每个存在且相关的因素:high_variance_penalty、incomplete_bucket_penalty、anomaly_length、single_bucket_impact、multi_bucket_impact。不要提及记录中不存在的因素。
示例
- “为什么尖峰看起来很大,但我的异常分数只有 15?” → 检查重新归一化:
initial_record_score(约 92)>>record_score(约 15)。尖峰确实存在;当前分数已向下重新缩放。使用初始分数进行告警。 - “流量停止了,但我得到一个 HIGH 分数——这是误报吗?” → 不是。
low_count且actual远低于typical,属于合理的缺失检测。请调查故障。 - “昨晚作业 X 的异常主要由哪些实体造成?” → 查询该时间范围内的影响因素。
- “显示此作业的模型边界。” → 启用
model_plot_config后,查询模型图。 - “列出分数被大幅向下重新归一化的记录。” → 按时间戳排序记录;筛选
initial_record_score − record_score差值较大的记录。
指南
- 仅报告 API 或用户提供的记录中包含的信息;不要编造分数、时间戳、实体值或解释因素。
- 解释记录时,始终同时显示
initial_record_score和record_score;明确说明是否发生了重新归一化。 - 如果记录中缺少某个分数因子,不要对此作出断言;请注明未返回该字段。
- 如果记录中的
high_variance_penalty或incomplete_bucket_penalty标志为false或缺失,不要将低分归因于这些因素。 - 对于调查类问题(“是什么导致了这个问题?”“哪个服务对此负责?”),请查询影响因素,或通过 references/explainer-reference.md 构建跨作业搜索。
- 检查作业运行状况时,使用
elasticsearch-anomaly-detection技能。
操作
| HTTP API(简写) | elastic CLI 命令 |
|---|---|
GET / | elastic es info |
GET /_ml/anomaly_detectors | elastic es ml get-jobs |
GET /_ml/anomaly_detectors/{job_id} | elastic es ml get-jobs --job-id '<job_id>' |
GET /_ml/anomaly_detectors/{job_id}/_stats | elastic es ml get-job-stats --job-id '<job_id>' |
POST /.ml-anomalies-*/_search | elastic es search --index '.ml-anomalies-*' --input-file '<search-body.json>' |
各个 result_type(record、influencer、model_plot、category_definition)对应的查询正文结构见
references/explainer-reference.md。