Megosztás a következőn keresztül:


Oktatóanyag: Csevegőrobot létrehozása az Azure App Service-vel és az Azure OpenAI-val (Spring Boot)

Ebben az oktatóanyagban egy intelligens AI-alkalmazást fog létrehozni az Azure OpenAI java Spring Boot-alkalmazással való integrálásával és az Azure App Service-ben való üzembe helyezésével. Létre fog hozni egy Spring Boot-vezérlőt, amely lekérdezést küld az Azure OpenAI-nak, és elküldi a választ a böngészőnek.

Jótanács

Bár ez az oktatóanyag a Spring Bootot használja, az Azure OpenAI-val rendelkező csevegőalkalmazások létrehozásának alapvető fogalmai minden Java-webalkalmazásra érvényesek. Ha egy másik üzemeltetési lehetőséget használ az App Service-ben, például a Tomcatet vagy a JBoss EAP-t, az itt látható hitelesítési mintákat és Azure SDK-használatot az előnyben részesített keretrendszerhez igazíthatja.

Képernyőkép az Azure App Service-ben futó csevegőrobotról.

Ebben az oktatóanyagban a következőket sajátíthatja el:

  • Hozzon létre egy Azure OpenAI-erőforrást, és helyezzen üzembe egy nyelvi modellt.
  • Hozzon létre egy Spring Boot-alkalmazást, amely az Azure OpenAI-hoz csatlakozik.
  • Függőséginjektálás használata az Azure OpenAI-ügyfél konfigurálásához.
  • Telepítse az alkalmazást az Azure App Service-ben.
  • Jelszó nélküli biztonságos hitelesítés implementálása a fejlesztési környezetben és az Azure-ban is.

Előfeltételek

1. Azure OpenAI-erőforrás létrehozása

Ebben a szakaszban az Azure CLI-t fogja használni a GitHub Codespacesben egy Azure OpenAI-erőforrás létrehozásához.

  1. Jelentkezzen be a GitHub Codespacesbe a GitHub-fiókjával.

  2. Válassza a Üres csempén a Sablon használata lehetőséget, hogy létrehozzon egy új üres kódtér.

  3. A Codespace terminálban telepítse az Azure CLI-t.

    curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
    
  4. Jelentkezzen be az Azure-fiókjába.

    az login
    

    A hitelesítéshez kövesse a terminál utasításait.

  5. Környezeti változók beállításához adja meg az erőforráscsoport és az Azure OpenAI szolgáltatás nevét, és állítson be egy megfelelő Azure-régiót helyként.

    export RESOURCE_GROUP="<group-name>"
    export OPENAI_SERVICE_NAME="<azure-openai-name>"
    export APPSERVICE_NAME="<app-name>"
    export LOCATION="<azure-region>"
    

    Fontos

    A hely a kiválasztott modell regionális elérhetőségéhez van kötve. A modell és az üzembehelyezési típus rendelkezésre állása az Azure-régiók és a számlázási szintek között eltérő. Ez az oktatóanyag a gpt-4o-mini-t használja, amely a Standard üzembehelyezési típus alatt több régióban is elérhető.

    A hely kiválasztása előtt tekintse meg a Modell összegzése és a régió rendelkezésre állása táblát a modell támogatásának ellenőrzéséhez az előnyben részesített régióban.

  6. Hozzon létre egy erőforráscsoportot és egy Azure OpenAI-erőforrást egy egyéni tartománnyal, majd adjon hozzá egy gpt-4o-mini modellt:

    # Resource group
    az group create --name $RESOURCE_GROUP --location $LOCATION
    # Azure OpenAI resource
    az cognitiveservices account create \
      --name $OPENAI_SERVICE_NAME \
      --resource-group $RESOURCE_GROUP \
      --location $LOCATION \
      --custom-domain $OPENAI_SERVICE_NAME \
      --kind OpenAI \
      --sku s0
    # gpt-4o-mini model
    az cognitiveservices account deployment create \
      --name $OPENAI_SERVICE_NAME \
      --resource-group $RESOURCE_GROUP \
      --deployment-name gpt-4o-mini \
      --model-name gpt-4o-mini \
      --model-version 2024-07-18 \
      --model-format OpenAI \
      --sku-name Standard \
      --sku-capacity 1
    # Cognitive Services OpenAI User role that lets the signed in Azure user read models from Azure OpenAI
    az role assignment create \
      --assignee $(az ad signed-in-user show --query id -o tsv) \
      --role "Cognitive Services OpenAI User" \
      --scope /subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.CognitiveServices/accounts/$OPENAI_SERVICE_NAME
    

