プロンプトをファイルに保存する
ここまでのユニットでは、kernel.InvokePromptAsync
を呼び出して再利用可能なプロンプトを作成する方法を学習しました。 次に例を示します。
Console.WriteLine(
await kernel.InvokePromptAsync(generateNamesOfPrompt, new() {{ "input", "fantasy characters" }})
);
インライン プロンプトを作成すると便利ですが、大規模なプロジェクトでは、プロンプトを別々のファイルに整理し、カーネルにインポートすることができます。 これは、組み込みのプラグインの使用方法に似ています。 独自のプロンプト プラグインを作成する場合のベスト プラクティスは、使用するプロンプトのために別個のフォルダーを作成する方法です。''
セマンティック プラグインの作成方法
Semantic Kernel SDK では、いくつかのシンプルな構文規則を使用したプロンプト テンプレート言語がサポートされています。 コードを記述したり、外部ライブラリをインポートしたりする必要はありません。中かっこ {{...}} を使用して プロンプトに式を埋め込みます。
セマンティック プラグインを作成するには、1 つのフォルダー内に、skprompt.txt
ファイルと config.json
ファイル、合計 2 個のファイルを用意する必要があります。 skprompt.txt
ファイルには、大規模言語モデル (LLM) へのプロンプトを含めます。これは今まで記述してきたさまざまなプロンプトと同様のものです。 config.json
ファイルには、そのプロンプトに関する詳細な構成情報を含めます。
config.json
ファイルでは以下のパラメーターがサポートされています。
type
: プロンプトの種類。 通常は、チャット補完プロンプト タイプを使用します。description
: プロンプトで何を行うかの説明。 この説明は、カーネルがプロンプトを自動的に呼び出すために使用できます。input_variables
: プロンプト内で使用する変数を定義します。execution_settings
: 補完モデルに関する設定。 OpenAI モデルの場合、これらの設定にはmax_tokens
およびtemperature
プロパティが含まれます。
たとえば、音楽コーチ エージェントを作成する場合を考えてみましょう。 あり得るコード進行に続くコードの提案機能をサポートする必要があるとします。 これは、ユーザーから示された冒頭のコード列に対し、流れに合った続きのコード候補を提案する機能です。
そのようなプラグインを作成するには、プロジェクト内に 'Prompts' フォルダーを作成し、さらに 'SuggestChords' というサブフォルダーを作成します。 この 'SuggestChords' フォルダーに、'skprompt.txt' ファイルと 'config.json' ファイルを追加します。
'skprompt.txt' ファイルの例:
<message role="system">Instructions: You are a helpful music theory assistant.
Provide the user with several chords that they could add to a chord progression
based on some starting chords they provide</message>
<message role="user">Am Em</message>
<message role="assistant">
C major, F major, G major, D major, E major, B minor
</message>
<message role="user"> {{$startingChords}}</message>
'config.json' ファイルの例:
{
"schema": 1,
"type": "completion",
"description": "Recommends chords to the user based on starting chords",
"execution_settings": {
"default": {
"max_tokens": 1000,
"temperature": 0
}
},
"input_variables": [
{
"name": "startingChords",
"description": "The starting chords provided by the user",
"required": true
},
]
}
この例で、temperature
は、生成されたテキストをどの程度ランダム化するかを制御するパラメーターです。 値は 0 から 2 までの範囲で指定する必要があります。 温度は、低いほど正確にポイントを絞った厳密な出力が得られ、高いほど多様で創造的な出力が得られます。
現在のモデルでは、プロンプトと補完の間で共有される最大 4,097 個のトークンを要求で使用できます。 つまり、プロンプトが 4,000 トークンの場合、チャットの完了は最大 97 トークンになります。 パラメーターの微調整の詳細については、LLM のドキュメントを参照してください。
カスタム セマンティック プラグインを使用するには、プロンプト ディレクトリをカーネルにインポートし、そのフォルダー名でプラグインを呼び出します。 次に例を示します。
var plugins = kernel.CreatePluginFromPromptDirectory("Prompts");
string input = "G, C";
var result = await kernel.InvokeAsync(
plugins["SuggestChords"],
new() {{ "startingChords", input }});
Console.WriteLine(result);
この例で、CreatePluginFromPromptDirectory
は KernelPlugin
オブジェクトを返します。 このオブジェクトは、関数のコレクションを表します。 CreatePluginFromPromptDirectory
は、指定されたプラグイン ディレクトリのパスを受け入れます。各サブフォルダーの名前が関数名として使用されます。
たとえば、"ChordProgressions" という名前のフォルダー内に "SuggestChords" を入れ子にした場合、prompt ディレクトリ "Prompts/ChordProgressions" を使用することになり、関数名は変わりません。 または、'Prompt' ディレクトリを指定し、関数名として 'ChordProgressions/SuggestChords' を参照することもできます。
// Example of nested prompt folders
var chordProgressionPlugin = kernel.CreatePluginFromPromptDirectory("Prompts/ChordProgressions");
string input = "G, C";
var result = await kernel.InvokeAsync(
chordProgressionPlugin["SuggestChords"],
new() {{ "startingChords", input }});
Console.WriteLine(result);
このコードを実行すると、次のような応答が生成されます。
D major, A minor, E minor, B minor, F major, G7
プロンプトをファイルに保存することは、コードを整理してメンテナンスしやすくするための優れた方法です。 より予測可能なユーザー エクスペリエンスを実現するために、構成ファイルを使用してプロンプトをさらに調整することもできます。