mcpField
P
predictive-intelligence

predictive-intelligence

github.com/serac-labsデータ・データベース7777 回インストール9 週間前に更新
リポジトリ

predictive-intelligence について

ServiceNow の Predictive Intelligence を扱うスキルで、機械学習による予測機能と実装例を紹介します。分類、類似レコード検索、クラスタリング、回帰、推奨に加え、MCP ツールによるソリューションの照会や学習方法も説明します。

主な機能

  1. 01レコードの自動分類
  2. 02類似レコードの検索
  3. 03クラスタリングと分析
  4. 04数値予測とアクション提案
  5. 05モデルの学習と状態確認
  6. 06フィードバック収集と精度分析

活用シーン

  1. 01インシデントやケースの分類
  2. 02関連する過去レコードの検索
  3. 03リスクなどの数値予測
  4. 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_solutionML ソリューションの定義
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_tableML テーブルをクエリする
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));
    `,
})

ベストプラクティス

  1. 高品質なデータ - クリーンなトレーニングデータが不可欠です
  2. 特徴量の選択 - 関連する入力フィールドを選択します
  3. 信頼度のしきい値 - 信頼度の高い予測のみを適用します
  4. フィードバックループ - ユーザーからのフィードバックを収集します
  5. 定期的な再トレーニング - モデルを定期的に更新します
  6. 精度の監視 - 予測のパフォーマンスを追跡します
  7. フォールバック - 予測に失敗した場合に備えて手動のプロセスを用意します
  8. ES5 のみ - 最新の JavaScript 構文は使用しません

コメント