Most, hogy rendelkezik egy Azure OpenAI-erőforrással, létrehozhat egy webalkalmazást, amellyel kezelheti azt.

2. Spring Boot-webalkalmazás létrehozása és beállítása

  1. A Codespace-terminálban klónozza a Spring Boot REST-mintát a munkaterületre, és próbálja meg először futtatni.

    git clone https://github.com/rd-1-2022/rest-service .
    mvn spring-boot:run
    

    Egy értesítésnek kell megjelennie a GitHub Codespacesben, amely jelzi, hogy az alkalmazás egy adott porton érhető el. Válassza a Megnyitás böngészőben lehetőséget az alkalmazás új böngészőlapon való elindításához. Amikor megjelenik a fehér címke hibaoldala, a Spring Boot alkalmazás működik.

  2. A Codespace terminálban állítsa le az alkalmazást a Ctrl+C billentyűkombinációval.

  3. Nyissa meg pom.xml , és adja hozzá a következő függőségeket:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-ai-openai</artifactId>
        <version>1.0.0-beta.16</version>
    </dependency>
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-core</artifactId>
        <version>1.55.3</version>
    </dependency>
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-identity</artifactId>
        <version>1.16.0</version>
        <scope>compile</scope>
    </dependency>
    
  4. Ugyanabban a könyvtárban, mint Application.java (src/main/java/com/example/restservice) adjon hozzá egy Java-fájlt ChatController.java néven, és másolja be a következő tartalmat:

    package com.example.restservice;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    import com.azure.ai.openai.OpenAIAsyncClient;
    import com.azure.ai.openai.models.ChatChoice;
    import com.azure.ai.openai.models.ChatCompletionsOptions;
    import com.azure.ai.openai.models.ChatRequestMessage;
    import com.azure.ai.openai.models.ChatRequestUserMessage;
    import com.azure.ai.openai.models.ChatResponseMessage;
    import com.azure.core.credential.TokenCredential;
    import com.azure.identity.DefaultAzureCredentialBuilder;
    
    @Configuration
    class AzureConfig {
        // Reads the endpoint from environment variable AZURE_OPENAI_ENDPOINT
        @Value("${azure.openai.endpoint}")
        private String openAiEndpoint;
    
        // Provides a credential for local dev and production
        @Bean
        public TokenCredential tokenCredential() {
            return new DefaultAzureCredentialBuilder().build();
        }
    
        // Configures the OpenAIAsyncClient bean
        @Bean
        public OpenAIAsyncClient openAIClient(TokenCredential tokenCredential) {
            return new com.azure.ai.openai.OpenAIClientBuilder()
                    .endpoint(openAiEndpoint)
                    .credential(tokenCredential)
                    .buildAsyncClient();
        }
    }
    
    @Controller
    public class ChatController {
        private final OpenAIAsyncClient openAIClient;
    
        // Inject the OpenAIAsyncClient bean
        public ChatController(OpenAIAsyncClient openAIClient) {
            this.openAIClient = openAIClient;
        }
    
        @RequestMapping(value = "/", method = RequestMethod.GET)
        public String chatFormOrWithMessage(Model model, @RequestParam(value = "userMessage", required = false) String userMessage) {
            String aiResponse = null;
            if (userMessage != null && !userMessage.isBlank()) {
    
                // Create a list of chat messages
                List<ChatRequestMessage> chatMessages = new ArrayList<>();
                chatMessages.add(new ChatRequestUserMessage(userMessage));
    
                // Send the chat completion request
                String deploymentName = "gpt-4o-mini";
                StringBuilder serverResponse = new StringBuilder();
                var chatCompletions = openAIClient.getChatCompletions(
                    deploymentName, 
                    new ChatCompletionsOptions(chatMessages)
                ).block();
                if (chatCompletions != null) {
                    for (ChatChoice choice : chatCompletions.getChoices()) {
                        ChatResponseMessage message = choice.getMessage();
                        serverResponse.append(message.getContent());
                    }
                }
                aiResponse = serverResponse.toString();
            }
            model.addAttribute("aiResponse", aiResponse);
            return "chat";
        }
    }
    

    Jótanács

    Az oktatóanyagban szereplő fájlok minimalizálása érdekében a kód egyesíti a Spring @Configuration és @Controller az osztályok egy fájlban való használatát. A termelésben általában különválasztaná a konfigurációt és az üzleti logikát a karbantarthatóság érdekében.

  5. Az src/main/resources területen hozzon létre egy sablonkönyvtárat , és adjon hozzá egy chat.html a következő tartalommal a csevegőfelülethez:

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Azure OpenAI Chat</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div class="container py-4">
        <h2 class="mb-4">Azure OpenAI Chat</h2>
        <form action="/" method="get" class="d-flex mb-3">
            <input name="userMessage" class="form-control me-2" type="text" placeholder="Type your message..." autocomplete="off" required />
            <button class="btn btn-primary" type="submit">Send</button>
        </form>
        <div class="mb-3">
            <div th:if="${aiResponse}" class="alert alert-info">AI: <span th:text="${aiResponse}"></span></div>
        </div>
    </div>
    </body>
    </html>
    
  6. A terminálban kérje le az OpenAI-végpontot:

    az cognitiveservices account show \
      --name $OPENAI_SERVICE_NAME \
      --resource-group $RESOURCE_GROUP \
      --query properties.endpoint \
      --output tsv
    
  7. Futtassa újra az alkalmazást úgy, hogy hozzáadja AZURE_OPENAI_ENDPOINT annak értékét a parancssori felület kimenetéből:

    AZURE_OPENAI_ENDPOINT=<output-from-previous-cli-command> mvn spring-boot:run
    
  8. Válassza a Megnyitás böngészőben lehetőséget az alkalmazás új böngészőlapon való elindításához.

  9. Írjon be egy üzenetet a szövegmezőbe, és válassza a Küldés lehetőséget, és adjon néhány másodpercet az alkalmazásnak, hogy válaszoljon az Azure OpenAI üzenetére.

