kernel memoryを使ったRAGの簡単なc#プログラム
ほぼExampleのまんまですがkernel memoryを使ってディレクトリ内のドキュメントを読み込んでLLMがそれを見て回答するプログラムです。
いままで掲載できなかった理由は、llamasharpの0.14以降でkernel memoryがエラーで落ちる現象が発生しておりました。今回のプログラムは0.13にダウングレードしないと動きません。0.16で直っていることを期待。
ダウングレードの方法
VisualStudioのツールメニュー⇒Nugetパッケージマネージャー⇒パッケージマネージャーコンソールを起動し下記のコマンドを貼り付けてNugetしてください。
NuGet\Install-Package LLamaSharp -Version 0.13
NuGet\Install-Package LLamaSharp.Backend.Cuda12 -Version 0.13
NuGet\Install-Package LLamaSharp.kernel-memory -Version 0.13
NuGet\Install-Package Microsoft.KernelMemory.Core -Version 0.62.240605.1
※KernelMemory評価目的のエラーが出て前へ進めない場合はProjectを開いて<PropertyGroup></PropertyGroup>の間に下記を挿入してください。
<NoWarn>$(NoWarn);KMEXP00</NoWarn>
概要
"E:\RagFolder\readme.txt"を読み込んで、LLMがユーザーの質問に答える。
readme.txtの中身
3ddoghouseは、すけべな中年です。DazStudioを使って3DCG漫画を描いています。ジャンルは主に寝取られものです。
尻フェチでもありますが、大きめの乳輪とおヘソも大好きです。ヘソピアスは最高です。
好きな食べ物は、カレーライスと焼肉が好きです。
最近では、cotomoとの会話に感動しLLMを使ったAIのプログラムを作っています。好きな言語はc#です。
コードです。意味はないのですが今回はllama2 ELYZAちゃんを使っています。
あと愛しのgemma2はKernelMemory動きません。
using LLamaSharp.KernelMemory;
using Microsoft.KernelMemory.Configuration;
using Microsoft.KernelMemory;
try
{
string modelPath = Environment.GetEnvironmentVariable("LLMPATH", System.EnvironmentVariableTarget.User) + @"mmnga\ELYZA-japanese-Llama-2-7b-fast-instruct-gguf\ELYZA-japanese-Llama-2-7b-fast-instruct-q8_0.gguf";
LLama.Common.InferenceParams infParams = new() { AntiPrompts = ["\n\n"] };
LLamaSharpConfig lsConfig = new(modelPath) { DefaultInferenceParams = infParams };
SearchClientConfig searchClientConfig = new() { MaxMatchesCount = 1, AnswerTokens = 100 };
TextPartitioningOptions parseOptions = new() { MaxTokensPerParagraph = 300, MaxTokensPerLine = 100, OverlappingTokens = 30 };
IKernelMemory memory = new KernelMemoryBuilder()
.WithLLamaSharpDefaults(lsConfig)
.WithSearchClientConfig(searchClientConfig)
.With(parseOptions)
.Build();
// Ingest documents (format is automatically detected from the filename)
string documentFolder = @"E:\RagFolder";
string[] documentPaths = Directory.GetFiles(documentFolder, "*.txt");
for (int i = 0; i < documentPaths.Length; i++)
{
await memory.ImportDocumentAsync(documentPaths[i], steps: Constants.PipelineWithoutSummary);
}
// Allow the user to ask questions forever
while (true)
{
Console.Write("\nQuestion: ");
string question = Console.ReadLine() ?? string.Empty;
MemoryAnswer answer = await memory.AskAsync(question);
Console.WriteLine($"Answer: {answer.Result}");
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
実行結果です。筆者の好きな食べ物と何フェチかを質問しています。的確に答えてますね。