Esercizio: Creazione di un connettore personalizzato per il copilota

Completato

Background

Questo esercizio compie un ulteriore passo avanti rispetto all'esercizio Configurazione del Servizio OpenAI di Azure per generare informazioni sul podcast. Le attività per questo esercizio sono la creazione di un'API .NET usando .NET Azure OpenAI SDK e la creazione di un connettore personalizzato da Visual Studio.

Definizioni

Le sezioni seguenti forniscono le definizioni degli elementi importanti che è necessario conoscere per questo esercizio.

.NET

.NET è una piattaforma di sviluppo open source, multipiattaforma gratuita per creare molti tipi diversi di applicazioni. Con .NET è possibile usare più linguaggi, editor e librerie per creare applicazioni per il Web, i dispositivi mobili, il desktop, i giochi, Internet delle cose (IoT) e l'intelligenza artificiale.

Per altre informazioni, consultare Introduzione a .NET.

.NET Azure OpenAI SDK

La libreria client di Azure OpenAI per .NET è un adattamento delle API REST di OpenAI che forniscono un'interfaccia idiomatica e un'avanzata integrazione con il resto dell'ecosistema di Azure SDK. Può connettersi alle risorse di Azure OpenAI o all'endpoint di inferenza non Azure OpenAI, diventando un'ottima scelta per lo sviluppo non Azure OpenAI.

Per altre informazioni, consultare Libreria client di Azure OpenAI per .NET.

Microsoft Power Platform

Grazie a Microsoft Power Platform, le organizzazioni consentono ai membri dei team di creare proprie soluzioni attraverso un set di servizi intuitivi senza codice o con poco codice. Questi servizi semplificano il processo di creazione di soluzioni. Con Microsoft Power Platform, è possibile creare soluzioni in giorni o settimane, anziché in mesi o anni. Microsoft Power Platform è composto da cinque prodotti principali: Power Apps, Power Automate, Power BI, Power Virtual Agents e Power Pages.

Per altre informazioni, consultare Microsoft Power Platform.

Connettore personalizzato

App per la logica di Microsoft Azure, Microsoft Power Automate e Microsoft Power Apps offrono oltre 1.000 connettori per la connessione ai servizi verificati e Microsoft. Tuttavia, potrebbe essere necessario comunicare con servizi non disponibili come connettori predefiniti. I connettori personalizzati risolvono questo scenario consentendo di creare, e persino condividere, un connettore con trigger e azioni dedicati.

Per altre informazioni, consultare Connettori personalizzati.

Prerequisiti

Per questo esercizio, assicurarsi di:

Passaggi dell'esercizio

Il video seguente illustra i passaggi per l'esercizio di questa unità.

Impostazione delle variabili di ambiente

Per impostare le variabili di ambiente, effettuare i passaggi seguenti:

  1. Aprire un prompt dei comandi, quindi eseguire i comandi seguenti uno alla volta:

     setx AZURE_OPENAI_KEY_WE "REPLACE_WITH_YOUR_WEST_EUROPE_KEY_VALUE_HERE"
     setx AZURE_OPENAI_ENDPOINT_WE https://podcastcopilotwe-{your initials}.openai.azure.com/
    

    Il comando precedente riguarda la chiave di risorsa e l'endpoint dell'Europa occidentale.

     setx AZURE_OPENAI_KEY_SC "REPLACE_WITH_YOUR_SWEDEN_CENTRAL_KEY_VALUE_HERE" 
     setx AZURE_OPENAI_ENDPOINT_SC "https://podcastcopilotsc-{your initials}.openai.azure.com/"    
    

    Il comando precedente riguarda la chiave di risorsa e l'endpoint della Svezia centrale.

    setx BING_SEARCH_KEY "REPLACE_WITH_YOUR_KEY_VALUE_HERE"

    Il comando precedente riguarda la chiave di risorsa Ricerca Bing.

  2. Dopo aver impostato le variabili ambiente, chiudere il prompt dei comandi.

Creazione di un nuovo progetto di API Web .NET

