다음을 통해 공유


자습서: Azure OpenAI 및 Azure AI Search를 사용하여 Azure App Service에서 검색 강화 생성 앱 만들기(Spring Boot)

이 자습서에서는 Spring Boot, Azure OpenAI 및 Azure AI Search를 사용하여 RAG(Java Retrieval Augmented Generation) 애플리케이션을 만들고 Azure App Service에 배포합니다. 이 애플리케이션은 사용자 고유의 문서에서 정보를 검색하고 Azure AI 서비스를 활용하여 적절한 인용을 통해 정확하고 상황에 맞는 답변을 제공하는 채팅 인터페이스를 구현하는 방법을 보여 줍니다. 이 솔루션은 서비스 간 암호 없는 인증에 관리 ID를 사용합니다.

팁 (조언)

이 자습서에서는 Spring Boot를 사용하지만 Azure OpenAI 및 Azure AI Search를 사용하여 RAG 애플리케이션을 빌드하는 핵심 개념은 Java 웹 애플리케이션에 적용됩니다. Tomcat 또는 JBoss EAP와 같은 App Service에서 다른 호스팅 옵션을 사용하는 경우 여기에 표시된 인증 패턴 및 Azure SDK 사용량을 기본 프레임워크에 적용할 수 있습니다.

소개의 Spring Boot 채팅 인터페이스를 보여 주는 스크린샷.

이 튜토리얼에서는 다음을 배우게 됩니다:

  • Azure AI 서비스에서 RAG 패턴을 사용하는 Spring Boot 애플리케이션을 배포합니다.
  • 하이브리드 검색을 위해 Azure OpenAI 및 Azure AI Search를 구성합니다.
  • AI 기반 애플리케이션에서 사용할 문서를 업로드하고 인덱싱합니다.
  • 보안 서비스 간 통신에 관리 ID를 사용합니다.
  • 프로덕션 서비스를 사용하여 RAG 구현을 로컬로 테스트합니다.

아키텍처 개요

배포를 시작하기 전에 빌드할 애플리케이션의 아키텍처를 이해하는 것이 유용합니다. 다음 다이어그램은 Azure AI Search에 대한 사용자 지정 RAG 패턴에서 가져옵니다.

Storage를 데이터 원본으로 사용하여 Azure OpenAI 및 Azure AI Search에 연결하는 웹앱을 보여 주는 아키텍처 다이어그램

이 자습서에서는 App Service의 Blazer 애플리케이션이 앱 UX와 앱 서버를 모두 처리합니다. 그러나 Azure AI Search에 대한 별도의 지식 쿼리는 만들지 않습니다. 대신 Azure OpenAI에 Azure AI Search를 데이터 원본으로 지정하는 지식 쿼리를 수행하도록 지시합니다. 이 아키텍처는 다음과 같은 몇 가지 주요 이점을 제공합니다.

  • 통합 벡터화: Azure AI Search의 통합 벡터화 기능을 사용하면 포함을 생성하기 위해 더 많은 코드를 요구하지 않고도 검색을 위해 모든 문서를 쉽고 빠르게 수집할 수 있습니다.
  • 간소화된 API 액세스: Azure OPENAI 완성을 위한 데이터 원본으로 Azure AI Search와 함께 Azure OpenAI On Your Data 패턴을 사용하면 복잡한 벡터 검색 또는 포함 생성을 구현할 필요가 없습니다. 단 하나의 API 호출이며 Azure OpenAI는 프롬프트 엔지니어링 및 쿼리 최적화를 포함하여 모든 것을 처리합니다.
  • 고급 검색 기능: 통합 벡터화는 키워드 일치, 벡터 유사성 및 AI 기반 순위의 장점을 결합한 의미 체계 재전송과 함께 고급 하이브리드 검색에 필요한 모든 것을 제공합니다.
  • 전체 인용 지원: 응답에는 원본 문서에 대한 인용이 자동으로 포함되므로 정보를 확인하고 추적할 수 있습니다.

