Tutorial: Construa uma aplicação web agente no Serviço de Aplicações do Azure com o Microsoft Kernel Semântico ou Foundry Agent Service (Spring Boot)

Este tutorial demonstra como adicionar capacidade de agente a um aplicativo CRUD Spring Boot WebFlux controlado por dados existente. Faz isto usando o Microsoft Kernel Semântico e o Foundry Agent Service.

Se a sua aplicação web já tem funcionalidades úteis, como compras, reservas de hotel ou gestão de dados, é relativamente simples adicionar funcionalidades de agente à sua aplicação web, envolvendo essas funcionalidades num plugin (para LangGraph) ou como endpoint OpenAPI (para Foundry Agent Service). Neste tutorial, começas com uma aplicação de lista simples to-do. No final, você poderá criar, atualizar e gerenciar tarefas com um agente em um aplicativo do Serviço de Aplicativo.

Tanto o Kernel Semântico como o Foundry Agent Service permitem-lhe construir aplicações web agentes com capacidades impulsionadas por IA. A tabela a seguir mostra algumas das considerações e compensações:

Consideração Kernel Semântico Serviço de Agente de Fundição
Performance Rápido (funciona localmente) Mais lento (gerenciado, serviço remoto)
Desenvolvimento Código completo, controlo máximo Baixo código, integração rápida
Testes Testes manuais/unitários em código Playground integrado para testes rápidos
Escalabilidade App-managed Gerenciado pelo Azure, dimensionado automaticamente
Guarda-corpos de segurança Implementação personalizada necessária Segurança e moderação de conteúdos incorporadas
Identidade Implementação personalizada necessária ID de agente incorporado e autenticação
Enterprise Integração personalizada necessária Implementação integrada do Microsoft 365/Teams e chamadas de ferramentas integradas no Microsoft 365.

Neste tutorial, aprenderás como:

  • Converta a funcionalidade existente do aplicativo em um plug-in para o Kernel Semântico.
  • Adicione o plug-in a um agente do Kernel Semântico e use-o em um aplicativo Web.
  • Converter funcionalidades existentes da aplicação num endpoint OpenAPI para o Foundry Agent Service.
  • Ligue para um agente da Foundry numa aplicação web.
  • Atribua as permissões necessárias para conectividade de identidade gerenciada.

Prerequisites

Abra o exemplo com Codespaces

A maneira mais fácil de começar é usando o GitHub Codespaces, que fornece um ambiente de desenvolvimento completo com todas as ferramentas necessárias pré-instaladas.

Abrir no GitHub Codespaces.

  1. Navegue até o repositório GitHub em https://github.com/Azure-Samples/app-service-agentic-semantic-kernel-java.

  2. Selecione o botão Código , selecione a guia Espaços de código e selecione Criar espaço de código na principal.

  3. Aguarde alguns instantes até que o Codespace seja inicializado. Quando estiver pronto, você verá um ambiente de desenvolvimento totalmente configurado em seu navegador.

  4. Execute o aplicativo localmente:

    mvn spring-boot:run
    
  5. Quando vir que a sua aplicação em execução na porta 8080 está disponível, selecione Abrir no Browser e adicione algumas tarefas.

Revise o código do agente

O agente do Kernel Semântico é inicializado em src/main/java/com/example/crudtaskswithagent/controller/AgentController.java, quando o usuário insere o primeiro prompt em uma nova sessão do navegador.

