
【ServiceNow PDI】OpenAIへの問い合わせアプリをIntegration Hubカスタムスポークをベースに実装する手順まとめ
以前、このブログで「Gemini APIへ問い合わせできるアプリケーション」をIntegration Hubのカスタムスポークで作成した記事を書きました。
※当該記事については、以下をご参考ください。
https://note.com/subaru_hero/n/n3dd27f7f3a94
今回はGemini APIではなく、Open AIを使い同一アプリを作ってみることにしました。今回のブログで書いてみようと思ったきっかけは、
・GeminiとOpen AIでのAPI呼び方や定義の違いなどの有無を確認したい
・繋ぐ先のLLMにより、投げた質問回答への精度の差異などを知りたい
といったところでしょうか・・。
1.PDI環境の準備
PDIを最新版のZurich(※本記事記載時:2026/3時点)にしておきます。

2.Open AIのアカウント作成&APIキーの取得
続いて、Open AIのアカウント作成並びにAPIキーの取得を行います。
以下URLにアクセスを行います。
アカウント登録を行いSign inします。
OpenAI Platformのホーム画面のエクスプローラの[Billing]メニューを選択し、チャージを行います。

費用については、以下のOpenAI APIの費用サイトを参考ください。今回の検証では、接続用にリクエストを数十回試す程度です。したがって数百回確認ができる程度のチャージに留めておきました。
LLMのモデルは、Integration Hubから1回の通信要求で応答をもらうチャットボットなどの利用ケースを想定しています。したがって、
・軽量タイプのgpt-5-miniを利用する形
を想定した費用感で十分です。
参考までにですが、2026/3時点では費用感的に、
・$5チャージで数千回の呼び出しが可能
程度なレベル感でした。
チャージ後に、[API Key]メニューより、APIキーの払い出しを実施し、文字列をメモ帳などにコピーして保存しておきます。
3.Integration Hubのスポークアクションを作成
開発ツールはWorkflow Studioを使います。ツールの起動方法や利用については、繰り返しになりますが、以下の記事を参考ください。
今回作成するカスタムアクションは
・Get Answer from OpenAI
という名前で作成を行います。
続いて、アクションデザイナーで定義するステップは以下の4つです。
①入力変数の定義:アプリからOpenAIへ問い合わせる質問の受け付け
②RESTステップ:Open AIへRESTを使って質問を送信し、応答を受領
③Scriptステップ:応答を抽出するための簡易ローコードステップ
※JSON Parserは使わず、Scriptステップで対象要素をさくっと抜き出すローコードステップを実装して対応します。
④出力の定義:フローを介しアプリ側へ表示させる回答の受け付け
次に利用するREST電文の様式ですが、OpenAI APIのリファレンスにあるREST様式(curlコマンド利用)のサンプルの以下を参考にします。
curl https://api.openai.com/v1/chat/completionscurl"" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer OPENAI_API_KEY" \
-d '{
"model": "gpt-5-mini",
"messages": [
{"role": "user", "content": "ServiceNowとは何か"}
]
}'※1. curl :REST ステップのベースURLに指定するURL
※2. content-Type:JSONを求めるヘッダー
※3. Authorization:APIキーを送付するためのヘッダー
※4. model:OpenAIのモデルの選択。gpt-5-miniと設定すると、最新の5バージョンへの問い合わせが可能。
※5. message :content要素部分に質問内容を入れて要求を送信します。
余談ですが、REST様式だけみると、Geminiと全く同じ様式であることが分かります。以前のGemini接続設定の以下箇所を変えるだけでスポークはOpenAI APIへの接続に改変可能と分かりました。これは簡単です。
・接続先のURL:https://api.openai.com/v1/chat/completionscurl/
・モデル:gpt-5-mini
①入力変数の定義
OpenAIへ投げる質問文用の入力変数を定義します。
・ラベル名:Quesition
・名前:question
・タイプ:String

②REST Stepの定義
入力変数ステップの下の[+]メニューを選択し、[REST]をアクションに追加します。

接続の詳細で、
・接続:インラインで接続を定義
※今回は、REST APIのリクエスト内にAPIキーも含めて認証を通します。
・ベースURL:https://api.openai.com/v1/
要求の詳細で、
・リソースパス:chat/completions
・HTTPメソッド:POST

次に、ヘッダー個所の定義です。
Gemini記事の時と同様に、Open AIへ接続するために重要なポイントのAuthorizationヘッダーがあるので、注意が必要です。
・Content-Type:application/json
・Authorization:Bearer XXXXXX
※Bearer文字後にスペースを入れ、XXXXXX部分に、先の手順で取得したAPIキー文字列を貼り付けます。この設定が不正だと、400エラーで応答され、応答を正しく受領できません。

続いて、要求本文(JSONペイロード)を定義します。
1)以下のサンプルを要求本文へ貼り付けます。
{
"model": "gpt-5-mini",
"messages": [
{"role": "user", "content":"ServiceNowとは何か"}
]
}2)content要素部分の"ServiceNowとは何か"文を削除して、そこに入力変数のデータピルより、Questionをドラッグ&ドロップで配置します。

