mcpField
K
kibana-anomaly-detection

kibana-anomaly-detection

github.com/elastic数据与数据库6023.1k 次安装今天更新
代码仓库

关于 kibana-anomaly-detection

kibana-anomaly-detection 是面向 Elastic ML 异常检测的分析与运维技能,供调查事件、解释分数及管理检测任务时使用。它按调查、解释、故障排查和管理场景组织操作,并通过 elastic CLI 执行 Elasticsearch 操作。

主要功能

  1. 01跨任务关联并定位异常实体
  2. 02解释分数、模型行为与重归一化
  3. 03诊断任务、数据馈送及生命周期问题
  4. 04创建任务并检索异常结果

适用场景

  1. 01追查多个检测任务共同出现的故障
  2. 02分析异常分数下降或偏高的原因
  3. 03排查数据缺失或数据馈送停止
  4. 04配置异常检测任务并查看结果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/elastic/agent-skills --skill kibana-anomaly-detection

安装后在 Claude Code 中输入/kibana-anomaly-detection确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
agent-builder-companion.md
anomaly-detection-functions.md
investigation-queries.md
job-creation-recipes.md
observability-anomaly-expert.md
README.md
score-reference.md
security-anomaly-expert.md
troubleshooting-reference.md
worked-example.md
references/protocols/
investigation.md

详细介绍

Elastic ML 异常检测

ML 异常检测专家流程:将事件归因于实体,解释分数和模型行为,诊断 作业生命周期故障,并管理作业。通过 POST /.ml-anomalies-*/_search(兼容 Serverless)读取异常结果, 并通过 ML REST API 读取作业/数据馈送状态。当用户在提示词中嵌入了样本证据(影响因素行、作业统计信息)时,直接应用以下判断——不要重新获取已提供的字段。

环境配置

此技能通过 elastic CLI 执行 Elasticsearch 操作。如果未安装 elastic CLI,请告知用户为何需要它。请勿猜测凭据、直接调用 HTTP API,或尝试其他变通方法。

此技能以 HTTP 简写形式引用操作(例如 GET /、GET /_cat/indices、GET /{index}/_mapping、 GET /{index}/_settings/index.mode、POST /_query)。本文末尾的 Operations 表格 列出了每种简写对应的 elastic CLI 命令——始终使用 CLI,不要直接调用 HTTP API。

模式选择器

用户意图模式
“出了什么问题?”/RCA/跨作业/影响范围/影响因素/日志类别调查
“为什么分数高/低?”/重新归一化/模型边界/预测解释
缺失文档/内存限制/数据馈送已停止/生命周期/日历故障排查
创建作业/配置数据馈送/开始分析/获取结果管理
安全视角(攻击链、MITRE、数据外泄)调查 + references/security-anomaly-expert.md
可观测性/SRE 视角(性能下降、容量、部署回归)调查 + references/observability-anomaly-expert.md

如果问题涉及多种模式:调查 → 解释 → 故障排查。先完成一种模式,再融合其他模式的逻辑。

**Serverless 说明:**旧版 /_ml/anomaly_detectors/{job_id}/results/* 端点在 Serverless 中会返回 HTTP 410。 始终通过 POST /.ml-anomalies-*/_search 并使用 result_type 过滤条件查询 .ml-anomalies-*。

分数速查

  • record_score 范围:>75 严重 · 50–75 警告 · 25–50 轻微 · <25 提示
  • multi_bucket_impact ≥ 3 → 持续偏移(不是短暂峰值)
  • initial_record_score >> record_score → 重新归一化(模型之后观察到更严重的异常)
  • actual << typical 且有 count/low_count/low_mean → 缺失/中断,而非仅数值偏低
  • 多个作业的低分比单个高分更值得关注——跨作业综合信号通常比单个检测器的严重程度更有参考价值

完整的分数定义、重新归一化机制以及 anomaly_score_explanation 组成部分: references/score-reference.md。

核心概念

在搜索查询中,通过 result_type 将 .ml-anomalies-* 视为分层结果类型:

