Esercitazione: Creare un'app Web dotata di agenti nel Servizio App di Azure con il Kernel Semantico di Microsoft o il Servizio Agente Foundry (Spring Boot)

Questa esercitazione illustra come aggiungere funzionalità agentiche a un'applicazione CRUD Spring Boot WebFlux basata sui dati esistente. A tale scopo, viene usato il servizio Microsoft Kernel semantico e Foundry Agent.

Se l'applicazione Web ha già funzionalità utili, ad esempio acquisti, prenotazioni di hotel o gestione dei dati, è relativamente semplice aggiungere funzionalità dell'agente all'applicazione Web eseguendo il wrapping di tali funzionalità in un plug-in (per LangGraph) o come endpoint OpenAPI (per il servizio agente Foundry). In questo tutorial, si inizia con una semplice app per lista di cose da fare. Alla fine, sarai in grado di creare, aggiornare e gestire attività con un agente in un'app di Servizio app.

Sia il kernel semantico che il servizio agente foundry consentono di creare applicazioni Web agentic con funzionalità basate su intelligenza artificiale. La tabella seguente illustra alcune considerazioni e compromessi:

Considerazione Kernel semantico Servizio agenti Foundry
Performance Veloce (funziona localmente) Più lento (gestito, servizio remoto)
Sviluppo Codice completo, controllo massimo Basso codice, integrazione rapida
Testing Test manuali e unit test nel codice Playground predefinito per i test rapidi
Scalabilità Gestito dall'app Gestito da Azure, con scalabilità automatica
Protezioni di sicurezza Implementazione personalizzata richiesta Sicurezza e moderazione dei contenuti predefiniti
Identità Implementazione personalizzata richiesta ID e autenticazione predefiniti dell'agente
Enterprise Integrazione personalizzata richiesta Distribuzione predefinita di Microsoft 365/Teams e chiamate agli strumenti integrati di Microsoft 365.

In questa esercitazione si apprenderà come:

  • Convertire le funzionalità dell'app esistenti in un plug-in per il kernel semantico.
  • Aggiungere il plug-in a un agente Kernel semantico e usarlo in un'app Web.
  • Convertire le funzionalità dell'app esistenti in un endpoint OpenAPI per il servizio agente Foundry.
  • Chiamare un agente Foundry in un'applicazione web.
  • Assegnare le autorizzazioni necessarie per la connettività dell'identità gestita.

Prerequisites

Aprire l'esempio con Codespaces

Il modo più semplice per iniziare consiste nell'usare GitHub Codespaces, che offre un ambiente di sviluppo completo con tutti gli strumenti necessari preinstallati.

Apri con GitHub Codespaces.

  1. Passare al repository GitHub all'indirizzo https://github.com/Azure-Samples/app-service-agentic-semantic-kernel-java.

  2. Selezionare il pulsante Codice , selezionare la scheda Codespaces e selezionare Crea spazio di codice nel main.

  3. Attendere alcuni istanti per inizializzare Codespace. Quando si è pronti, nel browser verrà visualizzato un ambiente di sviluppo completamente configurato.

  4. Eseguire l'applicazione in locale:

    mvn spring-boot:run
    
  5. Quando viene visualizzato L'applicazione in esecuzione sulla porta 8080 è disponibile, selezionare Apri nel browser e aggiungere alcune attività.

Esaminare il codice dell'agente

L'agente del kernel semantico viene inizializzato in src/main/java/com/example/crudtaskswithagent/controller/AgentController.java, quando l'utente immette la prima richiesta in una nuova sessione del browser.

È possibile trovare il codice di inizializzazione nel SemanticKernelAgentService costruttore (in src/main/java/com/example/crudtaskswithagent/service/SemanticKernelAgentService.java). Il codice di inizializzazione esegue le operazioni seguenti:

  • Crea un kernel con il completamento della chat.
  • Aggiunge un plug-in kernel che incapsula la funzionalità dell'applicazione CRUD (in src/main/java/com/example/crudtaskswithagent/plugin/TaskCrudPlugin.java). Le parti interessanti del plug-in sono le DefineKernelFunction annotazioni sulle dichiarazioni del metodo e i parametri description e returnType che aiutano il kernel a chiamare il plug-in in modo intelligente.
  • Crea un agente di completamento della chat e lo configura per consentire al modello di intelligenza artificiale di richiamare automaticamente le funzioni (FunctionChoiceBehavior.auto(true)).
  • Crea un thread agente che gestisce automaticamente la cronologia delle chat.
        // 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();

Ogni volta che viene ricevuta la richiesta, il codice del server usa ChatCompletionAgent.invokeAsync() per richiamare l'agente con la richiesta dell'utente e il thread dell'agente. Il thread dell'agente tiene traccia della cronologia delle chat.

// 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());
        });

Distribuire l'applicazione di esempio

