
ExcelからServiceNowインシデントをAI分析する業務自動化ツールをPythonで作成
Excel起点の分析業務は多く求められると思います。そこで、今回はExcelを起点にServiceNowのIncidentレコード収集からOpenAIへ分析要約までを実装したアプリケーションを作成します。
1.準備
今回は、以下の環境やソフトウェアを準備します。
・ServiceNow PDI ※Australiaバージョン
・OpenAI API ※APIキー取得
・Excel
・Python ※最新バージョンを推奨
ServiceNow PDIの払い出しについてはこちらより実施ください。
OpenAI APIのAPIキーの払い出しはこちらをご参考ください。
Pythonのインストーラはこちらより取得ください。
作業用フォルダを作成しておきます。
例)C:\work\sn_ai_tool
2.全体構成と処理シーケンス
今回のアプリケーションの全体の構成図は以下の図の通りです。

今回は、このロジック部分をPythonスクリプトで実装してみようと思います。ServiceNow内にクローズした開発となると、ロジック部分の作成手段はFlowステップだったり、JavaScriptに限られます。
しかし、実際にLLMのAPIを扱う上でのプログラムのフレキシビリティはPythonの方が適しているのではと思ったことも今回の要件を実装してみようと考えた背景です。
続いて、処理シーケンスは以下のような形を構成する予定です。

3.環境周りの準備
ServiecNowのインシデントレコードをREST APIで取得できるかの確認を行います。PDIにログイン後に、[REST APIエクスプローラー]を起動します。

REST APIエクスプローラーを使い、Table APIへ疎通確認を行ってみます。
・名前空間:now
・API名:Table API
・APIバージョン:v1
・tableName:インシデント[incident]
・sysparam_limit:1

送信を押下します。

ステータス200番で応答が返りました。Table APIを利用できることが分かりました。

続いて、Basic 認証でPDIに接続し、Incidentレコードを取得できるかを確認します。curlコマンドが簡単なので、これを使います。
Windows 10(バージョン1803以降)からcurlがデフォルトで組み込まれています。コマンドプロンプト(cmd)またはPowerShellどちらからでも実行できます。PowerShellコマンドでは以下のような定義を行います。
curl.exe -u "admin:password" "https://instance.service-now.com/api/now/table/incident?sysparm_limit=1" -H "Accept: application/json"1)password:adminユーザのパスワード文字列を指定
2)instance:PDIのインスタンス名を指定
実行すると以下のような結果が戻ってくれば、成功です。
incidentレコードが応答されています。

