惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
About on SuperTechFans
MongoDB | Blog
MongoDB | Blog
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Stack Overflow Blog
Stack Overflow Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
aimingoo的专栏
aimingoo的专栏
B
Blog
博客园 - 聂微东
博客园_首页
D
DataBreaches.Net
F
Fortinet All Blogs
小众软件
小众软件
M
MIT News - Artificial intelligence
H
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
The GitHub Blog
The GitHub Blog
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
F
Full Disclosure
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - 【当耐特】
Simon Willison's Weblog
Simon Willison's Weblog
云风的 BLOG
云风的 BLOG
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
G
Google Developers Blog
B
Blog RSS Feed
Attack and Defense Labs
Attack and Defense Labs
W
WeLiveSecurity
N
News | PayPal Newsroom
Recent Announcements
Recent Announcements
AI
AI
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
V2EX - 技术
V2EX - 技术
TaoSecurity Blog
TaoSecurity Blog
S
Security Affairs
Martin Fowler
Martin Fowler
Webroot Blog
Webroot Blog
P
Palo Alto Networks Blog
S
Schneier on Security
Latest news
Latest news

博客园 - Agile.Zhou

AgileAI - 一个新的 .NET AI 库 并发,并行与异步 为什么说 IO 操作异步才有意义 自定义 Visual Studio 主题 使用 Azure AI Foundry 微调模型 SK + Neo4j 实现简单问答系统 AgileConfig-1.11.0 发布:增强的权限管理 LongRunningTask-正确用法 如何正确实现一个 BackgroundService Dynamic adaptation to application sizes (DATAS) GC 策略 使用 AutoGen Studio 打造你的私有团队 在 Aspire 项目下使用 AgileConfig 本地部署 DeepSeek Janus Pro 文生图大模型 Kernel Memory 让 SK 记住更多内容 .NET 依赖注入中的 Captive Dependency 在 Development 环境下依赖注入的行为可能有所不同 使用 SK Plugin 给 LLM 添加能力 使用 SemanticKernel 对接 Ollma 在 Github Action 管道内集成 Code Coverage Report
使用 SK 进行向量操作
Agile.Zhou · 2025-03-01 · via 博客园 - Agile.Zhou

先祝大家 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");

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

// 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