Azure AI Anomalydetector Java
MicrosoftOfficialCreated by Microsoft
- Skill
- Tool integration
- Data and AI
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The Azure AI Anomaly Detector SDK for Java provides a comprehensive interface for building intelligent monitoring systems. It supports both univariate analysis for single-variable time series and multivariate analysis for detecting anomalies across hundreds of correlated signals using Graph Attention Networks. The SDK includes capabilities for batch processing, real-time streaming detection, and change-point identification, with robust support for authentication via Azure Identity.
What it does
- Performs univariate batch and streaming anomaly detection on time-series data.
- Identifies trend changes using change-point detection algorithms.
- Executes multivariate anomaly detection across up to 300 correlated signals.
- Manages model training, inference, and lifecycle operations.
- Provides flexible authentication options including API keys and managed identities.
- Offers interpretation of multivariate anomalies through contributor scoring.
When to use it
- When building AI-powered monitoring solutions for time-series data.
- When you need to detect anomalies in single-variable datasets.
- When analyzing complex systems with multiple correlated data streams.
- When implementing real-time anomaly detection for streaming data points.
- When you need to identify significant trend shifts in historical data.
Advantages
- Native Java support for Azure AI services.
- Supports both synchronous and asynchronous client patterns.
- Advanced multivariate detection using Graph Attention Networks.
- Seamless integration with Azure Identity for secure production deployments.
- Detailed contributor analysis for multivariate anomaly interpretation.
Usage examples
- “How do I detect anomalies in a single time series using Java?”
- The skill provides a UnivariateClient that accepts a list of TimeSeriesPoint objects and returns detection results, including anomaly flags and margins.
- “Can I detect anomalies across multiple correlated variables?”
- Yes, the MultivariateClient allows you to train models on multiple variables and perform batch or streaming inference to identify anomalies and contributing factors.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/microsoft/azure-ai-anomalydetector-java/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip azure-ai-anomalydetector-java.zip -d .agents/skills
Documentation by Microsoft
Azure AI Anomaly Detector SDK for Java
Build anomaly detection applications using the Azure AI Anomaly Detector SDK for Java.
Installation
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-ai-anomalydetector</artifactId>
<version>3.0.0-beta.6</version>
</dependency>Client Creation
Sync and Async Clients
import com.azure.ai.anomalydetector.AnomalyDetectorClientBuilder;
import com.azure.ai.anomalydetector.MultivariateClient;
import com.azure.ai.anomalydetector.UnivariateClient;
import com.azure.core.credential.AzureKeyCredential;
String endpoint = System.getenv("AZURE_ANOMALY_DETECTOR_ENDPOINT");
String key = System.getenv("AZURE_ANOMALY_DETECTOR_API_KEY");
// Multivariate client for multiple correlated signals
MultivariateClient multivariateClient = new AnomalyDetectorClientBuilder()
.credential(new AzureKeyCredential(key))
.endpoint(endpoint)
.buildMultivariateClient();
// Univariate client for single variable analysis
UnivariateClient univariateClient = new AnomalyDetectorClientBuilder()
.credential(new AzureKeyCredential(key))
.endpoint(endpoint)
.buildUnivariateClient();With DefaultAzureCredential
import com.azure.core.credential.TokenCredential;
import com.azure.identity.AzureIdentityEnvVars;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.ManagedIdentityCredentialBuilder;
TokenCredential credential = new DefaultAzureCredentialBuilder()
.requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)
.build();
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable#credential-classes
// TokenCredential credential = new ManagedIdentityCredentialBuilder().build();
MultivariateClient client = new AnomalyDetectorClientBuilder()
.credential(credential)
.endpoint(endpoint)
.buildMultivariateClient();Key Concepts
Univariate Anomaly Detection
Batch Detection: Analyze entire time series at once
Streaming Detection: Real-time detection on latest data point
Change Point Detection: Detect trend changes in time series
Multivariate Anomaly Detection
Detect anomalies across 300+ correlated signals
Uses Graph Attention Network for inter-correlations
Three-step process: Train → Inference → Results
Core Patterns
Univariate Batch Detection
import com.azure.ai.anomalydetector.models.*;
import java.time.OffsetDateTime;
import java.util.List;
List<TimeSeriesPoint> series = List.of(
new TimeSeriesPoint(OffsetDateTime.parse("2023-01-01T00:00:00Z"), 1.0),
new TimeSeriesPoint(OffsetDateTime.parse("2023-01-02T00:00:00Z"), 2.5),
// ... more data points (minimum 12 points required)
);
UnivariateDetectionOptions options = new UnivariateDetectionOptions(series)
.setGranularity(TimeGranularity.DAILY)
.setSensitivity(95);
UnivariateEntireDetectionResult result = univariateClient.detectUnivariateEntireSeries(options);
// Check for anomalies
for (int i = 0; i < result.getIsAnomaly().size(); i++) {
if (result.getIsAnomaly().get(i)) {
System.out.printf("Anomaly detected at index %d with value %.2f%n",
i, series.get(i).getValue());
}
}Univariate Last Point Detection (Streaming)
UnivariateLastDetectionResult lastResult = univariateClient.detectUnivariateLastPoint(options);
if (lastResult.isAnomaly()) {
System.out.println("Latest point is an anomaly!");
System.out.printf("Expected: %.2f, Upper: %.2f, Lower: %.2f%n",
lastResult.getExpectedValue(),
lastResult.getUpperMargin(),
lastResult.getLowerMargin());
}Change Point Detection
UnivariateChangePointDetectionOptions changeOptions =
new UnivariateChangePointDetectionOptions(series, TimeGranularity.DAILY);
UnivariateChangePointDetectionResult changeResult =
univariateClient.detectUnivariateChangePoint(changeOptions);
for (int i = 0; i < changeResult.getIsChangePoint().size(); i++) {
if (changeResult.getIsChangePoint().get(i)) {
System.out.printf("Change point at index %d with confidence %.2f%n",
i, changeResult.getConfidenceScores().get(i));
}
}Multivariate Model Training
import com.azure.ai.anomalydetector.models.*;
import com.azure.core.util.polling.SyncPoller;
// Prepare training request with blob storage data
ModelInfo modelInfo = new ModelInfo()
.setDataSource("https://storage.blob.core.windows.net/container/data.zip?sasToken")
.setStartTime(OffsetDateTime.parse("2023-01-01T00:00:00Z"))
.setEndTime(OffsetDateTime.parse("2023-06-01T00:00:00Z"))
.setSlidingWindow(200)
.setDisplayName("MyMultivariateModel");
// Train model (long-running operation)
AnomalyDetectionModel trainedModel = multivariateClient.trainMultivariateModel(modelInfo);
String modelId = trainedModel.getModelId();
System.out.println("Model ID: " + modelId);
// Check training status
AnomalyDetectionModel model = multivariateClient.getMultivariateModel(modelId);
System.out.println("Status: " + model.getModelInfo().getStatus());Multivariate Batch Inference
MultivariateBatchDetectionOptions detectionOptions = new MultivariateBatchDetectionOptions()
.setDataSource("https://storage.blob.core.windows.net/container/inference-data.zip?sasToken")
.setStartTime(OffsetDateTime.parse("2023-07-01T00:00:00Z"))
.setEndTime(OffsetDateTime.parse("2023-07-31T00:00:00Z"))
.setTopContributorCount(10);
MultivariateDetectionResult detectionResult =
multivariateClient.detectMultivariateBatchAnomaly(modelId, detectionOptions);
String resultId = detectionResult.getResultId();
// Poll for results
MultivariateDetectionResult result = multivariateClient.getBatchDetectionResult(resultId);
for (AnomalyState state : result.getResults()) {
if (state.getValue().isAnomaly()) {
System.out.printf("Anomaly at %s, severity: %.2f%n",
state.getTimestamp(),
state.getValue().getSeverity());
}
}Multivariate Last Point Detection
MultivariateLastDetectionOptions lastOptions = new MultivariateLastDetectionOptions()
.setVariables(List.of(
new VariableValues("variable1", List.of("timestamp1"), List.of(1.0f)),
new VariableValues("variable2", List.of("timestamp1"), List.of(2.5f))
))
.setTopContributorCount(5);
MultivariateLastDetectionResult lastResult =
multivariateClient.detectMultivariateLastAnomaly(modelId, lastOptions);
if (lastResult.getValue().isAnomaly()) {
System.out.println("Anomaly detected!");
// Check contributing variables
for (AnomalyContributor contributor : lastResult.getValue().getInterpretation()) {
System.out.printf("Variable: %s, Contribution: %.2f%n",
contributor.getVariable(),
contributor.getContributionScore());
}
}Model Management
// List all models
PagedIterable<AnomalyDetectionModel> models = multivariateClient.listMultivariateModels();
for (AnomalyDetectionModel m : models) {
System.out.printf("Model: %s, Status: %s%n",
m.getModelId(),
m.getModelInfo().getStatus());
}
// Delete a model
multivariateClient.deleteMultivariateModel(modelId);Error Handling
import com.azure.core.exception.HttpResponseException;
try {
univariateClient.detectUnivariateEntireSeries(options);
} catch (HttpResponseException e) {
System.out.println("Status code: " + e.getResponse().getStatusCode());
System.out.println("Error: " + e.getMessage());
}Environment Variables
AZURE_ANOMALY_DETECTOR_ENDPOINT=https://<resource>.cognitiveservices.azure.com/ # Required for all auth methods
AZURE_ANOMALY_DETECTOR_API_KEY=<your-api-key> # Only required for AzureKeyCredential auth
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in productionBest Practices
Minimum Data Points: Univariate requires at least 12 points; more data improves accuracy
Granularity Alignment: Match
TimeGranularityto your actual data frequencySensitivity Tuning: Higher values (0-99) detect more anomalies
Multivariate Training: Use 200-1000 sliding window based on pattern complexity
Error Handling: Always handle
HttpResponseExceptionfor API errors
Trigger Phrases
"anomaly detection Java"
"detect anomalies time series"
"multivariate anomaly Java"
"univariate anomaly detection"
"streaming anomaly detection"
"change point detection"
"Azure AI Anomaly Detector"
Files
- ATTRIBUTION.mdAdded by AutoGineer994 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md8.8 KiB
- references/examples.md23.8 KiB
references/examples.md
Azure AI Anomaly Detector Java SDK - Examples
Comprehensive code examples for the Azure AI Anomaly Detector SDK for Java.
Table of Contents
Maven Dependency
Client Creation
Univariate Detection
Univariate Streaming Detection
Change Point Detection
Multivariate Model Training
Multivariate Batch Inference
Multivariate Last Point Detection
Model Management
Error Handling
Complete Application Example
Maven Dependency
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-ai-anomalydetector</artifactId>
<version>3.0.0-beta.6</version>
</dependency>
<!-- For DefaultAzureCredential -->
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.14.2</version>
</dependency>Client Creation
With API Key
import com.azure.ai.anomalydetector.AnomalyDetectorClientBuilder;
import com.azure.ai.anomalydetector.MultivariateClient;
import com.azure.ai.anomalydetector.UnivariateClient;
import com.azure.core.credential.AzureKeyCredential;
String endpoint = System.getenv("AZURE_ANOMALY_DETECTOR_ENDPOINT");
String key = System.getenv("AZURE_ANOMALY_DETECTOR_API_KEY");
// Univariate client for single variable analysis
UnivariateClient univariateClient = new AnomalyDetectorClientBuilder()
.credential(new AzureKeyCredential(key))
.endpoint(endpoint)
.buildUnivariateClient();
// Multivariate client for multiple correlated signals
MultivariateClient multivariateClient = new AnomalyDetectorClientBuilder()
.credential(new AzureKeyCredential(key))
.endpoint(endpoint)
.buildMultivariateClient();With DefaultAzureCredential (Recommended)
import com.azure.identity.DefaultAzureCredentialBuilder;
UnivariateClient univariateClient = new AnomalyDetectorClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(endpoint)
.buildUnivariateClient();
MultivariateClient multivariateClient = new AnomalyDetectorClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(endpoint)
.buildMultivariateClient();Async Clients
import com.azure.ai.anomalydetector.UnivariateAsyncClient;
import com.azure.ai.anomalydetector.MultivariateAsyncClient;
UnivariateAsyncClient univariateAsyncClient = new AnomalyDetectorClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(endpoint)
.buildUnivariateAsyncClient();
MultivariateAsyncClient multivariateAsyncClient = new AnomalyDetectorClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint(endpoint)
.buildMultivariateAsyncClient();Univariate Detection
Batch Detection (Entire Series)
Detect anomalies across an entire time series at once.
import com.azure.ai.anomalydetector.models.*;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
// Prepare time series data (minimum 12 points required)
List<TimeSeriesPoint> series = new ArrayList<>();
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-01T00:00:00Z"), 826.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-02T00:00:00Z"), 799.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-03T00:00:00Z"), 890.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-04T00:00:00Z"), 900.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-05T00:00:00Z"), 961.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-06T00:00:00Z"), 935.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-07T00:00:00Z"), 894.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-08T00:00:00Z"), 855.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-09T00:00:00Z"), 809.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-10T00:00:00Z"), 810.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-11T00:00:00Z"), 766.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-12T00:00:00Z"), 805.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-13T00:00:00Z"), 821.0));
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-14T00:00:00Z"), 2000.0)); // Anomaly!
series.add(new TimeSeriesPoint(OffsetDateTime.parse("2023-01-15T00:00:00Z"), 888.0));
// Configure detection options
UnivariateDetectionOptions options = new UnivariateDetectionOptions(series)
.setGranularity(TimeGranularity.DAILY)
.setSensitivity(95); // Higher = more sensitive (0-99)
// Detect anomalies
UnivariateEntireDetectionResult result = univariateClient.detectUnivariateEntireSeries(options);
// Process results
System.out.println("=== Anomaly Detection Results ===");
System.out.println("Period: " + result.getPeriod());
for (int i = 0; i < result.getIsAnomaly().size(); i++) {
if (result.getIsAnomaly().get(i)) {
TimeSeriesPoint point = series.get(i);
System.out.printf("ANOMALY at %s: value=%.2f, expected=%.2f, upper=%.2f, lower=%.2f%n",
point.getTimestamp(),
point.getValue(),
result.getExpectedValues().get(i),
result.getUpperMargins().get(i),
result.getLowerMargins().get(i));
}
}
// Check positive/negative anomalies
for (int i = 0; i < result.getIsPositiveAnomaly().size(); i++) {
if (result.getIsPositiveAnomaly().get(i)) {
System.out.printf("Positive anomaly (spike) at index %d%n", i);
}
if (result.getIsNegativeAnomaly().get(i)) {
System.out.printf("Negative anomaly (dip) at index %d%n", i);
}
}Custom Period and Sensitivity
UnivariateDetectionOptions options = new UnivariateDetectionOptions(series)
.setGranularity(TimeGranularity.HOURLY)
.setCustomInterval(4) // Custom interval for non-standard granularity
.setSensitivity(85) // Lower sensitivity = fewer anomalies
.setImputeMode(ImputeMode.AUTO) // Handle missing values
.setImputeFixedValue(0.0); // Fixed value for imputation (if FIXED mode)
UnivariateEntireDetectionResult result = univariateClient.detectUnivariateEntireSeries(options);Univariate Streaming Detection
Last Point Detection (Real-time)
Detect if the most recent data point is an anomaly.
// Add your latest data point to the series
series.add(new TimeSeriesPoint(OffsetDateTime.now(), 1500.0));
UnivariateDetectionOptions options = new UnivariateDetectionOptions(series)
.setGranularity(TimeGranularity.DAILY)
.setSensitivity(95);
UnivariateLastDetectionResult result = univariateClient.detectUnivariateLastPoint(options);
System.out.println("=== Last Point Detection ===");
System.out.println("Is Anomaly: " + result.isAnomaly());
System.out.println("Is Positive Anomaly: " + result.isPositiveAnomaly());
System.out.println("Is Negative Anomaly: " + result.isNegativeAnomaly());
System.out.printf("Expected Value: %.2f%n", result.getExpectedValue());
System.out.printf("Upper Margin: %.2f%n", result.getUpperMargin());
System.out.printf("Lower Margin: %.2f%n", result.getLowerMargin());
System.out.println("Severity: " + result.getSeverity());
if (result.isAnomaly()) {
System.out.println("⚠️ ALERT: Anomaly detected in latest data point!");
}Streaming Detection Pattern
public class StreamingAnomalyDetector {
private final UnivariateClient client;
private final List<TimeSeriesPoint> buffer;
private final int windowSize;
public StreamingAnomalyDetector(UnivariateClient client, int windowSize) {
this.client = client;
this.buffer = new ArrayList<>();
this.windowSize = windowSize;
}
public boolean processDataPoint(OffsetDateTime timestamp, double value) {
// Add new point
buffer.add(new TimeSeriesPoint(timestamp, value));
// Keep window size manageable
if (buffer.size() > windowSize) {
buffer.remove(0);
}
// Need minimum 12 points for detection
if (buffer.size() < 12) {
return false;
}
// Detect anomaly
UnivariateDetectionOptions options = new UnivariateDetectionOptions(buffer)
.setGranularity(TimeGranularity.MINUTELY)
.setSensitivity(90);
UnivariateLastDetectionResult result = client.detectUnivariateLastPoint(options);
return result.isAnomaly();
}
}Change Point Detection
Detect trend changes in time series data.
UnivariateChangePointDetectionOptions changeOptions =
new UnivariateChangePointDetectionOptions(series, TimeGranularity.DAILY);
UnivariateChangePointDetectionResult result =
univariateClient.detectUnivariateChangePoint(changeOptions);
System.out.println("=== Change Point Detection ===");
System.out.println("Period: " + result.getPeriod());
int changePointCount = 0;
for (int i = 0; i < result.getIsChangePoint().size(); i++) {
if (result.getIsChangePoint().get(i)) {
changePointCount++;
TimeSeriesPoint point = series.get(i);
System.out.printf("Change point at %s (confidence: %.2f)%n",
point.getTimestamp(),
result.getConfidenceScores().get(i));
}
}
System.out.printf("Total change points detected: %d%n", changePointCount);Multivariate Model Training
Train a model on multiple correlated variables.
Prepare Training Data
Data must be in a ZIP file in Azure Blob Storage with CSV files for each variable:
training-data.zip
├── variable1.csv
├── variable2.csv
└── variable3.csvEach CSV format:
timestamp,value
2023-01-01T00:00:00Z,100.5
2023-01-01T01:00:00Z,102.3
...Train Model
import com.azure.ai.anomalydetector.models.*;
import java.time.OffsetDateTime;
String blobSasUrl = "https://storage.blob.core.windows.net/container/training-data.zip?sasToken";
ModelInfo modelInfo = new ModelInfo()
.setDataSource(blobSasUrl)
.setStartTime(OffsetDateTime.parse("2023-01-01T00:00:00Z"))
.setEndTime(OffsetDateTime.parse("2023-06-01T00:00:00Z"))
.setSlidingWindow(200) // Window size for pattern detection
.setAlignPolicy(new AlignPolicy()
.setAlignMode(AlignMode.OUTER)
.setFillNAMethod(FillNAMethod.LINEAR))
.setDisplayName("MyMultivariateModel");
// Start training (long-running operation)
AnomalyDetectionModel trainedModel = multivariateClient.trainMultivariateModel(modelInfo);
String modelId = trainedModel.getModelId();
System.out.println("Model ID: " + modelId);
// Poll for training completion
AnomalyDetectionModel model;
do {
Thread.sleep(10000); // Wait 10 seconds
model = multivariateClient.getMultivariateModel(modelId);
System.out.println("Training status: " + model.getModelInfo().getStatus());
} while (model.getModelInfo().getStatus() == ModelStatus.CREATED
|| model.getModelInfo().getStatus() == ModelStatus.RUNNING);
if (model.getModelInfo().getStatus() == ModelStatus.READY) {
System.out.println("Model trained successfully!");
System.out.println("Variables used: " + model.getModelInfo().getVariableStates().size());
} else {
System.err.println("Training failed: " + model.getModelInfo().getErrors());
}Multivariate Batch Inference
Detect anomalies across multiple variables at once.
String inferenceDataUrl = "https://storage.blob.core.windows.net/container/inference-data.zip?sasToken";
MultivariateBatchDetectionOptions detectionOptions = new MultivariateBatchDetectionOptions()
.setDataSource(inferenceDataUrl)
.setStartTime(OffsetDateTime.parse("2023-07-01T00:00:00Z"))
.setEndTime(OffsetDateTime.parse("2023-07-31T00:00:00Z"))
.setTopContributorCount(10); // Top contributing variables to show
// Start batch detection
MultivariateDetectionResult detectionResult =
multivariateClient.detectMultivariateBatchAnomaly(modelId, detectionOptions);
String resultId = detectionResult.getResultId();
System.out.println("Detection started, result ID: " + resultId);
// Poll for results
MultivariateDetectionResult result;
do {
Thread.sleep(5000);
result = multivariateClient.getBatchDetectionResult(resultId);
System.out.println("Detection status: " + result.getSummary().getStatus());
} while (result.getSummary().getStatus() == MultivariateBatchDetectionStatus.CREATED
|| result.getSummary().getStatus() == MultivariateBatchDetectionStatus.RUNNING);
// Process results
if (result.getSummary().getStatus() == MultivariateBatchDetectionStatus.READY) {
System.out.println("=== Multivariate Anomaly Detection Results ===");
int anomalyCount = 0;
for (AnomalyState state : result.getResults()) {
if (state.getValue().isAnomaly()) {
anomalyCount++;
System.out.printf("Anomaly at %s, severity: %.4f%n",
state.getTimestamp(),
state.getValue().getSeverity());
// Show contributing variables
if (state.getValue().getInterpretation() != null) {
System.out.println(" Contributing variables:");
for (AnomalyInterpretation interp : state.getValue().getInterpretation()) {
System.out.printf(" - %s: %.4f%n",
interp.getVariable(),
interp.getContributionScore());
}
}
}
}
System.out.printf("Total anomalies detected: %d%n", anomalyCount);
}Multivariate Last Point Detection
Real-time detection for multivariate data.
import java.util.Arrays;
// Prepare latest data point for each variable
List<VariableValues> variables = Arrays.asList(
new VariableValues("temperature",
Arrays.asList("2023-07-15T12:00:00Z"),
Arrays.asList(85.5f)),
new VariableValues("pressure",
Arrays.asList("2023-07-15T12:00:00Z"),
Arrays.asList(1013.2f)),
new VariableValues("humidity",
Arrays.asList("2023-07-15T12:00:00Z"),
Arrays.asList(65.0f))
);
MultivariateLastDetectionOptions lastOptions = new MultivariateLastDetectionOptions()
.setVariables(variables)
.setTopContributorCount(5);
MultivariateLastDetectionResult lastResult =
multivariateClient.detectMultivariateLastAnomaly(modelId, lastOptions);
System.out.println("=== Multivariate Last Point Detection ===");
System.out.println("Is Anomaly: " + lastResult.getValue().isAnomaly());
System.out.printf("Severity: %.4f%n", lastResult.getValue().getSeverity());
System.out.printf("Score: %.4f%n", lastResult.getValue().getScore());
if (lastResult.getValue().isAnomaly()) {
System.out.println("Contributing variables:");
for (AnomalyInterpretation interp : lastResult.getValue().getInterpretation()) {
System.out.printf(" - %s: contribution=%.4f, value=%.2f, expected=%.2f%n",
interp.getVariable(),
interp.getContributionScore(),
interp.getCorrelationChanges().getChangedValues().get(0),
interp.getCorrelationChanges().getExpectedValues().get(0));
}
}Model Management
List Models
import com.azure.core.http.rest.PagedIterable;
PagedIterable<AnomalyDetectionModel> models = multivariateClient.listMultivariateModels();
System.out.println("=== Available Models ===");
for (AnomalyDetectionModel m : models) {
System.out.printf("Model: %s, Status: %s, Created: %s%n",
m.getModelId(),
m.getModelInfo().getStatus(),
m.getCreatedTime());
}Get Model Details
AnomalyDetectionModel model = multivariateClient.getMultivariateModel(modelId);
System.out.println("=== Model Details ===");
System.out.println("Model ID: " + model.getModelId());
System.out.println("Display Name: " + model.getModelInfo().getDisplayName());
System.out.println("Status: " + model.getModelInfo().getStatus());
System.out.println("Created: " + model.getCreatedTime());
System.out.println("Last Updated: " + model.getLastUpdatedTime());
System.out.println("Sliding Window: " + model.getModelInfo().getSlidingWindow());
// Variable states
System.out.println("Variables:");
for (VariableState vs : model.getModelInfo().getVariableStates()) {
System.out.printf(" - %s: effective=%d, missing=%.2f%%%n",
vs.getVariable(),
vs.getEffectiveCount(),
vs.getMissingRatio() * 100);
}Delete Model
multivariateClient.deleteMultivariateModel(modelId);
System.out.println("Model deleted: " + modelId);Error Handling
import com.azure.core.exception.HttpResponseException;
try {
UnivariateDetectionOptions options = new UnivariateDetectionOptions(series)
.setGranularity(TimeGranularity.DAILY);
univariateClient.detectUnivariateEntireSeries(options);
} catch (HttpResponseException e) {
int statusCode = e.getResponse().getStatusCode();
System.err.println("HTTP Status: " + statusCode);
System.err.println("Error: " + e.getMessage());
switch (statusCode) {
case 400:
System.err.println("Bad request - check data format and minimum points (12 required)");
break;
case 401:
System.err.println("Unauthorized - check API key");
break;
case 404:
System.err.println("Model not found");
break;
case 429:
System.err.println("Rate limited - implement retry with backoff");
break;
default:
System.err.println("Unexpected error");
}
} catch (Exception e) {
System.err.println("Unexpected error: " + e.getMessage());
}Complete Application Example
import com.azure.ai.anomalydetector.AnomalyDetectorClientBuilder;
import com.azure.ai.anomalydetector.UnivariateClient;
import com.azure.ai.anomalydetector.models.*;
import com.azure.identity.DefaultAzureCredentialBuilder;
import java.time.OffsetDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
public class MetricsAnomalyDetector {
private final UnivariateClient client;
private final int sensitivity;
public MetricsAnomalyDetector(int sensitivity) {
this.client = new AnomalyDetectorClientBuilder()
.endpoint(System.getenv("AZURE_ANOMALY_DETECTOR_ENDPOINT"))
.credential(new DefaultAzureCredentialBuilder().build())
.buildUnivariateClient();
this.sensitivity = sensitivity;
}
public List<AnomalyResult> detectAnomalies(List<MetricDataPoint> metrics) {
// Convert to time series points
List<TimeSeriesPoint> series = new ArrayList<>();
for (MetricDataPoint metric : metrics) {
series.add(new TimeSeriesPoint(metric.timestamp, metric.value));
}
// Detect anomalies
UnivariateDetectionOptions options = new UnivariateDetectionOptions(series)
.setGranularity(TimeGranularity.MINUTELY)
.setSensitivity(sensitivity);
UnivariateEntireDetectionResult result = client.detectUnivariateEntireSeries(options);
// Build results
List<AnomalyResult> anomalies = new ArrayList<>();
for (int i = 0; i < result.getIsAnomaly().size(); i++) {
if (result.getIsAnomaly().get(i)) {
anomalies.add(new AnomalyResult(
metrics.get(i).timestamp,
metrics.get(i).value,
result.getExpectedValues().get(i),
result.getUpperMargins().get(i),
result.getLowerMargins().get(i),
result.getIsPositiveAnomaly().get(i) ? "SPIKE" : "DIP"
));
}
}
return anomalies;
}
public boolean isLatestPointAnomaly(List<MetricDataPoint> metrics) {
List<TimeSeriesPoint> series = new ArrayList<>();
for (MetricDataPoint metric : metrics) {
series.add(new TimeSeriesPoint(metric.timestamp, metric.value));
}
UnivariateDetectionOptions options = new UnivariateDetectionOptions(series)
.setGranularity(TimeGranularity.MINUTELY)
.setSensitivity(sensitivity);
UnivariateLastDetectionResult result = client.detectUnivariateLastPoint(options);
return result.isAnomaly();
}
// Data classes
public static class MetricDataPoint {
public final OffsetDateTime timestamp;
public final double value;
public MetricDataPoint(OffsetDateTime timestamp, double value) {
this.timestamp = timestamp;
this.value = value;
}
}
public static class AnomalyResult {
public final OffsetDateTime timestamp;
public final double actualValue;
public final double expectedValue;
public final double upperBound;
public final double lowerBound;
public final String type;
public AnomalyResult(OffsetDateTime timestamp, double actualValue,
double expectedValue, double upperBound,
double lowerBound, String type) {
this.timestamp = timestamp;
this.actualValue = actualValue;
this.expectedValue = expectedValue;
this.upperBound = upperBound;
this.lowerBound = lowerBound;
this.type = type;
}
@Override
public String toString() {
return String.format("[%s] %s: actual=%.2f, expected=%.2f (bounds: %.2f - %.2f)",
timestamp, type, actualValue, expectedValue, lowerBound, upperBound);
}
}
public static void main(String[] args) {
MetricsAnomalyDetector detector = new MetricsAnomalyDetector(90);
// Generate sample data with an anomaly
List<MetricDataPoint> metrics = new ArrayList<>();
OffsetDateTime baseTime = OffsetDateTime.now().minusHours(1);
Random random = new Random();
for (int i = 0; i < 60; i++) {
double value = 100 + random.nextGaussian() * 5;
// Inject anomaly at minute 45
if (i == 45) {
value = 200;
}
metrics.add(new MetricDataPoint(
baseTime.plus(i, ChronoUnit.MINUTES),
value
));
}
// Detect anomalies
List<AnomalyResult> anomalies = detector.detectAnomalies(metrics);
System.out.println("=== Detected Anomalies ===");
for (AnomalyResult anomaly : anomalies) {
System.out.println(anomaly);
}
// Check latest point
boolean isLatestAnomaly = detector.isLatestPointAnomaly(metrics);
System.out.println("\nLatest point is anomaly: " + isLatestAnomaly);
}
}Environment Variables
AZURE_ANOMALY_DETECTOR_ENDPOINT=https://<resource>.cognitiveservices.azure.com/
AZURE_ANOMALY_DETECTOR_API_KEY=<your-api-key>
# For DefaultAzureCredential
AZURE_CLIENT_ID=<service-principal-client-id>
AZURE_CLIENT_SECRET=<service-principal-secret>
AZURE_TENANT_ID=<tenant-id>Best Practices
Minimum data points — Univariate requires at least 12 points; more data improves accuracy
Match granularity — Set
TimeGranularityto match your actual data frequencyTune sensitivity — Higher values (0-99) detect more anomalies; tune based on use case
Multivariate training — Use 200-1000 sliding window based on pattern complexity
Handle missing data — Use
ImputeModeto handle gaps in time seriesUse streaming for real-time —
detectUnivariateLastPointfor continuous monitoringCheck contributing variables — For multivariate, analyze which variables caused the anomaly
Implement retry logic — Handle rate limiting with exponential backoff
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an API key
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Microsoft
- Publisher
- Microsoft (Official)
- Source
- microsoft/skills · .github/plugins/azure-sdk-java/skills/azure-ai-anomalydetector-java · commit 0696600
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Microsoft.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download azure-ai-anomalydetector-java.zip