Sdílet prostřednictvím


Kurz: Vytvoření chatovacího robota se službou Azure App Service a Azure OpenAI (Spring Boot)

V tomto kurzu vytvoříte inteligentní aplikaci AI integrací Azure OpenAI s aplikací Java Spring Boot a jejím nasazením do Služby Azure App Service. Vytvoříte kontroler Spring Boot, který odešle dotaz do Azure OpenAI a odešle odpověď do prohlížeče.

Návod

I když tento kurz používá Spring Boot, základní koncepty vytváření chatovací aplikace pomocí Azure OpenAI platí pro libovolnou webovou aplikaci v Javě. Pokud ve službě App Service používáte jinou možnost hostování, jako je Tomcat nebo JBoss EAP, můžete přizpůsobit vzory ověřování a využití sady Azure SDK, které vidíte tady, podle preferované architektury.

Snímek obrazovky s chatovacím robotem spuštěným ve službě Azure App Service

V tomto návodu se naučíte, jak:

  • Vytvořte prostředek Azure OpenAI a nasaďte jazykový model.
  • Vytvořte aplikaci Spring Boot, která se připojuje k Azure OpenAI.
  • Pomocí injektáže závislostí nakonfigurujte klienta Azure OpenAI.
  • Nasaďte aplikaci do služby Azure App Service.
  • Implementujte zabezpečené ověřování bez hesla jak ve vývojovém prostředí, tak v Azure.

Požadavky

1. Vytvoření prostředku Azure OpenAI

V této části použijete GitHub Codespaces k vytvoření prostředku Azure OpenAI pomocí Azure CLI.

  1. Přejděte na GitHub Codespaces a přihlaste se pomocí svého účtu GitHub.

  2. Najděte prázdnou šablonu podle GitHubu a vyberte Použít tuto šablonu k vytvoření nového prázdného prostoru Codespace.

  3. V terminálu Codespace nainstalujte Azure CLI:

    curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
    
  4. Přihlaste se ke svému účtu Azure:

    az login
    

    Proveďte ověření podle pokynů v terminálu.

  5. Nastavte proměnné prostředí pro název vaší skupiny prostředků, název služby Azure OpenAI a umístění:

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

    Důležité

    Oblast je kritická, protože je svázaná s regionální dostupností zvoleného modelu. Dostupnost modelu a dostupnost typu nasazení se liší od oblasti po oblast. Tento kurz používá gpt-4o-mini, který je k dispozici v eastus2 rámci typu standardního nasazení. Pokud nasadíte do jiné oblasti, nemusí být tento model dostupný nebo může vyžadovat jinou úroveň. Před změnou oblastí si projděte tabulku souhrnu modelů a dostupnost oblastí a ověřte podporu modelu ve vaší upřednostňované oblasti.

  6. Vytvořte skupinu prostředků a prostředek Azure OpenAI s vlastní doménou a pak přidejte model gpt-4o-mini:

    # 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 to 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
    

Teď, když máte prostředek Azure OpenAI, vytvoříte webovou aplikaci, která s ním bude pracovat.

2. Vytvoření a nastavení webové aplikace Spring Boot

  1. V terminálu Codespace naklonujte ukázku Spring Boot REST do pracovního prostoru a poprvé spusťte.

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

    V GitHub Codespaces byste měli vidět oznámení, že aplikace je dostupná na konkrétním portu. Výběrem možnosti Otevřít v prohlížeči spusťte aplikaci na nové kartě prohlížeče. Když se zobrazí chybová stránka s bílým popiskem, aplikace Spring Boot funguje.

  2. Zpátky v terminálu Codespace zastavte aplikaci pomocí Ctrl+C.

  3. Otevřete pom.xml a přidejte následující závislosti:

    <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. Do stejného adresáře jako Application.java (src/main/java/com/example/restservice) přidejte soubor Java s názvem ChatController.java a zkopírujte do něj následující obsah:

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

    Návod

    Aby se minimalizovaly soubory v tomto kurzu, kód kombinuje Spring @Configuration a @Controller třídy v jednom souboru. V produkčním prostředí byste normálně oddělily konfiguraci a obchodní logiku pro zajištění udržovatelnosti.

  5. V části src/main/resources vytvořte adresář šablon a přidejte chat.html s následujícím obsahem pro rozhraní chatu:

    <!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. V terminálu získejte koncový bod OpenAI.

    az cognitiveservices account show \
      --name $OPENAI_SERVICE_NAME \
      --resource-group $RESOURCE_GROUP \
      --query properties.endpoint \
      --output tsv
    
  7. Spusťte aplikaci znovu tak, že přidáte AZURE_OPENAI_ENDPOINT její hodnotu z výstupu rozhraní příkazového řádku:

    AZURE_OPENAI_ENDPOINT=<output-from-previous-cli-command> mvn spring-boot:run
    
  8. Výběrem možnosti Otevřít v prohlížeči spusťte aplikaci na nové kartě prohlížeče.

  9. Do textového pole zadejte zprávu a vyberte Odeslat a dejte aplikaci několik sekund, aby na zprávu odpověděla z Azure OpenAI.

