- RSS フィードを購読する
- 新着としてマーク
- 既読としてマーク
- ブックマーク
- 購読
- 印刷用ページ
- 不適切なコンテンツを報告
ServiceNow の AI はすべてスキルで動作します。プロンプト、AI エージェント、分析スキルは Now Platform 内に存在し、データ、テーブル、セキュリティモデルにネイティブにアクセスできます。通常、これらはプラットフォームの内部から、つまり UI アクション、フロー、Virtual Agent トピックなどを使って呼び出されます。
しかし、自動化がServiceNowの外部で開始された場合はどうでしょうか?外部アプリ、ミドルウェアレイヤー、または別の場所のスケジュール済みジョブからインスタンスにアクセスし、AI スキルを起動し、結果を単純な REST 呼び出しで取得したい場合はどうすればよいでしょうか?
このチュートリアルでは、まさにそれについて説明します。Now Assist スキルキットで AI スキルをゼロから構築し、HTTP 要求を送信できる場所ならどこからでも呼び出せるように、2 つの異なる方法で公開します。スクリプト済み REST API (同期メソッド) とData Brokerエンドポイント (プラットフォーム独自の非同期 2 コールパターン)。以下のすべてのスクリプトはテンプレート化され、コピーして貼り付け可能であり、正確に何を置き換えるかについてのメモが付いています。
目次
- 私たちが構築しているものとは何ですか?
- 前提条件
- ステップ 1:Now Assist スキルキットで AI スキルを構築する
- ステップ 2:機能 ID とスキル構成 ID を見つける
- 方法 A:スクリプト済み REST API (推奨)
- 手法 B:Data Broker (高度、非同期)
- デバッグ:生成 AI ログテーブル
- ライブストリームをご覧ください
- まとめ
私たちが構築しているものとは何ですか?
繰り返し可能なパターン、つまりインスタンスに存在し、REST を介してプラットフォーム外から呼び出し、その結果を要求を送信したものに返すことができる AI スキルが必要です。
構築するスキルの例では、問い合わせユーザーの好み (「高層ビル」、「多目的ビル」など) に基づいて、建築愛好家向けの旅行先を推奨します。スキル自体は設計上、基本的なものです。その周辺の基盤は再利用可能な部分であり、構築するプロンプト、AI エージェント、または分析スキルで同じように機能します。
接続しているものの形は次のとおりです。
External caller (Postman, middleware, another app)
|
| HTTP request (REST)
v
ServiceNow instance
|
|-- Method A: Scripted REST API --> sn_one_extend.OneExtendUtil.executeSecure() (synchronous, 1 call)
|
|-- Method B: Data Broker /exec + /batch (asynchronous, 2 calls)
v
AI Skill runs (with full access to instance data + security)
|
v
Result returned to the external caller
どちらの方法でも、基礎となるスキルの実行は同じです。ほとんどの場合、スクリプト化された REST API をお勧めします。これは同期的で、単一の呼び出しであり、正確な応答形状を制御できます。Data Broker メソッドはプラットフォームが内部で使用するメソッドであるため、理解しておく価値がありますが、2 回の呼び出しが必要であり、非同期的に実行されます。
前提条件
- **Now Assist スキルキット** (NASK) が利用可能で、生成 AI が構成されているインスタンス。
- `sn_skill_builder` のロールで Now Assist スキルキットへのアクセスを許可されていること。これがないと、スキルキットのナビゲーションは表示されません。
- REST 経由で認証できるユーザーアカウント (このチュートリアルでは、専用の`api_user` を使用します)。スキルはそのユーザーとして実行されるため、そのユーザーのデータアクセスと ACL が継承されます。これはまさにメリットです。
- テスト用の API クライアント。Postman を使用しています。
ヒント:ロールの変更はセッションベースです。ロールのリストは、セッションの開始時に 1 回作成されます。ご自身に `sn_skill_builder` の権限を付与した後、ログアウトしてから再度ログイン (または代理操作してから代理操作解除) して、新しいロールが実際に有効になるようにしてください。
ステップ 1:Now Assist スキルキットで AI スキルを構築する
まずスキルが必要です。公開するものが既にある場合は、ステップ 2 にスキップできます。REST 配管はどのスキルに対しても機能するためです。
スキルとプロンプトを作成する
- ナビゲーションで、Now Assist スキルキットを開きます。
- 新しいスキルを作成します。ゼロから作成し、プロンプトエディターに直接ジャンプします。
- 意味のある名前を付けます (私たちの例は 建築観光のおすすめ旅行先 です)。
入力の追加
タイプが文字列の単一の入力を追加します。私たちはそれを`something_you_like`と呼ぶことにし、物事をシンプルに保つために必須ではありません。
この入力名は、REST ペイロードが入力する必要があるキーになるため、覚えておいてください。正しい入力名の取得は、コールが「成功」しても何も返されない (スキルが未定義の入力で実行される) 最も一般的な 2 つの理由のうちの 1 つです。
プロンプトを記述してテストする
プロンプトエディターで、指示を記述し、モデルが読み取る場所に入力を挿入します。これが私たちが使用した正確なプロンプトです。この`{{something_you_like}}`トークンは、エディターから挿入された入力変数です。
Given the input below, recommend a travel destination that has good
architectural background or tours or history that a person would be
interested in learning about regarding this thing that they like. If
there is nothing provided below then just make a generic recommendation
based off of a ServiceNow Audience
Input: {{something_you_like}}
エディターでクイックテストを直接実行します。次のようなものを`土地使用の垂直権`または`超高層ビル`と入力し、賢明な推奨事項が返ってくることを確認します。スキルがオンデマンドで結果を生成すると、展開する準備が整います。
スキルを展開する (およびスクリプトを生成する)
次に、スキルの展開/スキル設定を開きます。いくつかの展開ターゲット (分析パネル、UI アクション、フローアクション、VA のコンテキストメニュー、UI ビルダー) が表示されます。
UI アクションターゲットを選択します。特定の理由:UI アクションの展開では、スキルを呼び出すサーバースクリプトが自動生成されますが、このスクリプトはスクリプト化された REST API に必要なスクリプトの 90% です。これにより、プラットフォームが私たちにとって難しい部分を書くことができます。
- **UI アクション**ターゲットを選択します。
- UI アクションにはテーブルが必要ですが、生成されたスクリプトのみが必要なため、目的上どのテーブルかは関係ありません。任意のテーブルを選択 (`incident`)。
- ファイナライズと公開スキル、次にアクティブ化します (Now Assist スキルキット→アドミン>スキル)。一部のスキルには小さなアクティベーション JSON が必要なため、デフォルトを受け入れてください。
- 生成された UI アクションを開き、そのスクリプトをコピーします。これは、次のセクションのテンプレートのようになります。
ステップ 2:機能 ID とスキル構成 ID を見つける
以下のすべてのメソッドには、スキルに固有の 2 つの識別子が必要です。
- 機能 ID:スキルを裏付ける One Extend 機能レコードのsys_idです。
- スキル構成 ID:スキルの構成レコードのsys_idです。
プラットフォームが生成した UI アクションスクリプトには、すでにハードコードされた両方が含まれています。そのスクリプトをコピーした場合は、そこから値をそのまま引き上げることができます。`capabilityId`および`skillConfigId`は生成されたコードに含まれます。これは、記録を探さずにそれらを取得する最速の方法です。
手動で検索する必要がある場合は、One Extend 機能レコードと作成したスキル構成レコードのsys_idsです。最初に UI アクションに展開することは、それらを表示するためのショートカットです。
方法 A:スクリプト済み REST API (推奨)
このメソッドでは、1 つのスクリプトによってバックアップされた単一の同期 GET を使用し、正確な応答を制御します。スキルは、ポーリングなしで同じコールで回答を返します。
スクリプト済み REST API の作成
- スクリプト済み REST API →システム Web サービスに移動し、新規作成します。
- それに名前とAPI IDを付けます。API ID は URL の一部になります。API ID は`archrecs`を名前空間`snc`の下で使用しました。
- 保存します。
ベースパスは`/api/<namespace>/<api_id>`のようになり、これは私たちにとっては`/api/snc/archrecs`です。
GET リソースの作成
- スクリプト済み REST API レコードで、新しいリソースを作成します。
- **HTTP メソッド**を**GET**に設定します。
- 相対パスはデフォルトのままにします (`/`) であるため、完全エンドポイントは単なるベースパスです。
- 次のセクションのスクリプトにドロップします。
クエリパラメーターを指定してGETを使用しているため、簡単に`?user_input=skyscrapers`で呼び出すことができます。代わりに POST 本文を受け入れることもできます。
リソーススクリプト (テンプレート化)
これが完全なスクリプトです。発信者のクエリパラメーターを読み取り、スキルの入力にマップし、One Extend を介してスキルを同期的に実行し、結果からスキルの応答を引き出して、JSON として返します。
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var inputsPayload = {};
// Map the incoming query param to your skill's input name.
// LEFT side = your skill input name (here: 'something_you_like')
// RIGHT side = the query param the caller sends (here: 'user_input')
inputsPayload['something_you_like'] = request.queryParams['user_input'];
// Paste YOUR capability ID (from the generated UI Action script).
var capabilityId = '{CAPABILITY_ID}';
var nask_request = {
executionRequests: [{
payload: inputsPayload,
capabilityId: capabilityId,
meta: {
// Paste YOUR skill config ID (from the generated UI Action script).
skillConfigId: '{SKILL_CONFIG_ID}'
}
}],
mode: 'sync'
};
try {
var nask_response = sn_one_extend.OneExtendUtil.executeSecure(nask_request) || {};
var skillResponse = ((nask_response["capabilities"] || {})[capabilityId] || {})["response"];
response.setContentType('application/json');
var response_body = skillResponse;
response.setStatus(200);
return response_body;
} catch (e) {
gs.error(e);
gs.addErrorMessage('Something went wrong while executing skill.');
}
})(request, response);
置き換えるもの:
- ``{CAPABILITY_ID}``:ステップ 2 で確認したスキルの Capability ID です。
- ``{SKILL_CONFIG_ID}``:ステップ 2 で確認したスキルのスキル構成 ID です。
- `'something_you_like'`:これをご自身のスキルの入力名に変更します。スキルに複数の入力がある場合は、`inputsPayload`オブジェクトに次の入力ごとに 1 行を追加します。
- `'user_input'`:問い合わせユーザーが送信するクエリパラメーター名。そのままにするか、名前を変更します。発信者が一致していることを確認してください。
これが機能する理由については、次の 2 つの点があります。
- `mode: 'sync'`:これが、これを単一の呼び出しにする理由です。スキルが実行され、インラインで返されます。(これにより、2 コール Data Broker パターンを回避できます)。
- ストリームライターを使用する代わりに、プレーンな応答本文オブジェクトを返すことで、フレームワークがこれを JSON にシリアル化してくれます。これにより、よりシンプルでエラーが発生しにくくなります。
2 本のラインビル`inputsPayload`および`capabilityId`/`skillConfigId`は、スキルキットが生成した UI アクションから直接取得されます。そのため、最初に UI アクションに展開しました。
セキュリティとアクセス
リソースで、本番稼働前にセキュリティ設定を確認します。
- **「認証が必要」**をオンのままにします。実際のユーザーとして実行される生成 AI 機能へのアクセス権を付与するため、認証されていない問い合わせユーザーにはリソースを開いたままにしないでください。
- スキルは、認証ユーザーの権限で実行されます。専用の統合ユーザーを使用します (以前は`api_user`) は、触れる必要があるデータに正確にスコープされます。
- 意図した問い合わせユーザーのみが到達できるように、リソースに適切な ACL/必要なロールを設定します。
Postman から呼び出す
任意の REST クライアントから GET 要求を行います。
GET https://{YOUR_INSTANCE}.service-now.com/api/snc/archrecs?user_input=skyscrapers
Authorization: Basic (username: api_user, password: {YOUR_PASSWORD})
Content-Type: application/json
置き換えるもの:
- `{YOUR_INSTANCE}`:インスタンス名。
- `snc/archrecs`:名前空間と API ID (名前が異なる場合)。
- `user_input=skyscrapers`:クエリパラメーター名と、スキルで推論する値。
- 統合ユーザーの基本認証情報。
スキルは同期的に実行されるため、少し時間がかかる場合があります (もう一方の端で生成呼び出しが発生しています)、その後`200`結果と。空のオブジェクトですぐに戻ってくる場合は、入力名が揃っていないため、デバッグにジャンプしてください。
応答を解析
応答は JSON オブジェクトとして返されます。実際のモデル出力は、**文字列化された JSON** 内の値`result`プロパティ。したがって、アクセスする消費側では`.result`、次に`JSON.parse()`、次にモデル出力フィールドを読み取ります。概念的には:
// 'body' is the parsed response from the call
var payload = JSON.parse(body.result);
var answer = payload.modelOutput; // the human-readable recommendation
// e.g. "For someone interested in skyscrapers, Chicago is an ideal destination..."
これが同期メソッド全体であり、ほとんどすべての実際の統合で私が手を伸ばすアプローチです。
手法 B:Data Broker (高度、非同期)
Data Broker メソッドは、ServiceNow 独自の UI が内部でスキルを駆動する方法です。そのためのサーバーサイドスクリプトを作成する必要はありませんが(プラットフォームの Data Broker エンドポイントを直接呼び出します)、これは2 コール、非同期で管理すべきパターンが増えます。これは、特に非同期動作 (スキルの起動、即時確認、結果の取得) が必要な場合、またはスクリプト化された REST API を展開できない場合に使用します。
これらのペイロードをリバースエンジニアリングする方法: ブラウザの開発ツールを開いて (F12)、Now Assist スキルキット内のスキルのテストパネルを実行しますネットワークタブ。プラットフォームが`exec`呼び出しを起動してからフォローアップの`batch`呼び出しを行うことがわかります。これらの要求本文をコピーします。まさに以下の形です。[ネットワーク] タブを開いている必要があります前にテストを実行します。遡及的に記録されることはありません。
2 コールパターンの仕組みとは何ですか?
- コール 1 (実行):Data Broker の`/exec`エンドポイントに POST します。これにより、スキルが非同期に開始され、実行中のジョブの識別子 (バッチ実行 ID と結果 ID) が返されます。答え自体は後で明らかになります。
- コール 2 (取得):これらの ID を使用して、スキルの完了後に実際の結果をフェッチする`/batch`エンドポイントに POST します。実際の統合では、ステータスが成功になるまでこれをポーリングします(短い待機ループ)。
コール 1:スキルを実行します
POST https://{YOUR_INSTANCE}.service-now.com/api/now/uxf/databroker/exec
Authorization: Basic (username: api_user, password: {YOUR_PASSWORD})
Content-Type: application/json
本体はアレイ(Data Broker は一度に複数の要求を受け入れます)、スキルパラメーターは`inputValues.payload.value`内部のJSON 文字列です。
[
{
"type": "TRANSFORM",
"definitionSysId": "{DEFINITION_SYS_ID}",
"parentResourceId": "run_prompt",
"inputValues": {
"payload": {
"type": "JSON_LITERAL",
"value": "{\"aiConfigId\":\"{AI_CONFIG_ID}\",\"capabilityId\":\"{CAPABILITY_ID}\",\"skillConfigId\":\"{SKILL_CONFIG_ID}\",\"inputAttributeMappings\":[{\"id\":\"{INPUT_ATTRIBUTE_ID}\",\"dataType\":\"string\",\"value\":\"{USER_INPUT}\"}],\"skillDatasetDetails\":{\"testDatasetId\":\"{TEST_DATASET_ID}\",\"testRecordId\":\"{TEST_RECORD_ID}\"},\"mode\":\"async\"}"
}
}
}
]
置き換えるもの: (これらはすべて、[ネットワーク] タブでキャプチャした`exec`要求 (記載されている場合を除く) から取得します)。
- `{YOUR_INSTANCE}`:インスタンス名。
- `{DEFINITION_SYS_ID}`:キャプチャされたコールからsys_idされたData Broker 変換定義。
- `{AI_CONFIG_ID}`、`{CAPABILITY_ID}`、`{SKILL_CONFIG_ID}`:スキルの ID。
- `{INPUT_ATTRIBUTE_ID}`:スキル入力の入力属性マッピング ID。
- `{USER_INPUT}`:スキルに推論してもらいたい値 (例:`mixed-use-buildings`)。これは、呼び出しごとに変更する 1 つの値です。
- `{TEST_DATASET_ID}`、`{TEST_RECORD_ID}`:キャプチャされたコールから。
ここでは`200`が返されますが、これはスキルが開始済みであることを意味します。応答から、バッチ実行 IDおよび結果の IDを取得する必要があります。コール 2 には両方が必要になるためです。
コール 2:バッチで結果を取得
取得は標準の ServiceNow を介して行われます。バッチAPI は、2 つの Data Broker サブ要求をラップします。1 つは ID で結果を取得し、もう 1 つは実行 ID でバッチステータスを取得します。
POST https://{YOUR_INSTANCE}.service-now.com/api/now/v1/batch
Authorization: Basic (username: api_user, password: {YOUR_PASSWORD})
Content-Type: application/json
{
"batch_request_id": "{ANY_UNIQUE_UUID}",
"enforce_order": false,
"rest_requests": [
{
"id": "{ANY_UNIQUE_UUID}",
"method": "POST",
"options": { "is_encoded": false, "should_encode_response": false },
"url": "/api/now/uxf/databroker/exec",
"headers": [
{ "name": "X-WantAuthSessionNotifications", "value": true },
{ "name": "X-UserToken", "value": "{X_USER_TOKEN}" }
],
"body": [
{
"type": "TRANSFORM",
"definitionSysId": "{GET_RESULT_DEFINITION_SYS_ID}",
"parentResourceId": "get_batch_result_by_id",
"inputValues": {
"batch_result_id": {
"type": "JSON_LITERAL",
"value": "{RESULT_ID_FROM_CALL_1}"
}
}
}
]
},
{
"id": "{ANY_UNIQUE_UUID}",
"method": "POST",
"options": { "is_encoded": false, "should_encode_response": false },
"url": "/api/now/uxf/databroker/exec",
"headers": [
{ "name": "X-WantAuthSessionNotifications", "value": true },
{ "name": "X-UserToken", "value": "{X_USER_TOKEN}" }
],
"body": [
{
"type": "TRANSFORM",
"definitionSysId": "{GET_STATUS_DEFINITION_SYS_ID}",
"parentResourceId": "get_batch_result_statuses_by_run_id",
"inputValues": {
"batch_run_id": {
"type": "JSON_LITERAL",
"value": "{BATCH_RUN_ID_FROM_CALL_1}"
}
}
}
]
}
]
}
置き換えるもの:
- `{ANY_UNIQUE_UUID}`:バッチとそのアイテムを識別するために生成する UUID。
- `{X_USER_TOKEN}`:有効なユーザートークン ([ネットワーク] タブからキャプチャされるか、セッション用に生成されたもの)。
- `{GET_RESULT_DEFINITION_SYS_ID}`および`{GET_STATUS_DEFINITION_SYS_ID}`:それぞれ`get_batch_result_by_id`および`get_batch_result_statuses_by_run_id`の変換定義sys_ids (キャプチャされたバッチ呼び出しから)。
- `{RESULT_ID_FROM_CALL_1}`:コール 1 によって返される結果の IDです (これにより実際の回答が取得されます)。
- `{BATCH_RUN_ID_FROM_CALL_1}`:コール 1 によって返されるバッチ実行 IDです (これによりステータスが取得されます)。
ここで注目すべき点の 1 つは、2 つのサブ要求が異なるID を必要とすることです。`get_batch_result_by_id`には結果の IDが、一方`get_batch_result_statuses_by_run_id`にはバッチ実行 IDが必要です。これらのリターンを混同すると`200`使用可能な結果がなく、まさにそれがストリームでつまずいた原因です。コール 1 は複数の要求を保持できるため、複数の結果 ID を取得するため、実際に関心のある要求にマップされる結果 ID を使用してください。
ID が揃い、スキルが終了すると、バッチ応答にモデル出力が含まれます。同期メソッドが返すのと同じ推奨事項が、さらに多くの手順を踏んで取得されるだけです。
デバッグ:生成 AI ログテーブル
呼び出しが「機能した」 (`200`) と表示されても、有用なものが返ってこない場合、最適なツールは**Generative AI Log** テーブル (`sys_generative_ai_log`) です。すべての生成 AI 実行は、送信されたプロンプト、応答、成功したかどうか、およびエラーコードとともにここに到着します。
ほとんどの失敗の背後にある 2 つの質問に答えるために使用します。
- スキルは実際に私の入力を受信しましたか?ログに記録されたプロンプトに入力が未定義またはnullの場合、ペイロードキーがスキルの入力名と一致しません。スクリプト済み REST API では、これは`inputsPayload['something_you_like']`であり、スキルの入力と完全に一致する必要があります。これはよくある「`user_input`を送ったのに、スキルは`something_you_like`を期待している」という不一致です。
- 実行され、返されない応答が生成されましたか?ログに成功した応答が表示されているが、呼び出し元が空のオブジェクトを取得した場合は、スキルに問題があり、取得または解析に問題があります (Data Broker バッチ呼び出しの ID が間違っているか、`.result`を正しく読み取れていない)
さらにいくつかのヒント:
- 各 AI 呼び出しでの断続的なエラーは、多くの場合、サービスが一時的に利用できなくなったことを意味します。統合を分解する前に、少し待ってから再試行し、Now Assist プラグインが最新であることを確認してください。
- Data Broker ルートの場合、[ネットワーク] タブ (F12) が信頼できる参照です。手動で作成したペイロードに障害が発生した場合は、プラットフォームが送信するペイロードと比較してください。通常の原因は配列のラッピング、文字列化された`payload.value`、および結果と実行 ID の区別。
ライブストリームをご覧ください
このチュートリアルは 2 つのEarl によるライブコーディングから生まれました。私がすべてを放送で行い、スキルを高め、壁にぶつかり、両方の方法を着地させたストリームです。エンドツーエンド (デバッグとすべて) で発生するのを見たい場合は、両方の部分があります。
パート 1、スキルの構築と最初の試行:
パート 2、スクリプト済み REST API と Data Broker の両方のメソッドを解決する:
まとめ
HTTP 要求を送信できる場所から ServiceNow AI スキルを呼び出すには、次の 2 つの方法があります。
- スクリプト済み REST API:同期、1 回の呼び出し、1 つのスクリプトで完全に制御できます。これが推奨されるデフォルトです。
- Data Broker:非同期、2 つの呼び出し、カスタムサーバースクリプトはありませんが、ペイロードのラングリングが多くかかります。プラットフォームが内部で使用する非同期の要求後取得パターンが必要な場合に便利です。
これを行う価値があるメリット:スキルの実行はインスタンス上で行われるため、データ、テーブル行、および要求を行うユーザーのセキュリティモデルへのネイティブアクセスが維持されます。REST 経由で呼び出し可能になったため、オフプラットフォームの自動化からこれらすべてをトリガーし、必要な場所で同じスキルを再利用できます。
これを使って何かを構築する場合は、コメントでぜひお聞かせください。
この記事は機械翻訳されております。最新は元となる記事をご覧ください: https://www.servicenow.com/community/developer-advocate-blog/calling-servicenow-ai-skills-via-rest-a...。
免責事項: 一部の日本語は、翻訳ソフトウェアを使用してお客様の便宜のために翻訳されています。正確な翻訳をご提供できるよう相当な努力を払っておりますが、いかなる自動翻訳も人間の翻訳者に代わすることはなく、そのようなことは意図されておりません。翻訳は「現状のまま」提供されています。他言語への翻訳の的確性、信頼性または正確性については、明示または黙示を問わず、いかなる保証も行われません。翻訳ソフトには限界があるため、一部のコンテンツが正確に翻訳されていない場合があります。これらの資料の公用言語は英語です。翻訳の際に生じる相違または不一致は、コンプライアンスまたは履行の目的に関しては拘束力を有さず、法的効力はないものとします。
This article was machine translated and replicated from the original source: https://www.servicenow.com/community/developer-advocate-blog/calling-servicenow-ai-skills-via-rest-a...。