필수 조건

1. Codespaces를 사용하여 샘플 열기

시작하는 가장 쉬운 방법은 모든 필수 도구가 미리 설치된 완전한 개발 환경을 제공하는 GitHub Codespaces를 사용하는 것입니다.

  1. GitHub 리포지토리의 https://github.com/Azure-Samples/app-service-rag-openai-ai-search-java로 이동하세요.

  2. 코드 단추를 선택하고, 코드스페이스 탭을 선택하고, 기본에서 코드스페이스 만들기를 클릭합니다.

  3. Codespace가 초기화되기까지 잠시 기다립니다. 준비가 되면 브라우저에 완전히 구성된 VS Code 환경이 표시됩니다.

2. 샘플 아키텍처 배포

  1. 터미널에서 Azure 개발자 CLI를 사용하여 Azure에 로그인합니다.

    azd auth login
    

    지침에 따라 인증 프로세스를 완료합니다.

  2. AZD 템플릿을 사용하여 Azure 리소스를 프로비전합니다.

    azd provision
    
  3. 메시지가 표시되면 다음 답변을 제공합니다.

    질문 답변
    새 환경 이름을 입력합니다. 고유한 이름을 입력합니다.
    사용할 Azure 구독을 선택합니다. 구독을 선택합니다.
    사용할 리소스 그룹을 선택합니다. 새 리소스 그룹 만들기를 선택합니다.
    리소스 그룹을 만들 위치를 선택합니다. 지역을 선택합니다. 리소스는 실제로 미국 동부 2에서 만들어집니다.
    새 리소스 그룹의 이름을 입력합니다. Enter 키를 누르세요.
  4. 배포가 완료되기를 기다립니다. 이 프로세스는 다음과 같습니다.

    • 필요한 모든 Azure 리소스를 만듭니다.
    • Azure App Service에 Blazor 애플리케이션을 배포합니다.
    • 관리 ID를 사용하여 보안 서비스 대 서비스 인증을 구성합니다.
    • 서비스 간의 보안 액세스를 위해 필요한 역할 할당을 설정합니다.

    비고

    관리 ID의 작동 방식에 대한 자세한 내용은 Azure 리소스에 대한 관리 ID란?App Service에서 관리 ID를 사용하는 방법을 참조하세요.

  5. 배포에 성공하면 배포된 애플리케이션에 대한 URL이 표시됩니다. 이 URL을 기록해 두지만 검색 인덱스도 설정해야 하므로 아직 액세스하지 마세요.

3. 문서 업로드 및 검색 인덱스 만들기

