Esercizio - Creare un convertitore di valute

Completato

Per questo esercizio si crea un plug-in che consente all'utente di convertire gli importi da una valuta a un'altra. Poiché il modello non è in grado di accedere a Internet per determinare il tasso di cambio corrente, è necessario fornire i tassi di cambio nel plug-in. Per questo esercizio si utilizza un file esistente currencies.txt per fornire i tassi di cambio.

Importante

Prima di iniziare questo esercizio, è necessario completare le attività di configurazione dell'unità precedente, Preparazione.

Creare una funzione nativa

In questa attività viene creata una funzione nativa, in grado di convertire un importo da una valuta di base a una valuta di destinazione.

  1. Creare un nuovo file denominato CurrencyConverter.cs nella cartella Plugins/ConvertCurrency

  2. Nel file CurrencyConverter.cs, aggiungere il codice seguente per creare una funzione plug-in:

    using AITravelAgent;
    
    class CurrencyConverter
    {
        [KernelFunction, 
        Description("Convert an amount from one currency to another")]
        public static string ConvertAmount()
        {
            var currencyDictionary = Currency.Currencies;
        }
    }
    

    In questo codice si usa l'elemento Decorator KernelFunction per dichiarare la funzione nativa. Si usa l'elemento Decorator Description anche per aggiungere una descrizione delle operazioni eseguite dalla funzione. È possibile usare Currency.Currencies per ottenere un dizionario di valute e i relativi tassi di cambio. Aggiungere quindi una logica per convertire un determinato importo da una valuta a un'altra.

  3. Modificare la funzione ConvertAmount con il codice seguente:

    [KernelFunction, Description("Convert an amount from one currency to another")]
    public static string ConvertAmount(
        [Description("The target currency code")] string targetCurrencyCode, 
        [Description("The amount to convert")] string amount, 
        [Description("The starting currency code")] string baseCurrencyCode)
    {
        var currencyDictionary = Currency.Currencies;
    
        Currency targetCurrency = currencyDictionary[targetCurrencyCode];
        Currency baseCurrency = currencyDictionary[baseCurrencyCode];
    
        if (targetCurrency == null)
        {
            return targetCurrencyCode + " was not found";
        }
        else if (baseCurrency == null)
        {
            return baseCurrencyCode + " was not found";
        }
        else
        {
            double amountInUSD = Double.Parse(amount) * baseCurrency.USDPerUnit;
            double result = amountInUSD * targetCurrency.UnitsPerUSD;
            return @$"${amount} {baseCurrencyCode} is approximately 
                {result.ToString("C")} in {targetCurrency.Name}s ({targetCurrencyCode})";
        }
    }
    

    In questo codice, si usa il dizionario Currency.Currencies per ottenere l'oggetto Currency per le valute di destinazione e di base. Usare quindi l'oggetto Currency per convertire l'importo dalla valuta di base alla valuta di destinazione. Infine, si restituisce una stringa con l'importo convertito. Adesso è possibile testare il plug-in.

    Nota

    Quando si usa Semantic Kernel SDK nei propri progetti, non è necessario impostare come hardcoded i dati nei file, se si ha accesso alle API RESTful. È invece possibile usare il plug-in Plugins.Core.HttpClient per recuperare i dati dalle API.

  4. Nel file Program.cs, importare e richiamare la nuova funzione plug-in con il codice seguente:

    kernel.ImportPluginFromType<CurrencyConverter>();
    kernel.ImportPluginFromType<ConversationSummaryPlugin>();
    var prompts = kernel.ImportPluginFromPromptDirectory("Prompts");
    
    var result = await kernel.InvokeAsync("CurrencyConverter", 
        "ConvertAmount", 
        new() {
            {"targetCurrencyCode", "USD"}, 
            {"amount", "52000"}, 
            {"baseCurrencyCode", "VND"}
        }
    );
    
    Console.WriteLine(result);
    

    In questo codice, si usa il metodo ImportPluginFromType per importare il plug-in. Usare quindi il metodo InvokeAsync per richiamare la funzione del plug-in. Il metodo InvokeAsync accetta il nome del plug-in, il nome della funzione e un dizionario di parametri. Infine, si stampa il risultato nella console. Eseguire quindi il codice per assicurarsi che funzioni.

  5. Nel terminale immettere dotnet run. Verrà visualizzato l'output seguente:

    $52000 VND is approximately $2.13 in US Dollars (USD)
    

    Ora che il plug-in funziona correttamente, creiamo un prompt del linguaggio naturale in grado di rilevare le valute e l'importo che l'utente vuole convertire.

Creare una richiesta

In questa attività viene creato un prompt che analizza l'input dell'utente per identificare la valuta di destinazione, la valuta di base e l'importo da convertire.

  1. Creare una nuova cartella denominata GetTargetCurrencies nella cartella Prompts

  2. Nella cartella GetTargetCurrencies, creare un nuovo file denominato config.json

  3. Immettere il testo seguente nel file config.json:

    {
        "schema": 1,
        "type": "completion",
        "description": "Identify the target currency, base currency, and amount to convert",
        "execution_settings": {
            "default": {
                "max_tokens": 800,
                "temperature": 0
            }
        },
        "input_variables": [
            {
                "name": "input",
                "description": "Text describing some currency amount to convert",
                "required": true
            }
        ]
    }
    
  4. Nella cartella GetTargetCurrencies, creare un nuovo file denominato skprompt.txt

  5. Immettere il testo seguente nel file skprompt.txt:

    <message role="system">Identify the target currency, base currency, and 
    amount from the user's input in the format target|base|amount</message>
    
    For example: 
    
    <message role="user">How much in GBP is 750.000 VND?</message>
    <message role="assistant">GBP|VND|750000</message>
    
    <message role="user">How much is 60 USD in New Zealand Dollars?</message>
    <message role="assistant">NZD|USD|60</message>
    
    <message role="user">How many Korean Won is 33,000 yen?</message>
    <message role="assistant">KRW|JPY|33000</message>
    
    <message role="user">{{$input}}</message>
    <message role="assistant">target|base|amount</message>
    

Controlla il tuo lavoro

In questa attività si esegue l'applicazione e si verifica che il codice funzioni correttamente.

  1. Testare il nuovo prompt aggiornando il file Program.cs con il codice seguente:

    kernel.ImportPluginFromType<CurrencyConverter>();
    var prompts = kernel.ImportPluginFromPromptDirectory("Prompts");
    
    var result = await kernel.InvokeAsync(prompts["GetTargetCurrencies"],
        new() {
            {"input", "How many Australian Dollars is 140,000 Korean Won worth?"}
        }
    );
    
    Console.WriteLine(result);
    
  2. Immettere dotnet run nel terminale. Verrà visualizzato l'output seguente:

    AUD|KRW|140000
    

    Nota

    Se il codice non produce l'output previsto, è possibile esaminare il codice nella cartella Solution. Potrebbe essere necessario modificare il prompt nel file skprompt.txt per ottenere risultati più precisi.

Ora si dispone di un plug-in che può convertire un importo da una valuta a un'altra e un prompt che può essere utilizzato per analizzare l'input dell'utente in un formato che la funzione ConvertAmount può usare. Nell'esercizio successivo, è possibile usare la finalità dell'utente per eseguire le proprie funzioni.