predictive-intelligence について
ServiceNow の Predictive Intelligence を扱うスキルで、機械学習による予測機能と実装例を紹介します。分類、類似レコード検索、クラスタリング、回帰、推奨に加え、MCP ツールによるソリューションの照会や学習方法も説明します。
主な機能
- 01レコードの自動分類
- 02類似レコードの検索
- 03クラスタリングと分析
- 04数値予測とアクション提案
- 05モデルの学習と状態確認
- 06フィードバック収集と精度分析
活用シーン
- 01インシデントやケースの分類
- 02関連する過去レコードの検索
- 03リスクなどの数値予測
- 04予測へのフィードバック収集と結果監視
MCP 対応
ServiceNow MCP ツールで ML テーブルの照会、予測のテストと実行、Predictive Intelligence ソリューションの学習を行う方法を説明します。
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ serac-labs/ serac --skill predictive-intelligenceインストール後、Claude Code で/predictive-intelligenceを入力して読み込まれたか確認します。
詳細
ServiceNow の予測インテリジェンス
予測インテリジェンスは、機械学習を使用して分類、振り分け、推奨を自動化します。
PI の機能
| 機能 | ユースケース |
|---|---|
| 分類 | インシデントやケースを自動分類 |
| 類似性 | 類似レコードを検索 |
| クラスタリング | 関連項目をグループ化 |
| 回帰 | 数値を予測 |
| 推奨 | 次のアクションを提案 |
主要なテーブル
| テーブル | 用途 |
|---|---|
ml_solution | ML ソリューションの定義 |
ml_solution_definition | ソリューションの設定 |
ml_capability_definition | 機能の設定 |
ml_model | トレーニング済みモデル |
ml_prediction_result | 予測結果 |
分類(ES5)
分類ソリューションを設定する
// 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 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
}
}
レコードに予測を適用する
// 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)
類似性(ES5)
類似レコードを検索する
// 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 []
}
}
類似レコードウィジェット
// 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 = []
}
})()
クラスタリング(ES5)
クラスターの割り当てを取得する
// 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
}
}
クラスターを分析する
// 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
}
モデルのトレーニング(ES5)
モデルのトレーニングを開始する
// 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 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
}
予測結果(ES5)
予測のフィードバックを保存する
// 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
}
予測精度を分析する
// 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 ツールの統合
利用可能なツール
| ツール | 用途 |
|---|---|
snow_query_table | ML テーブルをクエリする |
snow_execute_script | 予測をテストする |
snow_ml_predict | トレーニング済みモデルで予測を実行する |
snow_list_pi_solutions | 予測インテリジェンスのソリューションを一覧表示する |
snow_train_pi_solution | ソリューションをトレーニング/再トレーニングする |
ワークフローの例
// 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({
script: `
var result = getClassificationPrediction('incident', 'inc_sys_id', 'incident_classifier');
gs.info(JSON.stringify(result));
`,
})
ベストプラクティス
- 高品質なデータ - クリーンなトレーニングデータが不可欠です
- 特徴量の選択 - 関連する入力フィールドを選択します
- 信頼度のしきい値 - 信頼度の高い予測のみを適用します
- フィードバックループ - ユーザーからのフィードバックを収集します
- 定期的な再トレーニング - モデルを定期的に更新します
- 精度の監視 - 予測のパフォーマンスを追跡します
- フォールバック - 予測に失敗した場合に備えて手動のプロセスを用意します
- ES5 のみ - 最新の JavaScript 構文は使用しません
コメント
Markdown 対応