次の方法で共有


チュートリアル: Azure OpenAI と Azure AI 検索 (Spring Boot) を使用して、Azure App Serviceで取得拡張生成アプリを構築する

このチュートリアルでは、Spring Boot、Azure OpenAI、Azure AI 検索を使用してJava取得拡張生成 (RAG) アプリケーションを作成し、Azure App Serviceにデプロイします。 このアプリケーションは、独自のドキュメントから情報を取得し、Azureで AI サービスを活用して、適切な引用で正確でコンテキストに対応した回答を提供するチャット インターフェイスを実装する方法を示します。 このソリューションでは、サービス間のパスワードレス認証にマネージド ID を使用します。

ヒント

このチュートリアルでは Spring Boot を使用しますが、OpenAI と Azure AI 検索 Azureを使用して RAG アプリケーションを構築する主要な概念は、任意のJava Web アプリケーションに適用されます。 Tomcat や JBoss EAP など、App Service で別のホスティング オプションを使用している場合は、ここで示す認証パターンとAzure SDKの使用を好みのフレームワークに合わせて調整できます。

概要の Spring Boot チャット インターフェイスを示すスクリーンショット。

このチュートリアルでは、以下の内容を学習します。

  • AZUREの AI サービスで RAG パターンを使用する Spring Boot アプリケーションをデプロイします。
  • ハイブリッド検索Azure OpenAI とAzure AI 検索を構成します。
  • AI を利用したアプリケーションで使用するドキュメントをアップロードしてインデックスを作成します。
  • セキュリティで保護されたサービス間通信にはマネージド ID を使用します。
  • 運用サービスを使用して、RAG 実装をローカルでテストします。

アーキテクチャの概要

デプロイを開始する前に、ビルドするアプリケーションのアーキテクチャを理解しておくと役立ちます。 次の図は、Azure AI 検索の Custom RAG パターンから取得したものです。

ストレージをデータ ソースとしてAzure OpenAI とAzure AI 検索に接続する Web アプリを示すアーキテクチャ図

このチュートリアルでは、App Service のブレイザー アプリケーションがアプリ UX とアプリ サーバーの両方を処理します。 ただし、Azure AI 検索に対して個別の知識クエリは行われません。 代わりに、Azure AI 検索をデータ ソースとして指定してナレッジ クエリを実行するように OpenAI Azureに指示します。 このアーキテクチャには、いくつかの主な利点があります。

  • Integrated Vectorization: Azure AI 検索の統合されたベクター化機能により、埋め込みを生成するためのコードを追加しなくても、すべてのドキュメントを簡単かつ迅速に検索に取り込めます。
  • Simplified API Access: Azure OpenAI On Your Data パターンを使用して、Azure OpenAI 補完のデータ ソースとしてAzure AI 検索を使用することで、複雑なベクター検索や埋め込み生成を実装する必要はありません。 1 回の API 呼び出しだけで、Azure OpenAI がプロンプト エンジニアリングやクエリの最適化など、すべてを処理します。
  • 高度な検索機能: 統合されたベクター化は、高度なハイブリッド検索に必要なすべてのものをセマンティック 再ランク付けと共に提供します。これは、キーワード マッチング、ベクター類似性、AI を利用したランク付けの長所を組み合わせたものです。
  • 引用文献の完全なサポート: 応答には、ソース ドキュメントへの引用文献が自動的に含まれ、情報が検証可能で追跡可能になります。

[前提条件]

1. Codespaces を使用してサンプルを開く

開始する最も簡単な方法は、GitHub Codespaces を使用することです。Codespaces は、必要なすべてのツールがプレインストールされた完全な開発環境を提供します。

  1. https://github.com/Azure-Samples/app-service-rag-openai-ai-search-java にあるGitHub リポジトリに移動します。

  2. [ コード ] ボタンを選択し、[ Codespaces ] タブを選択し、[ メインでコードスペースの作成] をクリックします。

  3. Codespace が初期化されるまでしばらく待ちます。 準備ができたら、ブラウザーに完全に構成された VS Code 環境が表示されます。