L'attività successiva consiste nel creare un nuovo progetto di API Web .NET effettuando i passaggi seguenti:

  1. Aprire Visual Studio e selezionare Crea un nuovo progetto.

    Screenshot dell'opzione Crea un nuovo progetto in Visual Studio.

  2. Cercare API Web e selezionare ASP.NET API Web Core. Assicurarsi di usare il modello di progetto C#.

    Screenshot del modello di progetto API Web Core A S P dot net.

  3. Selezionare Avanti.

  4. Assegnare al progetto il nome PodcastAppAPI e selezionare Avanti.

  5. Assicurarsi che Framework sia impostato su .NET 8, che Tipo di autenticazione sia impostato su Nessuno e che l'opzione Configura per HTTPS sia selezionata. Selezionare Crea.

    Screenshot delle impostazioni del progetto.

  6. Dopo che il sistema ha creato il progetto, aprire Esplora soluzioni, fare clic con il pulsante destro del mouse sul progetto PodcastAppAPI per aprire il menu di scelta rapida, quindi selezionare Apri nel terminale.

  7. Nella finestra del terminale eseguire il comando seguente per installare la versione preliminare di Azure OpenAI SDK:

    dotnet add package Azure.AI.OpenAI --version 1.0.0-beta.13

  8. Eseguire il comando seguente per installare il pacchetto Newtonsoft.Json:

    dotnet add package Newtonsoft.Json --version 13.0.3

Creazione della classe PodcastCopilot