인프라가 배포되었으므로 문서를 업로드하고 애플리케이션에서 사용할 검색 인덱스는 만들어야 합니다.

  1. Azure Portal에서 배포에서 만든 스토리지 계정으로 이동합니다. 이름은 이전에 제공한 환경 이름으로 시작됩니다.

  2. 왼쪽 탐색 메뉴에서 컨테이너 를 선택하고 문서 컨테이너를 엽니다.

  3. 업로드를 클릭하여 샘플 문서를 업로드합니다. 리포지토리의 폴더 또는 사용자 고유의 sample-docs PDF, Word 또는 텍스트 파일에서 샘플 문서를 사용할 수 있습니다.

    스토리지 컨테이너에 문서를 업로드하는 방법을 보여 주는 스크린샷

  4. Azure Portal에서 Azure AI Search 서비스로 이동합니다.

  5. 데이터 가져오기 및 벡터화를 선택하여 검색 인덱스 만들기 프로세스를 시작합니다.

    Azure AI Search의 데이터 가져오기 및 벡터화 단추를 보여 주는 스크린샷

  6. 데이터 연결 단계에서 다음을 수행합니다.

    • 데이터 원본으로 Azure Blob Storage 를 선택합니다.
    • RAG을 선택합니다.
    • 스토리지 계정 및 문서 컨테이너를 선택합니다.
    • 관리 ID를 사용하여 인증이 선택되어 있는지 확인합니다.
    • 다음을 선택합니다.
  7. 텍스트 벡터화 단계에서 다음을 수행합니다.

    • Azure OpenAI 서비스를 선택합니다.
    • 포함 모델로 text-embedding-ada-002를 선택합니다. AZD 템플릿은 이미 이 모델을 배포했습니다.
    • 인증을 위해 시스템 할당 ID 를 선택합니다.
    • 추가 비용에 대한 승인 확인란을 체크하십시오.
    • 다음을 선택합니다.

    팁 (조언)

    Azure AI Search에서의 벡터 검색 및 Azure OpenAI에서의 텍스트 임베딩에 대해 자세히 알아보세요.

  8. 벡터화 및 이미지 보강 단계에서 다음 단계를 수행합니다.

    • 기본 설정을 유지합니다.
    • 다음을 선택합니다.
  9. 고급 설정 단계에서 다음을 수행합니다.

    • 의미 체계 순위 사용이 선택되어 있는지 확인합니다.
    • (선택 사항) 인덱싱 일정을 선택합니다. 이 기능은 최신 파일 변경 내용으로 인덱스 정기적으로 새로 고치려는 경우에 유용합니다.
    • 다음을 선택합니다.
  10. 검토 및 만들기 단계에서 다음을 수행합니다.

    • 개체 이름 접두사 값을 복사합니다. 검색 인덱스 이름입니다.
    • 만들기를 선택하여 인덱싱 프로세스를 시작합니다.
  11. 인덱싱 프로세스가 완료되기를 기다립니다. 문서의 크기와 수에 따라 몇 분 정도 걸릴 수 있습니다.

  12. 데이터 가져오기를 테스트하려면 검색 시작을 선택하고 "회사에 대해 알려주세요"와 같은 검색 쿼리를 시도합니다.

  13. Codespace 터미널로 돌아가서 검색 인덱스 이름을 AZD 환경 변수로 설정합니다.

    azd env set SEARCH_INDEX_NAME <your-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를 엽니다. 터미널 출력을 사용하여 각 자리 표시자에서 다음 값을 업데이트합니다 <input-manually-for-local-testing>.

    • 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 채팅 완료의 결과에서 인용을 어떻게 검색하는지 보여줍니다.

샘플은 채팅 클라이언트의 AzureSearchChatExtensionConfiguration 데이터 원본으로 사용하여 인용을 검색합니다. 채팅 완료가 요청되면 응답에 메시지 컨텍스트 내의 Citations 개체가 포함됩니다. 코드는 다음과 같이 이러한 인용을 추출합니다.

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;
}