result_type范围关键字段
bucket时间窗口anomaly_score、initial_anomaly_score、timestamp
record检测器行record_score、initial_record_score、actual、typical、anomaly_score_explanation
influencer实体 × 时间桶influencer_field_name、influencer_field_value、influencer_score
model_plot边界model_lower、model_upper、actual
category_definition日志模式category_id、terms、regex、examples

按以下方式解读分数:

  • anomaly_score / record_score = 当前归一化值(模型发现新的极端值时会变化)。
  • initial_anomaly_score / initial_record_score = 检测时的不可变快照。
  • influencer_score 用于对某个时间桶内实体的责任程度进行排序——最高分代表首要嫌疑对象,而不能只看时间桶级别的 anomaly_score。
  • 通过 partition_field_value / by_field_value / over_field_value 映射实体。
  • 查看 multi_bucket_impact(-5 到 +5),以区分单个时间桶的峰值和持续趋势。

模式:调查 — RCA

适用场景:“出了什么问题?”、“哪个实体导致了问题?”,跨任务关联、影响范围、攻击/级联链。

流程
  1. 发现作业。 作业 ID 未知时,调用 GET /_ml/anomaly_detectors。调用 GET /_ml/anomaly_detectors/{job_id} 和 GET /_ml/datafeeds/datafeed-{job_id},了解源索引、实体 字段(by_field_name、over_field_name、partition_field_name)以及 bucket_span。判断:识别 相关作业组——共享数据馈送索引或实体字段的作业从不同角度监控同一系统。

  2. 界定事件时间窗口。 调用 POST /.ml-anomalies-*/_search,指定 result_type: bucket、时间范围和 可选的最低 anomaly_score。判断:确定事件的开始和结束时间,并统计该窗口内同时触发异常的作业数量。多个作业同时出现低分,通常意味着存在系统性根因。

  3. 将异常归因到实体(对根因分析至关重要)。 对于异常桶的时间戳,调用 POST /.ml-anomalies-*/_search,指定 result_type: influencer、作业 ID 和桶的时间范围。按 influencer_score 降序排序。判断:将**influencer_score 最高**的实体列为 可能的原因——它会对实体在该桶中的异常程度进行排名。不要只复述桶的 anomaly_score,却不指出责任归属。建议接下来深入检查该实体的记录。

  4. 跨作业确认。 针对相同的实体值和时间窗口,跨相关作业 ID 重新查询影响者(或桶记录)。在至少 2 个作业中都出现异常的实体是首要嫌疑对象(资源故障或系统性故障);仅在单个作业中出现异常的实体通常是下游受影响对象。参见 references/protocols/investigation.md。

  5. 深入检查记录。 调用 POST /.ml-anomalies-*/_search,指定 result_type: record、确切的作业 ID、实体筛选条件 (partition_field_value、by_field_value),以及较低的最低 record_score(25 或更低)。将 multi_bucket_impact ≥ 3 视为持续的行为变化。通过 actual 与 typical 的对比判断故障类型(激增还是缺失/中断)。

  6. 用源数据证据确认。 针对可疑实体和时间窗口,在数据馈送的源索引上调用 POST /{index}/_search。 原始源文档是事实依据——没有这些证据,绝不要结束根因分析。

  7. 综合分析。 报告:根因实体 · 受影响的作业 · 时间演变 · 故障类型 · 严重程度 · 建议采取的措施。完整示例:references/worked-example.md。查询 模板:references/investigation-queries.md。

规则
  1. 对于“哪个实体?”,按 influencer_score 排名,而不是 anomaly_score——桶分数是汇总值;影响者分数用于归因。
  2. 跨多个作业出现异常的实体是首要嫌疑对象;仅在单个作业中出现异常的实体通常是受害者。
  3. 最早的异常时间戳优先——根据各作业的记录时间戳还原时间顺序。
  4. multi_bucket_impact ≥ 3 = 持续的行为变化,其权重高于短暂激增。
  5. 影响者/记录查询使用较低的分数阈值(25 或更低)——阈值过高会漏掉相关实体。
  6. 没有来自数据馈送索引的源数据证据,绝不要结束根因分析。

模式:解释——分数/模型行为

