4.1
Enterprise Edition機能の追加パッケージ

このパッケージで提供する機能はすべて Enterprise Edition の機能です。
Enterprise Editionのサンプルアプリでは、Amazon Bedrock と連携した AI 機能を提供します。

1. セットアップ

AI 機能は、iPLAss EE の AWS 連携モジュールを介して Amazon Bedrock を呼び出します。要約・タグ付与・ドラフト生成・マージは Bedrock Converse API(構造化出力)を、RAG 検索・類似ナレッジ提案は Knowledge Base(RetrieveAndGenerate API)を利用します。
利用するには、次の手順で追加パッケージの取り込みと Bedrock 連携設定を行います。

  1. 有償版の SDK に同梱されている Enterprise Edition 機能の追加パッケージ iplass-ee-sample-app-km-package.zip を取得します。このパッケージには、Community Edition には含まれない AI 機能のメタデータ(プロンプト定義・データ連携定義)が含まれます。

  2. 作成済のテナントで、Admin Console の Packaging 機能を利用して追加パッケージをインポートします。

    環境固有の値(Knowledge Base ID・S3 バケット名)は、インポート後に利用する環境の値へ書き換えてください。
    詳細については、パッケージ内のREADMEを参照してください。
  3. 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

ナレッジドラフトの生成

km/ai/knowledge/generate

KnowledgeGenerateCommand

タグの自動付与

km/ai/knowledge/tag-suggest

KnowledgeTagSuggestCommand

マージドラフトの生成

km/ai/knowledge/merge

KnowledgeMergeCommand

  • ナレッジドラフトの生成では、もとにする問合せの投稿内容をプレースホルダに渡し、構造化出力でタイトル(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 の同期に依存します。