次の方法で共有


Semantic Kernel SDK でメモリ ストレージに Redis を使用する

この記事では、Redis データベースと RediSearch モジュールを Semantic Kernel SDK に統合し、メモリの格納と取得に使用する方法について説明します。

ベクトル ストアは、テキスト全体に対して事前に計算された埋め込みベクトルと共に格納されているテキスト情報を表します。 LLM は、メモリの呼び出しを求められた場合、これらの事前計算済み埋め込みを使用して、メモリがプロンプトに関連しているかどうかを効率的に評価します。 LLM が一致するメモリを見つけた後、メモリのテキスト情報が、プロンプト補完の次の手順のコンテキストとして使用されます。

Semantic Kernel SDK に追加されたメモリ ストレージは、要求に対して、より広範なコンテキストを提供します。 また、従来のデータベースを格納するのと同じ方法でデータを格納できますが、自然言語を使用してクエリを実行できます。

前提条件

Redis データベースを使用してメモリ ストレージを実装する

Redis データベースを Semantic Kernel SDK に統合する前に、RediSearch モジュールが有効になっていることを確認してください。 Azure Cache for Redis のモジュールの情報については、「Azure Cache for Redis での Redis モジュールの使用」を参照してください。

  1. Redis データベースへの接続を初期化します。 次に例を示します。

    // Retrieve the Redis connection config.
    IConfigurationRoot config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
    string redisConfig = config["REDIS_CONFIG"]!;
    
    // Initialize a connection to the Redis database.
    ConnectionMultiplexer connectionMultiplexer = await ConnectionMultiplexer.ConnectAsync(
        redisConfig
    );
    IDatabase database = connectionMultiplexer.GetDatabase();
    
  2. ITextEmbeddingGenerationService を含めて Kernel をビルドします。 次に例を示します。

    // Retrieve the Azure OpenAI config and secrets saved during deployment.
    string endpoint = config["AZURE_OPENAI_ENDPOINT"]!;
    string embeddingModel = config["AZURE_OPENAI_EMBEDDING_NAME"]!;
    string completionModel = config["AZURE_OPENAI_GPT_NAME"]!;
    string key = config["AZURE_OPENAI_KEY"]!;
    
    // Build the Kernel; must add an embedding generation service.
    Kernel kernel = Kernel
        .CreateBuilder()
        .AddAzureOpenAITextEmbeddingGeneration(embeddingModel, endpoint, key)
        .AddAzureOpenAIChatCompletion(completionModel, endpoint, key)
        .Build();
    
  3. RedisMemoryStore インスタンスに Redis データベースをラップし、メモリ ストアと埋め込み生成サービスを使用して SemanticTextMemory オブジェクトを初期化します。 次に例を示します。

    // Retrieve the desired vector size for the memory store.
    // If unspecified, the default vector size is 1536.
    int vectorSize = int.Parse(config["REDIS_MEMORY_VECTOR_SIZE"]!);
    
    // Initialize a memory store using the redis database
    IMemoryStore memoryStore = new RedisMemoryStore(database, vectorSize);
    
    // Retrieve the embedding service from the Kernel.
    ITextEmbeddingGenerationService embeddingService =
        kernel.Services.GetRequiredService<ITextEmbeddingGenerationService>();
    
    // Initialize a SemanticTextMemory using the memory store and embedding generation service.
    SemanticTextMemory textMemory = new(memoryStore, embeddingService);
    
  4. TextMemoryPlugin クラスを使用してセマンティック テキスト メモリを Kernel に追加します。 次に例を示します。

    // Initialize a TextMemoryPlugin using the text memory.
    TextMemoryPlugin memoryPlugin = new(textMemory);
    
    // Import the text memory plugin into the Kernel.
    KernelPlugin memory = kernel.ImportPluginFromObject(memoryPlugin);
    
  5. Kernel とプラグインを使用してメモリの保存、取得、再呼び出しを行います。 次に例を示します。

    // Retrieve the desired memory collection name.
    string memoryCollectionName = config["REDIS_MEMORY_COLLECTION_NAME"]!;
    
    // Save a memory with the Kernel.
    await kernel.InvokeAsync(
        memory["Save"],
        new()
        {
            [TextMemoryPlugin.InputParam] = "My family is from New York",
            [TextMemoryPlugin.CollectionParam] = memoryCollectionName,
            [TextMemoryPlugin.KeyParam] = "info1",
        }
    );
    
    // Retrieve a memory with the Kernel.
    FunctionResult result = await kernel.InvokeAsync(
        memory["Retrieve"],
        new()
        {
            [TextMemoryPlugin.CollectionParam] = memoryCollectionName,
            [TextMemoryPlugin.KeyParam] = "info1",
        }
    );
    
    // Get the memory string from the function result; returns a null value if no memory is found.
    Console.WriteLine(
        $"Retrieved memory: {result.GetValue<string>() ?? "ERROR: memory not found"}"
    );
    
    // Alternatively, recall similar memories with the Kernel.
    // Can configure the memory collection, number of memories to recall, and relevance score.
    result = await kernel.InvokeAsync(
        memory["Recall"],
        new()
        {
            [TextMemoryPlugin.InputParam] = "Ask: where do I live?",
            [TextMemoryPlugin.CollectionParam] = memoryCollectionName,
            [TextMemoryPlugin.LimitParam] = "2",
            [TextMemoryPlugin.RelevanceParam] = "0.79",
        }
    );
    
    // If memories are recalled, the function result can be deserialized as a string[].
    string? resultStr = result.GetValue<string>();
    string[]? parsedResult = string.IsNullOrEmpty(resultStr)
        ? null
        : JsonSerializer.Deserialize<string[]>(resultStr);
    Console.WriteLine(
        $"Recalled memories: {(parsedResult?.Length > 0 ? resultStr : "ERROR: memory not found")}"
    );
    
  6. プロンプト テンプレート構文 {{...}} を使って、プロンプトの一部としてメモリの再呼び出しを使用します。 次に例を示します。

    // Create a prompt that includes memory recall.
    // The {{...}} syntax represents an expression to Semantic Kernel.
    // For more information on this syntax see:
    // https://learn.microsoft.com/semantic-kernel/prompts/prompt-template-syntax
    string memoryRecallPrompt = """ 
        Consider only the facts below when answering questions:
    
        BEGIN FACTS
        About me: {{recall 'where did I grow up?'}}
        END FACTS
    
        Question: What are some fun facts about my home state?
        """;
    
    // Invoke the prompt with the Kernel.
    // Must configure the memory collection, number of memories to recall, and relevance score.
    resultStr = await kernel.InvokePromptAsync<string>(
        memoryRecallPrompt,
        new()
        {
            [TextMemoryPlugin.CollectionParam] = memoryCollectionName,
            [TextMemoryPlugin.LimitParam] = "2",
            [TextMemoryPlugin.RelevanceParam] = "0.79",
        }
    );
    
    // If the memory recall fails, the model will indicate it has missing information in its output.
    // Otherwise the output will incorporate your memory as context.
    Console.WriteLine($"Output: {resultStr}");
    
  • [SQL で RAG を使用する]
  • [SharePoint からのデータ インジェスト]
  • [ベクトル データベースの操作]