Per creare la classe PodcastCopilot, effettuare i passaggi seguenti:

  1. Al termine del comando, aggiungere una nuova classe al progetto facendo clic con il pulsante destro del mouse sul progetto PodcastAppAPI per aprire il menu di scelta rapida. Selezionare Aggiungi > Classe. Assegnare alla classe il nome PodcastCopilot.

    Screenshot dell'aggiunta di una nuova classe al progetto.

  2. Aggiungere le istruzioni using seguenti in alto nella classe PodcastCopilot:

     using System.Web;
     using Azure.AI.OpenAI;
     using Azure;    
     using Newtonsoft.Json.Linq;
    
  3. Nella classe PodcastCopilot aggiungere il codice seguente:

     //Initializing the Endpoints and Keys
     static string endpointWE = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT_WE");
     static string keyWE = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY_WE");
    
     static string endpointSC = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT_SC");
     static string keySC = Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY_SC");
    
     static string bingSearchUrl = "https://api.bing.microsoft.com/v7.0/search";
     static string bingSearchKey = Environment.GetEnvironmentVariable("BING_SEARCH_KEY");
    
     //Instantiate OpenAI Client for Whisper and GPT-3
     static OpenAIClient clientWE = new OpenAIClient(
         new Uri(endpointWE), 
         new AzureKeyCredential(keyWE));
    
     //Instantiate OpenAI Client for Dall.E 3
     static OpenAIClient clientSC = new OpenAIClient(
         new Uri(endpointSC), 
         new AzureKeyCredential(keySC));
    
  4. Sotto il codice precedente, aggiungere il codice seguente per eseguire Trascrizione audio:

     //Get Audio Transcription
     public static async Task<string> GetTranscription(string podcastUrl)
     {
         var decodededUrl = HttpUtility.UrlDecode(podcastUrl);
    
         HttpClient httpClient = new HttpClient();
         Stream audioStreamFromBlob = await httpClient.GetStreamAsync(decodededUrl);
    
         var transcriptionOptions = new AudioTranscriptionOptions()
         {
             DeploymentName = "whisper",
             AudioData = BinaryData.FromStream(audioStreamFromBlob),
             ResponseFormat = AudioTranscriptionFormat.Verbose,
             Filename = "file.mp3"
         };
    
         Response<AudioTranscription> transcriptionResponse = await clientWE.GetAudioTranscriptionAsync(
             transcriptionOptions);
         AudioTranscription transcription = transcriptionResponse.Value;
    
         return transcription.Text;
     }
    
  5. Aggiungere il codice seguente per eseguire Estrazione nome guest:

     //Get Audio Transcription
     public static async Task<string> GetTranscription(string podcastUrl)
     {
         var decodededUrl = HttpUtility.UrlDecode(podcastUrl);
    
         HttpClient httpClient = new HttpClient();
         Stream audioStreamFromBlob = await httpClient.GetStreamAsync(decodededUrl);
    
         var transcriptionOptions = new AudioTranscriptionOptions()
         {
             DeploymentName = "whisper",
             AudioData = BinaryData.FromStream(audioStreamFromBlob),
             ResponseFormat = AudioTranscriptionFormat.Verbose,
             Filename = "file.mp3"
         };
    
         Response<AudioTranscription> transcriptionResponse = await clientWE.GetAudioTranscriptionAsync(
             transcriptionOptions);
         AudioTranscription transcription = transcriptionResponse.Value;
    
         return transcription.Text;
     }
    
  6. Aggiungere il codice seguente alla classe PodcastCopilot per eseguire Estrazione bio guest da Bing:

     //Get Guest Bio from Bing
     public static async Task<string> GetGuestBio(string guestName)
     {
         var client = new HttpClient();
    
         client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", bingSearchKey);
    
         HttpResponseMessage response = await client.GetAsync($"{bingSearchUrl}?q={guestName}");
    
         string responseBody = await response.Content.ReadAsStringAsync();
    
         // Parse responseBody as JSON and extract the bio.
         JObject searchResults = JObject.Parse(responseBody);
         var bio = searchResults["webPages"]["value"][0]["snippet"].ToString();
    
         return bio;
     }
    
  7. Aggiungere il codice seguente per eseguire il passaggio successivo del processo PodcastCopilot: Crea testo descrittivo social media.

     //Create Social Media Blurb
     public static async Task<string> GetSocialMediaBlurb(string transcription, string bio)
     {
         var completionOptions = new ChatCompletionsOptions()
         {
             DeploymentName = "gpt35turbo",
             Messages =
             {
                 new ChatRequestSystemMessage(
                     @"You are a helpful large language model that can create a 
                     LinkedIn promo blurb for episodes of the podcast 
                     Behind the Tech, when given transcripts of the podcasts.
                     The Behind the Tech podcast is hosted by Kevin Scott.\n"
                 ),
                 new ChatRequestUserMessage(
                     @"Create a short summary of this podcast episode 
                     that would be appropriate to post on LinkedIn to    
                     promote the podcast episode. The post should be 
                     from the first-person perspective of Kevin Scott, 
                     who hosts the podcast.\n" +
                     $"Here is the transcript of the podcast episode: {transcription} \n" +
                     $"Here is the bio of the guest: {bio} \n"
                 )
             },
             Temperature = (float)0.7
         };
    
         Response<ChatCompletions> completionsResponse = await clientWE.GetChatCompletionsAsync(
             completionOptions);
         ChatCompletions completion = completionsResponse.Value;
    
         return completion.Choices[0].Message.Content;
     }
    
  8. Aggiungere il codice seguente per eseguire il passaggio successivo del processo PodcastCopilot: Crea un prompt Dall.E.

     //Generate a Dall-E prompt
     public static async Task<string> GetDallEPrompt(string socialBlurb)
     {
         var completionOptions = new ChatCompletionsOptions()
         {
             DeploymentName = "gpt35turbo",
             Messages =
         {
             new ChatRequestSystemMessage(
                 @"You are a helpful large language model that generates 
                 DALL-E prompts, that when given to the DALL-E model can 
                 generate beautiful high-quality images to use in social 
                 media posts about a podcast on technology. Good DALL-E 
                 prompts will contain mention of related objects, and 
                 will not contain people or words. Good DALL-E prompts 
                 should include a reference to podcasting along with 
                 items from the domain of the podcast guest.\n"
             ),
             new ChatRequestUserMessage(
                 $@"Create a DALL-E prompt to create an image to post along 
                 with this social media text: {socialBlurb}"
             )
         },
             Temperature = (float)0.7
         };
    
         Response<ChatCompletions> completionsResponse = await clientWE.GetChatCompletionsAsync(
         completionOptions);
    
         ChatCompletions completion = completionsResponse.Value;
    
         return completion.Choices[0].Message.Content;
     }
    
  9. Aggiungere il codice seguente per eseguire il passaggio successivo del processo PodcastCopilot: Genera immagine social media da DallE.

     //Create social media image with a Dall-E
     public static async Task<string> GetImage(string prompt)
     {
         var generationOptions = new ImageGenerationOptions()
         {
             Prompt = prompt + ", high-quality digital art",
             ImageCount = 1,
             Size = ImageSize.Size1024x1024,
             Style = ImageGenerationStyle.Vivid,
             Quality = ImageGenerationQuality.Hd,
             DeploymentName = "dalle3",
             User = "1",
         };
    
         Response<ImageGenerations> imageGenerations =
             await clientSC.GetImageGenerationsAsync(generationOptions);
    
         return imageGenerations.Value.Data[0].Url.ToString();
     }
    

Si è creata la classe PodcastCopilot, che contiene i metodi per eseguire il processo che accetta un URL del podcast e restituisce un post sui social media e un'immagine per quel podcast. È ora possibile creare la classe SocialMediaPost.

Creazione della classe SocialMediaPost

L'attività successiva consiste nel creare la classe SocialMediaPost.

Iniziare facendo clic con il pulsante destro del mouse sul progetto PodcastAppAPI per aprire il menu di scelta rapida. Selezionare Aggiungi > Classe. Assegnare alla classe il nome SocialMediaPost, quindi aggiungere il codice seguente alla classe:

