Files
semantic-kernel/samples/dotnet/kernel-syntax-examples/Example14_SemanticMemory.cs
T
af03e00a79 Feature serviceregistry (#993)
### Motivation, Context and Description

This PR introduces several changes aimed to simplify the kernel and
enhancing its extensibility for AI services management. The changes
include the following:

1. Kernel simplification and extensibility: The code responsible for AI
services management, such as registration and resolution, has been moved
out of the Kernel and KernelConfig classes into a new class called
AIServiceProvider. This restructuring promotes the principle of Single
Responsibility, ensuring that each class has a clear and focused
purpose.

2. Hosting apps customization: With the introduction of the
AIServiceProvider, hosting applications now have the flexibility to
provide their own implementation of the provider if needed. This
promotes extensibility, allowing the hosting apps to tailor the AI
service management according to their specific requirements.

3. AI services registration improvements: A new method called
WithAiService has been added, which enables the registration of any new
AI service that is not currently supported.

4. Improved kernel builder interface: The Add* methods for AI services
registration have been moved from the KernelConfig class to the
KernelBuilder. This change aligns the interface with other KernelBilder
methods, such as WithLogger and WithMemory, creating a more cohesive and
intuitive kernel builder interface.

---------

Co-authored-by: Shawn Callegari <[email protected]>
Co-authored-by: Lee Miller <[email protected]>
2023-05-22 15:21:48 -07:00

172 lines
7.1 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.Memory.AzureCognitiveSearch;
using Microsoft.SemanticKernel.Memory;
using RepoUtils;
/* The files contains two examples about SK Semantic Memory.
*
* 1. Memory using Azure Cognitive Search.
* 2. Memory using a custom embedding generator and vector engine.
*
* Semantic Memory allows to store your data like traditional DBs,
* adding the ability to query it using natural language.
*/
// ReSharper disable once InconsistentNaming
public static class Example14_SemanticMemory
{
private const string MemoryCollectionName = "SKGitHub";
public static async Task RunAsync()
{
Console.WriteLine("==============================================================");
Console.WriteLine("======== Semantic Memory using Azure Cognitive Search ========");
Console.WriteLine("==============================================================");
/* This example leverages Azure Cognitive Search to provide SK with Semantic Memory.
*
* Azure Cognitive Search automatically indexes your data semantically, so you don't
* need to worry about embedding generation.
*/
var kernelWithACS = Kernel.Builder
.WithLogger(ConsoleLogger.Log)
.WithMemory(new AzureCognitiveSearchMemory(Env.Var("ACS_ENDPOINT"), Env.Var("ACS_API_KEY")))
.Build();
await RunExampleAsync(kernelWithACS);
Console.WriteLine("====================================================");
Console.WriteLine("======== Semantic Memory (volatile, in RAM) ========");
Console.WriteLine("====================================================");
/* You can build your own semantic memory combining an Embedding Generator
* with a Memory storage that supports search by similarity (ie semantic search).
*
* In this example we use a volatile memory, a local simulation of a vector DB.
*
* You can replace VolatileMemoryStore with Qdrant (see QdrantMemoryStore connector)
* or implement your connectors for Pinecone, Vespa, Postgres + pgvector, SQLite VSS, etc.
*/
var kernelWithCustomDb = Kernel.Builder
.WithLogger(ConsoleLogger.Log)
.WithOpenAITextEmbeddingGenerationService("ada", "text-embedding-ada-002", Env.Var("OPENAI_API_KEY"))
.WithMemoryStorage(new VolatileMemoryStore())
.Build();
await RunExampleAsync(kernelWithCustomDb);
}
public static async Task RunExampleAsync(IKernel kernel)
{
await StoreMemoryAsync(kernel);
await SearchMemoryAsync(kernel, "How do I get started?");
/*
Output:
Query: How do I get started?
Result 1:
URL: : https://github.com/microsoft/semantic-kernel/blob/main/README.md
Title : README: Installation, getting started, and how to contribute
Result 2:
URL: : https://github.com/microsoft/semantic-kernel/blob/main/samples/dotnet-jupyter-notebooks/00-getting-started.ipynb
Title : Jupyter notebook describing how to get started with the Semantic Kernel
*/
await SearchMemoryAsync(kernel, "Can I build a chat with SK?");
/*
Output:
Query: Can I build a chat with SK?
Result 1:
URL: : https://github.com/microsoft/semantic-kernel/tree/main/samples/skills/ChatSkill/ChatGPT
Title : Sample demonstrating how to create a chat skill interfacing with ChatGPT
Result 2:
URL: : https://github.com/microsoft/semantic-kernel/blob/main/samples/apps/chat-summary-webapp-react/README.md
Title : README: README associated with a sample chat summary react-based webapp
*/
}
private static async Task SearchMemoryAsync(IKernel kernel, string query)
{
Console.WriteLine("\nQuery: " + query + "\n");
var memories = kernel.Memory.SearchAsync(MemoryCollectionName, query, limit: 2, minRelevanceScore: 0.5);
int i = 0;
await foreach (MemoryQueryResult memory in memories)
{
Console.WriteLine($"Result {++i}:");
Console.WriteLine(" URL: : " + memory.Metadata.Id);
Console.WriteLine(" Title : " + memory.Metadata.Description);
Console.WriteLine();
}
Console.WriteLine("----------------------");
}
private static async Task StoreMemoryAsync(IKernel kernel)
{
/* Store some data in the semantic memory.
*
* When using Azure Cognitive Search the data is automatically indexed on write.
*
* When using the combination of VolatileStore and Embedding generation, SK takes
* care of creating and storing the index
*/
Console.WriteLine("\nAdding some GitHub file URLs and their descriptions to the semantic memory.");
var githubFiles = SampleData();
var i = 0;
foreach (var entry in githubFiles)
{
await kernel.Memory.SaveReferenceAsync(
collection: MemoryCollectionName,
description: entry.Value,
text: entry.Value,
externalId: entry.Key,
externalSourceName: "GitHub"
);
Console.Write($" #{++i} saved.");
}
Console.WriteLine("\n----------------------");
}
private static Dictionary<string, string> SampleData()
{
return new Dictionary<string, string>
{
["https://github.com/microsoft/semantic-kernel/blob/main/README.md"]
= "README: Installation, getting started, and how to contribute",
["https://github.com/microsoft/semantic-kernel/blob/main/samples/notebooks/dotnet/02-running-prompts-from-file.ipynb"]
= "Jupyter notebook describing how to pass prompts from a file to a semantic skill or function",
["https://github.com/microsoft/semantic-kernel/blob/main/samples/notebooks/dotnet/00-getting-started.ipynb"]
= "Jupyter notebook describing how to get started with the Semantic Kernel",
["https://github.com/microsoft/semantic-kernel/tree/main/samples/skills/ChatSkill/ChatGPT"]
= "Sample demonstrating how to create a chat skill interfacing with ChatGPT",
["https://github.com/microsoft/semantic-kernel/blob/main/dotnet/src/SemanticKernel/Memory/VolatileMemoryStore.cs"]
= "C# class that defines a volatile embedding store",
["https://github.com/microsoft/semantic-kernel/blob/main/samples/dotnet/KernelHttpServer/README.md"]
= "README: How to set up a Semantic Kernel Service API using Azure Function Runtime v4",
["https://github.com/microsoft/semantic-kernel/blob/main/samples/apps/chat-summary-webapp-react/README.md"]
= "README: README associated with a sample chat summary react-based webapp",
};
}
}