适用场景:“为什么我的分数是 30/90?”、“分数一夜之间下降了”、“什么是重新归一化?”、“为什么没有检测到这个问题?”。

流程
  1. 决定是获取还是直接解读。 如果用户提供的记录包含 record_score、initial_record_score、actual 和 typical,则直接解读。否则,使用 GET /_ml/anomaly_detectors/{job_id} 加载配置,并使用 POST /.ml-anomalies-*/_search(result_type: record)加载记录。

  2. 始终同时展示 initial_record_score 和 record_score。 两者的差距说明了重归一化的情况。较大的正向 漂移(initial_record_score >> record_score)表示后续出现了更极端的异常,导致该记录的分数被下调—— 这是符合预期的正常行为,并非模型损坏。

  3. 先对模式进行分类,再推测原因。

    模式解读
    initial_record_score >> record_score重归一化——建议更改配置前先解释这一点
    actual << typical 且有 low_count/count/low_mean缺失/中断异常——调查中断,而非调整分数
    anomaly_score_explanation 中的 high_variance_penalty: true指标噪声较大——较宽的边界吸收了峰值
    incomplete_bucket_penalty: true数据摄取延迟或数据桶稀疏——分数因此合理地下调

    仅引用记录中实际存在的 anomaly_score_explanation 因素。

  4. 量化重归一化(可选)。 重新查询记录,并按 timestamp 排序;计算 score_drift = initial_record_score - record_score,并标记较大的漂移。

  5. 必要时补充图表上下文。 如果 model_plot_config.enabled,查询 result_type: model_plot,并比较 actual 与 model_lower/model_upper。对于分类任务,查询 result_type: category_definition。

  6. 分数持续异常时检查任务健康状况。 调用 GET /_ml/anomaly_detectors/{job_id}/_stats—— model_size_stats.memory_status 为 hard_limit 时会破坏学习过程,并可能导致分数无效。升级到 故障排除模式。

anomaly_score_explanation 组件
组件影响含义
anomaly_length↑ 分数连续异常数据桶越多
single_bucket_impact↑ 分数概率越低 → 影响越大
multi_bucket_impact↑ 分数持续模式的贡献
anomaly_characteristics_impact↑ 分数均值变化与方差变化
high_variance_penalty↓ 分数数据噪声较大 → 边界较宽 → 异常较不出人意料
incomplete_bucket_penalty↓ 分数数据桶中的数据少于预期(摄取延迟、数据稀疏)
规则
  1. 诊断配置前先解释重归一化——分数漂移是“分数下降”最常见的原因。
  2. actual << typical 且有 count/low_count 时属于缺失异常——区分中断与数值峰值。
  3. 周季节性需要 ≥3 周的训练数据——将任务运行时间较短标记为原因。
  4. 检测器函数的方向很重要——参见 references/anomaly-detection-functions.md。

模式:故障排除——任务生命周期

适用情况:“文档缺失”、“数据馈送已停止”、hard_limit、“结果看起来不对”、生命周期变化。

流程
  1. 加载作业和数据馈送状态。 调用 GET /_ml/anomaly_detectors/{job_id}/_stats 和 GET /_ml/datafeeds/datafeed-{job_id}/_stats。读取 state、data_counts、model_size_stats 和数据馈送的 state。如果用户嵌入了统计信息 JSON,请直接根据 memory_status 和数据馈送状态进行诊断。

  2. 首先诊断内存状态(关键)。 检查 model_size_stats:

    字段含义
    memory_statusok / soft_limit(修剪)/ hard_limit(严重)
    model_bytes当前使用的内存
    model_bytes_memory_limit已配置的 model_memory_limit

    当 memory_status 为 hard_limit 且 model_bytes 等于 model_bytes_memory_limit 时,模型已达到内存上限——它会停止学习新的实体,结果也会变差或停止。数据馈送已停止通常是症状,而非根本原因。不要只建议重启数据馈送——仅此操作无法解除硬限制。

  3. 修复 hard_limit。 解决方法是提高 model_memory_limit(通过更新作业),和/或缩小模型规模,方法是降低基数(减少 partition/by/over 字段值,或拆分为多个作业)。提高限制需要执行以下生命周期流程(停止数据馈送 → 关闭作业 → 更新 → 打开 → 启动)。也可以调用 POST /_ml/anomaly_detectors/_estimate_model_memory,根据数据源基数估算新的限制。

  4. 诊断缺失文档/查询时间问题。 内存状态正常后,通过 GET /_ml/datafeeds/datafeed-{job_id} 检查数据馈送的 query_delay 和 delayed_data_check_config。在 .ml-annotations-* 中搜索延迟数据事件。将 query_delay 设为 P95 写入延迟加上缓冲时间(默认 60s–120s)。

  5. 读取作业消息。 如果无法明确错误原因,请在 .ml-notifications-* 中搜索作业 ID。

  6. 恢复已损坏的模型状态。 当模型在 hard_limit 期间损坏时,调用 POST /_ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}/_revert,回退到已知正常的快照。

