Semantic Kernel 入门系列:?Memory内存

这篇具有很好参考价值的文章主要介绍了Semantic Kernel 入门系列:?Memory内存。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Semantic Kernel 入门系列:?Memory内存

了解的运作原理之后,就可以开始使用Semantic Kernel来制作应用了。

Semantic Kernel将embedding的功能封装到了Memory中,用来存储上下文信息,就好像电脑的内存一样,而LLM就像是CPU一样,我们所需要做的就是从内存中取出相关的信息交给CPU处理就好了。

内存配置

使用Memory需要注册 embedding模型,目前使用的就是 text-embedding-ada-002。同时需要为Kernel添加MemoryStore,用于存储更多的信息,这里Semantic Kernel提供了一个 VolatileMemoryStore,就是一个普通的内存存储的MemoryStore。

var kernel = Kernel.Builder.Configure(c =>
{
	c.AddOpenAITextCompletionService("openai", "text-davinci-003", Environment.GetEnvironmentVariable("MY_OPEN_AI_API_KEY"));
	c.AddOpenAIEmbeddingGenerationService("openai", "text-embedding-ada-002", Environment.GetEnvironmentVariable("MY_OPEN_AI_API_KEY"));
})
.WithMemoryStorage(new VolatileMemoryStore())
.Build();

信息存储

完成了基础信息的注册后,就可以往Memroy中存储信息了。

const string MemoryCollectionName = "aboutMe";

await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info1", text: "My name is Andrea");
await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info2", text: "I currently work as a tourist operator");
await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info3", text: "I currently live in Seattle and have been living there since 2005");
await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info4", text: "I visited France and Italy five times since 2015");
await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info5", text: "My family is from New York");

SaveInformationAsync 会将text的内容通过 embedding 模型转化为对应的文本向量,存放在的MemoryStore中。其中CollectionName如同数据库的表名,Id就是Id。

语义搜索

完成信息的存储之后,就可以用来语义搜索了。

直接使用Memory.SearchAsync方法,指定对应的Collection,同时提供相应的查询问题,查询问题也会被转化为embedding,再在MemoryStore中计算查找最相似的信息。

var questions = new[]
{
	"what is my name?",
	"where do I live?",
	"where is my family from?",
	"where have I travelled?",
	"what do I do for work?",
};

foreach (var q in questions)
{
	var response = await kernel.Memory.SearchAsync(MemoryCollectionName, q).FirstOrDefaultAsync();
	Console.WriteLine(q + " " + response?.Metadata.Text);
}

// output
/*
what is my name? My name is Andrea
where do I live? I currently live in Seattle and have been living there since 2005
where is my family from? My family is from New York
where have I travelled? I visited France and Italy five times since 2015
what do I do for work? I currently work as a tourist operator
*/

到这个时候,即便不需要进行总结归纳,光是这样的语义查找,都会很有价值。

引用存储

除了添加信息以外,还可以添加引用,像是非常有用的参考链接之类的。

const string memoryCollectionName = "SKGitHub";

var githubFiles = 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/2-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/Getting-Started-Notebook.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/Volatile/VolatileMemoryStore.cs"]
		= "C# class that defines a volatile embedding store",
	["https://github.com/microsoft/semantic-kernel/tree/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/tree/main/samples/apps/chat-summary-webapp-react/README.md"]
		= "README: README associated with a sample starter react-based chat summary webapp",
};
foreach (var entry in githubFiles)
{
	await kernel.Memory.SaveReferenceAsync(
		collection: memoryCollectionName,
		description: entry.Value,
		text: entry.Value,
		externalId: entry.Key,
		externalSourceName: "GitHub"
	);
}

同样的,使用SearchAsync搜索就行。

string ask = "I love Jupyter notebooks, how should I get started?";
Console.WriteLine("===========================\n" +
					"Query: " + ask + "\n");

var memories = kernel.Memory.SearchAsync(memoryCollectionName, ask, limit: 5, minRelevanceScore: 0.77);
var 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("  ExternalSource: " + memory.Metadata.ExternalSourceName);
	Console.WriteLine("  Relevance: " + memory.Relevance);
	Console.WriteLine();
}
//output
/*
===========================
Query: I love Jupyter notebooks, how should I get started?

Result 1:
  URL:     : https://github.com/microsoft/semantic-kernel/blob/main/samples/notebooks/dotnet/Getting-Started-Notebook.ipynb
  Title    : Jupyter notebook describing how to get started with the Semantic Kernel
  ExternalSource: GitHub
  Relevance: 0.8677381632778319

Result 2:
  URL:     : https://github.com/microsoft/semantic-kernel/blob/main/samples/notebooks/dotnet/2-running-prompts-from-file.ipynb
  Title    : Jupyter notebook describing how to pass prompts from a file to a semantic skill or function
  ExternalSource: GitHub
  Relevance: 0.8162989178955157

Result 3:
  URL:     : https://github.com/microsoft/semantic-kernel/blob/main/README.md
  Title    : README: Installation, getting started, and how to contribute
  ExternalSource: GitHub
  Relevance: 0.8083238591883483
*/

