Упражнение. Создание преобразователя валют

Завершено

В этом упражнении вы создадите подключаемый модуль, позволяющий пользователю преобразовать денежные суммы из одной валюты в другую. Так как модель не может получить доступ к Интернету, чтобы определить текущий обменный курс, необходимо предоставить курсы обмена в подключаемый модуль. В этом упражнении используется существующий файл currencies.txt для предоставления обменных курсов.

Внимание

Перед началом этого упражнения необходимо выполнить инструкции по настройке в предыдущем уроке.

Создание собственной функции

В этой задаче создается собственная функция, которая может преобразовать сумму из базовой валюты в целевую валюту.

  1. Создание файла с именем CurrencyConverter.cs в папке Plugins/ConvertCurrency

  2. CurrencyConverter.cs В файле добавьте следующий код, чтобы создать функцию подключаемого модуля:

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

    В этом коде вы используете KernelFunction декоратор для объявления собственной функции. Вы также используете Description декоратор для добавления описания того, что делает функция. Вы можете использовать Currency.Currencies для получения словаря валют и их обменных курсов. Затем добавьте некоторую логику для преобразования заданной суммы из одной валюты в другую.

  3. Измените ConvertAmount функцию с помощью следующего кода:

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

    В этом коде Currency.Currencies используется словарь для получения Currency объекта для целевых и базовых валют. Затем объект используется Currency для преобразования суммы из базовой валюты в целевую валюту. Наконец, вы возвращаете строку с преобразованной суммой. Затем давайте протестируем подключаемый модуль.

    Примечание.

    При использовании пакета SDK для семантического ядра в собственных проектах вам не нужно жестко кодировать данные в файлы, если у вас есть доступ к API RESTful. Вместо этого можно использовать подключаемый Plugins.Core.HttpClient модуль для получения данных из API.

  4. Program.cs В файле импортируйте и вызовите новую функцию подключаемого модуля со следующим кодом:

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

    В этом коде вы используете метод для импорта подключаемого ImportPluginFromType модуля. Затем вы используете InvokeAsync метод для вызова функции подключаемого модуля. Метод InvokeAsync принимает имя подключаемого модуля, имя функции и словарь параметров. Наконец, вы распечатаете результат в консоли. Затем запустите код, чтобы убедиться, что он работает.

  5. В терминале введите dotnet run. Должен появиться следующий результат:

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

    Теперь, когда подключаемый модуль работает правильно, давайте создадим запрос естественного языка, который может определить, какие валюты и объем пользователь хочет преобразовать.

Создание запроса

В этой задаче создается запрос, который анализирует входные данные пользователя для определения целевой валюты, базовой валюты и суммы для преобразования.

  1. Создание новой папки с именем GetTargetCurrencies в папке "Запросы"

  2. В папке GetTargetCurrencies создайте файл с именем config.json

  3. Введите следующий текст в 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. В папке GetTargetCurrencies создайте файл с именем skprompt.txt

  5. Введите следующий текст в 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>
    

Проверьте свою работу

В этой задаче вы запустите приложение и убедитесь, что код работает правильно.

  1. Проверьте новый запрос, обновив Program.cs файл с помощью следующего кода:

    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. Введите в терминале dotnet run. Должен появиться следующий результат:

    AUD|KRW|140000
    

    Примечание.

    Если ваш код не создает ожидаемые выходные данные, можно просмотреть код в папке решения . Чтобы получить более точные результаты, может потребоваться настроить запрос в файле skprompt.txt.

Теперь у вас есть подключаемый модуль, который может преобразовать сумму из одной валюты в другую, и запрос, который можно использовать для анализа входных данных пользователя в формат ConvertAmount , который может использоваться функцией. В следующем упражнении можно использовать намерение пользователя для выполнения функций.