SemanticKernel/C#:检索增强生成(RAG)简易实践
检索增强生成(RAG)是什么?
RAG是“Reference-based Generative model with Attention”的缩写,也可以被称为“Retrieval-Augmented Generation”,是一种结合了检索技术和生成模型的方法,主要用于自然语言处理任务,如文本生成、对话系统、机器翻译等。RAG模型通过从外部知识库中检索相关信息,并将其与输入文本结合,以生成更准确、更丰富的输出。这种方法可以提高模型的准确性和可解释性,因为它可以明确地指出生成的文本与哪些外部知识相关。RAG模型在处理需要大量背景知识的任务时特别有用,如专业领域的问答系统或对话代理。
本示例实现的效果
在使用大语言模型的过程中,会发现大语言模型在通用知识上很强,但是如果你问的是跟私有数据有关的事情,它就不知道了。比如有一段私有文本数据如下所示:
小X于2000年创建了一家名为“小X的世界”的公司,公司总部在湖北武汉,员工有300人。小X最喜欢的编程语言是C#,小X最喜欢的书是《平凡的世界》。
这只是个简单的例子,所以文本先取的很短,实际上可以换成是你的一些私有文档,然后让大语言模型根据你的私有文档进行回答,现在你如果问大语言模型,“小X创建的公司叫什么?”、”小X最喜欢的编程语言是什么?“等等一些根据私有文档才能回答的问题,大语言模型是不知道的,但是通过RAG就可以让大语言模型回答诸如此类的需要根据私有文档才能回答的问题。


实现的思路是通过嵌入模型将文本转化为向量,将向量存入数据库,检索时基于输入查询的向量表示,从知识库中检索出最相关的文档或片段。将获取的相关片段,嵌入到Prompt中,让大语言模型根据获取到的片段进行回答。
开始实践
安装所需的nuget包:

首先先初始化一个Kernel,这里我使用的大语言模型是硅基流动平台提供的开源的Qwen/Qwen2-7B-Instruct。
private readonly Kernel _kernel;
public SemanticKernelService()
{
var handler = new OpenAIHttpClientHandler();
var builder = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: "Qwen/Qwen2-7B-Instruct",
apiKey: "api key",
httpClient: new HttpClient(handler));
var kernel = builder.Build();
_kernel = kernel;
}
由于硅基流动平台已经提供了与OpenAI兼容的格式,只需要在传入一个HttpClient将请求转发到硅基流动平台的api即可,OpenAIHttpClientHandler类如下所示:
public class OpenAIHttpClientHandler : HttpClientHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
UriBuilder uriBuilder;
switch (request.RequestUri?.LocalPath)
{
case "/v1/chat/completions":
uriBuilder = new UriBuilder(request.RequestUri)
{
// 这里是你要修改的 URL
Scheme = "https",
Host = "api.siliconflow.cn",
Path = "v1/chat/completions",
};
request.RequestUri = uriBuilder.Uri;
break;
case "/v1/embeddings":
uriBuilder = new UriBuilder(request.RequestUri)
{
// 这里是你要修改的 URL
Scheme = "https",
Host = "api.siliconflow.cn",
Path = "v1/embeddings",
};
request.RequestUri = uriBuilder.Uri;
break;
}
HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
return response;
}
}
现在需要将文本转化为向量,需要先构建一个ISemanticTextMemory:

现在先来看看如何构建一个ISemanticTextMemory:
public async Task<ISemanticTextMemory> GetTextMemory2()
{
var memoryBuilder = new MemoryBuilder();
memoryBuilder.WithOpenAITextEmbeddingGeneration("text-embedding-ada-002", "api key");
IMemoryStore memoryStore = await SqliteMemoryStore.ConnectAsync("memstore.db");
memoryBuilder.WithMemoryStore(memoryStore);
var textMemory = memoryBuilder.Build();
return textMemory;
}
首先需要有一个嵌入模型,这里使用的是OpenAI的text-embedding-ada-002模型,也尝试过使用硅基流动平台提供的嵌入模型,生成向量是没有问题的,但是在搜索的时候会报错,还没有解决。
使用SQLite来存储生成的向量。
var lines = TextChunker.SplitPlainTextLines(input, 100);
var paragraphs = TextChunker.SplitPlainTextParagraphs(lines, 1000);
foreach (var para in paragraphs)
{
await textMemory.SaveInformationAsync(index, id: Guid.NewGuid().ToString(), text: para, cancellationToken: default);
}
将文本分段,本示例文本内容很少,只有一段。
查看数据库:

已经将向量数据存入数据库了。
现在根据问题,搜索最相关的片段:

以“小X最喜欢的编程语言是什么?”这个问题为例。

将问题转化为向量并利用余弦相似度进行检索搜索最相关的片段:

将获取到的最相关的文本与问题嵌入到Prompt中,让大语言模型回答:

大语言模型的回答结果:

以上就基于SemanticKernel实现了一个简单的RAG应用。
下一步探索方向
虽然说我的电脑本地运行大语言模型不太行,但是在本地运行大语言模型还是有很多需求场景的,下一步探索如何在SemanticKernel中使用本地的大语言模型与嵌入模型。如果大语言模型运行不太行的话,再换成国内的平台,嵌入模型我试过,本地运行也还可以的。
本地运行使用的是Ollama,官方也有计划发布一个Ollama Connector:


