先祝大家 2025 新年好。

在 2024 年落地的 LLM 应用来看,基本上都是结合 RAG 技术来使用的。因为绝大多数人跟公司是没有 fine-turning 的能力的。不管是在难度还是成本的角度看 RAG 技术都友好的多。

在 RAG(Retrieval-Augmented Generation)中,向量的意义在于将文本数据转换为高维向量表示,以便进行高效的相似性搜索和信息检索。具体来说,向量在 RAG 中的作用包括:

文本嵌入:将文本数据(如用户查询、文档内容)转换为向量表示。这些向量捕捉了文本的语义信息,使得相似的文本在向量空间中距离较近。

相似性搜索:通过计算向量之间的距离(如余弦相似度),可以快速找到与查询向量最相似的文档向量,从而实现高效的信息检索。

增强生成:在生成式模型(如 GPT)生成文本时,利用检索到的相关文档向量作为辅助信息,提高生成结果的相关性和准确性。

使用 SK 对向量进行存储与检索

如果要使用 RAG 技术,基本上离不开对向量进行存储,检索等基础操作。好在 SK 已经为我们全都封装好了。以下让我们看看如何使用 SK 来玩转向量。

定义 User Model 类

定义 User Model 类用来描述数据结构。使用 VectorStoreRecordKeyAttribute 指示 key 字段,使用 VectorStoreRecordDataAttribute 指示数据字段,VectorStoreRecordVector 指示向量字段。

        public class UserModel
{
[VectorStoreRecordKey]
public string UserId { get; set; } [VectorStoreRecordData]
public string UserName { get; set; } [VectorStoreRecordData]
public string Hobby { get; set; } public string Description => $"{UserName}'s ID is {UserId} and hobby is {Hobby}"; [VectorStoreRecordVector(1024, DistanceFunction.CosineDistance, IndexKind.Hnsw)]
public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; } }

SK 为我们提供了 IVectorStore 接口。这样各种向量存储的方案只要实现这个接口就可以了。 SK 为我们提供了很多 out-of-the-box 的库,比如:InMemory, Redis, Azure Cosmos, Qdrant, PG。只要通过 nuget 安装就可以使用了。

下面我们使用 Redis 作为向量数据库给大家演示。

使用 docker 安装 redis stack server

默认 redis 是不支持向量搜索的,我们需要使用 redis/redis-stack-server:latest 这个镜像。

docker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:latest

初始化 RedisVectorStore

 var vectorStore = new RedisVectorStore(
ConnectionMultiplexer.Connect("localhost:6379").GetDatabase(),
new() { StorageType = RedisStorageType.HashSet });

初始化 collection

创建一个 collection 来存储用户信息。collection 可以认为就是关系数据库里的 表。

  // init collection
var collection = vectorStore.GetCollection<string, UserModel>("ks_user");
await collection.CreateCollectionIfNotExistsAsync();

初始化 EmbeddingGenerationService

以下还是使用本地的 ollama 服务提供 embedding generation 服务。这个服务是所有 text to vector 的核心。

 // init embedding serivce
var ollamaApiClient = new OllamaApiClient(new Uri(ollamaEndpoint), modelName);
var embeddingGenerator = ollamaApiClient.AsTextEmbeddingGenerationService();

Vector CRUD

以下代码演示了如何把 User 的 Description 字段转成 vector 后进行最基本的 Insert、Update、Delete、Get 操作。

// init user infos and vector
var users = this.CreateUserModels();
foreach (var user in users)
{
user.DescriptionEmbedding = await embeddingGenerator.GenerateEmbeddingAsync(user.Description);
}
// insert or update
foreach (var user in users)
{
await collection.UpsertAsync(user);
} // get
var alice = await collection.GetAsync("1");
Console.WriteLine(alice.UserName);
var all = collection.GetBatchAsync(users.Select(x=>x.UserId));
await foreach(var user in all)
{
Console.WriteLine(user.UserName);
} // delete
await collection.DeleteAsync("1");

Vector Search

以下演示了如何进行向量相识度搜索。先把问题的文本进行一次向量生成,然后使用这个向量进行搜索。搜索的时候可以配置匹配的字段,以及取前几个结果。

// search
var vectorSearchOptions = new VectorSearchOptions
{
VectorPropertyName = nameof(UserModel.DescriptionEmbedding),
Top = 3
};
var query = await embeddingGenerator.GenerateEmbeddingAsync("Who hobby is swimming?");
var searchResult = await collection.VectorizedSearchAsync(query,vectorSearchOptions);
await foreach (var user in searchResult.Results)
{
Console.WriteLine(user.Record.UserName);
Console.WriteLine(user.Score);
}

总结

以上我们演示了如何把数据模型向量化后配合 redis 进行 CRUD 的基本操作。同时还演示了把文本问题的向量化搜索,也就是相似的检索。虽然以上演示是配合 redis 运行的,但是 SK 还给我们提供了非常多的选择,你可以快速的选择你喜欢的向量数据库进行存储。比如:Azure Cosmos, Qdrant, PG, SQLite 等等。好了,也没啥可以多说的了,希望这篇文章能帮助到大家学习 SemanticKernel, 谢谢。

示例代码已上传到 github

https://github.com/kklldog/SKLearning

