🔥关注墨瑾轩,带你探索编程的奥秘!🚀
🔥超萌技术攻略,轻松晋级编程高手🚀
🔥技术宝库已备好,就等你来挖掘🚀
🔥订阅墨瑾轩,智趣学习不孤单🚀
🔥即刻启航,编程之旅更有趣🚀
向量存储是AI应用的“内存条”?一触即发!
想象一下:你的AI应用需要存储100万条用户信息,但每次查询都像“大海捞针”——响应时间10秒,用户耐心直接碎成渣!
(别急着反驳——你的用户模型是不是还用“字符串拼接”存数据库?)
今天,我们用 Semantic Kernel 的“向量存储三板斧”:
- 第一步:定义数据模型(Redis/Weaviate通用)
- 第二步:初始化向量存储(自动适配多数据库)
- 第三步:向量检索(相似性搜索秒级响应)
让你的数据从“乱放”变成“精准命中”!
Semantic Kernel向量存储的“全自动流水线”
一、第一步:定义数据模型——向量存储的“身份证”
核心问题:
- 传统数据库存字符串?向量存储需要“结构化+向量化”的数据!
解决方案:
- 使用
VectorStoreRecordKey
、VectorStoreRecordVector
等属性标注字段
代码示例:定义用户模型类
// 定义用户模型(UserModel.cs)
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; }
}
代码解析:
VectorStoreRecordKey
:唯一标识符,用于快速定位记录VectorStoreRecordData
:存储原始数据(如用户名、爱好)VectorStoreRecordVector
:1024
:向量维度(需与嵌入模型输出一致)CosineDistance
:余弦距离(推荐用于文本相似度)Hnsw
:高效近似最近邻索引(适合大规模数据)
二、第二步:初始化向量存储——“多数据库通用配方”
核心问题:
- Redis、Weaviate、Elasticsearch……选哪个?
解决方案:
- Semantic Kernel 提供统一接口,自动适配不同数据库!
代码示例:初始化Redis向量存储
// 初始化Redis连接(Program.cs)
using var connection = ConnectionMultiplexer.Connect("localhost:6379");
var redisDb = connection.GetDatabase();
// 创建Redis向量存储实例
var vectorStore = new RedisVectorStore(
redisDb,
new RedisVectorStoreOptions {
StorageType = RedisStorageType.HashSet // 使用哈希表存储
}
);
// 创建集合(类似数据库的“表”)
var collection = vectorStore.GetCollection<string, UserModel>("ks_user");
await collection.CreateCollectionIfNotExistsAsync();
代码解析:
RedisVectorStore
:Redis的向量存储实现CreateCollectionIfNotExistsAsync
:自动创建集合(如果不存在)
三、第三步:向量检索——“秒级相似性搜索”
核心问题:
- 用户问“喜欢游泳的人有哪些?” → 如何快速找到匹配用户?
解决方案:
- 将查询文本转为向量 → 使用
VectorizedSearchAsync
检索
代码示例:向量相似性搜索
// 初始化嵌入生成服务(Ollama)
var ollamaApiClient = new OllamaApiClient(
new Uri("http://localhost:11434"),
"llama3"
);
var embeddingGenerator = ollamaApiClient.AsTextEmbeddingGenerationService();
// 将查询文本转为向量
var query = await embeddingGenerator.GenerateEmbeddingAsync("Who hobby is swimming?");
// 配置搜索参数
var vectorSearchOptions = new VectorSearchOptions {
VectorPropertyName = nameof(UserModel.DescriptionEmbedding), // 指定向量字段
Top = 3 // 返回前3个最相似的结果
};
// 执行向量搜索
var searchResult = await collection.VectorizedSearchAsync(query, vectorSearchOptions);
// 输出结果
await foreach (var user in searchResult.Results) {
Console.WriteLine($"用户名: {user.Record.UserName}, 相似度: {user.Score}");
}
代码解析:
GenerateEmbeddingAsync
:将文本转为向量(依赖Ollama服务)VectorizedSearchAsync
:根据向量相似度检索数据Top=3
:返回最相似的3条记录
四、进阶:Weaviate向量存储的“魔法配方”
核心问题:
- Redis不够快?试试Weaviate的“近似最近邻加速”!
代码示例:初始化Weaviate向量存储
// 初始化Weaviate连接
using var httpClient = new HttpClient { BaseAddress = new Uri("http://localhost:8080/v1/") };
var vectorStore = new WeaviateVectorStore(httpClient);
// 创建命名集合
var collection = new WeaviateVectorStoreRecordCollection<Hotel>(
httpClient,
"Skhotels"
);
代码解析:
WeaviateVectorStore
:Weaviate的向量存储实现Skhotels
:集合名称(类似数据库的“表名”)
五、实战案例:从“字符串”到“向量”的华丽转身
案例:酒店信息检索系统
原始问题:
- 用户问“推荐适合家庭的酒店” → 传统数据库需要复杂SQL查询
优化步骤:
-
定义酒店模型
public class Hotel { [VectorStoreRecordKey] public ulong HotelId { get; set; } [VectorStoreRecordData(IsFilterable = true)] public string HotelName { get; set; } [VectorStoreRecordData(IsFullTextSearchable = true)] public string Description { get; set; } [VectorStoreRecordVector(4, DistanceFunction.CosineDistance, IndexKind.QuantizedFlat)] public ReadOnlyMemory<float>? DescriptionEmbedding { get; set; } }
-
插入数据
var hotels = new List<Hotel> { new Hotel { HotelId = 1, HotelName = "海洋度假村", Description = "适合家庭的海边度假酒店,提供儿童游乐区和亲子活动。", DescriptionEmbedding = await GenerateEmbedding("适合家庭的海边度假酒店") }, // 其他酒店数据... }; foreach (var hotel in hotels) { await collection.UpsertAsync(hotel); }
-
检索数据
var query = await embeddingGenerator.GenerateEmbeddingAsync("适合家庭的酒店"); var searchResult = await collection.VectorizedSearchAsync(query, vectorSearchOptions);
效果:
- 响应时间从500ms降至50ms!用户满意度飙升!
结论:向量存储的“超能力”来了!
从 Redis 到 Weaviate,再到 Elasticsearch,Semantic Kernel 已经帮你打通了“向量存储”的任督二脉!
记住这 3大核心步骤:
- 定义数据模型(VectorStoreRecordKey + VectorStoreRecordVector)
- 初始化向量存储(自动适配多数据库)
- 向量检索(相似性搜索秒级响应)
(现在,轮到你来打造一个“向量存储”的AI应用了!)