配置变更的生命周期(内存限制、query_delay)

按顺序执行——跳过步骤会导致更新被拒绝:

  1. POST /_ml/datafeeds/datafeed-{job_id}/_stop
  2. POST /_ml/anomaly_detectors/{job_id}/_close
  3. POST /_ml/anomaly_detectors/{job_id}/_update(内存限制)和/或 POST /_ml/datafeeds/datafeed-{job_id}/_update (query_delay)
  4. POST /_ml/anomaly_detectors/{job_id}/_open
  5. POST /_ml/datafeeds/datafeed-{job_id}/_start

重启前,使用 POST /_ml/datafeeds/datafeed-{job_id}/_preview 预览变更。

hard_limit 会损坏模型状态,并导致下游出现误报的缺失文档问题。先修复内存,再处理 query_delay。 完整的故障排查详情: references/troubleshooting-reference.md。

规则
  1. 基于 memory_status 诊断生命周期问题——不要给出笼统的“重启即可”建议。
  2. 先修复内存,再处理 query_delay——hard_limit 会使下游诊断失效。
  3. 任何内存或数据馈送配置变更都要依次执行:停止数据馈送 → 关闭作业 → 更新 → 打开 → 启动。
  4. 不要将删除作业作为修复 hard_limit 的首选方案——提高限制和/或降低基数。

模式:管理 — 创建 / 配置作业

适用场景:“设置一个作业”“创建一个 ML 检测器”“持续监控 X”。

对于完整的创建 / 打开 / 启动作业生命周期,优先使用 elasticsearch-anomaly-detection 技能。此模式概述操作顺序和检测器选择:

  1. 验证目标索引。 调用 GET /{index}/_mapping,确认时间字段和检测器字段存在。
  2. 创建作业。 调用 PUT /_ml/anomaly_detectors/{job_id},传入 analysis_config(检测器、bucket_span、影响因素)和 data_description.time_field。
  3. 创建数据馈送。 调用 PUT /_ml/datafeeds/datafeed-{job_id},传入 indices、query 和 query_delay。
  4. 打开并启动。 调用 POST /_ml/anomaly_detectors/{job_id}/_open,然后调用 POST /_ml/datafeeds/datafeed-{job_id}/_start。
  5. 确认状态。 调用 GET /_ml/anomaly_detectors/{job_id}/_stats 和 GET /_ml/datafeeds/datafeed-{job_id}/_stats。

根据用户意图选择检测器函数——参见 references/anomaly-detection-functions.md。包含完整步骤的 JSON 请求体: references/job-creation-recipes.md。

规则
  1. 先创建作业,再创建数据馈送。 启动数据馈送前先打开作业。
  2. query_delay = P95 数据摄取延迟 + 缓冲时间(安全默认值为 60s–120s)。
  3. by_field_name 与 over_field_name: by 将实体与其自身的历史记录进行比较;over 将实体与同组对象进行比较。
  4. 预测要求使用非总体作业——包含 over_field_name 的作业无法进行预测。

示例

根因分析:“某些因素导致结账延迟激增——是哪个实体?”→ 查询该时间桶的影响因素 → web-07 的 influencer_score 最高(91.5),高于 22.0 和 8.4 → 将 web-07 列为可能的原因 → 建议进一步检查其 记录——不要只用时间桶的 anomaly_score 88 作答。