Az alkalmazás a DefaultAzureCredential-t használja, amely automatikusan az Azure CLI-be bejelentkezett felhasználót használja kivonathitelesítéshez. Az oktatóanyag későbbi részében üzembe helyezi a webalkalmazást az Azure App Service-ben, és konfigurálja úgy, hogy biztonságosan csatlakozzon az Azure OpenAI-erőforráshoz felügyelt identitás használatával. A kódban lévő DefaultAzureCredential felismeri a felügyelt identitást, és hitelesítéshez használja. Nincs szükség további kódra.

3. Üzembe helyezés az Azure App Service-ben és OpenAI-kapcsolat konfigurálása

Most, hogy az alkalmazás helyileg működik, helyezzük üzembe az Azure App Service-ben, és állítsunk be egy szolgáltatáskapcsolatot az Azure OpenAI-hoz felügyelt identitás használatával.

  1. Hozzon létre egy üzembehelyezési csomagot a Mavennel.

    mvn clean package
    
  2. Először helyezze üzembe az alkalmazást az Azure App Service-ben az Azure CLI paranccsal az webapp up. Ez a parancs létrehoz egy új webalkalmazást, és üzembe helyezi rajta a kódot:

    az webapp up \
      --resource-group $RESOURCE_GROUP \
      --location $LOCATION \
      --name $APPSERVICE_NAME \
      --plan $APPSERVICE_NAME \
      --sku B1 \
      --runtime "JAVA:21" \
      --os-type Linux \
      --track-status false
    

    A parancs végrehajtása eltarthat néhány percig. Egy új webalkalmazást hoz létre ugyanabban az erőforráscsoportban, mint az OpenAI-erőforrás.

  3. Az alkalmazás üzembe helyezése után hozzon létre egy szolgáltatáskapcsolatot a webalkalmazás és az Azure OpenAI-erőforrás között felügyelt identitás használatával:

    az webapp connection create cognitiveservices \
      --resource-group $RESOURCE_GROUP \
      --name $APPSERVICE_NAME \
      --target-resource-group $RESOURCE_GROUP \
      --account $OPENAI_SERVICE_NAME \
      --system-identity
    

    Ez a parancs a következő módon hoz létre kapcsolatot a webalkalmazás és az Azure OpenAI-erőforrás között:

    • Rendszer által hozzárendelt felügyelt identitás létrehozása a webalkalmazáshoz.
    • A Cognitive Services OpenAI-közreműködői szerepkör hozzáadása az Azure OpenAI-erőforrás felügyelt identitásához.
    • AZURE_OPENAI_ENDPOINT Az alkalmazásbeállítás hozzáadása a webalkalmazáshoz.
  4. Nyissa meg az üzembe helyezett webalkalmazást a böngészőben.

    az webapp browse
    
  5. Írjon be egy üzenetet a szövegmezőbe, és válassza a "Küldés" lehetőséget, és adjon meg néhány másodpercet az alkalmazásnak, hogy válaszoljon az Azure OpenAI üzenetére.

    Képernyőkép az Azure App Service-ben futó csevegőrobotról.

