演習 - 通貨コンバーターを作成する

完了

この演習では、ユーザーが通貨の金額を別の通貨に換算できるプラグインを作成します。 モデルはインターネットにアクセスして現在の為替レートを決定できないため、プラグインに為替レートを提供する必要があります。 この演習では、既存のcurrencies.txt ファイルを使用して為替レートを指定します。

重要

この演習を開始する前に、前の準備のユニットにある設定手順を完了する必要があります。

ネイティブ関数を作成する

このタスクでは、基本通貨からターゲットの通貨に金額を換算できるネイティブ関数を作成します。

  1. Plugins/ConvertCurrency フォルダーに CurrencyConverter.cs という名前の新しいファイルを作成します

  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 オブジェクトを使用して、金額を基本通貨からターゲットの通貨に換算します。 最後に、換算された金額の文字列を返します。 次に、プラグインをテストしてみましょう。

    Note

    独自のプロジェクトで Semantic Kernel SDK を使用するとき、RESTful API にアクセスできる場合は、データをファイルにハードコーディングする必要はありません。 代わりに、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. Prompts フォルダーに、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
    

    Note

    コードが期待した出力を生成しない場合は、Solution フォルダー内のコードを確認できます。 より正確な結果を生成するには、skprompt.txt ファイル内のプロンプトを調整することが必要な場合があります。

これで、金額をある通貨から別の通貨に換算できるプラグインと、ユーザーの入力を ConvertAmount 関数が使用できる形式に解析するために使用できるプロンプトができました。 次の演習では、ユーザーの意図を使用して関数を実行できます。