Il repository di esempio contiene un modello di Azure Developer CLI (AZD), che crea un'app di App Service con identità gestita e distribuisce l'applicazione di esempio.

  1. Nel terminale accedere ad Azure usando l'interfaccia della riga di comando per sviluppatori di Azure:

    azd auth login
    

    Seguire le istruzioni per completare il processo di autenticazione.

  2. Distribuire l'app del servizio app di Azure con il modello AZD:

    azd up
    
  3. Quando richiesto, fornire le risposte seguenti:

    Question Answer
    Immettere un nuovo nome di ambiente: Digitare un nome univoco.
    Selezionare una sottoscrizione di Azure da usare: Selezionare la sottoscrizione.
    Selezionare un gruppo di risorse da usare: Selezionare Crea un nuovo gruppo di risorse.
    Selezionare un percorso in cui creare il gruppo di risorse: Selezionare Svezia centrale.
    Immettere un nome per il nuovo gruppo di risorse: Immettere Invio.
  4. Nell'output AZD, individua l'URL della tua app e accedi a esso tramite il browser. L'URL è simile al seguente nell'output AZD:

     Deploying services (azd deploy)
    
       (✓) Done: Deploying service web
       - Endpoint: <URL>
     
  5. Aprire lo schema OpenAPI generato automaticamente nel https://....azurewebsites.net/api/schema percorso. Questo schema sarà necessario in un secondo momento.

    Ora hai un'app di App Service con un'identità gestita assegnata dal sistema.

Creare e configurare la risorsa Microsoft Foundry

  1. Nel portale Foundry, crea un progetto.

  2. Distribuire un modello preferito (vedere Avvio rapido di Microsoft Foundry: Creare risorse).

  3. Nella parte superiore del playground del modello copiare il nome del modello.

  4. Nella pagina iniziale, copia l'endpoint di Azure OpenAI per usarlo in seguito.

Assegnare le autorizzazioni necessarie

  1. Nel portale Foundry, seleziona Gestisci nel menu superiore.

  2. In Project details, seleziona la risorsa Genitore per il tuo project, poi seleziona Apri in Azure portal.

    Dal portale Azure puoi assegnare l'accesso basato sul ruolo per la risorsa.

  3. Aggiungi il seguente ruolo sia per l'identità gestita dell'app di App Service sia per l'utente che usi con az login:

    Risorsa di destinazione Ruolo obbligatorio Necessario per
    Fonderia Utente di Servizi Cognitivi OpenAI Servizio di completamento della chat in Microsoft Agent Framework.

    Per istruzioni, vedere Assegnare ruoli di Azure usando il portale di Azure.

Configurare le variabili di connessione nell'applicazione di esempio

  1. Aprire src/main/resources/application.properties. Usando i valori copiati in precedenza dal portale foundry, configurare le variabili seguenti:

    Variable Description
    azure.openai.endpoint Azure OpenAI endpoint (copiato dalla homepage del portale Foundry).
    azure.openai.deployment Nome del modello nella distribuzione (copiato dall'area di sperimentazione del modello nel nuovo portale Foundry).

    Note

    Per semplificare l'esercitazione, queste variabili verranno usate in .env invece di sovrascriverle con le impostazioni dell'app nel servizio app.

    Note

    Per semplificare l'esercitazione, verranno usate queste variabili in src/main/resources/application.properties anziché sovrascriverle con le impostazioni dell'app nel servizio app.

  2. Accedere ad Azure con l'interfaccia della riga di comando di Azure:

    az login
    

    Ciò consente alla libreria client di Identità di Azure nel codice di esempio di ricevere un token di autenticazione per l'utente connesso. Tenere presente che è stato aggiunto il ruolo necessario per questo utente in precedenza.

  3. Eseguire l'applicazione in locale:

    mvn spring-boot:run
    
  4. Quando viene visualizzato L'applicazione in esecuzione sulla porta 8080 è disponibile, selezionare Apri nel browser.

  5. Provare l'interfaccia della chat. Se si riceve una risposta, l'applicazione si connette correttamente alla risorsa Microsoft Foundry.

  6. Tornare nello spazio di codice GitHub, distribuire le modifiche dell'app.

    azd up
    
  7. Passare di nuovo all'applicazione distribuita e testare gli agenti di chat.

Domande frequenti

Come posso aggiungere la generazione aumentata di recupero (RAG) all'agente Foundry?

Queste indicazioni si applicano al percorso Foundry Agent Service in questo tutorial. Non cambia le implementazioni di LangGraph, Kernel semantico o Microsoft Agent Framework mostrate nell'altra scheda.

Crea o seleziona una knowledge base di Foundry IQ, e poi collega la knowledge base all'agente di Foundry Agent Service. La connessione viene esposta all'agente come uno strumento di conoscenza MCP gestito.

Il codice di App Service continua a richiamare lo stesso agente per nome tramite il client Foundry esistente e agent_reference. L'app web non ha bisogno di un'integrazione diretta con Azure AI Search né di un proprio client MCP. Se l'interfaccia mostra le fonti, elabora le annotazioni di citazione restituite dall'agente.

Pulire le risorse

Al termine dell'applicazione, è possibile eliminare le risorse del servizio app per evitare di sostenere ulteriori costi:

azd down --purge

Poiché il modello AZD non include le risorse di Microsoft Foundry, è necessario eliminarle manualmente, se necessario.

Altre risorse