プロンプトレジストリ機能の概要
SAP AI Coreのプロンプトレジストリ機能は、生成AIにおけるプロンプト(指示文)のテンプレートを一元管理するための仕組みです。SAP AI Core上のGenerative AI Hubの一部として提供され、プロンプトテンプレートをAI Core内部に統合することで、さまざまなアプリケーションやAIワークフロー(オーケストレーション)から再利用可能な形で提供します。従来、各アプリケーションごとに個別管理・LLMアプリケーション内にハードコードしがちであったプロンプトを中央集約して管理することで、プロンプトのライフサイクル(作成・共有・更新・バージョン管理)の効率化を図ります。
この機能により、LLMアプリエンジニアはビジネスシナリオごとのプロンプトデザインから運用までを統一的に扱うことができ、プロンプトエンジニアリングのベストプラクティスを組織横断で適用しやすくなります。また、プロンプトテンプレートに対するバージョン管理やアクセス制御も可能になるため、企業内での生成AI利用ガバナンスを強化する役割も担っています。
アーキテクチャ上の位置づけと構成要素
プロンプトレジストリはSAP AI Coreサービス内のコンポーネントであり、Generative AI Hubの中核機能の一つです。アーキテクチャ上、プロンプトテンプレートはAI Coreの他機能(オーケストレーション、グランディングなど)と連携し、動的にLLMを呼び出す際の指示文生成に組み込無事ができます。例えば、オーケストレーション機能(生成AIワークフロー管理)では、このレジストリに登録されたテンプレートを参照し、AIモデルへの呼び出し時に適切なプロンプトを適用できます。
プロンプトレジストリへのプロンプト登録に関しては、下記の通り大きく分けて2種類のインターフェースを提供しています。
命令型API(Imperative API): RESTベースのAPIにより、プログラムから直接プロンプトテンプレートを登録・更新・取得する方法です。プロンプトに関するCRUD操作(作成・読み取り・更新・削除)をサポートし、主に開発時のプロンプト作成・調整に適しています。開発者はこのAPIを使ってテンプレートを反復的に修正でき、その都度履歴が記録され後で確認できます。(SAP AI Coreの変更履歴APIエンドポイントから変更履歴を参照可能)
宣言型API(Declarative API): SAP AI Coreの「Application」機能と「Git Repository」 機能による連携を用いた管理方法です。CI/CDパイプラインや本番運用時に適した手法で、GitHub上のプロンプト定義ファイルをソースとしてSAP AI Core側のプロンプトレジストリに自動同期します。開発者はプロンプトテンプレートをyamlファイルで記述しGitHubのリポジトリにコミットするだけで、SAP AI Coreがその内容を検出してレジストリに反映します。この仕組みにより、インフラとしてコード管理するようにプロンプトを扱うことが可能です。(いわゆるPrompts-as-Code)なお、GitHub連携で管理されたテンプレートは内部的にmanagedBy: declarativeとマークされ、常に最新版(ヘッドバージョン)のみ有効となります。また、こうしたテンプレートは後述の命令型API経由では編集できず、変更はGit経由で行う必要があります。これは、登録されたプロンプトとGitHubリポジトリの内容の一貫性を保つための仕様となります。
上記のような手順で登録されたプロンプトの利用に関しては、SAP AI CoreのSDK(各種言語向け)を使ってプログラムから簡潔に利用することもできます。例えば、SAP AI CoreのNode.js SDKパッケージを使えば、コード一行で登録済みテンプレートの一覧取得や参照が可能です。これにより、外部アプリケーションやサービスからプロンプトレジストリを統合的に利用する拡張性も確保されています。
想定ユースケースとメリット
プロンプトレジストリ機能は、組織内で生成AIを活用する際に次のようなユースケースと利点をもたらします。
複数プロジェクト・アプリ間でのプロンプト共有: 共通の目的を持つプロンプト(例えば「製品レビュー要約用プロンプト」や「社内文書分類プロンプト」)を一度定義すれば、レジストリ経由で他のAIシナリオやプロジェクトから再利用できます。各チームが独自に類似プロンプトを作成する手間を省き、一貫性のある回答品質を維持できます。
再利用性と開発効率の向上: プロンプトテンプレートはパラメータ化(プレースホルダーの使用)されているため、入力データや用途に応じて動的に内容を差し替えて使い回すことができます。例えばカテゴリ分類用のプロンプトテンプレートを作成し、カテゴリ名だけプレースホルダーにしておけば、金融ニュース分類にもスポーツ記事分類にも同じテンプレートを適用できます。一度作ったテンプレートを様々な場面で使い回すことで、プロンプト設計の重複を削減し、素早いソリューション展開が可能です。
管理性・ガバナンスの向上: すべてのプロンプト定義が中央レジストリで管理されるため、変更管理やレビューが容易になります。変更履歴やバージョン管理機能により、誰がいつどのようにプロンプトを変更したかを追跡できます。問題が発生した際に以前のバージョンへロールバックしたり、改善提案を履歴に基づいて検討したりといったライフサイクル管理が制度的にサポートされます。また、アクセス権を制御することで、プロンプトの編集・承認プロセスにガバナンスを適用することもできます(例えば本番環境のテンプレートは管理者のみ編集可とする、など)。
CI/CDへの組み込み: 宣言型(Git管理)のモデルでは、プロンプトテンプレートの変更を通常のコードと同様にPull Requestでレビューし、テストを経てから本番環境に適用する、といったDevOps的運用が可能です。プロンプトをコードと同じプロセスで扱えるため、アプリケーション開発の一部として統合的に品質管理できます。これは生成AIの挙動を安定・向上させる上で重要なポイントです。
迅速な実験とチューニング: 命令型APIを用いることで、本番影響を与えない環境で素早くプロンプトの試行錯誤(プロンプトエンジニアリング実験)ができます。たとえば、新しいプロンプトをAPI経由で登録しテストした後、良好な結果が得られればそれをGitにも反映して正式版テンプレートとする、といったワークフローです。開発スピードと本番管理のバランスを取りながら、効率的にプロンプトを磨き上げられます。
統合機能との連携: プロンプトテンプレートは単に文章を保存するだけでなく、他のGenerative AI Hubの機能と連動した使い方も想定されています。例えばGrounding(グランディング)機能で取得した企業データをプロンプトの一部に差し込む、といったシナリオでも、テンプレートにプレースホルダーを用意しておけばOrchestration機能側で連携しつつ、プロンプトとグラウンディングをうまく組み合わせた運用が可能です。さらにデータマスキングやコンテンツフィルタリングと組み合わせ、機密情報を伏せた上でテンプレート出力をLLMに渡すといった高度な制御も、テンプレートを介することで簡潔になります。あくまでこれらはプロンプトレジストリ機能単体ではなく、SAP AI Core のOrchestration機能で提供される機能と組み合わせて実現します。
以上のように、プロンプトレジストリは複数チーム・複数ユースケースにまたがるプロンプト資産の共有基盤として機能し、生成AI活用のスケーラビリティと統制を両立させる役割を果たします。
プロンプトレジストリに触れてみる
事前準備:GitHubリポジトリをクローンする
今回のハンズオンはSAP Build Code上にて実施します。Devスペースにログインしてターミナルを立ち上げ、まずはサンプルコードをクローンしましょう。
git clone https://github.com/watwatwhat/SAPAICore_Grounding_sample.git
事前準備:認証情報の設定を行う
今回のハンズオンの前提条件として、SAP AI Core(Extendedプラン)のインスタンスをSAP BTP Cockpitから作成して、SAP AI LaunchpadにSAP AI Coreのインスタンスをオンボーディングしておきます。
まずは、今回のハンズオンで用いるサービス群のサービスキーとユーザー定義文字列を設定しましょう。
クローンしたファイル群の中から、下記の2つのファイルを編集します。
credentials/ai_core_sk.json
credentials/user_defined_variable.json
1つ目に関しては、SAP AI Coreのインスタンスに作成したサービスキーのjson、Object Store on SAP BTP のインスタンスに作成したサービスキーのjsonをペーストしてください。2つ目に関しては、任意の値を入力してください。使える文字には制限があるようなので、特にこだわりがなければデフォルトと同じような名前をつけることを推奨します。IDの文字が規定に沿っていないという旨のエラーが後段で出た場合、この辺りを設定し直してください。
プロンプトレジストリ新規プロンプトを登録する
Imperative API(命令型API)を介してプロンプトを登録する
新規ターミナルで、下記のコマンドを実行してnodeスクリプトを実行します。
node 03_promptRegistry/01_createPromptTemplate/01_imperative/01_imperative.js
このnodeスクリプトでは下記のようにプロンプトテンプレートを同じディレクトリに存在するspec.jsonから読み込み、それをImperative APIを介してプロンプトレジストリに登録しています。
// Prompt Template 作成
async function createPromptTemplate(token, templateName) {
const url = `${AI_API_HOST}/v2/lm/promptTemplates`;
const payload = {
name: templateName,
version: userCreds.promptVersion,
scenario: userCreds.promptScenarioName,
spec: spec
};
console.log(` Prompt Template ペイロード:`, JSON.stringify(payload, null, 2));
try {
const response = await axios.post(url, payload, {
headers: {
Authorization: `Bearer ${token}`,
‘Content-Type’: ‘application/json’,
‘AI-Resource-Group’: resourceGroupId
}
});
const promptId = response.data.id;
console.log(` Prompt Template 作成成功!ID: ${promptId}`);
// IDを userCreds に書き込んで保存
userCreds.promptTemplateId = promptId;
fs.writeFileSync(userCredsPath, JSON.stringify(userCreds, null, 2));
console.log(` promptTemplateId を ${userCredsPath} に保存しました`);
return promptId;
} catch (err) {
console.error(‘ Prompt Template 作成エラーが発生しました。詳細:’);
if (err.response) {
console.error(` ステータスコード: ${err.response.status}`);
console.error(` レスポンスボディ: ${JSON.stringify(err.response.data, null, 2)}`);
} else if (err.request) {
console.error(‘ リクエストは送信されましたが、レスポンスがありませんでした。’);
console.error(err.request);
} else {
console.error(‘ エラー詳細メッセージ:’, err.message);
}
console.error(‘ スタックトレース:’);
console.error(err.stack);
throw err;
}
}
spec.jsonには下記のような内容が記載されています。システムプロンプトとユーザープロンプトが一つづつ入力されており、かつ{{?inputExample}}というプレースホルダーが定義されています。
{
“template”: [
{
“role”: “system”,
“content”: “You classify input text into the two following categories: {{?categories}}”
},
{
“role”: “user”,
“content”: “{{?inputExample}}”
}
],
“defaults”: {
“categories”: “Finance, Tech, Sports”
},
“additionalFields”: {
“modelParams”: {
“temperature”: 0.7,
“max_tokens”: 100
},
“modelGroup”: “chat”
}
}
プロンプトの登録が完了すると、credentials/user_defined_variable.jsonの中のpromptTemplateIdというキーの値にプロンプトのIDが保存されます。これは後ほど使います。
Dec larativeAPI(宣言型API)を介してプロンプトを登録する
次に、Declarative APIを用いてプロンプトを登録してみましょう。この登録パターンでは、GitHubのリポジトリを経由してプロンプトを登録していきます。
まずは、GitHubの空の新規リポジトリを作成し、ghpから始まるシークレットキーを取得してください。この部分の詳細な手順は一般的な内容となりますので、本ブログでは割愛します。
リポジトリのURLとシークレットキーが発行できたら、 credentials/git_repo_config.jsonにurl、username、passwordを入力してください。なお、シークレットキーは機密情報になりますので、取り扱いにはくれぐれもご注意ください。
{
“url”: “https://github.com/john/examplerepo.git”,
“username”: “john”,
“password”: “ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX”
}
この設定が完了次第、下記のコマンドを実行してください。このnodeスクリプトは、上記のファイルからGitHubの認証情報を取得し、対象のリポジトリに設定ファイルをpushします。
node 03_promptRegistry/01_createPromptTemplate/02_declarative/01_pushToGitHub.js
うまく実行できると、対象のGitHubリポジトリに上記のようなファイルがpushされます。ここに格納されているのがプロンプトの設定ファイルであり、例えば内容は下記のようになっています。
# ========================
#
# Decralative APIを利用して、プロンプトテンプレートを登録する
# https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-prompt-template-declarative
#
# ========================
name: simple
version: 0.0.1
scenario: my-scenario
spec:
template:
– role: “system”
content: “{{ ?instruction }}”
– role: “user”
content: “Some more {{ ?user_input }}”
defaults:
instruction: “default instruction”
additionalFields:
isDev: true
validations:
required: true
blockedModels:
– name: “gpt-4”
versions: “gpt-4-vision”
– name: “gpt-4o”
versions: “*”
上記を持ってGitHubにプロンプトの準備ができたので、これをSAP AI Core – Generative AI Hubのプロンプトレジストリにオンボードしていきます。下記のnodeスクリプトを実行してください。
node 03_promptRegistry/01_createPromptTemplate/02_declarative/02_registerGitRepository.js
このスクリプトではSAP AI CoreのAPIから、GitHubのリポジトリに対する接続を試行します。主要な処理部分は下記の通りです。
const axios = require(‘axios’);
const fs = require(‘fs’);
const path = require(‘path’);
const qs = require(‘qs’);
// === 設定読み込み ===
const aiCoreCreds = JSON.parse(fs.readFileSync(path.join(__dirname, ‘../../../credentials/ai_core_sk.json’), ‘utf8’));
const gitRepoConfig = JSON.parse(fs.readFileSync(path.join(__dirname, ‘../../../credentials/git_repo_config.json’), ‘utf8’));
const xsuaaHostname = aiCoreCreds.url;
const xsuaaClient = aiCoreCreds.clientid;
const xsuaaSecret = aiCoreCreds.clientsecret;
const AI_API_HOST = aiCoreCreds.serviceurls.AI_API_URL;
// === アクセストークン取得 ===
async function getXsuaaToken() {
const url = `${xsuaaHostname}/oauth/token`;
const authHeader = Buffer.from(`${xsuaaClient}:${xsuaaSecret}`).toString(‘base64’);
const data = qs.stringify({
grant_type: ‘client_credentials’,
client_id: xsuaaClient,
client_secret: xsuaaSecret,
});
const response = await axios.post(url, data, {
headers: {
Authorization: `Basic ${authHeader}`,
‘Content-Type’: ‘application/x-www-form-urlencoded’,
},
});
console.log(‘ Access token 取得完了’);
return response.data.access_token;
}
// === Gitリポジトリ登録 ===
async function registerGitRepository(token) {
const url = `${AI_API_HOST}/v2/admin/repositories`;
const payload = {
url: gitRepoConfig.url,
username: gitRepoConfig.username,
password: gitRepoConfig.password
};
console.log(‘ Gitリポジトリ登録ペイロード:’, JSON.stringify(payload, null, 2));
try {
const response = await axios.post(url, payload, {
headers: {
Authorization: `Bearer ${token}`,
‘Content-Type’: ‘application/json’
}
});
console.log(‘ Gitリポジトリの登録が成功しました’);
return true;
} catch (err) {
if (err.response && err.response.status === 409) {
console.warn(‘ 既に同じリポジトリが登録されています(409 Conflict)’);
return true; // 登録済みとしてOK扱い
}
console.error(‘ Gitリポジトリの登録エラー:’);
if (err.response) {
console.error(` ステータスコード: ${err.response.status}`);
console.error(` レスポンス: ${JSON.stringify(err.response.data, null, 2)}`);
} else if (err.request) {
console.error(‘ リクエスト送信済みだがレスポンスなし’);
} else {
console.error(‘ エラーメッセージ:’, err.message);
}
throw err;
}
}
// === 登録済みリポジトリの確認 ===
async function verifyRepositoryRegistered(token) {
const url = `${AI_API_HOST}/v2/admin/repositories`;
try {
const response = await axios.get(url, {
headers: {
Authorization: `Bearer ${token}`,
‘Content-Type’: ‘application/json’
}
});
const repositories = response.data?.resources || [];
const found = repositories.find(repo => repo.url === gitRepoConfig.url);
if (found) {
console.log(` 登録済みのリポジトリを確認できました:${found.url}`);
console.log(` Repository ID: ${found.id}`);
} else {
console.error(` 登録されたはずのリポジトリが見つかりませんでした: ${gitRepoConfig.url}`);
}
} catch (err) {
console.error(‘ 登録リポジトリの確認中にエラーが発生しました:’);
console.error(err.response?.data || err.message);
}
}
// === 実行 ===
(async () => {
try {
console.log(‘ アクセストークン取得中…’);
const token = await getXsuaaToken();
console.log(‘ Gitリポジトリを登録中…’);
const success = await registerGitRepository(token);
if (success) {
console.log(‘ リポジトリ登録確認を実行します…’);
await verifyRepositoryRegistered(token);
}
console.log(‘ 完了:Gitリポジトリの登録および確認が終了しました’);
} catch (err) {
console.error(‘ スクリプト実行中に致命的なエラーが発生しました:’, err.message);
}
})();
うまくいくと、下記のようにSAP AI Launchpadから登録されたGitHubリポジトリが確認できます。
次に、このリポジトリからプロンプトレジストリにデータを読み込むための「アプリケーション」というコンポーネントをデプロイします。下記のスクリプトを実行してください。
node 03_promptRegistry/01_createPromptTemplate/02_declarative/03_onboardGitRepository.js
主要な処理スクリプトは下記の通りです。
// アプリケーション作成
async function createApplication(token) {
const url = `${AI_API_HOST}/v2/admin/applications`;
const payload = {
applicationName: userCreds.applicationName,
repositoryUrl: gitRepoConfig.url,
revision: “HEAD”,
path: userCreds.applicationPath
};
console.log(‘ アプリケーション作成ペイロード:’, JSON.stringify(payload, null, 2));
try {
const response = await axios.post(url, payload, {
headers: {
Authorization: `Bearer ${token}`,
‘Content-Type’: ‘application/json’
}
});
console.log(‘ アプリケーション作成に成功しました!’);
console.log(` Application Name: ${payload.applicationName}`);
return payload.applicationName;
} catch (err) {
console.error(‘ アプリケーション作成エラー:’);
if (err.response) {
console.error(` ステータス: ${err.response.status}`);
console.error(` レスポンス: ${JSON.stringify(err.response.data, null, 2)}`);
} else {
console.error(‘ メッセージ:’, err.message);
}
throw err;
}
}
うまく実行されるとSAP AI Launchpadから、追加されたアプリケーションが確認できます。詳細画面に移動すると、どのGitHubリポジトリと繋がっているのか、最後にいつ内容の同期が行われたかなどを確認したり、同期を手動実行したりすることが可能です。
ここまでで、プロンプトテンプレートのプロンプトレジストリに対する登録は完了です。次に、登録されたプロンプトを取り出してみましょう。
プロンプトテンプレートのメタデータを取得する
下記のコマンドを実行してください。このnodeスクリプトは、プロンプトレジストリに登録されたすべてのプロンプトテンプレートのメタデータを取得して表示します。
node 03_promptRegistry/02_getPromptTemplate/01_getPromptTemplate.js
主要な処理は下記の通りです。
// すべての Prompt Templates を取得
async function getAllPromptTemplates(token) {
const url = `${AI_API_HOST}/v2/lm/promptTemplates`;
try {
const response = await axios.get(url, {
headers: {
Authorization: `Bearer ${token}`,
‘AI-Resource-Group’: resourceGroupId
}
});
const templates = response.data?.resources || [];
if (templates.length === 0) {
console.log(‘ 登録されているPrompt Templateはありません。’);
} else {
console.log(` 登録済みPrompt Templates(${templates.length}件):`);
templates.forEach((t, index) => {
console.log(`n[${index + 1}]`);
console.log(` ID: ${t.id}`);
console.log(` Name: ${t.name}`);
console.log(` Scenario: ${t.scenario}`);
console.log(` Version: ${t.version}`);
console.log(` Created: ${t.creationTimestamp}`);
console.log(` Managed By: ${t.managedBy}`);
console.log(` Head Version?: ${t.isVersionHead}`);
});
}
return templates;
} catch (err) {
console.error(‘ Prompt Templates の取得中にエラー:’);
if (err.response) {
console.error(` ステータス: ${err.response.status}`);
console.error(` 内容: ${JSON.stringify(err.response.data, null, 2)}`);
} else {
console.error(‘ エラー:’, err.message);
}
throw err;
}
}
うまく実行できると、下記のように登録されたプロンプトテンプレートのIDやその他の情報が確認できます。
次に、これらのプロンプトテンプレートを実際に利用する方法を解説します。
プロンプトテンプレートを利用する
Orchestration機能と統合して利用する
SAP AI LaunchpadからOrchestration機能を開き、Templatingモジュールをクリックすると、Selectボタンが存在することが確認できます。
このSelectボタンをクリックすると、テンプレートレジストリに登録されたプロンプトの一覧が表示され、そこから選択することでOrchestrationワークフローの中でプロンプトを利用することができるようになります。
プロンプトテンプレートを選択すると、下記の通りシステム・ユーザープロンプトや変数の定義、などがTemplatingエディタに反映されます。
この後の設定や利用に関しては、前回のブログ 「SAP AI Core Orchestration機能 を解き明かす」 をご参照いただくと、イメージが掴めるはずです。
APIから直接プロンプトを利用する
プロンプトテンプレート機能には、Substitution(代入)を行うAPIが用意されています。このAPIは、SAP AI Coreのテンプレートレジストリに登録されたプロンプトテンプレートを指定しつつ、そのテンプレートに用意されたプレースホルダーに代入するべき文字列を一緒に渡すと、代入された完成形のプロンプトを返すというAPIとなっています。下記のnodeスクリプトを実行してください。
node 03_promptRegistry/03_usePromptTemplate/01_getSubstitutedPromptTemplate.js
このnodeスクリプトでは下記のような主要な処理が行われており、完成形のプロンプトをコンソールに出力するようになっています。この際、credentials/user_defined_variable.jsonのpromptTemplateIdの値を参照してプロンプトテンプレートを取得し、APIを呼び出す構成になっています。必要に応じて、プロンプトテンプレートIDの値は変更してみてください。
// Prompt Template 使用(substitution)
async function usePromptTemplate(token) {
const {
promptTemplateId,
promptTemplateName,
promptScenarioName,
promptVersion
} = userCreds;
// 入力パラメータ(登録されたpromptTemplateに対して余計なinputがある分には問題ないが、足りないとエラー400が返ってくる)
const inputParams = {
inputExample: userCreds.promptInput_inputExample,
user_input: userCreds.promptInput_user_input
};
let url;
if (promptTemplateId) {
url = `${AI_API_HOST}/v2/lm/promptTemplates/${promptTemplateId}/substitution`;
console.log(` Prompt Template (ID: ${promptTemplateId}) を使用して substitution します`);
} else {
url = `${AI_API_HOST}/v2/lm/scenarios/${promptScenarioName}/promptTemplates/${promptTemplateName}/versions/${promptVersion}/substitution`;
console.log(` Prompt Template (Name: ${promptTemplateName}) を使用して substitution します`);
}
try {
const response = await axios.post(url, {
inputParams
}, {
headers: {
Authorization: `Bearer ${token}`,
‘Content-Type’: ‘application/json’
}
});
console.log(‘ Substitution 成功!完成した Prompt:’);
console.log(JSON.stringify(response.data, null, 2));
return response.data;
} catch (err) {
console.error(‘ Substitution 実行中にエラーが発生しました’);
if (err.response) {
console.error(` ステータス: ${err.response.status}`);
console.error(` 内容: ${JSON.stringify(err.response.data, null, 2)}`);
} else {
console.error(‘ エラー内容:’, err.message);
}
throw err;
}
}
うまく動くと、下記のような形で完成されたプロンプトが返されます。
このように取得したプロンプトを、LLMアプリケーションの中で利用するようにアプリケーションを構成することで、プロンプトを中央集約的に管理しつつ、LLMアプリケーションの運用を行なっていくことができます。
Declarative APIを使ってプロンプトをアップデートする
最後に、本番運用に向けたDeclarative APIを用いてプロンプトをアップデートする例を見てみましょう。連携対象に設定しているGitHubリポジトリで、下記のようにプロンプトを少しだけ変えてみましょう。変更がすみ次第、Commit Changes…ボタンから変更をリポジトリに反映します。
しばらくすると自動的にSAP AI Coreが変更を検知してプロンプトレジストリにデータを反映しますが、うまくいかない場合には下記のようにSAP AI Launchpadのアプリケーションの詳細画面から、手動で同期させることも可能です。
その後、再度下記のnodeスクリプトを実行すると、変更されたプロンプトが出力されることが確認できます。
node 03_promptRegistry/03_usePromptTemplate/01_getSubstitutedPromptTemplate.js
このように、LLMアプリケーションにプロンプトをハードコードする場合に比べ、プロンプトのライフサイクルを別途切り離して管理することができるようになります。これにより、LLMアプリケーション自体を再デプロイすることなく、内部で利用しているプロンプトを変更することができます。
技術者が押さえておきたいポイント(ベストプラクティス・拡張性・セキュリティ)
最後に、プロンプトレジストリ機能を最大限に活用するためのベストプラクティスや留意点をいくつか紹介します。
バージョン管理と参照戦略: テンプレートの変更にはバージョン番号を適切に更新し、互換性の大きな変更はメジャー/マイナー番号で表現するようにしましょう(例:0.1系→0.2系で大きな改良を示す)。オーケストレーション等から参照する際は、安定稼働中のワークフローは固定バージョンもしくはIDで参照し、新バージョンを試す際にはテスト環境でlatest参照に切り替えて動作確認するといった運用が安全です。特に本番環境でlatestを参照していると意図しないタイミングで挙動が変わり得るため、慎重に使う必要があります。
命令型と宣言型の使い分け: 開発サイクルでは、まず命令型APIで素早くプロトタイピングし、確立したテンプレートを宣言型(Git管理)に移行する方法が有効です。命令型で作成したテンプレートJSONをYAMLに転記しGitコミットすることで、開発で得られたベストなテンプレートを本番管理下に置けます。逆に、本番環境のテンプレートを急遽修正する場合も、可能であればGit経由で行い、履歴を残すことが推奨されます。原則として長期運用するテンプレートはGitで一元管理する方針が望ましいでしょう。
テンプレート設計のベストプラクティス: プロンプトテンプレート自体の内容設計にも留意しましょう。システムメッセージ(role: system)にはAIモデルにタスクや制約を与える指示を書く、ユーザメッセージ(role: user)には実際の入力や質問内容を埋め込む、といった基本に忠実に、テンプレートとして汎用性が高くなるよう工夫します。社内のスタイルガイドがある場合はテンプレートに予め盛り込んでおき、どの開発者が使っても一定品質のプロンプトとなるようにします。プレースホルダーの命名もわかりやすくし、テンプレート自体にコメントや説明(additionalFieldsに説明を書いたり、テンプレート名やscenario名に用途を明示したり)を付けると管理が容易です。
拡張性と他サービス連携: SAP AI CoreのプロンプトレジストリはSAPの他サービスや外部システムとも連携可能です。SAP AI Launchpadとの統合はもちろん、SAP Cloud SDKを使えばクラウド拡張アプリケーションから直接プロンプトを呼び出すこともできます。将来的にテンプレート数が膨大になった場合でも、APIで検索・フィルタ(シナリオや名前のクエリ)して必要なテンプレートだけ取得するなど、柔軟な利用が可能です。他のLLMオーケストレーションツール(例:LangChain)との概念対応も考慮すると、テンプレート管理をAI Core側に任せ、実行部分はLangChainエージェントからAI Core経由でLLM呼び出しをする、といったハイブリッド構成も取り得ます。こうした拡張性を視野に入れ、自社のAI基盤戦略にプロンプトレジストリを位置付けると良いでしょう。
セキュリティとアクセス制御: プロンプトには業務上重要なロジックや文言が含まれるため、適切なアクセス管理が必要です。SAP AI Core自体がBTPのセキュリティ機構(SAP IASによるユーザ認証・権限付与など)で守られていますが、特にプロンプトの編集権限は限定し、承認ワークフローを導入することが望ましいです。前述のように本番テンプレートはGitの変更権限でコントロールし、ブランチ保護やコードオーナーレビューを設定することで、不用意な変更や悪意ある改変を防止できます。また、テンプレート中にハードコードすべきでない情報(APIキーや個人情報など)を埋め込まないのは言うまでもありません。AIモデルへの指示内容も一種のコードとみなし、レビューとテストを経てデプロイする姿勢が安全性確保につながります。
最後に
以上、SAP AI Coreのプロンプトレジストリ機能について技術的観点からまとめました。プロンプトのライフサイクル管理を支援する本機能を活用することで、生成AIソリューション開発における生産性と品質を大きく向上させることができるでしょう。公式ドキュメントやSAPの開発者向けブログなども参考に、ぜひ自社シナリオへの適用を検討してみてください。
参考文献
SAP AI Core公式ドキュメント
https://help.sap.com/doc/c31b38b32a5d4e07a4488cb0f8bb55d9/CLOUD/en-US/f17fa8568d0448c685f2a0301061a6ee.pdf
SAP Help Portal – SAP AI Core Prompt Registry
https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/prompt-registry
プロンプトレジストリ機能の概要SAP AI Coreのプロンプトレジストリ機能は、生成AIにおけるプロンプト(指示文)のテンプレートを一元管理するための仕組みです。SAP AI Core上のGenerative AI Hubの一部として提供され、プロンプトテンプレートをAI Core内部に統合することで、さまざまなアプリケーションやAIワークフロー(オーケストレーション)から再利用可能な形で提供します。従来、各アプリケーションごとに個別管理・LLMアプリケーション内にハードコードしがちであったプロンプトを中央集約して管理することで、プロンプトのライフサイクル(作成・共有・更新・バージョン管理)の効率化を図ります。この機能により、LLMアプリエンジニアはビジネスシナリオごとのプロンプトデザインから運用までを統一的に扱うことができ、プロンプトエンジニアリングのベストプラクティスを組織横断で適用しやすくなります。また、プロンプトテンプレートに対するバージョン管理やアクセス制御も可能になるため、企業内での生成AI利用ガバナンスを強化する役割も担っています。 アーキテクチャ上の位置づけと構成要素プロンプトレジストリはSAP AI Coreサービス内のコンポーネントであり、Generative AI Hubの中核機能の一つです。アーキテクチャ上、プロンプトテンプレートはAI Coreの他機能(オーケストレーション、グランディングなど)と連携し、動的にLLMを呼び出す際の指示文生成に組み込無事ができます。例えば、オーケストレーション機能(生成AIワークフロー管理)では、このレジストリに登録されたテンプレートを参照し、AIモデルへの呼び出し時に適切なプロンプトを適用できます。 プロンプトレジストリへのプロンプト登録に関しては、下記の通り大きく分けて2種類のインターフェースを提供しています。命令型API(Imperative API): RESTベースのAPIにより、プログラムから直接プロンプトテンプレートを登録・更新・取得する方法です。プロンプトに関するCRUD操作(作成・読み取り・更新・削除)をサポートし、主に開発時のプロンプト作成・調整に適しています。開発者はこのAPIを使ってテンプレートを反復的に修正でき、その都度履歴が記録され後で確認できます。(SAP AI Coreの変更履歴APIエンドポイントから変更履歴を参照可能)宣言型API(Declarative API): SAP AI Coreの「Application」機能と「Git Repository」 機能による連携を用いた管理方法です。CI/CDパイプラインや本番運用時に適した手法で、GitHub上のプロンプト定義ファイルをソースとしてSAP AI Core側のプロンプトレジストリに自動同期します。開発者はプロンプトテンプレートをyamlファイルで記述しGitHubのリポジトリにコミットするだけで、SAP AI Coreがその内容を検出してレジストリに反映します。この仕組みにより、インフラとしてコード管理するようにプロンプトを扱うことが可能です。(いわゆるPrompts-as-Code)なお、GitHub連携で管理されたテンプレートは内部的にmanagedBy: declarativeとマークされ、常に最新版(ヘッドバージョン)のみ有効となります。また、こうしたテンプレートは後述の命令型API経由では編集できず、変更はGit経由で行う必要があります。これは、登録されたプロンプトとGitHubリポジトリの内容の一貫性を保つための仕様となります。上記のような手順で登録されたプロンプトの利用に関しては、SAP AI CoreのSDK(各種言語向け)を使ってプログラムから簡潔に利用することもできます。例えば、SAP AI CoreのNode.js SDKパッケージを使えば、コード一行で登録済みテンプレートの一覧取得や参照が可能です。これにより、外部アプリケーションやサービスからプロンプトレジストリを統合的に利用する拡張性も確保されています。 想定ユースケースとメリットプロンプトレジストリ機能は、組織内で生成AIを活用する際に次のようなユースケースと利点をもたらします。複数プロジェクト・アプリ間でのプロンプト共有: 共通の目的を持つプロンプト(例えば「製品レビュー要約用プロンプト」や「社内文書分類プロンプト」)を一度定義すれば、レジストリ経由で他のAIシナリオやプロジェクトから再利用できます。各チームが独自に類似プロンプトを作成する手間を省き、一貫性のある回答品質を維持できます。再利用性と開発効率の向上: プロンプトテンプレートはパラメータ化(プレースホルダーの使用)されているため、入力データや用途に応じて動的に内容を差し替えて使い回すことができます。例えばカテゴリ分類用のプロンプトテンプレートを作成し、カテゴリ名だけプレースホルダーにしておけば、金融ニュース分類にもスポーツ記事分類にも同じテンプレートを適用できます。一度作ったテンプレートを様々な場面で使い回すことで、プロンプト設計の重複を削減し、素早いソリューション展開が可能です。管理性・ガバナンスの向上: すべてのプロンプト定義が中央レジストリで管理されるため、変更管理やレビューが容易になります。変更履歴やバージョン管理機能により、誰がいつどのようにプロンプトを変更したかを追跡できます。問題が発生した際に以前のバージョンへロールバックしたり、改善提案を履歴に基づいて検討したりといったライフサイクル管理が制度的にサポートされます。また、アクセス権を制御することで、プロンプトの編集・承認プロセスにガバナンスを適用することもできます(例えば本番環境のテンプレートは管理者のみ編集可とする、など)。CI/CDへの組み込み: 宣言型(Git管理)のモデルでは、プロンプトテンプレートの変更を通常のコードと同様にPull Requestでレビューし、テストを経てから本番環境に適用する、といったDevOps的運用が可能です。プロンプトをコードと同じプロセスで扱えるため、アプリケーション開発の一部として統合的に品質管理できます。これは生成AIの挙動を安定・向上させる上で重要なポイントです。迅速な実験とチューニング: 命令型APIを用いることで、本番影響を与えない環境で素早くプロンプトの試行錯誤(プロンプトエンジニアリング実験)ができます。たとえば、新しいプロンプトをAPI経由で登録しテストした後、良好な結果が得られればそれをGitにも反映して正式版テンプレートとする、といったワークフローです。開発スピードと本番管理のバランスを取りながら、効率的にプロンプトを磨き上げられます。統合機能との連携: プロンプトテンプレートは単に文章を保存するだけでなく、他のGenerative AI Hubの機能と連動した使い方も想定されています。例えばGrounding(グランディング)機能で取得した企業データをプロンプトの一部に差し込む、といったシナリオでも、テンプレートにプレースホルダーを用意しておけばOrchestration機能側で連携しつつ、プロンプトとグラウンディングをうまく組み合わせた運用が可能です。さらにデータマスキングやコンテンツフィルタリングと組み合わせ、機密情報を伏せた上でテンプレート出力をLLMに渡すといった高度な制御も、テンプレートを介することで簡潔になります。あくまでこれらはプロンプトレジストリ機能単体ではなく、SAP AI Core のOrchestration機能で提供される機能と組み合わせて実現します。以上のように、プロンプトレジストリは複数チーム・複数ユースケースにまたがるプロンプト資産の共有基盤として機能し、生成AI活用のスケーラビリティと統制を両立させる役割を果たします。 プロンプトレジストリに触れてみる事前準備:GitHubリポジトリをクローンする今回のハンズオンはSAP Build Code上にて実施します。Devスペースにログインしてターミナルを立ち上げ、まずはサンプルコードをクローンしましょう。 git clone https://github.com/watwatwhat/SAPAICore_Grounding_sample.git 事前準備:認証情報の設定を行う今回のハンズオンの前提条件として、SAP AI Core(Extendedプラン)のインスタンスをSAP BTP Cockpitから作成して、SAP AI LaunchpadにSAP AI Coreのインスタンスをオンボーディングしておきます。まずは、今回のハンズオンで用いるサービス群のサービスキーとユーザー定義文字列を設定しましょう。クローンしたファイル群の中から、下記の2つのファイルを編集します。 credentials/ai_core_sk.json
credentials/user_defined_variable.json 1つ目に関しては、SAP AI Coreのインスタンスに作成したサービスキーのjson、Object Store on SAP BTP のインスタンスに作成したサービスキーのjsonをペーストしてください。2つ目に関しては、任意の値を入力してください。使える文字には制限があるようなので、特にこだわりがなければデフォルトと同じような名前をつけることを推奨します。IDの文字が規定に沿っていないという旨のエラーが後段で出た場合、この辺りを設定し直してください。 プロンプトレジストリ新規プロンプトを登録するImperative API(命令型API)を介してプロンプトを登録する新規ターミナルで、下記のコマンドを実行してnodeスクリプトを実行します。 node 03_promptRegistry/01_createPromptTemplate/01_imperative/01_imperative.js このnodeスクリプトでは下記のようにプロンプトテンプレートを同じディレクトリに存在するspec.jsonから読み込み、それをImperative APIを介してプロンプトレジストリに登録しています。 // Prompt Template 作成
async function createPromptTemplate(token, templateName) {
const url = `${AI_API_HOST}/v2/lm/promptTemplates`;
const payload = {
name: templateName,
version: userCreds.promptVersion,
scenario: userCreds.promptScenarioName,
spec: spec
};
console.log(` Prompt Template ペイロード:`, JSON.stringify(payload, null, 2));
try {
const response = await axios.post(url, payload, {
headers: {
Authorization: `Bearer ${token}`,
‘Content-Type’: ‘application/json’,
‘AI-Resource-Group’: resourceGroupId
}
});
const promptId = response.data.id;
console.log(` Prompt Template 作成成功!ID: ${promptId}`);
// IDを userCreds に書き込んで保存
userCreds.promptTemplateId = promptId;
fs.writeFileSync(userCredsPath, JSON.stringify(userCreds, null, 2));
console.log(` promptTemplateId を ${userCredsPath} に保存しました`);
return promptId;
} catch (err) {
console.error(‘ Prompt Template 作成エラーが発生しました。詳細:’);
if (err.response) {
console.error(` ステータスコード: ${err.response.status}`);
console.error(` レスポンスボディ: ${JSON.stringify(err.response.data, null, 2)}`);
} else if (err.request) {
console.error(‘ リクエストは送信されましたが、レスポンスがありませんでした。’);
console.error(err.request);
} else {
console.error(‘ エラー詳細メッセージ:’, err.message);
}
console.error(‘ スタックトレース:’);
console.error(err.stack);
throw err;
}
} spec.jsonには下記のような内容が記載されています。システムプロンプトとユーザープロンプトが一つづつ入力されており、かつ{{?inputExample}}というプレースホルダーが定義されています。 {
“template”: [
{
“role”: “system”,
“content”: “You classify input text into the two following categories: {{?categories}}”
},
{
“role”: “user”,
“content”: “{{?inputExample}}”
}
],
“defaults”: {
“categories”: “Finance, Tech, Sports”
},
“additionalFields”: {
“modelParams”: {
“temperature”: 0.7,
“max_tokens”: 100
},
“modelGroup”: “chat”
}
} プロンプトの登録が完了すると、credentials/user_defined_variable.jsonの中のpromptTemplateIdというキーの値にプロンプトのIDが保存されます。これは後ほど使います。 Dec larativeAPI(宣言型API)を介してプロンプトを登録する次に、Declarative APIを用いてプロンプトを登録してみましょう。この登録パターンでは、GitHubのリポジトリを経由してプロンプトを登録していきます。まずは、GitHubの空の新規リポジトリを作成し、ghpから始まるシークレットキーを取得してください。この部分の詳細な手順は一般的な内容となりますので、本ブログでは割愛します。リポジトリのURLとシークレットキーが発行できたら、 credentials/git_repo_config.jsonにurl、username、passwordを入力してください。なお、シークレットキーは機密情報になりますので、取り扱いにはくれぐれもご注意ください。 {
“url”: “https://github.com/john/examplerepo.git”,
“username”: “john”,
“password”: “ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXX”
} この設定が完了次第、下記のコマンドを実行してください。このnodeスクリプトは、上記のファイルからGitHubの認証情報を取得し、対象のリポジトリに設定ファイルをpushします。 node 03_promptRegistry/01_createPromptTemplate/02_declarative/01_pushToGitHub.js うまく実行できると、対象のGitHubリポジトリに上記のようなファイルがpushされます。ここに格納されているのがプロンプトの設定ファイルであり、例えば内容は下記のようになっています。 # ========================
#
# Decralative APIを利用して、プロンプトテンプレートを登録する
# https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/create-prompt-template-declarative
#
# ========================
name: simple
version: 0.0.1
scenario: my-scenario
spec:
template:
– role: “system”
content: “{{ ?instruction }}”
– role: “user”
content: “Some more {{ ?user_input }}”
defaults:
instruction: “default instruction”
additionalFields:
isDev: true
validations:
required: true
blockedModels:
– name: “gpt-4”
versions: “gpt-4-vision”
– name: “gpt-4o”
versions: “*” 上記を持ってGitHubにプロンプトの準備ができたので、これをSAP AI Core – Generative AI Hubのプロンプトレジストリにオンボードしていきます。下記のnodeスクリプトを実行してください。 node 03_promptRegistry/01_createPromptTemplate/02_declarative/02_registerGitRepository.js このスクリプトではSAP AI CoreのAPIから、GitHubのリポジトリに対する接続を試行します。主要な処理部分は下記の通りです。 const axios = require(‘axios’);
const fs = require(‘fs’);
const path = require(‘path’);
const qs = require(‘qs’);
// === 設定読み込み ===
const aiCoreCreds = JSON.parse(fs.readFileSync(path.join(__dirname, ‘../../../credentials/ai_core_sk.json’), ‘utf8’));
const gitRepoConfig = JSON.parse(fs.readFileSync(path.join(__dirname, ‘../../../credentials/git_repo_config.json’), ‘utf8’));
const xsuaaHostname = aiCoreCreds.url;
const xsuaaClient = aiCoreCreds.clientid;
const xsuaaSecret = aiCoreCreds.clientsecret;
const AI_API_HOST = aiCoreCreds.serviceurls.AI_API_URL;
// === アクセストークン取得 ===
async function getXsuaaToken() {
const url = `${xsuaaHostname}/oauth/token`;
const authHeader = Buffer.from(`${xsuaaClient}:${xsuaaSecret}`).toString(‘base64’);
const data = qs.stringify({
grant_type: ‘client_credentials’,
client_id: xsuaaClient,
client_secret: xsuaaSecret,
});
const response = await axios.post(url, data, {
headers: {
Authorization: `Basic ${authHeader}`,
‘Content-Type’: ‘application/x-www-form-urlencoded’,
},
});
console.log(‘ Access token 取得完了’);
return response.data.access_token;
}
// === Gitリポジトリ登録 ===
async function registerGitRepository(token) {
const url = `${AI_API_HOST}/v2/admin/repositories`;
const payload = {
url: gitRepoConfig.url,
username: gitRepoConfig.username,
password: gitRepoConfig.password
};
console.log(‘ Gitリポジトリ登録ペイロード:’, JSON.stringify(payload, null, 2));
try {
const response = await axios.post(url, payload, {
headers: {
Authorization: `Bearer ${token}`,
‘Content-Type’: ‘application/json’
}
});
console.log(‘ Gitリポジトリの登録が成功しました’);
return true;
} catch (err) {
if (err.response && err.response.status === 409) {
console.warn(‘ 既に同じリポジトリが登録されています(409 Conflict)’);
return true; // 登録済みとしてOK扱い
}
console.error(‘ Gitリポジトリの登録エラー:’);
if (err.response) {
console.error(` ステータスコード: ${err.response.status}`);
console.error(` レスポンス: ${JSON.stringify(err.response.data, null, 2)}`);
} else if (err.request) {
console.error(‘ リクエスト送信済みだがレスポンスなし’);
} else {
console.error(‘ エラーメッセージ:’, err.message);
}
throw err;
}
}
// === 登録済みリポジトリの確認 ===
async function verifyRepositoryRegistered(token) {
const url = `${AI_API_HOST}/v2/admin/repositories`;
try {
const response = await axios.get(url, {
headers: {
Authorization: `Bearer ${token}`,
‘Content-Type’: ‘application/json’
}
});
const repositories = response.data?.resources || [];
const found = repositories.find(repo => repo.url === gitRepoConfig.url);
if (found) {
console.log(` 登録済みのリポジトリを確認できました:${found.url}`);
console.log(` Repository ID: ${found.id}`);
} else {
console.error(` 登録されたはずのリポジトリが見つかりませんでした: ${gitRepoConfig.url}`);
}
} catch (err) {
console.error(‘ 登録リポジトリの確認中にエラーが発生しました:’);
console.error(err.response?.data || err.message);
}
}
// === 実行 ===
(async () => {
try {
console.log(‘ アクセストークン取得中…’);
const token = await getXsuaaToken();
console.log(‘ Gitリポジトリを登録中…’);
const success = await registerGitRepository(token);
if (success) {
console.log(‘ リポジトリ登録確認を実行します…’);
await verifyRepositoryRegistered(token);
}
console.log(‘ 完了:Gitリポジトリの登録および確認が終了しました’);
} catch (err) {
console.error(‘ スクリプト実行中に致命的なエラーが発生しました:’, err.message);
}
})(); うまくいくと、下記のようにSAP AI Launchpadから登録されたGitHubリポジトリが確認できます。 次に、このリポジトリからプロンプトレジストリにデータを読み込むための「アプリケーション」というコンポーネントをデプロイします。下記のスクリプトを実行してください。 node 03_promptRegistry/01_createPromptTemplate/02_declarative/03_onboardGitRepository.js 主要な処理スクリプトは下記の通りです。 // アプリケーション作成
async function createApplication(token) {
const url = `${AI_API_HOST}/v2/admin/applications`;
const payload = {
applicationName: userCreds.applicationName,
repositoryUrl: gitRepoConfig.url,
revision: “HEAD”,
path: userCreds.applicationPath
};
console.log(‘ アプリケーション作成ペイロード:’, JSON.stringify(payload, null, 2));
try {
const response = await axios.post(url, payload, {
headers: {
Authorization: `Bearer ${token}`,
‘Content-Type’: ‘application/json’
}
});
console.log(‘ アプリケーション作成に成功しました!’);
console.log(` Application Name: ${payload.applicationName}`);
return payload.applicationName;
} catch (err) {
console.error(‘ アプリケーション作成エラー:’);
if (err.response) {
console.error(` ステータス: ${err.response.status}`);
console.error(` レスポンス: ${JSON.stringify(err.response.data, null, 2)}`);
} else {
console.error(‘ メッセージ:’, err.message);
}
throw err;
}
} うまく実行されるとSAP AI Launchpadから、追加されたアプリケーションが確認できます。詳細画面に移動すると、どのGitHubリポジトリと繋がっているのか、最後にいつ内容の同期が行われたかなどを確認したり、同期を手動実行したりすることが可能です。 ここまでで、プロンプトテンプレートのプロンプトレジストリに対する登録は完了です。次に、登録されたプロンプトを取り出してみましょう。 プロンプトテンプレートのメタデータを取得する下記のコマンドを実行してください。このnodeスクリプトは、プロンプトレジストリに登録されたすべてのプロンプトテンプレートのメタデータを取得して表示します。 node 03_promptRegistry/02_getPromptTemplate/01_getPromptTemplate.js 主要な処理は下記の通りです。 // すべての Prompt Templates を取得
async function getAllPromptTemplates(token) {
const url = `${AI_API_HOST}/v2/lm/promptTemplates`;
try {
const response = await axios.get(url, {
headers: {
Authorization: `Bearer ${token}`,
‘AI-Resource-Group’: resourceGroupId
}
});
const templates = response.data?.resources || [];
if (templates.length === 0) {
console.log(‘ 登録されているPrompt Templateはありません。’);
} else {
console.log(` 登録済みPrompt Templates(${templates.length}件):`);
templates.forEach((t, index) => {
console.log(`n[${index + 1}]`);
console.log(` ID: ${t.id}`);
console.log(` Name: ${t.name}`);
console.log(` Scenario: ${t.scenario}`);
console.log(` Version: ${t.version}`);
console.log(` Created: ${t.creationTimestamp}`);
console.log(` Managed By: ${t.managedBy}`);
console.log(` Head Version?: ${t.isVersionHead}`);
});
}
return templates;
} catch (err) {
console.error(‘ Prompt Templates の取得中にエラー:’);
if (err.response) {
console.error(` ステータス: ${err.response.status}`);
console.error(` 内容: ${JSON.stringify(err.response.data, null, 2)}`);
} else {
console.error(‘ エラー:’, err.message);
}
throw err;
}
} うまく実行できると、下記のように登録されたプロンプトテンプレートのIDやその他の情報が確認できます。 次に、これらのプロンプトテンプレートを実際に利用する方法を解説します。 プロンプトテンプレートを利用するOrchestration機能と統合して利用するSAP AI LaunchpadからOrchestration機能を開き、Templatingモジュールをクリックすると、Selectボタンが存在することが確認できます。 このSelectボタンをクリックすると、テンプレートレジストリに登録されたプロンプトの一覧が表示され、そこから選択することでOrchestrationワークフローの中でプロンプトを利用することができるようになります。 プロンプトテンプレートを選択すると、下記の通りシステム・ユーザープロンプトや変数の定義、などがTemplatingエディタに反映されます。 この後の設定や利用に関しては、前回のブログ 「SAP AI Core Orchestration機能 を解き明かす」 をご参照いただくと、イメージが掴めるはずです。 APIから直接プロンプトを利用するプロンプトテンプレート機能には、Substitution(代入)を行うAPIが用意されています。このAPIは、SAP AI Coreのテンプレートレジストリに登録されたプロンプトテンプレートを指定しつつ、そのテンプレートに用意されたプレースホルダーに代入するべき文字列を一緒に渡すと、代入された完成形のプロンプトを返すというAPIとなっています。下記のnodeスクリプトを実行してください。 node 03_promptRegistry/03_usePromptTemplate/01_getSubstitutedPromptTemplate.js このnodeスクリプトでは下記のような主要な処理が行われており、完成形のプロンプトをコンソールに出力するようになっています。この際、credentials/user_defined_variable.jsonのpromptTemplateIdの値を参照してプロンプトテンプレートを取得し、APIを呼び出す構成になっています。必要に応じて、プロンプトテンプレートIDの値は変更してみてください。 // Prompt Template 使用(substitution)
async function usePromptTemplate(token) {
const {
promptTemplateId,
promptTemplateName,
promptScenarioName,
promptVersion
} = userCreds;
// 入力パラメータ(登録されたpromptTemplateに対して余計なinputがある分には問題ないが、足りないとエラー400が返ってくる)
const inputParams = {
inputExample: userCreds.promptInput_inputExample,
user_input: userCreds.promptInput_user_input
};
let url;
if (promptTemplateId) {
url = `${AI_API_HOST}/v2/lm/promptTemplates/${promptTemplateId}/substitution`;
console.log(` Prompt Template (ID: ${promptTemplateId}) を使用して substitution します`);
} else {
url = `${AI_API_HOST}/v2/lm/scenarios/${promptScenarioName}/promptTemplates/${promptTemplateName}/versions/${promptVersion}/substitution`;
console.log(` Prompt Template (Name: ${promptTemplateName}) を使用して substitution します`);
}
try {
const response = await axios.post(url, {
inputParams
}, {
headers: {
Authorization: `Bearer ${token}`,
‘Content-Type’: ‘application/json’
}
});
console.log(‘ Substitution 成功!完成した Prompt:’);
console.log(JSON.stringify(response.data, null, 2));
return response.data;
} catch (err) {
console.error(‘ Substitution 実行中にエラーが発生しました’);
if (err.response) {
console.error(` ステータス: ${err.response.status}`);
console.error(` 内容: ${JSON.stringify(err.response.data, null, 2)}`);
} else {
console.error(‘ エラー内容:’, err.message);
}
throw err;
}
} うまく動くと、下記のような形で完成されたプロンプトが返されます。 このように取得したプロンプトを、LLMアプリケーションの中で利用するようにアプリケーションを構成することで、プロンプトを中央集約的に管理しつつ、LLMアプリケーションの運用を行なっていくことができます。 Declarative APIを使ってプロンプトをアップデートする最後に、本番運用に向けたDeclarative APIを用いてプロンプトをアップデートする例を見てみましょう。連携対象に設定しているGitHubリポジトリで、下記のようにプロンプトを少しだけ変えてみましょう。変更がすみ次第、Commit Changes…ボタンから変更をリポジトリに反映します。 しばらくすると自動的にSAP AI Coreが変更を検知してプロンプトレジストリにデータを反映しますが、うまくいかない場合には下記のようにSAP AI Launchpadのアプリケーションの詳細画面から、手動で同期させることも可能です。 その後、再度下記のnodeスクリプトを実行すると、変更されたプロンプトが出力されることが確認できます。 node 03_promptRegistry/03_usePromptTemplate/01_getSubstitutedPromptTemplate.js このように、LLMアプリケーションにプロンプトをハードコードする場合に比べ、プロンプトのライフサイクルを別途切り離して管理することができるようになります。これにより、LLMアプリケーション自体を再デプロイすることなく、内部で利用しているプロンプトを変更することができます。 技術者が押さえておきたいポイント(ベストプラクティス・拡張性・セキュリティ)最後に、プロンプトレジストリ機能を最大限に活用するためのベストプラクティスや留意点をいくつか紹介します。バージョン管理と参照戦略: テンプレートの変更にはバージョン番号を適切に更新し、互換性の大きな変更はメジャー/マイナー番号で表現するようにしましょう(例:0.1系→0.2系で大きな改良を示す)。オーケストレーション等から参照する際は、安定稼働中のワークフローは固定バージョンもしくはIDで参照し、新バージョンを試す際にはテスト環境でlatest参照に切り替えて動作確認するといった運用が安全です。特に本番環境でlatestを参照していると意図しないタイミングで挙動が変わり得るため、慎重に使う必要があります。命令型と宣言型の使い分け: 開発サイクルでは、まず命令型APIで素早くプロトタイピングし、確立したテンプレートを宣言型(Git管理)に移行する方法が有効です。命令型で作成したテンプレートJSONをYAMLに転記しGitコミットすることで、開発で得られたベストなテンプレートを本番管理下に置けます。逆に、本番環境のテンプレートを急遽修正する場合も、可能であればGit経由で行い、履歴を残すことが推奨されます。原則として長期運用するテンプレートはGitで一元管理する方針が望ましいでしょう。テンプレート設計のベストプラクティス: プロンプトテンプレート自体の内容設計にも留意しましょう。システムメッセージ(role: system)にはAIモデルにタスクや制約を与える指示を書く、ユーザメッセージ(role: user)には実際の入力や質問内容を埋め込む、といった基本に忠実に、テンプレートとして汎用性が高くなるよう工夫します。社内のスタイルガイドがある場合はテンプレートに予め盛り込んでおき、どの開発者が使っても一定品質のプロンプトとなるようにします。プレースホルダーの命名もわかりやすくし、テンプレート自体にコメントや説明(additionalFieldsに説明を書いたり、テンプレート名やscenario名に用途を明示したり)を付けると管理が容易です。拡張性と他サービス連携: SAP AI CoreのプロンプトレジストリはSAPの他サービスや外部システムとも連携可能です。SAP AI Launchpadとの統合はもちろん、SAP Cloud SDKを使えばクラウド拡張アプリケーションから直接プロンプトを呼び出すこともできます。将来的にテンプレート数が膨大になった場合でも、APIで検索・フィルタ(シナリオや名前のクエリ)して必要なテンプレートだけ取得するなど、柔軟な利用が可能です。他のLLMオーケストレーションツール(例:LangChain)との概念対応も考慮すると、テンプレート管理をAI Core側に任せ、実行部分はLangChainエージェントからAI Core経由でLLM呼び出しをする、といったハイブリッド構成も取り得ます。こうした拡張性を視野に入れ、自社のAI基盤戦略にプロンプトレジストリを位置付けると良いでしょう。セキュリティとアクセス制御: プロンプトには業務上重要なロジックや文言が含まれるため、適切なアクセス管理が必要です。SAP AI Core自体がBTPのセキュリティ機構(SAP IASによるユーザ認証・権限付与など)で守られていますが、特にプロンプトの編集権限は限定し、承認ワークフローを導入することが望ましいです。前述のように本番テンプレートはGitの変更権限でコントロールし、ブランチ保護やコードオーナーレビューを設定することで、不用意な変更や悪意ある改変を防止できます。また、テンプレート中にハードコードすべきでない情報(APIキーや個人情報など)を埋め込まないのは言うまでもありません。AIモデルへの指示内容も一種のコードとみなし、レビューとテストを経てデプロイする姿勢が安全性確保につながります。 最後に以上、SAP AI Coreのプロンプトレジストリ機能について技術的観点からまとめました。プロンプトのライフサイクル管理を支援する本機能を活用することで、生成AIソリューション開発における生産性と品質を大きく向上させることができるでしょう。公式ドキュメントやSAPの開発者向けブログなども参考に、ぜひ自社シナリオへの適用を検討してみてください。 参考文献SAP AI Core公式ドキュメントhttps://help.sap.com/doc/c31b38b32a5d4e07a4488cb0f8bb55d9/CLOUD/en-US/f17fa8568d0448c685f2a0301061a6ee.pdfSAP Help Portal – SAP AI Core Prompt Registryhttps://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/prompt-registry Read More Technology Blogs by SAP articles
#SAP
#SAPTechnologyblog