Semantic Kernel 入门系列:Memory内存

image

了解的运作原理之后,就可以开始使用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 了。

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/58907.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

部署模型并与 TVM 集成

本篇文章译自英文文档 Deploy Models and Integrate TVM tvm 0.14.dev0 documentation 更多 TVM 中文文档可访问 →Apache TVM 是一个端到端的深度学习编译框架&#xff0c;适用于 CPU、GPU 和各种机器学习加速芯片。 | Apache TVM 中文站 本节介绍如何将 TVM 部署到各种平台&…

现代C++中的从头开始深度学习:【5/8】卷积

一、说明 在上一个故事中&#xff0c;我们介绍了机器学习的一些最相关的编码方面&#xff0c;例如 functional 规划、矢量化和线性代数规划。 现在&#xff0c;让我们通过使用 2D 卷积实现实际编码深度学习模型来开始我们的道路。让我们开始吧。 二、关于本系列 我们将学习如何…

【阻止IE强制跳转到Edge浏览器】

由于微软开始限制用户使用Internet Explorer浏览网站&#xff0c;IE浏览器打开一些网页时会自动跳转到新版Edge浏览器&#xff0c;那应该怎么禁止跳转呢&#xff1f; 1、点击电脑左下角的“搜索框”或者按一下windows键。 2、输入“internet”&#xff0c;点击【Internet选项…

springboot工程使用阿里云OSS传输文件

在application.yml文件中引入对应的配置&#xff0c;一个是对应的节点&#xff0c;两个是密钥和账号&#xff0c;还有一个是对应文件的名称&#xff1b; 采用这样方式进行解耦&#xff0c;便于后期修改。 然后需要设置一个properties类&#xff0c;去读对应的配置信息 用到了…

【前端】Vue生命周期函数(详细讲解+中文图解)

目录 一、何为生命周期1、含义2、理解 二、生命周期定义&#xff08;官网&#xff09;1、vue22、vue3 三、生命周期图解1、vue2生命周期图解2、vue3生命周期图解 四、Vue的生命周期五、Vue2生命周期和Vue3生命周期的区别六、Vue生命周期的主要阶段以及8个周期函数1、options AP…

使用MyEclipse如何部署Descriptor (XML)编辑器?

Descriptor (XML) Editor编辑器包含了高级的XML编辑功能&#xff0c;在本文中您将了解到这些编辑功能、Web XML编辑等&#xff0c;此功能包含在MyEclipse中可用。 MyEclipse v2023.1.2离线版下载 1. Web XML 编辑器 MyEclipse Web XML编辑器包括高级XML编辑功能&#xff0c;…

OpenLayers入门,OpenLayers涂鸦手绘线条、圆形和多边形,涂鸦线条自动收尾连接成多边形

专栏目录: OpenLayers入门教程汇总目录 前言 本章再次讲解OpenLayers绘制图形功能,上一章中《OpenLayers图形绘制,OpenLayers实现在地图上绘制线段、圆形和多边形》我们已经讲过多种图形的绘制,本章主要讲解自由涂鸦手绘绘制线条,圆形和任意形状。 二、依赖和使用 &q…

C#在自动化领域的应用前景与潜力

人机界面&#xff08;HMI&#xff09;开发&#xff1a;使用C#开发人机界面软件&#xff0c;实现与自动化设备的交互和监控。C#的图形界面设计能力和丰富的控件库使得开发人员能够创建直观、易用的界面。 数据采集与处理&#xff1a;C#可以与各种传感器、设备进行数据通信和采集…

xml布局不显示的编写代码方法

新建项目在新项目用dp编写布局复制粘贴去掉所有dp在复制dimen/dp_

【数据结构与算法——TypeScript】哈希表

【数据结构与算法——TypeScript】 哈希表(HashTable) 哈希表介绍和特性 哈希表是一种非常重要的数据结构&#xff0c;但是很多学习编程的人一直搞不懂哈希表到底是如何实现的。 在这一章节中&#xff0c;我门就一点点来实现一个自己的哈希表。通过实现来理解哈希表背后的原理…

抖音的竞争对手?Meta计划人工智能聊天机器人增加社交媒体数量

在来自抖音的竞争中&#xff0c;Meta着眼于用户参与的下一个前沿。 报道&#xff0c;Meta正在开发一系列具有不同个性的人工智能聊天机器人&#xff0c;此举旨在增加用户在脸书和Instagram等社交平台上的参与度金融时报和边缘。这些聊天机器人被Meta staff称为“personas ”,将…

snowboy+sherpa-onnx+Rasa+Coqui实现语音音箱【语音助手】

背景 本系列主要目标初步完成一款智能音箱的基础功能&#xff0c;包括语音唤醒、语音识别(语音转文字)、处理用户请求&#xff08;比如查天气等&#xff0c;主要通过rasa自己定义意图实现&#xff09;、语音合成(文字转语音)功能。 coqui主要在项目中完成接收rasa响应的内容&…