这里多使用了两个参数,一个是limit,用于限制返回信息的条数,只返回最相似的前几条数据,另外一个是minRelevanceScore,限制最小的相关度分数,这个取值范围在0.0 ~ 1.0 之间,1.0意味着完全匹配。

语义问答

将Memory的存储、搜索功能和语义技能相结合,就可以快速的打造一个实用的语义问答的应用了。

只需要将搜索到的相关信息内容填充到 prompt中,然后将内容和问题都抛给LLM,就可以等着得到一个满意的答案了。

const string MemoryCollectionName = "aboutMe";

await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info1", text: "My name is Andrea");
await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info2", text: "I currently work as a tourist operator");
await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info3", text: "I currently live in Seattle and have been living there since 2005");
await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info4", text: "I visited France and Italy five times since 2015");
await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info5", text: "My family is from New York");

var prompt = 
"""
It can give explicit instructions or say 'I don't know' if it does not have an answer.

Information about me, from previous conversations:
{{ $fact }}

User: {{ $ask }}
ChatBot:
""";

var skill = kernel.CreateSemanticFunction(prompt);
var ask = "Hello, I think we've met before, remember? my name is...";
var fact = await kernel.Memory.SearchAsync(MemoryCollectionName,ask).FirstOrDefaultAsync();
var context = kernel.CreateNewContext();
context["fact"] = fact?.Metadata?.Text;
context["ask"] = ask;

var resultContext =await skill.InvokeAsync(context);
resultContext.Result.Dump();

//output
/*
Hi there! Yes, I remember you. Your name is Andrea, right?
*/

优化搜索过程

由于这种场景太常见了,所以Semantic Kernel中直接提供了一个技能TextMemorySkill,通过Function调用的方式简化了搜索的过程。

// .. SaveInformations 

// TextMemorySkill provides the "recall" function
kernel.ImportSkill(new TextMemorySkill());

var prompt = 
"""
It can give explicit instructions or say 'I don't know' if it does not have an answer.

Information about me, from previous conversations:
{{ recall $ask }}

User: {{ $ask }}
ChatBot:
""";

var skill = kernel.CreateSemanticFunction(prompt);
var ask = "Hello, I think we've met before, remember? my name is...";

var context = kernel.CreateNewContext();
context["ask"] = ask;
context[TextMemorySkill.CollectionParam] = MemoryCollectionName;

var resultContext =await skill.InvokeAsync(context);
resultContext.Result.Dump();
// output
/*
Hi there! Yes, I remember you. Your name is Andrea, right?
*/

这里直接使用 recall 方法,将问题传给了 TextMemorySkill,搜索对应得到结果,免去了手动搜索注入得过程。

内存的持久化

VolatileMemoryStore本身也是易丢失的,往往使用到内存的场景,其中的信息都是有可能长期存储的,起码并不会即刻过期。那么将这些信息的 embedding 能够长期存储起来,也是比较划算的事情。毕竟每一次做 embedding的转化也是需要调接口,需要花钱的。

Semantic Kernel库中包含了SQLite、Qdrant和CosmosDB的实现,自行扩展的话,也只需要实现 IMemoryStore 这个接口就可以了。

至于未来,可能就是专用的 Vector Database 了。


参考资料:文章来源地址https://www.toymoban.com/news/detail-412607.html

  1. https://learn.microsoft.com/en-us/semantic-kernel/concepts-sk/memories
  2. https://github.com/microsoft/semantic-kernel/blob/main/samples/notebooks/dotnet/6-memory-and-embeddings.ipynb
  3. https://github.com/johnmaeda/SK-Recipes/blob/main/e4-memories/notebook.ipynb
  4. https://learn.microsoft.com/en-us/semantic-kernel/concepts-ai/vectordb