Você pode encontrar o código de inicialização no SemanticKernelAgentService construtor (em src/main/java/com/example/crudtaskswithagent/service/SemanticKernelAgentService.java). O código de inicialização faz o seguinte:

  • Cria um kernel com conclusão de chat.
  • Adiciona um plugin do kernel que encapsula a funcionalidade do aplicativo CRUD (em src/main/java/com/example/crudtaskswithagent/plugin/TaskCrudPlugin.java). As partes interessantes do plugin são as anotações DefineKernelFunction nas declarações de método e os parâmetros description e returnType que ajudam o kernel a chamar o plugin de forma inteligente.
  • Cria um agente de conclusão de chat e o configura para permitir que o modelo de IA invoque automaticamente funções ().FunctionChoiceBehavior.auto(true)
  • Cria um thread de agente que gerencia automaticamente o histórico de bate-papo.
        // Create OpenAI client
        OpenAIAsyncClient openAIClient = new OpenAIClientBuilder()
                .endpoint(endpoint)
                .credential(new DefaultAzureCredentialBuilder().build())
                .buildAsyncClient();
        
        // Create chat completion service
        OpenAIChatCompletion chatCompletion = OpenAIChatCompletion.builder()
                .withOpenAIAsyncClient(openAIClient)
                .withModelId(deployment)
                .build();
        
        // Create kernel plugin from the task plugin
        KernelPlugin kernelPlugin = KernelPluginFactory.createFromObject(taskCrudPlugin, "TaskPlugin");
        
        // Create kernel with TaskCrudPlugin and chat completion service
        Kernel kernel = Kernel.builder()
                .withAIService(OpenAIChatCompletion.class, chatCompletion)
                .withPlugin(kernelPlugin)
                .build();
        
        // Use automatic function calling
        InvocationContext invocationContext = InvocationContext.builder()
            .withFunctionChoiceBehavior(FunctionChoiceBehavior.auto(true))
            .build();

        // Create ChatCompletionAgent
        configuredAgent = ChatCompletionAgent.builder()
                .withKernel(kernel)
                .withName("TaskAgent")
                .withInvocationContext(invocationContext)
                .withInstructions(
                    "You are an agent that manages tasks using CRUD operations. " +
                    "Use the TaskCrudPlugin functions to create, read, update, and delete tasks. " +
                    "Always call the appropriate plugin function for any task management request. " +
                    "Don't try to handle any requests that are not related to task management."
                )
                .build();
        
    } catch (Exception e) {
        logger.error("Error initializing SemanticKernelAgentService: {}", e.getMessage(), e);
    }
}

this.agent = configuredAgent;

// Initialize thread for this instance
this.thread = ChatHistoryAgentThread.builder().build();

Cada vez que o prompt é recebido, o código do servidor usa ChatCompletionAgent.invokeAsync() para invocar o agente com o prompt do usuário e o thread do agente. O segmento do agente mantém o registo do histórico de bate-papo.

// Use the agent to process the message with automatic function calling
return agent.invokeAsync(userMessageContent, thread)
        .<String>map(responses -> {
            
            if (responses != null && !responses.isEmpty()) {
                // Process all responses and concatenate them
                StringBuilder combinedResult = new StringBuilder();
                
                for (int i = 0; i < responses.size(); i++) {
                    var response = responses.get(i);
                    
                    // Update thread with the last response thread (as per Microsoft docs)
                    if (i == responses.size() - 1) {
                        var responseThread = response.getThread();
                        if (responseThread instanceof ChatHistoryAgentThread) {
                            this.thread = (ChatHistoryAgentThread) responseThread;
                        }
                    }
                    
                    // Get response content
                    ChatMessageContent<?> content = response.getMessage();
                    String responseContent = content != null ? content.getContent() : "";
                    
                    if (!responseContent.isEmpty()) {
                        if (combinedResult.length() > 0) {
                            combinedResult.append("\n\n"); // Separate multiple responses
                        }
                        combinedResult.append(responseContent);
                    }
                }
                
                String result = combinedResult.toString();
                if (result.isEmpty()) {
                    result = "No content returned from agent.";
                }
                return result;
            } else {
                return "I'm sorry, I couldn't process your request. Please try again.";
            }
        })
        .onErrorResume(throwable -> {
            logger.error("Error in processMessage: {}", throwable.getMessage(), throwable);
            return Mono.just("Error processing message: " + throwable.getMessage());
        });

Implementar o exemplo de aplicação

O repositório de exemplo contém um modelo de CLI do Desenvolvedor do Azure (AZD), que cria um aplicativo do Serviço de Aplicativo com identidade gerenciada e implanta seu aplicativo de exemplo.

  1. No terminal, faça logon no Azure usando a CLI do Azure Developer:

    azd auth login
    

    Siga as instruções para concluir o processo de autenticação.

  2. Implante o aplicativo do Serviço de Aplicativo do Azure com o modelo AZD:

    azd up
    
  3. Quando solicitado, forneça as seguintes respostas:

    Question Answer
    Insira um novo nome de ambiente: Escreva um nome exclusivo.
    Selecione uma Assinatura do Azure para usar: Selecione uma subscrição.
    Escolha um grupo de recursos para usar: Selecione Criar um novo grupo de recursos.
    Selecione um local para criar o grupo de recursos em: Selecione Suécia Central.
    Insira um nome para o novo grupo de recursos: Digite Enter.
  4. Na saída AZD, localize a URL do seu aplicativo e navegue até ela no navegador. O URL tem esta aparência na saída AZD:

     Deploying services (azd deploy)
    
       (✓) Done: Deploying service web
       - Endpoint: <URL>
     
  5. Abra o esquema OpenAPI gerado automaticamente no https://....azurewebsites.net/api/schema caminho. Você precisará desse esquema mais tarde.

    Agora você tem um aplicativo do Serviço de Aplicativo com uma identidade gerenciada atribuída ao sistema.