続いて、Python実行環境の確認とインストールを行います。
python --version当方環境では"3.13.12"がインストールされていました。インストールされてない場合にはインストールの実行を行ってください。
続いて、以下の2つのPython用ライブラリをインストールします。
・PythonでExcelの読み取り/書き込みを行うopenpyxl
・PythonでOpenAI APIへ接続するライブラリ
pip install requests openpyxl openaiライブラリのインストールが成功したら、環境準備は完了です。
4.Pythonによるコード作成
では、ここから実際のプログラムを作成してゆきます。
まず読み取り用構成定義ファイルの作成です。接続定義を分離して管理できるようにします。
・ファイル名:config.py
・定義:ファイルへ以下定義を追加
# ServiceNow接続情報
SN_INSTANCE = "INSTANCE"
SN_USERNAME = "admin"
SN_PASSWORD = "XXXXXX"
# OpenAI接続情報
OPENAI_API_KEY = "OpenAI APIキーをここに指定"
# 取得するインシデント数上限
INCIDENT_LIMIT = 51)SN_INSTANCE:PDIのインスタンス名
2)SN_PASSWORD:System Administratorのパスワード文字列
3)OPENAI_API_KEY:OpenAIのAPIキーをここに指定
今回のメイン処理であるPythonスクリプトを作成します。
・ファイル名:sn_ai_report.py
・全体コード:以下のサンプルをコピー&ペースト
import requests
import openpyxl
import json
from requests.auth import HTTPBasicAuth
from openai import OpenAI
from config import SN_INSTANCE, SN_USERNAME, SN_PASSWORD, OPENAI_API_KEY, INCIDENT_LIMIT
# ===== 1. ServiceNow接続設定 =====
SN_BASE_URL = f"https://{SN_INSTANCE}.service-now.com"
auth = HTTPBasicAuth(SN_USERNAME, SN_PASSWORD)
headers = {"Accept": "application/json"}
# ===== 2. OpenAI接続設定 =====
client = OpenAI(api_key=OPENAI_API_KEY)
# ===== 3. インシデント一覧取得 =====
def get_incidents():
url = f"{SN_BASE_URL}/api/now/table/incident"
params = {
"sysparm_limit": INCIDENT_LIMIT,
"sysparm_fields": "number,short_description,description,priority,state,opened_at",
"sysparm_query": "active=true^ORDERBYDESCsys_created_on"
}
response = requests.get(url, auth=auth, headers=headers, params=params)
response.raise_for_status()
return response.json().get("result", [])
# ===== 4. ChatGPTで分析 =====
def analyze_incident(incident):
prompt = f"""
以下のServiceNowインシデント情報を分析してください。
【インシデント番号】{incident.get('number')}
【タイトル】{incident.get('short_description')}
【詳細】{incident.get('description')}
【優先度】{incident.get('priority')} (1=Critical, 2=High, 3=Moderate, 4=Low)
【状態】{incident.get('state')}
以下の3点を簡潔に日本語で回答してください:
1. 要約(2文以内)
2. 推奨アクション(具体的に1〜2つ)
3. 対応優先度評価(High / Medium / Low)と理由
"""
response = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[{"role": "user", "content": prompt}],
#max_tokens=300
max_completion_tokens=300
)
return response.choices[0].message.content
# ===== 5. Excelに出力 =====
def export_to_excel(results):
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "インシデント分析レポート"
# ヘッダー行
headers_row = [
"インシデント番号",
"タイトル",
"優先度",
"登録日時",
"AI要約・推奨アクション・優先度評価"
]
ws.append(headers_row)
# ヘッダーのスタイル設定
from openpyxl.styles import Font, PatternFill
for col in range(1, 6):
cell = ws.cell(row=1, column=col)
cell.font = Font(bold=True, color="FFFFFF")
cell.fill = PatternFill(fill_type="solid", fgColor="4472C4")
# データ行
for row in results:
ws.append([
row["number"],
row["short_description"],
row["priority"],
row["opened_at"],
row["ai_analysis"]
])
# 列幅調整
ws.column_dimensions["A"].width = 18
ws.column_dimensions["B"].width = 35
ws.column_dimensions["C"].width = 10
ws.column_dimensions["D"].width = 22
ws.column_dimensions["E"].width = 80
# 折り返し設定
from openpyxl.styles import Alignment
for row in ws.iter_rows(min_row=2):
for cell in row:
cell.alignment = Alignment(wrap_text=True, vertical="top")
output_path = "incident_ai_report.xlsx"
wb.save(output_path)
print(f"\n✅ 完了!出力ファイル: {output_path}")
# ===== 6. メイン処理 =====
def main():
print("🔄 ServiceNowからインシデントを取得中...")
incidents = get_incidents()
print(f"✅ {len(incidents)}件取得完了")
results = []
for i, incident in enumerate(incidents, 1):
print(f"🤖 AI分析中... ({i}/{len(incidents)}) {incident.get('number')}")
analysis = analyze_incident(incident)
results.append({
"number": incident.get("number"),
"short_description": incident.get("short_description"),
"priority": incident.get("priority"),
"opened_at": incident.get("opened_at"),
"ai_analysis": analysis
})
print("\n📊 Excelに出力中...")
export_to_excel(results)
if __name__ == "__main__":
main()この作成したファイル2つを先の作業フォルダ内に保存しておきます。
コードステップ数が多いのでステップを分割しながら要点部分をまとめてコメントの記載をします。
[ライブラリ取り込み]
import requests
import openpyxl
import json
from requests.auth import HTTPBasicAuth
from openai import OpenAI1)opepyxl:先にインストールしたExcelアクセス用ライブラリ
2)from openai import OpenAI:OpenAI APIへの接続用ライブラリ
このライブラリにより後続のOpenAI APIへの接続ステップがとても簡略化されます。内部的には、エンドポイントURL管理(api.openai.com/v1/chat/completions)、Authorizationヘッダーへのキー設定、リクエストボディのJSON変換、HTTPエラーハンドリング(429レートリミット・500エラー等)、レスポンスのオブジェクトマッピングをすべて自動でやってくれています。こうしたライブラリが使えるので、やはりPythonを使うメリットは高いですね。
[ServiceNowとOpenAI 接続定義]
# ===== 1. ServiceNow接続設定 =====
SN_BASE_URL = f"https://{SN_INSTANCE}.service-now.com"
auth = HTTPBasicAuth(SN_USERNAME, SN_PASSWORD)
headers = {"Accept": "application/json"}
# ===== 2. OpenAI接続設定 =====
client = OpenAI(api_key=OPENAI_API_KEY)config.py設定ファイルからの接続用パラメータ値の読み取りされます。
1)ServiceNow接続:Basic認証でログイン
2)OpenAI接続:ライブラリにAPIキーを渡して接続
繰り返しのコメントになりますが、OpenAIのライブラリが利用できるので、この単一ステップ1行で接続できるようになってます。
[Incidentレコードの取得関数の定義]
# ===== 3. インシデント一覧取得 =====
def get_incidents():
url = f"{SN_BASE_URL}/api/now/table/incident"
params = {
"sysparm_limit": INCIDENT_LIMIT,
"sysparm_fields": "number,short_description,description,priority,state,opened_at",
"sysparm_query": "active=true^ORDERBYDESCsys_created_on"
}
response = requests.get(url, auth=auth, headers=headers, params=params)
response.raise_for_status()
return response.json().get("result", [])1)Table APIのIncidentよりレコード取得
2)sysparam_query:ServiceNow REST APIの検索条件パラメータ。以下はREST APIパラメータの利用に関するDocsです。参考にしてください。
3)response.raise_for_status:レスポンスの応答検証をこの単一ステップで実施。200番→正常で処理継続、400番や500番→エラー停止処理といったように自動対応させるステップとなっており、この単一ステップでエラーハンドリグステップを組めるあたりもPyrhonは効率化されている気がします。
[ChatGPTへの分析要求の関数定義]
# ===== 4. ChatGPTで分析 =====
def analyze_incident(incident):
prompt = f"""
以下のServiceNowインシデント情報を分析してください。
【インシデント番号】{incident.get('number')}
【タイトル】{incident.get('short_description')}
【詳細】{incident.get('description')}
【優先度】{incident.get('priority')} (1=Critical, 2=High, 3=Moderate, 4=Low)
【状態】{incident.get('state')}
以下の3点を簡潔に日本語で回答してください:
1. 要約(2文以内)
2. 推奨アクション(具体的に1〜2つ)
3. 対応優先度評価(High / Medium / Low)と理由
"""
response = client.chat.completions.create(
model="gpt-5.4-mini",
messages=[{"role": "user", "content": prompt}],
#max_tokens=300
max_completion_tokens=300
)
return response.choices[0].message.content
1)ChatGPTへのプロンプト:incidentレコードの各フィールド値をセット
2)client.chat.completions.create():OpenAI APIライブラリのresponse API。これがOpenAIモデルとやり取りするための主要なAPIでテキスト生成が行えるようになっています。
3)model:ChatGPTのバージョン指定
※2026/03/25時点でのChatGPTモデル一覧を纏めました。今回のようなAPI接続利用の可否も併せて一覧に記載しています。ご参考までに。