続いて、Responseの様式を見てみます。公式サイトを見ると、おそらくcontent要素に回答が含まれるということが予測できます。
"output": [
{
"type": "message",
"id": "msg_67ccd2bf17f0819081ff3bb2cf6508e60bb6a6b452d3795b",
"status": "completed",
"role": "assistant",
"content": [
{
"type": "output_text",
"text": "In a peaceful grove beneath a silver moon, a unicorn named Lumina discovered a hidden pool that reflected the stars. As she dipped her horn into the water, the pool began to shimmer, revealing a pathway to a magical realm of endless night skies. Filled with wonder, Lumina whispered a wish for all who dream to find their own hidden magic, and as she glanced back, her hoofprints sparkled like stardust.",
"annotations": []
}
]では、実際にServiceNow PDIからテスト走行で実施したResponseをJSON Parserの機能を使って様式を確認してみます。
※この作業は実際に行う必要はありません。以下内容だけ確認ください。

実行結果を確認すると、応答が正しく戻ってきてるようです。
続いて、JSON Parserで見ると、messageノード下にcontentがあり、ここで回答が受けられるようになっていることが分かります。

ということで、Gemini設定時にcontentまでのパスで抽出していたJSON Parseステップも以下のようにそのまま利用できそうです。
// === JSONをパース ===
var json = JSON.parse(inputs.Response);
// === content要素を抽出 ===
var extract_output = json.choices[0].message.content;実装するスクリプトのコードステップ内容が固まりました。
RESTステップ下の[+]より、Scriptステップを追加します。
Scriptステップへの入力変数を定義します。
・Response:値に、REST Stepの応答本文をドラッグ&ドロップで配置
・スクリプトは以下サンプルを貼り付けます。
(function execute(inputs, outputs) {
// === JSONをパース ===
var json = JSON.parse(inputs.Response);
// === content要素を抽出 ===
var extract_output = json.choices[0].message.content;
// === 出力変数にセット ===
outputs.openai_answer = extract_output;
})(inputs, outputs);※1. JSON.parseステップには、入力変数値を指定
※2. 要素抽出に、先のJSON Parserで表示した階層ノードを参考に指定
※3. 出力変数として用意した、openai_answerへ回答を代入

画面下部へスクロールして、出力変数を定義します。
・OpenAI_Answer : タイプをStringで作成

④の出力変数を定義します。
アクションステップの[出力]へ移動し、[出力の作成]より定義します。
・OpenAI_Answer : タイプをStringで定義

出力の編集モードを無効化し、入力変数OpenAI_Answerの値に、スクリプトステップで得られた変数のOpenAI_Answerをドラッグ&ドロップで配置します。

完了後に、スポークの[公開]を行います。OpenAIへの質問を投げるシステム連携の機能部品が完成しました。
4.カスタムスポークを呼び出すフローの作成
アプリケーションのデータモデルやワークスペースの設定については、こちらのブログを参考ください。ここでは、フローの設定箇所のみ記載します。
アクション設定で、
・Get Answer from OpenAIを指定
・アクション入力変数は、レコードの問い合わせフォーム値を指定

続いて、レコードの更新ステップを追加します。
・レコード:トリガーのRecordをドラッグ&ドロップで配置
・フィールド:回答フォームへ、スポークの呼び出しステップより受領できる変数OpenAI_Answerをドラッグ&ドロップで指定

フローを[アクティブ化]します。
これでアプリケーションの作成は完了しました。
5.アプリケーション上での動作確認
Workspaceより、新規作成でタスクレコードを作成します。
フォーム画面の問い合わせフォームに質問を入力し、レコードを保存します。

正しく、OpenAIより応答が得られました。

6.まとめ
さて、前回はGeminiへ接続するアプリ、そして今回はOpenAIへ接続するアプリを作成してみました。まず明確に分かったことを記載します。
・APIを呼び出す接続定義はどちらも同じ
Integration Hubのカスタムアクションで設定する定義はまったく一緒でした。ですので、一度作成したカスタムアクションの設定内容を編集するだけで、接続先を切り替えることは簡単に行えます。
続いて、LLMの性能面や回答精度の違いについてですが、本ブログでは、このLLMの差異を検証することを主体テーマとはしてない点を予め申し上げたうえでの所感となります。
・Open AIが有償版モデルへ接続したという点も踏まえ、応答性能、精度はOpenAIに軍配が上がる
ちなみに、今回接続した軽量モデルのgpt-5-miniではなく、回答精度が高いgpt-5.2も利用できます。ただし、上位モデルは費用が高価となるため、試行回数が少なくなる点で注意が必要です。
如何でしたでしょうか? 今回はServiceNowのIntegration Hubを使い、OpenAIへ接続させるアプリを作り、Gemini接続時との共通点や差異などの技術観点を纏めました。皆様の参考にして頂ければ幸いです。