2. サンプル アーキテクチャをデプロイする

  1. ターミナルで、Azure Developer CLI を使用してAzureにログインします。

    azd auth login
    

    手順に従って認証プロセスを完了します。

  2. AZD テンプレートを使用してAzure リソースをプロビジョニングします。

    azd provision
    
  3. メッセージが表示されたら、次の回答を入力します。

    質問 答え
    新しい環境名を入力します。 一意の名前を入力します。
    使用するAzure サブスクリプションを選択します。 サブスクリプションを選択します。
    使用するリソース グループを選択します。 [Create a new resource group]\(新しいリソース グループの作成\) を選択します。
    リソース グループを作成する場所を選択します。 任意のリージョンを選択します。 リソースは実際には 米国東部 2 に作成されます。
    新しいリソース グループの名前を入力します。 「Enter」と入力します。
  4. デプロイが完了するまで待ちます。 このプロセスでは、次の処理が行われます。

    • 必要なすべてのAzure リソースを作成します。
    • アプリケーションを Azure App Service にデプロイします。
    • マネージド ID を使用してセキュリティで保護されたサービス間認証を構成します。
    • サービス間のセキュリティで保護されたアクセスに必要なロールの割り当てを設定します。

    マネージド ID のしくみの詳細については、「Azure リソースのマネージド ID とは何ですか?>」および「 App Service でマネージド ID を使用する方法を参照してください。

  5. デプロイが成功すると、デプロイされたアプリケーションの URL が表示されます。 この URL は書き留めておきますが、検索インデックスを設定する必要があるため、まだアクセスしないでください。

3. ドキュメントをアップロードして検索インデックスを作成する

インフラストラクチャがデプロイされたので、ドキュメントをアップロードし、アプリケーションで使用する検索インデックスを作成する必要があります。

  1. Azure ポータルで、デプロイによって作成されたストレージ アカウントに移動します。 この名前は、前に指定した環境名で始まります。

  2. 左側のナビゲーション メニューから [データ ストレージContainers ] を選択し、 ドキュメント コンテナーを開きます。

  3. [アップロード] をクリックしてサンプル ドキュメントを アップロードします。 リポジトリ内の sample-docs フォルダーのサンプル ドキュメント、または独自の PDF、Word、またはテキスト ファイルを使用できます。

    ストレージ コンテナーにドキュメントをアップロードする方法を示すスクリーンショット。

  4. Azure ポータルでAzure AI 検索 サービスに移動します。

  5. [ データのインポート ](新規) を選択して、検索インデックスの作成プロセスを開始します。

    Azure AI 検索 の [データのインポートとベクター化] ボタンを示すスクリーンショット

  6. [ データへの接続] ステップで、次の操作を行います 。

    • データ ソースとして Azure Blob Storage を選択します。
    • RAG を選択します。
    • ストレージ アカウントと ドキュメント コンテナーを選択します。
    • [ マネージド ID を使用した認証] を選択します。
    • [次へ] を選択します。
  7. テキストのベクター化ステップで、 次の操作を行います 。

    • Azure OpenAI サービスを選択します。
    • 埋め込みモデルとして text-embedding-ada-002 を選択します。 AZD テンプレートでは、このモデルが既にデプロイされています。
    • 認証に システム割り当て ID を 選択します。
    • 追加コストの確認チェック ボックスをオンにします。
    • [次へ] を選択します。

    ヒント

    Azure AI 検索 Azure OpenAI でのテキスト埋め込みの詳細について説明します。

  8. [Vectorize and enrich your images]\(イメージのベクター化とエンリッチメント\) ステップで、次の操作を行います。

    • 既定の設定のままにします。
    • [次へ] を選択します。
  9. [詳細設定] ステップで、次の操作を行います。

    • [セマンティック ランカーを有効にする] が選択されていることを確認します。
    • (省略可能)インデックス作成スケジュールを選択します。 これは、最新のファイル変更でインデックスを定期的に更新する場合に便利です。
    • [次へ] を選択します。
  10. [ 確認と作成 ] 手順で、次の手順を実行します。

    • オブジェクト名のプレフィックス値をコピーします。 検索インデックス名です。
    • [ 作成] を選択してインデックス作成プロセスを開始します。
  11. インデックス作成プロセスが完了するまで待ちます。 ドキュメントのサイズと数によっては、数分かかる場合があります。

  12. データのインポートをテストするには、[検索を開始] を選択し、"会社について教えてください" などの検索クエリを試します。

  13. Codespace ターミナルに戻り、検索インデックス名を AZD 環境変数として設定します。

    azd env set SEARCH_INDEX_NAME <your-search-index-name>
    

    は、前にコピーしたインデックス名に置き換えます。 AZD は、後続のデプロイでこの変数を使用して App Service アプリ設定を設定します。

4.アプリケーションをテストしてデプロイする