Crie e configure o recurso Microsoft Foundry

  1. No portal da Foundry, cria um projeto.

  2. Implemente um modelo à sua escolha (veja Microsoft Foundry Quickstart: Criar recursos).

  3. Do topo do parque de diversões de modelos, copie o nome do modelo.

  4. Na página inicial, copie o endpoint Azure OpenAI para mais tarde.

Atribuir permissões necessárias

  1. No portal Foundry, selecione Gerir no menu superior.

  2. Em Detalhes do projeto, selecione o Recurso principal para o seu projeto e, em seguida, selecione Abrir no portal do Azure.

    A partir do portal Azure, pode atribuir acesso baseado em funções para o recurso.

  3. Adicione a seguinte função à identidade gerida da aplicação do App Service e ao utilizador que utiliza com az login:

    Recurso de destino Função obrigatória Necessário para
    Fundição Utilizador dos Serviços Cognitivos OpenAI O serviço de conclusão de chat no Microsoft Agent Framework.

    Para obter instruções, consulte Atribuir funções do Azure utilizando o portal do Azure.

Configurar variáveis de conexão em seu aplicativo de exemplo

  1. Abra src/main/resources/application.properties. Usando os valores que copiou anteriormente do portal Foundry, configure as seguintes variáveis:

    Variable Description
    azure.openai.endpoint Azure OpenAI endpoint (copiado da página inicial do portal Foundry).
    azure.openai.deployment Nome do modelo na implementação (copiado da área de testes do modelo no novo portal da Foundry).

    Note

    Para manter o tutorial simples, você usará essas variáveis em .env em vez de substituí-las pelas configurações do aplicativo no Serviço de Aplicativo.

    Note

    Para manter o tutorial simples, você usará essas variáveis em src/main/resources/application.properties em vez de substituí-las pelas configurações do aplicativo no Serviço de Aplicativo.

  2. Entre no Azure com a CLI do Azure:

    az login
    

    Isso permite que a biblioteca de cliente do Azure Identity no código de exemplo receba um token de autenticação para o usuário conectado. Lembre-se de que você adicionou a função necessária para esse usuário anteriormente.

  3. Execute o aplicativo localmente:

    mvn spring-boot:run
    
  4. Quando vir que a sua aplicação em execução na porta 8080 está disponível, selecione Abrir no Browser.

  5. Experimente interface de chat. Se receber uma resposta, a sua aplicação está a ligar-se com sucesso ao recurso Microsoft Foundry.

  6. De volta ao espaço de código do GitHub, implante as alterações do seu aplicativo.

    azd up
    
  7. Navegue até o aplicativo implantado novamente e teste os agentes de chat.

Perguntas mais frequentes

Como posso adicionar geração aumentada de recuperação (RAG) ao agente da Foundry?

Esta orientação aplica-se ao caminho Foundry Agent Service neste tutorial. Não altera as implementações do LangGraph, Kernel Semântico ou Microsoft Agent Framework mostradas no outro separador.

Crie ou selecione uma base de conhecimento Foundry IQ e depois ligue essa base ao agente do Serviço de Agentes da Foundry. A conexão é apresentada ao agente como uma ferramenta de conhecimento MCP gerida.

O código do App Service continua a invocar o mesmo agente pelo respetivo nome através do cliente Foundry existente e agent_reference. A aplicação web não precisa de uma integração direta com Pesquisa de IA do Azure nem de um cliente MCP próprio. Se a interface mostrar as fontes, processe as anotações de citação devolvidas pelo agente.

Limpeza de recursos

Quando terminar de usar o aplicativo, você poderá excluir os recursos do Serviço de Aplicativo para evitar incorrer em custos adicionais:

azd down --purge

Como o modelo do AZD não inclui os recursos do Microsoft Foundry, tens de os apagar manualmente se quiseres.

Mais recursos