Aplikace používá defaultAzureCredential, který k ověřování tokenů automaticky používá přihlášeného uživatele Azure CLI. Později v tomto kurzu nasadíte webovou aplikaci do služby Azure App Service a nakonfigurujete ji tak, aby se bezpečně připojila k prostředku Azure OpenAI pomocí spravované identity. Ve vašem kódu může stejná DefaultAzureCredential detekovat spravovanou identitu a použít ji k ověřování. Není potřeba žádný další kód.

3. Nasazení do služby Azure App Service a konfigurace připojení OpenAI

Teď, když vaše aplikace funguje místně, ji nasadím do služby Azure App Service a nastavíme připojení služby k Azure OpenAI pomocí spravované identity.

  1. Vytvořte balíček pro nasazení pomocí Mavenu.

    mvn clean package
    
  2. Nejprve pomocí příkazu az webapp upAzure CLI nasaďte aplikaci do služby Azure App Service. Tento příkaz vytvoří novou webovou aplikaci a nasadí do ní váš kód:

    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
    

    Dokončení tohoto příkazu může trvat několik minut. Vytvoří novou webovou aplikaci ve stejné skupině prostředků jako prostředek OpenAI.

  3. Po nasazení aplikace vytvořte připojení služby mezi vaší webovou aplikací a prostředkem Azure OpenAI pomocí spravované identity:

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

    Tento příkaz vytvoří propojení mezi vaší webovou aplikací a prostředkem Azure OpenAI:

    • Generování spravované identity přiřazené systémem pro webovou aplikaci
    • Přidání role Přispěvatele pro OpenAI ve službách Cognitive Services ke spravované identitě pro prostředek Azure OpenAI.
    • Přidání nastavení aplikace AZURE_OPENAI_ENDPOINT do vaší webové aplikace.
  4. Otevřete nasazenou webovou aplikaci v prohlížeči.

    az webapp browse
    
  5. Do textového pole napište zprávu a vyberte Odeslat a dejte aplikaci několik sekund, abyste mohli odpovědět se zprávou z Azure OpenAI.

    Snímek obrazovky s chatovacím robotem spuštěným ve službě Azure App Service

Vaše aplikace je teď nasazená a připojená k Azure OpenAI se spravovanou identitou. Všimněte si, že přistupuje k AZURE_OPENAI_ENDPOINT nastavení aplikace prostřednictvím injekce @Configuration.

Nejčastější dotazy

Proč ukázka používá @Configuration a Spring beans pro klienta OpenAI?

Použití Spring beanu pro OpenAIAsyncClient zajišťuje, že:

  • Všechny vlastnosti konfigurace (jako koncový bod) jsou načteny a vloženy frameworkem Spring.
  • Přihlašovací údaje a klient se vytvoří po úplné inicializaci kontextu aplikace.
  • Injektáž závislostí se používá, což je standardní a nej robustnější vzor v aplikacích Spring.

Asynchronní klient je robustnější, zejména při použití DefaultAzureCredential s ověřováním Azure CLI. Synchronní OpenAIClient může v některých místních scénářích vývoje narazit na problémy s získáním tokenů. Použití asynchronního klienta se těmto problémům vyhne a je doporučeným přístupem.


Co když se chci připojit k OpenAI místo Azure OpenAI?

Pokud se chcete místo toho připojit k OpenAI, použijte následující kód:

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

Další informace najdete v tématu Ověřování rozhraní API OpenAI.

Při práci s tajnými kódy připojení ve službě App Service byste měli místo ukládání tajných kódů přímo do základu kódu použít odkazy služby Key Vault . Tím zajistíte, že citlivé informace zůstanou zabezpečené a budou spravovány centrálně.


Můžu se místo toho připojit k Azure OpenAI pomocí klíče rozhraní API?

Ano, k Azure OpenAI se můžete připojit pomocí klíče rozhraní API místo spravované identity. Tento přístup podporuje sady SDK Azure OpenAI a sémantické jádro.

Při práci s tajnými kódy připojení ve službě App Service byste měli místo ukládání tajných kódů přímo do základu kódu použít odkazy služby Key Vault . Tím zajistíte, že citlivé informace zůstanou zabezpečené a budou spravovány centrálně.


Jak v tomto kurzu funguje DefaultAzureCredential?

Zjednodušuje DefaultAzureCredential ověřování tím, že automaticky vybere nejlepší dostupnou metodu ověřování:

  • Během místního vývoje: Po spuštění az loginpoužije vaše místní přihlašovací údaje Azure CLI.
  • Při nasazení do služby Azure App Service používá spravovanou identitu aplikace k zabezpečenému ověřování bez hesla.

Tento přístup umožňuje bezpečně a bezproblémově spouštět kód v místním i cloudovém prostředí beze změny.

Další kroky