Az alkalmazás üzembe lett helyezve, és felügyelt identitással csatlakozik az Azure OpenAI-hoz. Vegye figyelembe, hogy a AZURE_OPENAI_ENDPOINT alkalmazás beállítását a @Configuration injektálásával éri el.

Gyakori kérdések

Miért használja a minta a @Configuration és a Spring beaneket az OpenAI-ügyfélhez?

Spring bean használata a OpenAIAsyncClient következőket biztosítja:

  • A Spring minden konfigurációs tulajdonságot (például a végpontot) betölt és injektál.
  • A hitelesítő adatok és az ügyfél az alkalmazáskörnyezet teljes inicializálása után jönnek létre.
  • Függőséginjektálást használnak, amely a Spring-alkalmazások standard és leg robusztusabb mintája.

Az aszinkron ügyfél robusztusabb, különösen az Azure CLI-hitelesítés használatakor DefaultAzureCredential . A szinkron OpenAIClient néhány helyi fejlesztési forgatókönyvben problémák léphetnek fel a token megszerzése során. Az aszinkron ügyfél használata elkerüli ezeket a problémákat, és ez a javasolt megközelítés.


Mi a teendő, ha az Azure OpenAI helyett az OpenAI-hoz szeretnék csatlakozni?

Az OpenAI-hoz való csatlakozáshoz használja a következő kódot:

OpenAIClient client = new OpenAIClientBuilder()
    .credential(new KeyCredential(<openai-api-key>))
    .buildClient();

További információ: OpenAI API-hitelesítés.

Amikor az App Service-ben kapcsolati titkos kulcsokkal dolgozik, a titkos kulcsok közvetlenül a kódbázisban való tárolása helyett Key Vault-hivatkozásokat kell használnia. Ez biztosítja, hogy a bizalmas információk biztonságosak és központilag kezelhetők maradnak.


Csatlakozhatok az Azure OpenAI-hoz API-kulcs használatával helyette?

Igen, felügyelt identitás helyett API-kulccsal csatlakozhat az Azure OpenAI-hoz. Ezt a megközelítést az Azure OpenAI SDK-k és a Szemantikus Kernel is támogatja.

Amikor az App Service-ben kapcsolati titkos kulcsokkal dolgozik, a titkos kulcsok közvetlenül a kódbázisban való tárolása helyett Key Vault-hivatkozásokat kell használnia. Ez biztosítja, hogy a bizalmas információk biztonságosak és központilag kezelhetők maradnak.


Hogyan működik a DefaultAzureCredential ebben az oktatóanyagban?

A DefaultAzureCredential legjobb elérhető hitelesítési módszer automatikus kiválasztásával egyszerűbb a hitelesítés:

  • Helyi fejlesztés során: A futtatás az loginután a helyi Azure CLI-hitelesítő adatokat használja.
  • Az Azure App Service-ben üzembe helyezve: Az alkalmazás felügyelt identitását használja a biztonságos, jelszó nélküli hitelesítéshez.

Ez a megközelítés lehetővé teszi, hogy a kód biztonságosan és zökkenőmentesen fusson mind a helyi, mind a felhőbeli környezetben módosítás nélkül.

Következő lépések