Ejercicio: Creación de un convertidor de divisas

Completado

En este ejercicio, creará un complemento que permita al usuario convertir importes de divisas de una divisa a otra. Dado que el modelo no puede acceder a Internet para determinar el tipo de cambio actual, debe proporcionar los tipos de cambio en el complemento. En este ejercicio, usará un archivo currencies.txt existente para proporcionar los tipos de cambio.

Importante

Debe completar las instrucciones de instalación de la unidad anterior, Preparación, antes de comenzar este ejercicio.

Creación de una función nativa

En esta tarea, creará una función nativa que puede convertir una cantidad de una divisa base a una divisa de destino.

  1. Cree un nuevo archivo denominado CurrencyConverter.cs en la carpeta Plugins/ConvertCurrency

  2. En el archivo CurrencyConverter.cs, agregue el código siguiente para crear una función de complemento:

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

    En este código, se usa el decorador para declarar la función nativa KernelFunction. También se usa el decorador Description para agregar una descripción de lo que hace la función. Puede usar Currency.Currencies para obtener un diccionario de divisas y sus tipos de cambio. A continuación, agregue alguna lógica para convertir una cantidad determinada de una divisa a otra.

  3. Modifique la función ConvertAmount con el código siguiente:

    [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})";
        }
    }
    

    En este código, se usa el diccionario Currency.Currencies para obtener el objeto Currency de las divisas base y de destino. A continuación, use el objeto Currency para convertir la cantidad de la divisa base a la divisa de destino. Por último, se devuelve una cadena con la cantidad convertida. A continuación, vamos a probar el complemento.

    Nota:

    Al usar el SDK de kernel semántico en sus propios proyectos, no es necesario codificar datos de forma difícil en archivos si tiene acceso a las API de RESTful. En su lugar, puede usar el complemento Plugins.Core.HttpClient para recuperar datos de las API.

  4. En el archivo Program.cs, importe e invoque la nueva función del complemento con el código siguiente:

    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);
    

    En este código, usará el método para importar el complemento ImportPluginFromType. Después, use el método InvokeAsync para invocar la función del complemento. El método InvokeAsync toma el nombre del complemento, el nombre de la función y un diccionario de parámetros. Por último, imprima el resultado en la consola. A continuación, ejecute el código para asegurarse de que funciona.

  5. En el terminal, escriba dotnet run. Debería ver la siguiente salida:

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

    Ahora que el complemento funciona correctamente, vamos a crear un mensaje de lenguaje natural que pueda detectar las divisas y la cantidad que el usuario quiere convertir.

Creación de una pregunta

En esta tarea, creará un mensaje que analiza la entrada del usuario para identificar la divisa de destino, la divisa base y la cantidad que se va a convertir.

  1. Cree una nueva carpeta denominada GetTargetCurrencies en la carpeta Prompts

  2. En la carpeta GetTargetCurrencies, cree un nuevo archivo denominado config.json

  3. Escriba el texto siguiente en el archivo 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. En la carpeta GetTargetCurrencies, cree un nuevo archivo denominado skprompt.txt

  5. Pegue el texto siguiente en el archivo 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>
    

Comprobar el trabajo

En esta tarea, ejecute su aplicación y verifique que su código funciona correctamente.

  1. Pruebe la nueva solicitud actualizando el archivo Program.cs con el código siguiente:

    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. Escriba dotnet run en el terminal. Debería ver la siguiente salida:

    AUD|KRW|140000
    

    Nota:

    Si el código no genera la salida esperada, puede revisar el código en la carpeta Solution. Es posible que tenga que ajustar la solicitud en el archivo skprompt.txt para generar resultados más exactos.

Ahora tiene un complemento que puede convertir una cantidad de una divisa a otra y una solicitud que se puede usar para analizar la entrada del usuario en un formato que la función ConvertAmount puede usar. En el ejercicio siguiente, puede usar la intención del usuario para ejecutar las funciones.