使用 SK 进行向量操作的更多相关文章

  1. OpenMesh 之向量操作

    OpenMesh 提供了许多可供使用的向量操作函数,使用特别方便. 计算距离: 从官方文档可以看到OpenMesh提供了5个函数,分别为 Scalar length() const        // ...

  2. C++ code:向量操作之添加元素

    读入一个文件aaa.txt的数据到向量中,文件中是一些整数(个数未知).要判断向量中的元素有多少个两两相等的数对. 代码如下: #include<iostream> #include< ...

  3. ca75a_c++_标准IO库-利用流对象把文件内容读取到向量-操作文件

    /*ca75a_c++_标准IO库习题练习习题8.3,8.4,8.6习题8.9.8.10 ifstream inFile(fileName.c_str());1>d:\users\txwtech ...

  4. matlab 向量操作作业

    写出下列语句的计算结果及作用 clear    清除所有变量 clc    清屏 A = [2 5 7 1 3 4];    创建行向量并赋值 odds = 1:2:length(A);    冒号操 ...

  5. C++ STL中vector(向量容器)使用简单介绍

    原文:http://www.seacha.com/article.php/knowledge/cbase/2013/0903/2205.html C++ vector(向量容器)是一个线性顺序结构.相 ...

  6. 【转】C++ Vector(向量容器)

    转自:https://blog.csdn.net/studentyyl/article/details/21177445 vector是一个线性顺序结构.相当于数组,但其大小可以不预先指定,并且自动扩 ...

  7. 【足迹C++primer】32、定制操作_2

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/cutter_point/article/details/32301839 定制操作_2 完整的big ...

  8. Eigen子矩阵操作

    1 子矩阵操作简介 子矩阵操作又称块操作,在矩阵运算中,子矩阵的提取和操作应用也十分广泛.因此Eigen中也提供了相关操作的方法.提取的子矩阵在操作过程中既可以用作左值也可以用作右值. 2 块操作的一 ...

  9. [OpenCV-Python] OpenCV 核心操作 部分 III

    部分 III核心操作 OpenCV-Python 中文教程(搬运)目录 9 图像的基础操作 目标 • 获取像素值并修改 • 获取图像的属性(信息) • 图像的 ROI() • 图像通道的拆分及合并几乎 ...

  10. R语言多元素向量

    使用冒号运算带有数值数据(数值的增加为1) # Creating a sequence from 5 to 13. v <- 5:13 print(v) # Creating a sequenc ...

随机推荐

  1. 如何使用图片压缩降低COS流量成本?

    导语 本文将介绍如何通过[图片压缩]能力,让您降本增效的使用 COS ,文章将写得浅显易懂,旨在快速带领用户了解图片压缩的用法及带来的收益. **** 图片压缩为什么会让您降本增效?******** ...

  2. 黑苹果 - 搭建python自动化测试环境

    通用环境 1. 安装 xcode 从 AppStore 安装 安装完成之后,打开 xcode,同意各种协议 不用新建项目 注意: xcode下载完成后,安装的过程很慢,需要等待.我是12.5版本,差不 ...

  3. java到报名的编码运行

    Hello.java package a.b; import com.beyondiary.kit.KitConstant; public class Hello { public static vo ...

  4. 时间轮在 Netty , Kafka 中的设计与实现

    本文基于 Netty 4.1.112.Final , Kafka 3.9.0 版本进行讨论 在业务开发的场景中,我们经常会遇到很多定时任务的需求.比如,生成业务报表,周期性对账,同步数据,订单支付超时 ...

  5. shell(希尔)排序------python实现

    if __name__ == '__main__': ''' 希尔排序 1.选择一个增量序列t1,t2,...,tk,其中ti>tj,tk=1 2.按增量序列个数K,对序列进行K躺排序 3.每趟 ...

  6. Qt音视频开发04-保存音频文件(pcm/wav/aac)

    一.前言 音频的保存相对来说比视频的要简单,具有通用性,不需要经过ffmpeg的编码,ffmpeg解码出来后一般会转换成pcm原始的数据用来播放,所以对数据直接写文件即可,但是这种格式是无法用播放器直 ...

  7. Qt编写可视化大屏电子看板系统22-平滑曲线图

    一.前言 平滑曲线是所有涉及到曲线图的项目中,绕不开的一个话题,尽管很多人爱看折线图,但是很多时候来个平滑曲线图,会更加赏心悦目,这就好比现在的手机app移动客户端上,从最初的四方四正到现在的平滑圆角 ...

  8. 11.15javaweb学习

  9. Windows下用CMake构建和编译第三方依赖库并向C:\Program Files\或C:\Program Files (x86)\目录下安装编译好的静态库(.lib)和动态链接库(.dll)时的步骤和注意事项

    从CMake构建和编译第三方依赖库的步骤: 1.下载第三方依赖库的源码,并解压到指定的目录中. 2.在第三方依赖库的的源码所在的目录下(一般是src/目录下)创建一个文件夹build. 3.打开CMa ...

  10. eclipse中汉字横着的问题解决

    最近在eclipse中加上中午注释,出现那种汉字是横着的情况,解决方案如下: 方法一: 同一种字体有两种显示方式,比如Fixedsys Excelsior 3.01和@Fixedsys Excelsi ...