デプロイ前またはデプロイ後にアプリケーションをローカルでテストする場合は、Codespace から直接実行できます。

  1. Codespace ターミナルで、AZD 環境の値を取得します。

    azd env get-values
    
  2. src/main/resources/application.properties を開きます。 ターミナル出力を使用して、それぞれのプレースホルダー で、次の値を更新します。

    • azure.openai.endpoint
    • azure.search.url
    • azure.search.index.name
  3. Azure CLIを使用してAzureにサインインします。

    az login
    

    これにより、サンプル コードのAzure ID クライアント ライブラリは、ログインしているユーザーの認証トークンを受け取ることができます。

  4. アプリケーションをローカルで実行します。

    mvn spring-boot:run
    
  5. ポート 8080 で実行されているアプリケーションが表示されたら、[ブラウザーで開く] を選択します。

  6. チャット インターフェイスでいくつかの質問をしてみてください。 応答が返された場合、アプリケーションは Azure OpenAI リソースに正常に接続しています。

  7. Ctrl + C キーを押して開発サーバーを停止します。

  8. Azureで新しい SEARCH_INDEX_NAME 構成を適用し、サンプル アプリケーション コードをデプロイします。

    azd up
    

5. デプロイされた RAG アプリケーションをテストする

アプリケーションが完全にデプロイされ、構成されたので、RAG 機能をテストできるようになりました。

  1. デプロイの最後に指定されたアプリケーション URL を開きます。

  2. アップロードしたドキュメントの内容に関する質問を入力できるチャット インターフェイスが表示されます。

    Blazor チャット インターフェイスを示すスクリーンショット。

  3. ドキュメントの内容に固有の質問をしてみてください。 たとえば、 sample-docs フォルダーにドキュメントをアップロードした場合は、次の質問を試すことができます。

    • Contoso は個人データをどのように使用しますか?
    • 保証請求はどのように行いますか?
  4. 応答に、ソース ドキュメントを参照する引用文献が含まれていることがわかります。 これらの引用は、ユーザーが情報の正確性を確認し、ソース資料の詳細を見つけるのに役立ちます。

    ソース ドキュメントへの引用を含む応答を示すスクリーンショット。

  5. さまざまな検索方法のメリットを得られる可能性のある質問をして、ハイブリッド検索機能をテストします。

    • 特定の用語を含む質問 (キーワード検索に適しています)。
    • 異なる用語を使用して記述される可能性のある概念に関する質問 (ベクター検索に適しています)。
    • コンテキストを理解する必要がある複雑な質問 (セマンティック ランク付けに適しています)。

リソースをクリーンアップする

アプリケーションの使用が完了したら、すべてのリソースを削除して、追加のコストが発生しないようにすることができます。

azd down --purge

このコマンドは、アプリケーションに関連付けられているすべてのリソースを削除します。

よく寄せられる質問


サンプルコードは、Azure OpenAIチャットの完了から引用情報を取得する方法を示します。

このサンプルでは、チャット クライアントのデータ ソースとして を使用して引用文献を取得します。 チャットの完了が要求されると、応答にはメッセージ コンテキスト内に オブジェクトが含まれます。 このコードでは、次のようにこれらの引用文献が抽出されます。

public static ChatResponse fromChatCompletions(ChatCompletions completions) {
    ChatResponse response = new ChatResponse();
    
    if (completions.getChoices() != null && !completions.getChoices().isEmpty()) {
        var message = completions.getChoices().get(0).getMessage();
        if (message != null) {
            response.setContent(message.getContent());

            if (message.getContext() != null && message.getContext().getCitations() != null) {
                var azureCitations = message.getContext().getCitations();
                for (int i = 0; i < azureCitations.size(); i++) {
                    var azureCitation = azureCitations.get(i);
                    
                    Citation citation = new Citation();
                    citation.setIndex(i + 1);
                    citation.setTitle(azureCitation.getTitle());
                    citation.setContent(azureCitation.getContent());
                    citation.setFilePath(azureCitation.getFilepath());
                    citation.setUrl(azureCitation.getUrl());
                    
                    response.getCitations().add(citation);
                }
            }
        }
    }
    
    return response;
}

チャット応答では、コンテンツは 表記を使用してリスト内の対応する引用文献を参照し、ユーザーは元のソース ドキュメントに情報をトレースできます。 詳細については、以下を参照してください。


このソリューションでマネージド ID を使用する利点は何ですか?

マネージド ID を使用すると、コードまたは構成に資格情報を格納する必要がなくなります。 マネージド ID を使用することで、アプリケーションはシークレットを管理することなく、Azure OpenAI や Azure AI 検索 などのAzure サービスに安全にアクセスできます。 この方法はゼロ トラストセキュリティ原則に従い、資格情報の公開のリスクを軽減します。


このアーキテクチャとサンプル アプリケーションでは、システム割り当てマネージド ID はどのように使用されますか?

AZD デプロイでは、Azure App Service、Azure OpenAI、およびAzure AI 検索のシステム割り当てマネージド ID が作成されます。 また、それぞれのロールの割り当てを行います ( main.bicep ファイルを参照)。 必要なロールの割り当ての詳細については、「データ上の OpenAI Azureのネットワーク構成とアクセス構成を参照してください。