网上查了一些资料,有些大佬已经实现了在SemanticKernel中使用Ollama中的对话模型与嵌入模型。可以等官方支持,也可以根据大佬们的分享,自己去实践一下。
Using local LLM with Ollama and Semantic Kernel - Learnings in IT (sachinsu.github.io)
Use Custom and Local AI Models with the Semantic Kernel SDK for .NET | Microsoft Learn
参考
2、https://github.com/microsoft/semantic-kernel/blob/main/dotnet/notebooks/09-memory-with-chroma.ipynb
SemanticKernel/C#:检索增强生成(RAG)简易实践的更多相关文章
- 以小25倍参数量媲美GPT-3的检索增强自回归语言模型:RETRO
NLP论文解读 原创•作者 | 吴雪梦Shinemon 研究方向 | 计算机视觉 导读说明: 一个具有良好性能的语言模型,一定量的数据样本必不可少.现有的各种语言模型中,例如GPT3具有1750亿的参 ...
- docker简易实践
docker简易实践 实验环境 操作系统:deepin 15.4 安装步骤 1.安装docker sudo apt-get install docker.io 2.启动docker服务 sudo se ...
- 基于OVS的VLAN虚拟化简易实践方案
基于OVS的VLAN虚拟化简易实践方案 前言 本实验基于ovs的vlan流表匹配,根据端口进行vlan标签插入.手工配置ovs,使其具有vlan虚拟化方案. 实验拓扑 ---- ---- | h1 | ...
- 如何为已有的类没有生成toString的方法增强生成toString方法
1:只要提到增强,我的第一思路就是代理,动态代理.但是仅仅是一个toString其实没必要使用代理模式了,有点大材小用了(动态代理其实也是最后通过反射生成toString的方法). 2:简单粗暴,可以 ...
- IDEA 中生成 MyBatis 逆向工程实践
IDEA 逆向 MyBatis 工程时,不像支持 Hibernate 那样有自带插件,需要集成第三方的 MyBatis Generator. MyBatis Generator的详细介绍 http:/ ...
- IDEA 中生成 Hibernate 逆向工程实践
谈起 Hibernate 应该得知道 Gavin King 大叔,他构建了 Hibernate ,并将其捐献给了开源社区. Hibernate 对象关系映射解决方案,为面向对象的领域模型到传统的关系型 ...
- 生成UUID简易版
最近一体化项目的主键ID都要求使用UUID,生成方法如下: import org.safehaus.uuid.UUIDGenerator; /** UUID生成器对象 */ private ...
- 简易实践的vue自定义tab入门
本文基于vue官方文档,分别为:动态组件 & 异步组件.插槽.进入/离开 & 列表过渡 章节链接描述 要想实现tab动画,首先要了解vue中哪些元素/那些组件适合在那些条件下实现动画效 ...
- 2023计算机领域顶会(A类)以及ACL 2023自然语言处理(NLP)研究子方向领域汇总
2023年的计算语言学协会年会(ACL 2023)共包含26个领域,代表着当前前计算语言学和自然语言处理研究的不同方面.每个领域都有一组相关联的关键字来描述其潜在的子领域, 这些子领域并非排他性的,它 ...
- C# 8.0 添加和增强的功能【基础篇】
.NET Core 3.x和.NET Standard 2.1支持C# 8.0. 一.Readonly 成员 可将 readonly 修饰符应用于结构的成员,来限制成员为不可修改状态.这比在C# 7. ...
随机推荐
- NOIP模拟54
我觉得,不改变也很好. 前言 这题太难了,场上竟然无人切题..(听说别的学校切题的人不少.. T1 选择 解题思路 范围比较小,并且每个边的度也比较小,因此考虑 树形DP+状压 . 大概就是对于每一个 ...
- react 高阶函数
HOC(Higher Order Components)就是一个函数,传给它一个组件,它返回一个新的组件. 高阶组件:就相当于手机壳,通过包装组件,增强组件功能. 实现步骤: 首先创建一个函数 指定函 ...
- AtCoder Beginner Contest 357
ABC357总结 AtCoder Beginner Contest 357 A - Sanitize Hands 翻译 有一瓶消毒剂,正好可以消毒 \(M\) 双手. \(N\) 名外星人陆续前来消毒 ...
- 【 INFINI Workshop 上海站】7 月 27 日一起动手实验玩转 Easysearch
[ INFINI Workshop 上海站]7 月 27 日下午 和 INFINI Labs 的技术专家面对面,第一时间了解极限实验室的发布最新产品和功能特性,通过动手实战,快速掌握最前沿的搜索技术, ...
- .NET5 IIS ASP.NET CORE 部署时 HTTP Error 502.5 - ANCM Out-Of-Process Startup Failure
.NET5 IIS ASP.NET CORE 部署时 HTTP Error 502.5 - ANCM Out-Of-Process Startup Failure 部署机器只安装了dotnet-hos ...
- 关于Compilation failed: internal java compiler error的解决方法(Idea)
关于Compilation failed: internal java compiler error的解决方法(Idea) idea编译项目时出现java: Compilation failed: i ...
- CentOS7学习笔记(七) 磁盘管理
查看硬盘分区信息 在Linux中使用lsblk命令查看硬盘以及分区信息 [root@192 ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda ...
- Spring Cloud微服务核心架构分析
Spring Cloud是一个相对比较成熟的微服务框架.虽然,Spring Cloud于2016年才推出1.0的release版本, 时间最短, 但是相比Dubbo等RPC框架, Spring Clo ...
- uniapp windows 上架 apple store
香蕉云 蒲公英 ios上架助手iOS Development 开发!先用上架助手在certificates里面生成一个p12文件在profiles里面生成mobileprovision文件就欧克了 需 ...
- STP生成树协议详解
看了网上关于STP生成树的解释感觉不是很懂,随即自己研究了一番 如有错误,欢迎指正,欢迎留言 ----------------------------------------------------- ...