关于 kibana-anomaly-detection
kibana-anomaly-detection 是面向 Elastic ML 异常检测的分析与运维技能,供调查事件、解释分数及管理检测任务时使用。它按调查、解释、故障排查和管理场景组织操作,并通过 elastic CLI 执行 Elasticsearch 操作。
主要功能
- 01跨任务关联并定位异常实体
- 02解释分数、模型行为与重归一化
- 03诊断任务、数据馈送及生命周期问题
- 04创建任务并检索异常结果
适用场景
- 01追查多个检测任务共同出现的故障
- 02分析异常分数下降或偏高的原因
- 03排查数据缺失或数据馈送停止
- 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.mdanomaly-detection-functions.mdinvestigation-queries.mdjob-creation-recipes.mdobservability-anomaly-expert.mdREADME.mdscore-reference.mdsecurity-anomaly-expert.mdtroubleshooting-reference.mdworked-example.mdreferences/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
适用场景:“出了什么问题?”、“哪个实体导致了问题?”,跨任务关联、影响范围、攻击/级联链。
流程
-
发现作业。 作业 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。判断:识别 相关作业组——共享数据馈送索引或实体字段的作业从不同角度监控同一系统。 -
界定事件时间窗口。 调用
POST /.ml-anomalies-*/_search,指定result_type: bucket、时间范围和 可选的最低anomaly_score。判断:确定事件的开始和结束时间,并统计该窗口内同时触发异常的作业数量。多个作业同时出现低分,通常意味着存在系统性根因。 -
将异常归因到实体(对根因分析至关重要)。 对于异常桶的时间戳,调用
POST /.ml-anomalies-*/_search,指定result_type: influencer、作业 ID 和桶的时间范围。按influencer_score降序排序。判断:将**influencer_score最高**的实体列为 可能的原因——它会对实体在该桶中的异常程度进行排名。不要只复述桶的anomaly_score,却不指出责任归属。建议接下来深入检查该实体的记录。 -
跨作业确认。 针对相同的实体值和时间窗口,跨相关作业 ID 重新查询影响者(或桶记录)。在至少 2 个作业中都出现异常的实体是首要嫌疑对象(资源故障或系统性故障);仅在单个作业中出现异常的实体通常是下游受影响对象。参见 references/protocols/investigation.md。
-
深入检查记录。 调用
POST /.ml-anomalies-*/_search,指定result_type: record、确切的作业 ID、实体筛选条件 (partition_field_value、by_field_value),以及较低的最低record_score(25 或更低)。将multi_bucket_impact ≥ 3视为持续的行为变化。通过actual与typical的对比判断故障类型(激增还是缺失/中断)。 -
用源数据证据确认。 针对可疑实体和时间窗口,在数据馈送的源索引上调用
POST /{index}/_search。 原始源文档是事实依据——没有这些证据,绝不要结束根因分析。 -
综合分析。 报告:根因实体 · 受影响的作业 · 时间演变 · 故障类型 · 严重程度 · 建议采取的措施。完整示例:references/worked-example.md。查询 模板:references/investigation-queries.md。
规则
- 对于“哪个实体?”,按
influencer_score排名,而不是anomaly_score——桶分数是汇总值;影响者分数用于归因。 - 跨多个作业出现异常的实体是首要嫌疑对象;仅在单个作业中出现异常的实体通常是受害者。
- 最早的异常时间戳优先——根据各作业的记录时间戳还原时间顺序。
multi_bucket_impact ≥ 3= 持续的行为变化,其权重高于短暂激增。- 影响者/记录查询使用较低的分数阈值(25 或更低)——阈值过高会漏掉相关实体。
- 没有来自数据馈送索引的源数据证据,绝不要结束根因分析。
模式:解释——分数/模型行为
适用场景:“为什么我的分数是 30/90?”、“分数一夜之间下降了”、“什么是重新归一化?”、“为什么没有检测到这个问题?”。
流程
-
决定是获取还是直接解读。 如果用户提供的记录包含
record_score、initial_record_score、actual和typical,则直接解读。否则,使用GET /_ml/anomaly_detectors/{job_id}加载配置,并使用POST /.ml-anomalies-*/_search(result_type: record)加载记录。 -
始终同时展示
initial_record_score和record_score。 两者的差距说明了重归一化的情况。较大的正向 漂移(initial_record_score >> record_score)表示后续出现了更极端的异常,导致该记录的分数被下调—— 这是符合预期的正常行为,并非模型损坏。 -
先对模式进行分类,再推测原因。
模式 解读 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因素。 -
量化重归一化(可选)。 重新查询记录,并按
timestamp排序;计算score_drift = initial_record_score - record_score,并标记较大的漂移。 -
必要时补充图表上下文。 如果
model_plot_config.enabled,查询result_type: model_plot,并比较actual与model_lower/model_upper。对于分类任务,查询result_type: category_definition。 -
分数持续异常时检查任务健康状况。 调用
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 | ↓ 分数 | 数据桶中的数据少于预期(摄取延迟、数据稀疏) |
规则
- 诊断配置前先解释重归一化——分数漂移是“分数下降”最常见的原因。
actual << typical且有 count/low_count 时属于缺失异常——区分中断与数值峰值。- 周季节性需要 ≥3 周的训练数据——将任务运行时间较短标记为原因。
- 检测器函数的方向很重要——参见 references/anomaly-detection-functions.md。
模式:故障排除——任务生命周期
适用情况:“文档缺失”、“数据馈送已停止”、hard_limit、“结果看起来不对”、生命周期变化。
流程
-
加载作业和数据馈送状态。 调用
GET /_ml/anomaly_detectors/{job_id}/_stats和GET /_ml/datafeeds/datafeed-{job_id}/_stats。读取state、data_counts、model_size_stats和数据馈送的state。如果用户嵌入了统计信息 JSON,请直接根据memory_status和数据馈送状态进行诊断。 -
首先诊断内存状态(关键)。 检查
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时,模型已达到内存上限——它会停止学习新的实体,结果也会变差或停止。数据馈送已停止通常是症状,而非根本原因。不要只建议重启数据馈送——仅此操作无法解除硬限制。 -
修复 hard_limit。 解决方法是提高
model_memory_limit(通过更新作业),和/或缩小模型规模,方法是降低基数(减少 partition/by/over 字段值,或拆分为多个作业)。提高限制需要执行以下生命周期流程(停止数据馈送 → 关闭作业 → 更新 → 打开 → 启动)。也可以调用POST /_ml/anomaly_detectors/_estimate_model_memory,根据数据源基数估算新的限制。 -
诊断缺失文档/查询时间问题。 内存状态正常后,通过
GET /_ml/datafeeds/datafeed-{job_id}检查数据馈送的query_delay和delayed_data_check_config。在.ml-annotations-*中搜索延迟数据事件。将query_delay设为 P95 写入延迟加上缓冲时间(默认60s–120s)。 -
读取作业消息。 如果无法明确错误原因,请在
.ml-notifications-*中搜索作业 ID。 -
恢复已损坏的模型状态。 当模型在 hard_limit 期间损坏时,调用
POST /_ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}/_revert,回退到已知正常的快照。
配置变更的生命周期(内存限制、query_delay)
按顺序执行——跳过步骤会导致更新被拒绝:
POST /_ml/datafeeds/datafeed-{job_id}/_stopPOST /_ml/anomaly_detectors/{job_id}/_closePOST /_ml/anomaly_detectors/{job_id}/_update(内存限制)和/或POST /_ml/datafeeds/datafeed-{job_id}/_update(query_delay)POST /_ml/anomaly_detectors/{job_id}/_openPOST /_ml/datafeeds/datafeed-{job_id}/_start
重启前,使用 POST /_ml/datafeeds/datafeed-{job_id}/_preview 预览变更。
hard_limit会损坏模型状态,并导致下游出现误报的缺失文档问题。先修复内存,再处理query_delay。 完整的故障排查详情: references/troubleshooting-reference.md。
规则
- 基于
memory_status诊断生命周期问题——不要给出笼统的“重启即可”建议。 - 先修复内存,再处理
query_delay——hard_limit 会使下游诊断失效。 - 任何内存或数据馈送配置变更都要依次执行:停止数据馈送 → 关闭作业 → 更新 → 打开 → 启动。
- 不要将删除作业作为修复 hard_limit 的首选方案——提高限制和/或降低基数。
模式:管理 — 创建 / 配置作业
适用场景:“设置一个作业”“创建一个 ML 检测器”“持续监控 X”。
对于完整的创建 / 打开 / 启动作业生命周期,优先使用 elasticsearch-anomaly-detection 技能。此模式概述操作顺序和检测器选择:
- 验证目标索引。 调用
GET /{index}/_mapping,确认时间字段和检测器字段存在。 - 创建作业。 调用
PUT /_ml/anomaly_detectors/{job_id},传入analysis_config(检测器、bucket_span、影响因素)和data_description.time_field。 - 创建数据馈送。 调用
PUT /_ml/datafeeds/datafeed-{job_id},传入indices、query和query_delay。 - 打开并启动。 调用
POST /_ml/anomaly_detectors/{job_id}/_open,然后调用POST /_ml/datafeeds/datafeed-{job_id}/_start。 - 确认状态。 调用
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。
规则
- 先创建作业,再创建数据馈送。 启动数据馈送前先打开作业。
query_delay= P95 数据摄取延迟 + 缓冲时间(安全默认值为 60s–120s)。by_field_name与over_field_name:by将实体与其自身的历史记录进行比较;over将实体与同组对象进行比较。- 预测要求使用非总体作业——包含
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 →
按顺序创建 / 打开 / 启动作业。
指南
- 先选择一种模式。 不要在同一回复中混合根因分析逻辑和分数解释逻辑。
- 对于“是哪个实体?”,按
influencer_score排序,而不是按时间桶的anomaly_score排序。 - 对于生命周期故障,建议重启数据馈送前先读取
memory_status。 - 同时显示
initial_record_score和record_score——两者的差值可以说明分数重新归一化的情况。 - 先解决内存问题,再处理
query_delay。 Hard_limit 会使后续诊断失效。 - 使用数据馈送索引中的源数据证据确认根因分析结果。
操作
| HTTP API (shorthand) | elastic CLI command |
|---|---|
GET /{index}/_mapping | elastic es indices get-mapping --index '<index>' |
POST /{index}/_search | elastic es search --index '<index>' --input-file '<search-body.json>' |
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>' |
GET /_ml/datafeeds/datafeed-{job_id} | elastic es ml get-datafeeds --datafeed-id 'datafeed-<job_id>' |
GET /_ml/datafeeds/datafeed-{job_id}/_stats | elastic es ml get-datafeed-stats --datafeed-id 'datafeed-<job_id>' |
POST /.ml-anomalies-*/_search | elastic es search --index '.ml-anomalies-*' --input-file '<search-body.json>' |
POST /.ml-annotations-*/_search | elastic es search --index '.ml-annotations-*' --input-file '<search-body.json>' |
POST /.ml-notifications-*/_search | elastic es search --index '.ml-notifications-*' --input-file '<search-body.json>' |
POST /_ml/anomaly_detectors/_estimate_model_memory | elastic 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}/_open | elastic es ml open-job --job-id '<job_id>' |
POST /_ml/anomaly_detectors/{job_id}/_close | elastic es ml close-job --job-id '<job_id>' |
POST /_ml/anomaly_detectors/{job_id}/_update | elastic es ml update-job --job-id '<job_id>' --analysis-limits '<json>' |
POST /_ml/datafeeds/datafeed-{job_id}/_update | elastic es ml update-datafeed --datafeed-id 'datafeed-<job_id>' --input-file '<update-body.json>' |
POST /_ml/datafeeds/datafeed-{job_id}/_start | elastic es ml start-datafeed --datafeed-id 'datafeed-<job_id>' |
POST /_ml/datafeeds/datafeed-{job_id}/_stop | elastic es ml stop-datafeed --datafeed-id 'datafeed-<job_id>' |
POST /_ml/datafeeds/datafeed-{job_id}/_preview | elastic es ml preview-datafeed --datafeed-id 'datafeed-<job_id>' |
POST /_ml/anomaly_detectors/{job_id}/model_snapshots/{snapshot_id}/_revert | elastic es ml revert-model-snapshot --job-id '<job_id>' --snapshot-id '<snapshot_id>' |
每种 result_type 对应的搜索正文结构以及故障排查查询,详见
references/investigation-queries.md 和
references/troubleshooting-reference.md。