3)max_completion_tokens:API接続時に受領メッセージサイズ規定です。
旧モデルでの定義は"max_tokens"で、これを最初は設定していたところ、当該最新モデルではエラー停止してました。ですので、モデルを最新で実行する場合には、この"max_completion_tokens"を定義しておきます。
ちなみに日本語は1トークン≒1〜2文字になります。日本語は英語より文字あたりのトークン消費が多い点が重要です。
面白いので、どれくらいのコストがかかるかも試算してみました。
gpt-5.4-miniの価格は入力100万トークンあたり$0.75、出力100万トークンあたり$4.50あたりとなっているので、これを係数として算出してみます。
入力トークン(プロンプト):約200トークン
・インシデントデータ送信分
・指示文(要約・推奨・優先度)
出力トークン(AI回答):約300トークン
・max_tokens=300の上限
1回の呼び出しコスト:
入力 200 × $0.75 / 1,000,000 = $0.00015
出力 300 × $4.50 / 1,000,000 = $0.00135
合計 約 $0.0015 / 1回$5 ÷ $0.0015 ≒ 約3,300回5$をチャージしておくと、3,300回くらいのインシデントレコードの分析は行える算段です。
参考までに旧モデルと比べると、gpt-4o-miniは入力$0.15/100万トークン・出力$0.60/100万トークンなのでgpt-5.4-miniよりコストは安いですが、精度が劣ります。
[Excelへの書き込み定義]
# ===== 5. Excelに出力 =====
def export_to_excel(results):
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "インシデント分析レポート"openpyxl.workbook():openpxlライブラリを使ったExcelアクセス定義
書き込み処理はforステートメントを使ったレコード転記
[メイン処理]
# ===== 6. メイン処理 =====
def main():
print("🔄 ServiceNowからインシデントを取得中...")
incidents = get_incidents()
--(中略)--
for i, incident in enumerate(incidents, 1):
print(f"🤖 AI分析中... ({i}/{len(incidents)}) {incident.get('number')}")
analysis = analyze_incident(incident)
-- (中略) --
export_to_excel(results)1)get_incients():インシデントレコード取得関数の呼び出し
2)analyze_incident():ChatGPT分析関数の呼び出し
3)export_to_excel():Excel書き出し関数の呼び出し
これがメイン処理の実行シーケンスです。
これで全機能が完成しました。
5.動作確認
それでは、実際に動作を確認してゆきたいと思います。
PowerShellを使ってPythonプログラムを実際に動かしていきます。
cd C:\work\sn_ai_tool
python sn_ai_report.py以下のようにステップが実行されてゆきます。今回は5件までのレコード取得を試みています。