分数下降:“分数从 90 降到了 55——模型变了吗?”→ 比较 initial_record_score 与 record_score → 如果偏移较大,说明是分数重新归一化。

内存限制:“作业显示 hard_limit,而且数据馈送已停止。”→ 根据 model_size_stats.memory_status = hard_limit 进行诊断 → 通过关闭 / 更新 / 打开作业的生命周期提高 model_memory_limit,和 / 或降低 基数——不要只说“重新启动数据馈送”。

新建作业:“检测每台主机上异常的错误率。”→ 使用 high_count 和 by_field_name: host.keyword → 按顺序创建 / 打开 / 启动作业。


指南

  1. 先选择一种模式。 不要在同一回复中混合根因分析逻辑和分数解释逻辑。
  2. 对于“是哪个实体?”,按 influencer_score 排序,而不是按时间桶的 anomaly_score 排序。
  3. 对于生命周期故障,建议重启数据馈送前先读取 memory_status。
  4. 同时显示 initial_record_score 和 record_score——两者的差值可以说明分数重新归一化的情况。
  5. 先解决内存问题,再处理 query_delay。 Hard_limit 会使后续诊断失效。
  6. 使用数据馈送索引中的源数据证据确认根因分析结果。

操作

HTTP API (shorthand)elastic CLI command
GET /{index}/_mappingelastic es indices get-mapping --index '<index>'
POST /{index}/_searchelastic es search --index '<index>' --input-file '<search-body.json>'
GET /_ml/anomaly_detectorselastic 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}/_statselastic es ml get-job-stats --job-id '<job_id>'
GET /_ml/datafeeds/datafeed-{job_id}elastic es ml get-datafeeds --datafeed-id 'datafeed-<job_id>'
GET /_ml/datafeeds/datafeed-{job_id}/_statselastic es ml get-datafeed-stats --datafeed-id 'datafeed-<job_id>'
POST /.ml-anomalies-*/_searchelastic es search --index '.ml-anomalies-*' --input-file '<search-body.json>'
POST /.ml-annotations-*/_searchelastic es search --index '.ml-annotations-*' --input-file '<search-body.json>'
POST /.ml-notifications-*/_searchelastic es search --index '.ml-notifications-*' --input-file '<search-body.json>'
POST /_ml/anomaly_detectors/_estimate_model_memoryelastic es ml estimate-model-memory --analysis-config '<json>'
PUT /_ml/anomaly_detectors/{job_id}elastic es ml put-job --job-id '<job_id>' --input-file '<job-body.json>'
PUT /_ml/datafeeds/datafeed-{job_id}elastic es ml put-datafeed --datafeed-id 'datafeed-<job_id>' --input-file '<datafeed-body.json>'
POST /_ml/anomaly_detectors/{job_id}/_openelastic es ml open-job --job-id '<job_id>'
POST /_ml/anomaly_detectors/{job_id}/_closeelastic es ml close-job --job-id '<job_id>'
POST /_ml/anomaly_detectors/{job_id}/_updateelastic es ml update-job --job-id '<job_id>' --analysis-limits '<json>'
POST /_ml/datafeeds/datafeed-{job_id}/_updateelastic es ml update-datafeed --datafeed-id 'datafeed-<job_id>' --input-file '<update-body.json>'
POST /_ml/datafeeds/datafeed-{job_id}/_startelastic es ml start-datafeed --datafeed-id 'datafeed-<job_id>'
POST /_ml/datafeeds/datafeed-{job_id}/_stopelastic es ml stop-datafeed --datafeed-id 'datafeed-<job_id>'
POST /_ml/datafeeds/datafeed-{job_id}/_previewelastic es ml preview-datafeed --datafeed-id 'datafeed-<job_id>'
POST /_ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}/_revertelastic es ml revert-model-snapshot --job-id '<job_id>' --snapshot-id '<snapshot_id>'

每种 result_type 对应的搜索正文结构以及故障排查查询,详见 references/investigation-queries.md 和 references/troubleshooting-reference.md。

评论

支持 Markdown