Explain anomaly scores, model behavior, and why results look the way they do. Use the
ML REST API for job config and
the
standard API against
for results — no ES|QL, fully compatible with Elastic
Serverless. For job lifecycle (create, start, stop), use the
elasticsearch-anomaly-detection
skill.
This skill executes Elasticsearch operations through the
CLI. If the
CLI is not installed, tell the user what it is needed for. Do
not guess credentials, call the HTTP API directly, or attempt other workarounds.
This skill references operations in HTTP-shorthand form (e.g.,
,
,
,
GET /{index}/_settings/index.mode
,
). The
Operations table at the end of this document
maps each shorthand to the equivalent
CLI command — always use the CLI rather than calling the HTTP API
directly.
Prerequisite: ML anomaly detection requires a Platinum-equivalent license on self-managed clusters. Serverless
projects include ML. The caller needs
to read job config and anomaly results.
Serverless note: The
REST endpoints return HTTP 410 in Elastic Serverless. Always use
POST /.ml-anomalies-*/_search
for result queries instead — fully supported everywhere this skill runs.
-
Decide whether to fetch data or interpret what the user supplied. If the user embeds an anomaly record (or job
config) in the prompt, interpret it directly using the domain knowledge below — do not call APIs to re-fetch fields
already present. If the job ID, time range, or record is missing, retrieve it from the cluster.
The decision: proceed with judgment-only explanation when the record contains
,
,
,
, and
; otherwise fetch the missing pieces before explaining.
-
Verify connectivity when calling the cluster. Call
. If the call fails, stop and surface the connection
error — do not guess endpoints or credentials.
-
Resolve the job ID and load config. When the job ID is unknown, call
GET /_ml/anomaly_detectors
to list
candidates. Call
GET /_ml/anomaly_detectors/{job_id}
for full
(bucket_span, detectors,
custom_rules, use_null, model_plot_config) and
GET /_ml/anomaly_detectors/{job_id}/_stats
for
,
model_size_stats.memory_status
, and data counts.
The decision: confirm detector function and direction match the user's question before interpreting scores. A
job legitimately fires on drops; a
job does not.
-
Retrieve anomaly records for the time range. Call
POST /.ml-anomalies-*/_search
with
, the
job ID, a timestamp range, and optional
filter. Read
,
,
,
,
,
, and
anomaly_score_explanation
.
Always show
both and
. The gap is the renormalization story.
-
Classify the score pattern before speculating on causes.
- >> — Renormalization. A later, more extreme anomaly rescale this
record downward. This is expected, healthy model behavior — not a broken model or reason to distrust the detection.
Use for alerting severity; show both scores and explain the gap explicitly.
- == — No renormalization has occurred since detection.
- << with , , or — Absence / drop anomaly. A high score is
legitimate — the job detected an outage, pipeline stall, or service failure. This is not a false positive.
Recommend incident investigation, not score tuning.
- >> with or — Spike anomaly; confirm with .
Only cite anomaly_score_explanation
factors present in the record. If
is
, do
not blame variance. If a factor is absent, note that it was not returned — do not invent it.
-
Quantify renormalization across the job (optional). Re-query
POST /.ml-anomalies-*/_search
for records in the
time range sorted by
ascending. Compute
score_drift = initial_record_score − record_score
per record
and filter to
. Large negative drift (initial >> record) confirms renormalization after a more
extreme anomaly appeared later.
-
Add context when the user asks "what caused this?" or "why so low/high?"
- Model bounds — If
model_plot_config.enabled
is true, call POST /.ml-anomalies-*/_search
with
for the same job and time range. Compare to / .
- Influencers — Call
POST /.ml-anomalies-*/_search
with for the bucket time range;
sort by descending.
- Categorization jobs — Call
POST /.ml-anomalies-*/_search
with result_type: category_definition
to list
learned log patterns (, , per ).
For aggregations, cross-job queries, bucket-level results, or custom filters beyond score and time, see
references/explainer-reference.md.
The
anomaly_score_explanation
field on each record breaks the score into components:
Query body shapes for each
(
,
,
,
) are documented in
references/explainer-reference.md.