predictive-intelligence
$
npx mdskill add serac-labs/serac/predictive-intelligenceAutomate categorization, clustering, and prediction using ServiceNow Predictive Intelligence
- Solve auto-categorization, anomaly detection, and recommendation tasks
- Uses ServiceNow tables and ML models via Snow Query and Execute Script tools
- Leverages trained models to classify, cluster, and predict based on input data
- Returns predictions, related records, and insights directly in workflows
SKILL.md
.github/skills/predictive-intelligenceView on GitHub ↗
---
name: predictive-intelligence
description: Use ServiceNow Predictive Intelligence — sn_ml.ClassificationPredictor for auto-categorization, SimilarityPredictor for related records, ClusteringPredictor, model training/retraining, and prediction-feedback accuracy tracking.
license: Apache-2.0
compatibility: Designed for Snow-Code and ServiceNow development
metadata:
author: serac
version: "1.0.0"
category: servicenow
tools:
- snow_query_table
- snow_execute_script_with_output
- ml_predict_change_risk
- ml_detect_anomalies
---
# Predictive Intelligence for ServiceNow
Predictive Intelligence uses machine learning to automate categorization, routing, and recommendations.
## PI Capabilities
| Capability | Use Case |
| ------------------ | -------------------------------- |
| **Classification** | Auto-categorize incidents, cases |
| **Similarity** | Find similar records |
| **Clustering** | Group related items |
| **Regression** | Predict numeric values |
| **Recommendation** | Suggest next actions |
## Key Tables
| Table | Purpose |
| -------------------------- | ----------------------- |
| `ml_solution` | ML solution definitions |
| `ml_solution_definition` | Solution configuration |
| `ml_capability_definition` | Capability settings |
| `ml_model` | Trained models |
| `ml_prediction_result` | Prediction results |
## Classification (ES5)
### Configure Classification Solution
```javascript
// Create classification solution (ES5 ONLY!)
// Note: Usually done via UI, shown for understanding
var solution = new GlideRecord("ml_solution")
solution.initialize()
solution.setValue("name", "Incident Category Classifier")
solution.setValue("label", "Incident Category Classifier")
solution.setValue("table", "incident")
solution.setValue("active", true)
// Capability type
solution.setValue("capability", "classification")
// Target field to predict
solution.setValue("target_field", "category")
// Input fields for training
solution.setValue("input_fields", "short_description,description")
solution.insert()
```
### Get Classification Prediction
```javascript
// Get classification prediction for record (ES5 ONLY!)
function getClassificationPrediction(tableName, recordSysId, solutionName) {
var predictor = new sn_ml.ClassificationPredictor(solutionName)
var gr = new GlideRecord(tableName)
if (!gr.get(recordSysId)) {
return null
}
try {
var result = predictor.predict(gr)
return {
predicted_value: result.getPredictedValue(),
confidence: result.getConfidence(),
top_predictions: result.getTopPredictions(5),
}
} catch (e) {
gs.error("Prediction failed: " + e.message)
return null
}
}
```
### Apply Prediction to Record
```javascript
// Auto-apply classification prediction (ES5 ONLY!)
// Business Rule: before, insert, incident
;(function executeRule(current, previous) {
// Skip if already categorized
if (current.category) {
return
}
var solutionName = "incident_category_classifier"
try {
var predictor = new sn_ml.ClassificationPredictor(solutionName)
var result = predictor.predict(current)
// Only apply if confidence is high enough
if (result.getConfidence() >= 0.8) {
current.category = result.getPredictedValue()
current.work_notes =
"Category auto-assigned by Predictive Intelligence " +
"(Confidence: " +
Math.round(result.getConfidence() * 100) +
"%)"
}
} catch (e) {
gs.warn("Classification prediction failed: " + e.message)
}
})(current, previous)
```
## Similarity (ES5)
### Find Similar Records
```javascript
// Find similar incidents (ES5 ONLY!)
function findSimilarIncidents(incidentSysId, maxResults) {
maxResults = maxResults || 5
var incident = new GlideRecord("incident")
if (!incident.get(incidentSysId)) {
return []
}
try {
var similarity = new sn_ml.SimilarityPredictor("incident_similarity")
var results = similarity.findSimilar(incident, maxResults)
var similar = []
for (var i = 0; i < results.length; i++) {
var match = results[i]
similar.push({
sys_id: match.getRecordSysId(),
similarity_score: match.getSimilarityScore(),
record: match.getRecord(),
})
}
return similar
} catch (e) {
gs.error("Similarity search failed: " + e.message)
return []
}
}
```
### Similar Record Widget
```javascript
// Widget Server Script for similar records (ES5 ONLY!)
;(function () {
if (!input || !input.table || !input.sys_id) {
data.similar = []
return
}
var solutionName = input.table + "_similarity"
try {
var gr = new GlideRecord(input.table)
if (!gr.get(input.sys_id)) {
data.similar = []
return
}
var similarity = new sn_ml.SimilarityPredictor(solutionName)
var results = similarity.findSimilar(gr, 5)
data.similar = []
for (var i = 0; i < results.length; i++) {
var match = results[i]
var record = match.getRecord()
data.similar.push({
sys_id: match.getRecordSysId(),
score: Math.round(match.getSimilarityScore() * 100),
number: record.getValue("number"),
short_description: record.getValue("short_description"),
state: record.state.getDisplayValue(),
})
}
} catch (e) {
data.error = "Similarity search unavailable"
data.similar = []
}
})()
```
## Clustering (ES5)
### Get Cluster Assignment
```javascript
// Get cluster for record (ES5 ONLY!)
function getClusterAssignment(tableName, recordSysId, solutionName) {
var gr = new GlideRecord(tableName)
if (!gr.get(recordSysId)) {
return null
}
try {
var clustering = new sn_ml.ClusteringPredictor(solutionName)
var result = clustering.predict(gr)
return {
cluster_id: result.getClusterId(),
cluster_label: result.getClusterLabel(),
confidence: result.getConfidence(),
}
} catch (e) {
gs.error("Clustering failed: " + e.message)
return null
}
}
```
### Analyze Clusters
```javascript
// Get cluster statistics (ES5 ONLY!)
function getClusterStats(solutionName) {
var stats = []
var cluster = new GlideRecord("ml_cluster")
cluster.addQuery("solution.name", solutionName)
cluster.query()
while (cluster.next()) {
stats.push({
cluster_id: cluster.getValue("cluster_id"),
label: cluster.getValue("label"),
size: parseInt(cluster.getValue("record_count"), 10),
keywords: cluster.getValue("keywords"),
})
}
return stats
}
```
## Training Models (ES5)
### Trigger Model Training
```javascript
// Trigger retraining of ML solution (ES5 ONLY!)
function retrainSolution(solutionName) {
var solution = new GlideRecord("ml_solution")
if (!solution.get("name", solutionName)) {
gs.error("Solution not found: " + solutionName)
return false
}
try {
// Queue training job
var trainer = new sn_ml.MLTrainer()
trainer.train(solution.getUniqueValue())
gs.info("Training queued for solution: " + solutionName)
return true
} catch (e) {
gs.error("Training failed: " + e.message)
return false
}
}
```
### Check Training Status
```javascript
// Check model training status (ES5 ONLY!)
function getTrainingStatus(solutionName) {
var model = new GlideRecord("ml_model")
model.addQuery("solution.name", solutionName)
model.orderByDesc("sys_created_on")
model.setLimit(1)
model.query()
if (model.next()) {
return {
model_id: model.getUniqueValue(),
status: model.getValue("state"),
accuracy: model.getValue("accuracy"),
trained_on: model.getValue("sys_created_on"),
record_count: model.getValue("training_record_count"),
}
}
return null
}
```
## Prediction Results (ES5)
### Store Prediction Feedback
```javascript
// Record prediction feedback for model improvement (ES5 ONLY!)
function recordPredictionFeedback(predictionSysId, wasCorrect, actualValue) {
var prediction = new GlideRecord("ml_prediction_result")
if (!prediction.get(predictionSysId)) {
return false
}
prediction.setValue("feedback", wasCorrect ? "correct" : "incorrect")
prediction.setValue("actual_value", actualValue)
prediction.setValue("feedback_date", new GlideDateTime())
prediction.setValue("feedback_user", gs.getUserID())
prediction.update()
return true
}
```
### Analyze Prediction Accuracy
```javascript
// Get prediction accuracy stats (ES5 ONLY!)
function getPredictionAccuracy(solutionName, days) {
days = days || 30
var startDate = new GlideDateTime()
startDate.addDaysLocalTime(-days)
var ga = new GlideAggregate("ml_prediction_result")
ga.addQuery("solution.name", solutionName)
ga.addQuery("sys_created_on", ">=", startDate)
ga.addNotNullQuery("feedback")
ga.addAggregate("COUNT")
ga.groupBy("feedback")
ga.query()
var stats = { correct: 0, incorrect: 0 }
while (ga.next()) {
var feedback = ga.getValue("feedback")
var count = parseInt(ga.getAggregate("COUNT"), 10)
stats[feedback] = count
}
var total = stats.correct + stats.incorrect
stats.accuracy = total > 0 ? Math.round((stats.correct / total) * 100) : 0
stats.total = total
return stats
}
```
## MCP Tool Integration
### Available Tools
| Tool | Purpose |
| --------------------------------- | ------------------- |
| `snow_query_table` | Query ML tables |
| `snow_execute_script_with_output` | Test predictions |
| `ml_predict_change_risk` | Predict change risk |
| `ml_detect_anomalies` | Anomaly detection |
### Example Workflow
```javascript
// 1. Query ML solutions
await snow_query_table({
table: "ml_solution",
query: "active=true",
fields: "name,table,capability,target_field",
})
// 2. Check model status
await snow_query_table({
table: "ml_model",
query: "solution.active=true",
fields: "solution,state,accuracy,sys_created_on",
})
// 3. Test prediction
await snow_execute_script_with_output({
script: `
var result = getClassificationPrediction('incident', 'inc_sys_id', 'incident_classifier');
gs.info(JSON.stringify(result));
`,
})
```
## Best Practices
1. **Quality Data** - Clean training data is essential
2. **Feature Selection** - Choose relevant input fields
3. **Confidence Thresholds** - Only apply high-confidence predictions
4. **Feedback Loop** - Collect user feedback
5. **Regular Retraining** - Update models periodically
6. **Monitor Accuracy** - Track prediction performance
7. **Fallback** - Have manual process when prediction fails
8. **ES5 Only** - No modern JavaScript syntax
More from serac-labs/serac
- acl-securityCreate and debug ServiceNow ACLs (record, field, REST, script-include). Covers role/condition/script patterns, evaluation order, field-level visibility, and impersonation testing for row- and field-level security.
- agent-workspaceBuild ServiceNow Agent Workspace configurations — workspaces, lists, forms, contextual side panels, Agent Assist similar-record finders, and workspace-specific UI actions on sys_aw_* tables.
- approval-workflowsConfigure ServiceNow approval rules and sysapproval_approver records — manager/group/script approvers, multi-level routing, delegation via sys_user_delegate, and parent-record state rollup.
- asset-managementManage ServiceNow hardware assets, software licenses, and lifecycle states on alm_hardware/alm_license — license allocation, CMDB-to-asset linking, warranty tracking, inventory aggregation (HAM/SAM).
- atf-testingBuild ServiceNow Automated Test Framework tests and suites — impersonation, form steps, assertions, server-side script steps, test parameters, and execution via snow_create_atf_test / snow_execute_atf_test.
- blast-radiusTrace ServiceNow configuration dependencies — what artifacts touch a given field, what calls a script include, table/app-level config inventory. Use before deletes, renames, or refactors.
- bun-file-ioUse this when you are working on file operations like reading, writing, scanning, or deleting files. It summarizes the preferred file APIs and patterns used in this repo. It also notes when to use filesystem helpers for directories.
- business-rule-patternsWrite ServiceNow business rules (before/after/async/display) — current vs previous, changesTo/changesFrom, recursion avoidance, setAbortAction, and async dispatch for heavy work.
- catalog-itemsBuild ServiceNow Service Catalog items, variables, variable sets, catalog client scripts, record producers, and order guides with reference qualifiers and dynamic pricing.
- client-scriptsWrite ServiceNow client scripts (onLoad/onChange/onSubmit/onCellEdit) using g_form, g_user, GlideAjax, field visibility/mandatory toggles, and validation with debounced server calls.