作業用フォルダにExcelファイルが作成されています。

早速開いてみます。
おおっ! バッチリ、分析要約を含むレポートが作成されていますね。
体裁も良い感じで整っています。

実際のインシデントレコードがこの要約に記載されている内容なのかどうかをPDI上で確認してみましょう。
INC0000055は、重大インシデント(1:重大)ですので、緊急度が高いインシデントでした。
short_descriptionとdescriptionフィールドの内容から、SAPセールス関連アプリが利用不可という点をChatGPTが分析しています。
そして、レポート内に推奨アクションなどをテキスト生成してくれたという動きでした。

如何でしたでしょうか? 今回はExcelを起点にServiceNowのデータをAPI経由でレコード取得し、それをOpenAI APIへ分析要約を行い、結果をExcelへ転記させるという機能を開発してみました。
個人的には、今回の気づきとして、ベタですが”Pythonは生成AIを扱うプログラム言語としては非常に効率的である”と感じました。
常日頃、ServiceNowプラットフォームの内側で開発作業を進めてきた手前、プラットフォーム内の技術制約の中で機能開発をしており、なかなかこうした感覚は味わえなかったというところです。
外に機能構成を切り出してみると、”こんなに簡単に便利な機能がすぐ使える!”という点、良い知見にもなり、面白かったです。
また次の技術ブログにご期待ください。では。