【Semantic Kernel】RAG(检索增强生成)
RAG(Retrieval-Augmented Generation)是一种结合信息检索和生成模型的自然语言处理方法。它通过检索相关文档片段作为生成模型的上下文,提高生成文本的准确性和相关性。RAG广泛应用于问答系统、对话系统和文本摘要等领域,兼具高效性和灵活性。公司的客户机器人都特别适合。下面的案例是使用GPT的embedding来向量化相关信息,然后通过关键字检索,最后把这些信息,结合用户问题送给gpt-4o,得到一个相对友好的回复结果。
代码:
/// <summary>
/// RAG(Retrieval Augmented Generation)检索增强生成
/// </summary>
public static class RAGSample
{
public static async Task Exec()
{
#pragma warning disable SKEXP0001
#pragma warning disable SKEXP0010
#pragma warning disable SKEXP0050
ISemanticTextMemory memory = new MemoryBuilder()
.WithOpenAITextEmbeddingGeneration("text-embedding-ada-002", Config.OpenAiKey)
.WithMemoryStore(new VolatileMemoryStore())//内存数据库,生产环境不能用
.Build();
#region 数据导入Memory
#pragma warning restore SKEXP0050
#pragma warning restore SKEXP0010
#pragma warning restore SKEXP0001
var sampleData = new Dictionary<string, string>
{
["info4"]
= "3年级2班有56人",
["info5"]
= "小明在3年级2班",
["info6"]
= "小明在第二中学",
["info7"]
= "第二中学有1500人"
};
var i = 0;
foreach (var entry in sampleData)
{
await memory.SaveReferenceAsync(
collection: "个人信息",
externalSourceName: "GitHub",
externalId: entry.Key,
description: entry.Value,
text: entry.Value);
}
#endregion
var builder = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(modelId: Config.OpenAiChatModel, Config.OpenAiKey);
var kernel = builder.Build();
var chatHistory = new ChatHistory();
var chat = kernel.GetRequiredService<IChatCompletionService>();
while (true)
{
Console.ResetColor();
Console.WriteLine("----------学生提问:----------");
var ask = Console.ReadLine();
chatHistory.Clear();
chatHistory.AddSystemMessage("基于下面的信息回复问题:");
await foreach (var answer in memory.SearchAsync(collection: "个人信息", query: ask, limit: 3, minRelevanceScore: 0.65d, withEmbeddings: true))
{
chatHistory.AddSystemMessage(answer.Metadata.Description);
}
chatHistory.AddUserMessage(ask);
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("==========讲师回答:==========");
AuthorRole? role = AuthorRole.Assistant;
var contentBuilder = new StringBuilder();
await foreach (var reply in chat.GetStreamingChatMessageContentsAsync(chatHistory))
{
if (reply.Role.HasValue && role != reply.Role)
{
role = reply.Role;
}
Console.Write(reply.Content);
contentBuilder.Append(reply.Content);
}
chatHistory.AddMessage(role.Value, contentBuilder.ToString());
Console.WriteLine();
}
}
}