このパッケージで提供する機能はすべて Enterprise Edition の機能です。
Enterprise Editionのサンプルアプリでは、Amazon Bedrock と連携した AI 機能を提供します。
1. セットアップ
AI 機能は、iPLAss EE の AWS 連携モジュールを介して Amazon Bedrock を呼び出します。要約・タグ付与・ドラフト生成・マージは Bedrock Converse API(構造化出力)を、RAG 検索・類似ナレッジ提案は Knowledge Base(RetrieveAndGenerate API)を利用します。
利用するには、次の手順で追加パッケージの取り込みと Bedrock 連携設定を行います。
-
有償版の SDK に同梱されている Enterprise Edition 機能の追加パッケージ
iplass-ee-sample-app-km-package.zipを取得します。このパッケージには、Community Edition には含まれない AI 機能のメタデータ(プロンプト定義・データ連携定義)が含まれます。 -
作成済のテナントで、Admin Console の Packaging 機能を利用して追加パッケージをインポートします。
環境固有の値(Knowledge Base ID・S3 バケット名)は、インポート後に利用する環境の値へ書き換えてください。
詳細については、パッケージ内のREADMEを参照してください。 -
Amazon Bedrock との連携設定を行います。AWS 側の準備と、service-config による AI 連携の設定が必要です。
1.1. AWS 側の準備
Bedrock コンソールから、次を準備します。
-
利用するモデルの有効化
-
S3 バケットの作成(Knowledge Base のデータソース用)
-
Knowledge Base の作成
-
iPLAss を実行する IAM プリンシパルへの、Bedrock と S3 への権限付与
| 認証情報は AWS SDK の標準解決チェーン(環境変数・認証情報ファイル・IAM ロール等)から解決させます。アクセスキーを設定ファイルに直接書かないでください。 |
1.2. service-config の設定
mtp-service-config.xml で、AWS 連携モジュールの読み込みと AI サービスプロバイダの登録を行います。AI サービスプロバイダ登録の一般的な設定方法は、開発者ガイドのサービスプロバイダを参照してください。ここではこのサンプル固有の配線のみを示します。
ファイル名 |
/src/main/resources/mtp-service-config.xml |
|---|
<inherits>/aws2-service-config.xml</inherits> (1)
// ...
<service>
<interface>org.iplass.mtp.impl.awsv2.AWSSetting</interface>
<class>org.iplass.mtp.impl.awsv2.AWSSetting</class>
<property name="clientConfig" class="org.iplass.mtp.impl.awsv2.AWSClientConfig">
<property name="region" value="ap-northeast-1" />
</property>
</service>
<service>
<interface>org.iplass.mtp.impl.ai.AiIntegrationService</interface>
<property name="aiServiceProvider"
class="org.iplass.mtp.impl.ai.awsv2.AWSSettingAiServiceProviderConfig">
<property name="name" value="bedrock" /> (2)
</property>
</service>
| 1 | iplass-ee-aws2 に同梱された設定を読み込み、Bedrock 関連のメタデータクラス・サービスを登録します。 |
| 2 | このサンプルが利用する AI プロバイダ名です。インポートするプロンプト定義・データ連携定義の providerName と一致させます。 |
プロンプト定義(Bedrock Converse・Knowledge Base)とデータ連携定義(S3 への出力)の設定項目の詳細は、開発者ガイドのAWSプラットフォームおよびデータ連携先(AWS)を参照してください。
2. 問合せの AI 機能
問合せに対する AI 機能として、投稿内容からの要約生成と、タグの自動付与を提供します。
2.1. AI の呼び出し
AI の呼び出しは、共通のユーティリティに集約しています。プロンプト定義名と、プロンプトのプレースホルダに渡す値(bindings)を指定して呼び出します。
ファイル名 |
/src/main/java/km/common/util/ai/AiInvoker.java |
|---|
public static AiPlatformResponse invoke(
String definitionName, Map<String, Object> bindings, AiPlatformPayload... payloads) {
AiManager ai = ManagerLocator.getInstance().getManager(AiManager.class);
AiPlatformRequest req = AiPlatformRequest.of(payloads);
if (bindings != null && !bindings.isEmpty()) {
req.setBindings(new HashMap<>(bindings)); (1)
}
return ai.request(definitionName, req); (2)
}
| 1 | プロンプト内のプレースホルダ(${…})に渡す値です。 |
| 2 | プロンプト定義名を指定して AI を実行します。 |
2.2. 問合せの要約生成
要約は、構造化出力(JSON Schema)を使うプロンプトで生成します。
プロンプト定義名 |
km/ai/inquiry/summary |
|---|---|
ファイル名 |
/src/main/java/km/inquiry/command/ai/InquirySummaryGenerateCommand.java |
aiResponse = AiInvoker.invoke(
AI_PROMPT_DEFINITION_NAME,
Map.of(PLACEHOLDER_INQUIRY_BODY, String.join("\n\n---\n\n", postContents))); (1)
// ...
JsonNode node = JSON.readTree(aiResponse.getText()); (2)
summaryShort = AiResponseText.normalizeLineBreaks(node.get("summaryShort").asText()); (3)
summaryDetail = AiResponseText.normalizeLineBreaks(node.get("summaryDetail").asText());
| 1 | 全投稿を連結したテキストをプレースホルダに渡します。 |
| 2 | 構造化出力の応答(JSON)をパースします。 |
| 3 | AI が改行を <br> で返すことがあるため、実際の改行へ正規化してから保存します。 |
プロンプト定義は、構造化出力の JSON Schema を持ちます。
ファイル名 |
/metadata-import/prompt.xml |
|---|
<platform xsi:type="metaAiPlatformBedrock">
<providerName>bedrock</providerName>
<platformType>BEDROCK</platformType>
<structuredOutputConfig>
<jsonSchema>{
"type": "object",
"properties": {
"summaryShort": { "type": "string" },
"summaryDetail": { "type": "string" }
},
"required": ["summaryShort", "summaryDetail"],
"additionalProperties": false
}</jsonSchema>
<name>InquirySummaryResult</name>
</structuredOutputConfig>
<modelId>google.gemma-3-12b-it</modelId>
</platform>
2.3. 問合せのタグ自動付与
回答の投稿などをきっかけに、問合せのタグを自動付与します(プロンプト定義 km/ai/inquiry/tag-suggest)。AI にタグの候補(タグマスタ)を渡し、応答で選ばれたタグをマスタと照合する、という共通処理にまとめています(TagSuggestionUtil)。
要約やタグ付与は、問合せ・投稿の登録処理が完了した後に、付随処理として起動します(AiAutoTrigger)。AI の呼び出しに失敗しても、本体の登録処理は中断しません。
|
3. ナレッジの AI 機能
ナレッジに対する AI 機能として、問合せからのナレッジドラフト生成、タグの自動付与、複数ナレッジのマージドラフト生成を提供します。いずれも構造化出力(JSON Schema)を使うプロンプトで生成します。
| 機能 | プロンプト定義名 | Command |
|---|---|---|
ナレッジドラフトの生成 |
|
|
タグの自動付与 |
|
|
マージドラフトの生成 |
|
|
-
ナレッジドラフトの生成では、もとにする問合せの投稿内容をプレースホルダに渡し、構造化出力でタイトル(
name)と本文(課題・解決)のドラフトを受け取ります。ドラフトはその場では保存せず、回答者がナレッジ管理画面で確認・編集してから登録します。ファイル名
/src/main/java/km/knowledge/command/ai/KnowledgeGenerateCommand.java
aiResponse = AiInvoker.invoke( AI_PROMPT_DEFINITION_NAME, Map.of(PLACEHOLDER_INQUIRY_BODY, String.join("\n\n---\n\n", postContents))); (1) JsonNode node = JSON.readTree(aiResponse.getText()); String name = requireNonEmptyText(node, "name"); String question = requireNonEmptyText(node, "question"); (2) String solution = requireNonEmptyText(node, "solution"); // 課題・解決を Markdown 見出しで1つの本文に結合し、改行を正規化する String content = HEADING_QUESTION + "\n\n" + AiResponseText.normalizeLineBreaks(question) + "\n\n" + HEADING_SOLUTION + "\n\n" + AiResponseText.normalizeLineBreaks(solution); (3)1 全投稿を連結したテキストをプレースホルダに渡します。AI 呼び出しの型は問合せの AI 機能と同じです。 2 構造化出力(JSON)から、タイトルと課題・解決の本文を取り出します。タグは別のプロンプト( tag-suggest)で付与するため、ここには含まれません。3 課題・解決を Markdown 見出しで1つのナレッジ文に結合し、改行を正規化します。 -
マージドラフトの生成では、選択した複数のナレッジを入力に、統合後のナレッジ文のドラフトを生成します。マージ後、もとのナレッジは統合先への参照(
mergedTo)を持ち、検索結果から除外されます(全文検索参照)。
| 構造化出力の受け取り方(JSON のパース・改行の正規化)は問合せの AI 機能と同じです。問合せの AI 機能を参照してください。 |
4. RAG 検索・類似ナレッジ提案
ナレッジ検索(RAG)と、問合せ画面での類似ナレッジ提案は、Bedrock の Knowledge Base(RetrieveAndGenerate API)を利用します。自由文の質問に対し、AI がナレッジを検索して回答を生成し、参照元(引用元)のナレッジを返します。
4.1. データ連携(ナレッジ → S3)
Knowledge Base のデータソースは S3 です。ナレッジの更新を JSON 化して S3 へ出力する連携を、データ連携定義(AiDataConnectDefinition)で構成します。
ファイル名 |
/metadata-import/dataconnect.xml |
|---|
<source xsi:type="metaAiDataEqlSource">
<eql>SELECT oid, name, content, tags.tagName, visibility FROM km.knowledge.Knowledge</eql> (1)
</source>
<destination xsi:type="metaAiDataJsonS3Destination">
<bucketName>(S3 バケット名)</bucketName>
<prefix>knowledge/</prefix>
<objectKeyGenerateSetting>
<injectType>SCRIPT</injectType>
<script>attr.uniqueId + ".json"</script> (2)
</objectKeyGenerateSetting>
</destination>
| 1 | S3 へ出力するナレッジを EQL で抽出します。 |
| 2 | knowledge/{oid}.json というキーで出力します。この規約が、後述の引用元の逆引きの根拠になります。 |
4.2. RAG の呼び出しと引用元の解決
RAG では、AI が生成した回答テキストと、引用元のナレッジ(S3 オブジェクト)を受け取ります。引用元の S3 URI から OID を逆引きして、参照元ナレッジへのリンクを作ります。
プロンプト定義名 |
km/ai/knowledge/ask |
|---|---|
ファイル名 |
/src/main/java/km/knowledge/command/ai/KnowledgeRagSearchCommand.java |
aiResponse = AiInvoker.invoke(AI_PROMPT_DEFINITION_NAME, Map.of(PLACEHOLDER_QUERY, query)); (1)
// ...
String answer = aiResponse.getText(); (2)
answer = AiResponseText.normalizeLineBreaks(answer);
List<String> citationOids = KnowledgeSourceLocator.extractCitationOids(aiResponse); (3)
| 1 | 自由文の質問をプレースホルダに渡して RAG を実行します。 |
| 2 | 生成された回答テキストです。 |
| 3 | 引用元の S3 URI から、ナレッジの OID を逆引きします。 |
引用元の解決は、RAG 応答に含まれる引用情報から S3 URI を辿り、knowledge/{oid}.json の OID を取り出します。
ファイル名 |
/src/main/java/km/common/util/ai/KnowledgeSourceLocator.java |
|---|
kbResponse.citations().forEach(citation -> citation.retrievedReferences()
.forEach(ref -> {
String s3Uri = ref.location().s3Location().uri();
String extracted = extractOid(s3Uri); (1)
if (extracted != null) { oids.add(extracted); }
}));
| 1 | S3 URI(s3://…/knowledge/{oid}.json)から OID を取り出します。 |
4.3. 類似ナレッジ提案
問合せ画面の類似ナレッジ提案(プロンプト定義 km/ai/inquiry/knowledge-suggest)も、同じく Knowledge Base を利用します。問合せ内容を質問として検索し、引用元のナレッジを提案として表示します。質問者には外部公開ナレッジのみを提案するよう、ロールに応じて結果を絞り込みます。
| RAG・類似ナレッジ提案で参照されるのはナレッジ本文です。検索の鮮度は、データ連携(S3 への出力)と Knowledge Base の同期に依存します。 |