```
public class SocialMediaPost
{
    public string ImageUrl { get; set; }
    public string Blurb { get; set; }
}
```

La classe dovrà avere un aspetto simile all'esempio seguente.

Screenshot della classe SocialMediaPost.

Dopo aver creato la classe SocialMediaPost, è possibile aggiungere un altro metodo alla classe PodcastCopilot per restituire un oggetto SocialMediaPost.

Aggiornamento della classe PodcastCopilot

Per aggiornare la classe PodcastCopilot, aprire la classe PodcastCopilot e aggiungere il metodo seguente alla classe:

```
public static async Task<SocialMediaPost> GenerateSocialMediaPost(string podcastUrl)
{
    var transcription = await GetTranscription(podcastUrl);
    var guestName = await GetGuestName(transcription);
    var guestBio = await GetGuestBio(guestName);
    var generatedBlurb = await GetSocialMediaBlurb(transcription, guestBio);
    var dallePrompt = await GetDallEPrompt(generatedBlurb);
    var generatedImage = await GetImage(dallePrompt);

    var socialMediaPost = new SocialMediaPost()
    {
        ImageUrl = generatedImage,
        Blurb = generatedBlurb
    };

    return socialMediaPost;
}
```

Ora è possibile procedere all'aggiornamento del file Program.cs per poter implementare l'API minima.

Aggiornamento del file Program.cs con l'implementazione API minima

L'attività successiva consiste nell'aggiornare il file Program.cs con l'implementazione API minima.

A tale scopo, iniziare aprendo il file Program.cs. Sostituire tutto il codice in questo file con il codice seguente:

```
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

//Implement Minimal APIs

app.Run();
```

Ora è possibile trasformare l'API in un connettore personalizzato da usare in Microsoft Power Platform.

Creazione di un connettore personalizzato da Visual Studio

Per creare un connettore personalizzato da Visual Studio, effettuare i passaggi seguenti:

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo Servizi connessi per aprire il menu di scelta rapida. Selezionare Aggiungi > Microsoft Power Platform.

    Screenshot dell'aggiunta di un nuovo servizio connesso.

  2. Assicurarsi di aver effettuato l'accesso con lo stesso account del piano di sviluppo di Power Apps. Nella finestra pop-up Connetti a Microsoft Power Platform configurare le impostazioni seguenti:

    • Ambienti Power Platform: selezionare un ambiente a scelta.

    • Soluzioni Power Platform: selezionare una soluzione a scelta.

    • Connettori personalizzati: creare un nuovo connettore personalizzato e denominarlo PodcastCopilot_Connector.

    • Specifica di OpenAPI: selezionare l'opzione Genera automaticamente la specifica OpenAPI V2.

    • Seleziona un tunnel di sviluppo pubblico: creare un nuovo tunnel di sviluppo e denominarlo PodcastCopilot_Tunnel.

  3. Selezionare Avanti > Fine.

    Screenshot della configurazione di un servizio connesso.

  4. Dopo aver completato il processo di configurazione delle dipendenze, chiudere la finestra pop-up.

  5. Eseguire l'applicazione. Se nella finestra del browser viene visualizzato il messaggio seguente, selezionare Continua per connettersi al tunnel di sviluppo.

    Screenshot del messaggio Connetti al tunnel di sviluppo e del pulsante Continua.

    Dopo la connessione del tunnel di sviluppo, il sistema visualizza una singola operazione API che è possibile testare per determinare se funziona correttamente o meno.

  6. Selezionare l'operazione GenerateSocialMediaPost per espanderla, quindi selezionare il pulsante Prova.

    Screenshot dell'operazione Prova.

  7. Immettere l'URL dell'episodio del podcast caricato in Archiviazione BLOB di Azure nell'esercizio precedente, quindi selezionare Esegui.

  8. Prestare attenzione a un risposta dall'operazione API che raffigura l'URL di un'immagine e un testo descrittivo per i social media generato dal sistema dall'audio del podcast con Azure OpenAI.

    Screenshot della risposta dall'operazione API.

Si è creata un'API .NET usando .NET Azure OpenAI SDK e si è anche creato un connettore personalizzato da Visual Studio. Ora è possibile usare l'API in Microsoft Power Platform.

Passaggi successivi

Si è appreso come creare un'API .NET e il relativo connettore personalizzato. Successivamente, si è appreso come integrare questo connettore personalizzato negli strumenti di Microsoft Power Platform.