到了这里,关于Semantic Kernel 入门系列:?Memory内存的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Semantic Kernel 入门系列:?Native Function

    语义的归语义,语法的归语法。 最基本的Native Function定义只需要在方法上添加 SKFunction 的特性即可。 默认情况下只需要传递一个string 参数就行,如果需要多个参数的话,和Semantic Function一样,也是使用Context,不过这里传进去是 SKContext 。在方法上使用 SKFunctionContextParameter 声

    2023年04月11日
    浏览(42)
  • Semantic Kernel 入门系列:?LLM的魔法

    ChatGPT 只是LLM 的小试牛刀,让人类能够看到的是机器智能对于语言系统的理解和掌握。 如果只是用来闲聊,而且只不过是将OpenAI的接口封装一下,那么市面上所有的ChatGPT的换皮应用都差不多。这就像是买了个徕卡镜头的手机,却只用来扫二维码一样。 由于微软的财大气粗,

    2023年04月09日
    浏览(29)
  • Semantic Kernel 入门系列:?LLM降临的时代

    不论你是否关心,不可否认,AGI的时代即将到来了。 在这个突如其来的时代中,OpenAI的ChatGPT无疑处于浪潮之巅。而在ChatGPT背后,我们不能忽视的是LLM(Large Language Model)大型语言模型。 一夜之间所有的大厂商都在搞LLM,虽然很难有谁能和OpenAI相匹敌,但是随着AI领域的新摩

    2023年04月08日
    浏览(34)
  • Semantic Kernel 入门系列:?Connector连接器

    当我们使用Native Function的时候,除了处理一些基本的逻辑操作之外,更多的还是需要进行外部数据源和服务的对接,要么是获取相关的数据,要么是保存输出结果。这一过程在Semantic Kernel中可以被归类为Connector。 Connector更像是一种设计模式,并不像Function和Memory 一样有强制和

    2023年04月15日
    浏览(42)
  • Semantic Kernel 入门系列:?突破提示词的限制

    LLM对自然语言的理解和掌握在知识内容的解读和总结方面提供了强大的能力。 但是由于训练数据本身来自于公共领域,也就注定了无法在一些小众或者私有的领域能够足够的好的应答。 因此如何给LLM 提供足够多的信息上下文,就是如今的LLM AI应用可以充分发挥能力的地方了

    2023年04月13日
    浏览(50)
  • LangChain vs Semantic Kernel

    每当向他人介绍 Semantic Kernel, 会得到的第一个问题就是 Semantic Kernel 类似于LangChain吗,或者是c# 版本的LangChain吗? 为了全面而不想重复的回答这个问题,因此我写下这篇文章。 在 ChatGPT 之前,构建 集成AI的应用程序的主要分为两个步骤: 机器学习工程师/数据科学家创建模

    2023年04月20日
    浏览(38)
  • CUDA编程模型系列六(利用shared memory和统一内存优化矩阵乘)

    CUDA编程模型系列六(利用shared memory和统一内存优化矩阵乘) 本系列教程将介绍具体的CUDA编程代码的细节 CUDA编程模型系列六(利用shared memory和统一内存优化矩阵乘)

    2024年02月11日
    浏览(47)
  • 体验Semantic Kernel图片内容识别

        前几日在浏览devblogs.microsoft.com的时候,看到了一篇名为Image to Text with Semantic Kernel and HuggingFace的文章。这篇文章大致的内容讲的是,使用 Semantic Kernel 结合 HuggingFace 来实现图片内容识别。注意,这里说的是图片内容识别,并非是 OCR ,而是它可以大致的描述图片里的主要

    2024年04月08日
    浏览(50)
  • 使用 Semantic Kernel 实现 Microsoft 365 Copilot 架构

    3月16日,微软发布了微软365 Copilot[1]。 Microsoft 365 Copilot 将您现有的 Word、Excel、PowerPoint、Outlook 和 Teams 与大型语言模型 (LLM) 的强大功能以及来自 Microsoft Graph 和 Microsoft 365 应用的数据相结合,以创建前所未有的体验。正如您在官方视频中看到的那样,Microsoft 365 Copilot的核心

    2024年02月02日
    浏览(37)
  • 旁门左道:借助 HttpClientHandler 拦截请求,体验 Semantic Kernel 插件

    前天尝试通过 one-api + dashscope(阿里云灵积) + qwen(通义千问) 运行 Semantic Kernel 插件(Plugin) ,结果尝试失败,详见前天的博文。 今天换一种方式尝试,选择了一个旁门左道走走看,看能不能在不使用大模型的情况下让 Semantic Kernel 插件运行起来,这个旁门左道就是从 Stephen T

    2024年02月19日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包