サンプル Java アプリケーションでは、Azure SDKはセキュリティで保護された認証にこのマネージド ID を使用するため、資格情報やシークレットをどこにも格納する必要はありません。 たとえば、OpenAIAsyncClientDefaultAzureCredential で初期化され、Azureで実行するときにマネージド ID が自動的に使用されます。

@Bean
public TokenCredential tokenCredential() {
   return new DefaultAzureCredentialBuilder().build();
}

@Bean
public OpenAIAsyncClient openAIClient(TokenCredential tokenCredential) {
   return new OpenAIClientBuilder()
         .endpoint(openAiEndpoint)
         .credential(tokenCredential)
         .buildAsyncClient();
}

同様に、Azure AI 検索用にデータ ソースを構成する場合、マネージド ID は認証用に指定されます。

AzureSearchChatExtensionConfiguration searchConfiguration =
   new AzureSearchChatExtensionConfiguration(
      new AzureSearchChatExtensionParameters(appSettings.getSearch().getUrl(), appSettings.getSearch().getIndex().getName())
         .setAuthentication(new OnYourDataSystemAssignedManagedIdentityAuthenticationOptions())
         // ...
   );

このセットアップにより、ゼロ トラストセキュリティのベスト プラクティスに従って、Spring Boot アプリとAzure サービス間の安全でパスワードなしの通信が可能になります。 DefaultAzureCredentialAzure Identity client library for Java について説明します。


サンプル アプリケーションでセマンティック ランカーを使用したハイブリッド検索はどのように実装されますか?

サンプル アプリケーションでは、Azure OpenAI SDK と Azure AI 検索 Java SDK を使用して、セマンティック ランク付けを使用してハイブリッド検索を構成します。 バックエンドでは、データ ソースは次のように設定されます。

AzureSearchChatExtensionParameters parameters = new AzureSearchChatExtensionParameters(
   appSettings.getSearch().getUrl(),
   appSettings.getSearch().getIndex().getName())
    // ...
    .setQueryType(AzureSearchQueryType.VECTOR_SEMANTIC_HYBRID)
    .setEmbeddingDependency(new OnYourDataDeploymentNameVectorizationSource(appSettings.getOpenai().getEmbedding().getDeployment()))
    .setSemanticConfiguration(appSettings.getSearch().getIndex().getName() + "-semantic-configuration");

この構成により、アプリケーションはベクター検索 (セマンティック類似性)、キーワード マッチング、セマンティック ランク付けを 1 つのクエリで組み合わせることができます。 セマンティック ランカーは結果を並べ替えて、最も関連性が高くコンテキストに応じて適切な回答を返します。これは、Azure OpenAI によって応答を生成するために使用されます。

セマンティック構成名は、統合ベクター化プロセスによって自動的に定義されます。 検索インデックス名をプレフィックスとして使用し、サフィックスとして を追加します。 これにより、セマンティック構成が対応するインデックスに一意に関連付けられることが保証され、一貫した名前付け規則に従います。


すべてのリソースが米国東部 2 で作成される理由

このサンプルでは 、gpt-4o-mini モデルと text-embedding-ada-002 モデルを 使用します。どちらも米国東部 2 の Standard デプロイ タイプで使用できます。 これらのモデルは、すぐには退役させる予定がないため、サンプルデプロイの安定性を確保するために選ばれています。 モデルの可用性とデプロイの種類はリージョンによって異なることがあるため、サンプルがすぐに動作するように、米国東部 2 が選ばれています。 別のリージョンまたはモデルを使用する場合は、同じリージョン内の同じデプロイの種類で使用できるモデルを選択してください。 独自のモデルを選択する場合は、中断を回避するために、可用性と提供終了日の両方を確認します。


Azureが提供するモデルではなく、独自の OpenAI モデルを使用できますか?

このソリューションは、Azure OpenAI Serviceを使用するように設計されています。 他の OpenAI モデルを使用するようにコードを変更することもできますが、統合されたセキュリティ機能、マネージド ID のサポート、およびこのソリューションが提供するAzure AI 検索とのシームレスな統合は失われます。


応答の品質を向上させるにはどうすればよいですか?

次の方法で応答品質を向上させることができます。

  • より高品質で関連性の高いドキュメントをアップロードする。
  • Azure AI 検索インデックス作成パイプラインでのチャンク戦略の調整。 ただし、このチュートリアルで示す統合ベクター化を使用してチャンクをカスタマイズすることはできません。
  • アプリケーション コードでさまざまなプロンプト テンプレートを試す。
  • AzureSearchChatExtensionParameters クラスの他のプロパティを使用して検索を微調整します。
  • 特定のドメインに対してより特殊な Azure OpenAI モデルを使用する。

その他のリソース