채팅 응답에서 콘텐츠는 표기법을 사용하여 [doc#] 목록에서 해당 인용을 참조하여 사용자가 원래 원본 문서로 정보를 다시 추적할 수 있도록 합니다. 자세한 내용은 다음을 참조하세요.


이 솔루션에서 관리 ID를 사용할 경우의 이점은 무엇인가요?

관리 ID는 코드 또는 구성에 자격 증명을 저장할 필요가 없습니다. 애플리케이션은 관리 ID를 사용하여 비밀을 관리하지 않고도 Azure OpenAI 및 Azure AI Search와 같은 Azure 서비스에 안전하게 액세스할 수 있습니다. 이 방법은 제로 트러스트 보안 원칙을 따르고 자격 증명 노출 위험을 줄입니다.


이 아키텍처 및 샘플 애플리케이션에서 시스템 할당 관리 ID는 어떻게 사용합니까?

AZD 배포는 Azure App Service, Azure OpenAI 및 Azure AI Search에 대한 시스템 할당 관리 ID를 만듭니다. 또한 각각의 역할에 맞는 할당을 수행합니다. (파일 참조: main.bicep) 필요한 역할 할당에 대한 자세한 내용은 Azure OpenAI On Your Data에 대한 네트워크 및 액세스 구성을 참조하세요.

샘플 Java 애플리케이션에서 Azure SDK는 보안 인증에 이 관리 ID를 사용하므로 자격 증명 또는 비밀을 어디에도 저장할 필요가 없습니다. 예를 들어, Azure에서 실행될 때 관리 ID를 자동으로 사용하는 OpenAIAsyncClientDefaultAzureCredential가 초기화됩니다.

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

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

마찬가지로 Azure AI Search에 대한 데이터 원본을 구성할 때 인증을 위해 관리 ID가 지정됩니다.

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

이 설정을 사용하면 Zero Trust 보안 모범 사례에 따라 Spring Boot 앱과 Azure 서비스 간에 안전하고 암호 없는 통신을 수행할 수 있습니다. Java용 DefaultAzureCredentialAzure Identity 클라이언트 라이브러리에 대해 자세히 알아봅니다.


샘플 애플리케이션에서 의미 체계 순위가 있는 하이브리드 검색은 어떻게 구현되는가?

샘플 애플리케이션은 Azure OpenAI 및 Azure AI Search 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");

이 구성을 사용하면 애플리케이션이 단일 쿼리에서 벡터 검색(의미 체계 유사성), 키워드 일치 및 의미 체계 순위를 결합할 수 있습니다. 의미 체계 순위는 결과를 다시 정렬하여 가장 관련성이 있고 상황에 맞는 적절한 답변을 반환한 다음, Azure OpenAI에서 응답을 생성하는 데 사용됩니다.

의미 체계 구성 이름은 통합 벡터화 프로세스에 의해 자동으로 정의됩니다. 검색 인덱스 이름을 접두사로 사용하고 접미사로 추가합니다 -semantic-configuration . 이렇게 하면 의미 체계 구성이 해당 인덱스와 고유하게 연결되고 일관된 명명 규칙을 따릅니다.


모든 리소스가 미국 동부 2에서 만들어지는 이유는 무엇인가요?

이 샘플에서는 gpt-4o-minitext-embedding-ada-002 모델을 사용하며, 둘 다 미국 동부 2의 표준 배포 유형에서 사용할 수 있습니다. 이러한 모델은 곧 사용 중지될 예정이 아니기 때문에 선택되어 샘플 배포에 대한 안정성을 제공합니다. 모델 가용성 및 배포 유형은 지역에 따라 다를 수 있으므로 샘플이 기본적으로 작동하는지 확인하기 위해 미국 동부 2가 선택됩니다. 다른 지역 또는 모델을 사용하려면 동일한 지역에서 동일한 배포 유형에 사용할 수 있는 모델을 선택해야 합니다. 고유한 모델을 선택할 때 가용성 및 사용 중지 날짜를 모두 확인하여 중단을 방지합니다.


Azure에서 제공하는 모델 대신 내 고유의 OpenAI 모델을 사용할 수 있나요?

이 솔루션은 Azure OpenAI Service에서 작동하도록 설계되었습니다. 다른 OpenAI 모델을 사용하도록 코드를 수정할 수 있지만 통합 보안 기능, 관리 ID 지원 및 이 솔루션이 제공하는 Azure AI Search와의 원활한 통합이 손실됩니다.


응답 품질을 어떻게 개선할 수 있나요?

다음을 통해 응답 품질을 향상시킬 수 있습니다.

  • 더 높은 품질의 관련 문서를 업로드합니다.
  • Azure AI Search 인덱싱 파이프라인에서 청크 분할 전략 조정 그러나 이 자습서에 표시된 통합 벡터화를 사용하여 청크를 사용자 지정할 수는 없습니다.
  • 애플리케이션 코드에서 다양한 프롬프트 템플릿을 실험합니다.
  • AzureSearchChatExtensionParameters 클래스의 다른 속성을 사용하여 검색을 미세 조정합니다.
  • 특정 도메인에 보다 특수화된 Azure OpenAI 모델 사용

추가 리소스