Nello scorso script abbiamo iniziato ad occuparci dei Large Language Model, e in particolare di come integrare la nostra applicazione con essi tramite Semantic Kernel.
L'esempio che abbiamo realizzato sfrutta il cosiddetto endpoint sincrono: è di semplice utilizzo, ma ha il difetto di restituire la risposta solo dopo che questa sia stata interamente elaborata del modello AI. Ciò si traduce in tempi di attesa per l'utente, durante i quali effettivamente non accade nulla.
Un'alternativa - che richiede alcune minime modifiche al codice - è quella di utilizzare lo streaming endpoint, che invece ritorna uno stream di parole che, dal nostro controller, possiamo direttamente girare al client.
Riprendiamo l'esempio che abbiamo visto in precedenza, e modifichiamo la action in questo modo:
[HttpPost] public async IAsyncEnumerable<string> PostMessage([FromBody] string message) { ChatHistory.AddUserMessage(message); var result = _chatCompletionService.GetStreamingChatMessageContentsAsync(ChatHistory); string responseMessage = string.Empty; await foreach (var messageContent in result) { responseMessage += messageContent.Content; yield return messageContent.Content; } ChatHistory.AddAssistantMessage(responseMessage); }
Come possiamo notare, innanzi tutto il tipo restituito dal codice in alto è ora un IAsyncEnumerable, ossia un array di string che viene ritornato al client sotto forma di stream. Ci siamo occupati di questa funzionalità di ASP.NET Core in un precedente script (https://www.aspitalia.com/script/1458/Effettuare-Stream-Risposta-ASP.NET-Core-Tramite-IAsyncEnumerable.aspx).
Inoltre, questa volta abbiamo invocato il metodo GetStreamingChatMessageContentsAsync, che invece dell'intera risposta, ritorna a sua volta un oggetto IAsyncEnumerable, che possiamo iterare tramite un costrutto aync foreach.
Ognuno degli elementi della risposta, che altro non sono i vari token generati dal modello, può essere poi restituito al client tramite yield return. Come possiamo notare, però, è anche importante accumulare tutti gli elementi all'interno di una variable responseMessage, così che una volta che la risposta sia terminata, possiamo aggiungerla interamente alla history in modo da mantenerne traccia nella successive interazioni.
Se ora proviamo a eseguire questo codice, vedremo semplicemente che il risultato ottenuto è questa volta un array di elementi string. Ma se proviamo a invocarlo da un client che supporti lo streaming, come per esempio il codice di questo script (https://www.aspitalia.com/script/1459/Sfruttare-Streaming-Chiamata-Http-Blazor.aspx) noteremo come effettivamente la risposta di ChatGPT si componga gradualmente, man mano che viene generata dal modello in Azure.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Generare HTML a runtime a partire da un componente Razor in ASP.NET Core
Creare una libreria CSS universale: Immagini
Creare una libreria CSS universale: Nav menu
Creare una libreria CSS universale: i bottoni
Usare i servizi di Azure OpenAI e ChatGPT in ASP.NET Core con Semantic Kernel
Eseguire una ricerca avanzata per recuperare le issue di GitHub
Change tracking e composition in Entity Framework
Garantire la provenienza e l'integrità degli artefatti prodotti su GitHub
Generare velocemente pagine CRUD in Blazor con QuickGrid
Gestire eccezioni nei plugin di Semantic Kernel in ASP.NET Core Web API
Effettuare il refresh dei dati di una QuickGrid di Blazor
Migliorare la sicurezza dei prompt con Azure AI Studio
I più letti di oggi
- Validazione automatica dei parametri in Web API con ASP.NET Core 2.1
- Recuperare i file utilizzati di recente in un'Universal App
- Applicare un'animazione al contenuto di un ContentControl nella Universal Windows Platform
- AI&ML Conference 2019 - Milano
- .NET Serverless Day - Online
- Rilasciata la versione Beta 2 di Silverlight 2.0