首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >.NET + AI | Semantic Kernel 向量搜索使用指南

.NET + AI | Semantic Kernel 向量搜索使用指南

作者头像
郑子铭
发布2025-06-21 10:42:06
发布2025-06-21 10:42:06
15200
代码可运行
举报
运行总次数:0
代码可运行

前情提要

在SK 最新的1.51.0 发布后,ITextEmbeddingGenerationService 被标记为[Obsolete],进而推荐直接使用IEmbeddingGenerator,本篇文章将介绍具体的食用指南。

使用内存向量数据库

安装 NuGet 包

使用向量搜索,需要使用以下NuGet包,其中:

代码语言:javascript
代码运行次数:0
运行
复制
#r "nuget:Microsoft.SemanticKernel.Connectors.InMemory,*-*"
#r "nuget:Microsoft.Extensions.AI,*-*"
#r "nuget:Microsoft.Extensions.AI.OpenAI,*-*"
#r "nuget:Azure.AI.OpenAI,*-*"

以上代码指定了项目所需的NuGet包。

  • Microsoft.SemanticKernel.Connectors.InMemory:提供内存向量存储连接器。
  • Microsoft.Extensions.AI:提供AI相关的扩展。
  • Microsoft.Extensions.AI.OpenAI:提供OpenAI相关的扩展。
  • Azure.AI.OpenAI:提供Azure OpenAI SDK。

初始化 AI Client

为方便演示,我这边使用的是Azure OpenAI 的模型进行嵌入。大家可以按需切换其他AI 服务提供商的模型。

代码语言:javascript
代码运行次数:0
运行
复制
using System.ClientModel;
using Microsoft.Extensions.AI;
using Azure.AI.OpenAI;

var endpoint = "YOUR_AZURE_OPENAI_ENDPOINT";
var apikey = "YOUR_API_KEY";

var azureClinet = new AzureOpenAIClient(
    endpoint: new Uri(endpoint),
    credential: new ApiKeyCredential("apikey")
);

以上代码初始化了Azure OpenAI客户端。

  • 首先,引入了必要的命名空间。
  • 然后,定义了Azure OpenAI服务的终结点和API密钥(请替换为您自己的值)。
  • 最后,创建了一个AzureOpenAIClient实例,用于与Azure OpenAI服务进行交互。

获取 IEmbeddingGenerator 实例

代码语言:javascript
代码运行次数:0
运行
复制
var generator = azureClinet.GetEmbeddingClient("text-embedding-3-small")
                            .AsIEmbeddingGenerator();

var embeddings = await generator.GenerateAsync("What is AI?");

embeddings.Display();

以上代码演示了如何获取IEmbeddingGenerator实例并生成文本嵌入。

  • azureClinet.GetEmbeddingClient("text-embedding-3-small"):获取指定嵌入模型的客户端。
  • .AsIEmbeddingGenerator():将客户端转换为IEmbeddingGenerator接口类型。
  • generator.GenerateAsync("What is AI?"):异步生成给定文本“What is AI?”的嵌入向量。

定义数据模型

代码语言:javascript
代码运行次数:0
运行
复制
using Microsoft.Extensions.VectorData;

// The data model
internalclassFinanceInfo
{
    [VectorStoreRecordKey]
    publicstring Key { get; set; } = string.Empty;

    [VectorStoreRecordData]
    publicstring Text { get; set; } = string.Empty;

    // Note that the vector property is typed as a string, and
    // its value is derived from the Text property. The string
    // value will however be converted to a vector on upsert and
    // stored in the database as a vector.
    [VectorStoreRecordVector(1536)]
    publicstring Embedding => this.Text;
}

以上代码定义了一个名为FinanceInfo的数据模型,用于存储财务信息及其向量表示。

  • [VectorStoreRecordKey]:标记Key属性为向量存储记录的主键。
  • [VectorStoreRecordData]:标记Text属性为需要进行向量化的原始文本数据。
  • [VectorStoreRecordVector(1536)]:标记Embedding属性为文本的向量表示,维度为1536。注意,这里的Embedding属性是一个计算属性,其值来源于Text属性。在数据插入时,Text属性的值会被自动转换为向量。

保存至向量数据库

代码语言:javascript
代码运行次数:0
运行
复制
using Microsoft.SemanticKernel.Connectors.InMemory;

// Use the embedding generator with the vector store.

// use in memory vector store
var vectorStore = new InMemoryVectorStore(new() { EmbeddingGenerator = generator });

var collection = vectorStore.GetCollection<string, FinanceInfo>("finances");
await collection.CreateCollectionAsync();


// Create some test data.
string[] FinanceInfo =
{
    "The budget for 2020 is EUR 100 000",
    "The budget for 2021 is EUR 120 000",
    "The budget for 2022 is EUR 150 000",
    "The budget for 2023 is EUR 200 000",
    "The budget for 2024 is EUR 364 000"
};

// Embeddings are generated automatically on upsert.
var records = FinanceInfo.Select((input, index) => new FinanceInfo { Key = index.ToString(), Text = input });
await collection.UpsertAsync(records);

以上代码演示了如何将数据保存到内存向量数据库中。

  • new InMemoryVectorStore(new() { EmbeddingGenerator = generator }):创建一个内存向量存储实例,并传入之前获取的IEmbeddingGenerator实例。
  • vectorStore.GetCollection<string, FinanceInfo>("finances"):获取一个名为“finances”的集合,该集合用于存储FinanceInfo类型的对象,主键类型为string
  • collection.CreateCollectionAsync():异步创建集合(如果尚不存在)。
  • 接着,定义了一些预算信息的测试数据。
  • FinanceInfo.Select((input, index) => new FinanceInfo { Key = index.ToString(), Text = input }):将测试数据转换为FinanceInfo对象列表。
  • collection.UpsertAsync(records):异步将记录插入或更新到集合中。在插入过程中,Embedding属性会根据Text属性自动生成向量。

执行查询

代码语言:javascript
代码运行次数:0
运行
复制
// Embeddings for the search is automatically generated on search.
var searchResult = collection.SearchAsync(
    "What is my budget for 2024?",
    top: 1);

// Output the matching result.
await foreach (var result in searchResult)
{
    result.Display();
}

以上代码演示了如何在向量数据库中执行相似性搜索。

  • collection.SearchAsync("What is my budget for 2024?", top: 1):异步搜索与查询文本“What is my budget for 2024?”最相似的1条记录。在搜索过程中,查询文本也会被自动转换为向量。
  • await foreach (var result in searchResult):遍历搜索结果。

使用依赖注入

先行安装以下NuGet 包:

代码语言:javascript
代码运行次数:0
运行
复制
#r "nuget:Microsoft.Extensions.DependencyInjection"
#r "nuget:Microsoft.SemanticKernel.Connectors.Qdrant,*-*"

以上代码指定了使用依赖注入所需的NuGet包。

  • Microsoft.Extensions.DependencyInjection:提供依赖注入相关的核心功能。

注册服务

代码语言:javascript
代码运行次数:0
运行
复制

using Microsoft.Extensions.DependencyInjection;
using Microsoft.SemanticKernel;
using Microsoft.Extensions.AI;
using System.ClientModel;
using Microsoft.Extensions.AI;
using Azure.AI.OpenAI;
using Qdrant.Client;


var endpoint = "YOUR_AZURE_OPENAI_ENDPOINT";
var apikey = "YOUR_API_KEY";

var azureClinet = new AzureOpenAIClient(
    endpoint: new Uri(endpoint),
    credential: new ApiKeyCredential("apikey")
);

var services = new ServiceCollection();

var embeddingGenerator = azureClinet.GetEmbeddingClient("text-embedding-3-small")
                            .AsIEmbeddingGenerator();     


// Register embedding generator (依赖Microsoft.Extensions.AI NuGet 包)
services.AddEmbeddingGenerator(embeddingGenerator);

var qdrantEndpoint = "YOUR_QDRANT_ENDPOINT";
var qdrantApiKey= "YOUR_QDRANT_API_KEY";

var qdrantClient = new QdrantClient(
  address: new Uri("qdrantEndpoint"),
  apiKey: "qdrantApiKey"
);

services.AddSingleton<QdrantClient>(sp => qdrantClient); // 假设 qdrantClient 已经定义

var options = new QdrantVectorStoreOptions 
{
    EmbeddingGenerator = embeddingGenerator
};

// Register the Qdrant vector store
services.AddQdrantVectorStore(options); // 假设 AddQdrantVectorStore 已经定义

// Register the Qdrant vector store collection
services.AddQdrantVectorStoreRecordCollection<Guid, FinanceInfo>( 
    "finances",
    new QdrantVectorStoreRecordCollectionOptions<FinanceInfo>
    {
        EmbeddingGenerator = embeddingGenerator
    });


var serviceProvider = services.BuildServiceProvider();

以上代码演示了如何使用依赖注入来注册服务。

  • 首先,初始化了Azure OpenAI客户端,与之前的示例类似。
  • new ServiceCollection():创建了一个服务集合,用于注册各种服务。
  • azureClinet.GetEmbeddingClient("text-embedding-3-small").AsIEmbeddingGenerator():获取IEmbeddingGenerator实例。
  • services.AddEmbeddingGenerator(embeddingGenerator):将IEmbeddingGenerator实例注册到服务集合中。
  • services.AddQdrantVectorStore(options) 注册了Qdrant的IVectorStore 服务实现
  • services.AddQdrantVectorStoreRecordCollection<Guid, FinanceInfo>("finances", ...):注册了一个名为“finances”的集合,集合中存储FinanceInfo类型的对象,主键类型为Guid。这里的QdrantVectorStoreRecordCollectionOptions<FinanceInfo>指定了嵌入生成器。该扩展方法相当于注册了:
    • IVectorStoreRecordCollection<Guid, FinanceInfo>的实现。
    • IVectorSearch<FinanceInfo>的实现。
  • services.BuildServiceProvider():构建服务提供程序,用于后续获取已注册的服务实例。

获取 IVectorStore 实例

代码语言:javascript
代码运行次数:0
运行
复制
var vectorStore = serviceProvider.GetRequiredService<IVectorStore>();

// List all collections
var collections = vectorStore.ListCollectionNamesAsync();
await foreach (var collectionName in collections)
{
    collectionName.Display();
}

// Get the collection 
// Note that the collection is created automatically if it does not exist
var collection = vectorStore.GetCollection<Guid, FinanceInfo>("finances"); 
collection.Display();

以上代码演示了如何从服务提供程序中获取IVectorStore实例并进行操作。

  • serviceProvider.GetRequiredService<IVectorStore>():从服务提供程序中获取已注册的IVectorStore实例。
  • vectorStore.ListCollectionNamesAsync():异步列出向量存储中的所有集合名称。
  • await foreach (var collectionName in collections):遍历集合名称并显示。
  • vectorStore.GetCollection<Guid, FinanceInfo>("finances"):获取名为“finances”的集合,该集合用于存储FinanceInfo类型的对象,主键类型为Guid。如果集合不存在,通常会自动创建。
  • collection.Display():显示获取到的集合信息。

获取 IEmbeddingGenerator 实例

代码语言:javascript
代码运行次数:0
运行
复制
var embeddingGenerator = serviceProvider.GetRequiredService<IEmbeddingGenerator<string,Embedding<float>>>();
var embeddingResult = await embeddingGenerator.GenerateAsync("what's the weather like today?");
embeddingResult.Display();

以上代码演示了如何从服务提供程序中获取IEmbeddingGenerator实例并生成嵌入。

  • serviceProvider.GetRequiredService<IEmbeddingGenerator<string,Embedding<float>>>():从服务提供程序中获取已注册的IEmbeddingGenerator实例。这里指定了输入类型为string,输出类型为Embedding<float>
  • embeddingGenerator.GenerateAsync("what's the weather like today?"):异步生成给定文本的嵌入向量。
  • embeddingResult.Display():显示生成的嵌入结果。

获取 IVectorSearch 实例

代码语言:javascript
代码运行次数:0
运行
复制
var financeSearch = serviceProvider.GetRequiredService<IVectorSearch<FinanceInfo>>(); 
var searchResult = financeSearch.SearchAsync("What is my budget for 2024?", top: 1);
await foreach (var item in searchResult)
{
    item.Display();
}

以上代码演示了如何从服务提供程序中获取IVectorSearch<T>实例并执行搜索。

  • serviceProvider.GetRequiredService<IVectorSearch<FinanceInfo>>():从服务提供程序中获取已注册的IVectorSearch<FinanceInfo>实例,用于搜索FinanceInfo类型的记录(假设FinanceInfo已定义)。
  • financeSearch.SearchAsync("What is my budget for 2024?", top: 1):异步搜索与查询文本最相似的1条记录。
  • await foreach (var item in searchResult):遍历搜索结果并显示。

获取 IVectorStoreRecordCollection 实例

代码语言:javascript
代码运行次数:0
运行
复制
// directly get the regirsted collection
var financeCollection = serviceProvider.GetRequiredService<IVectorStoreRecordCollection<Guid,FinanceInfo>>(); 

financeCollection.Display();

var result = financeCollection.SearchAsync("What is my budget for 2024?", top: 1);
await foreach (var item in result)
{
    item.Display();
}

以上代码演示了如何直接从服务提供程序中获取已注册的IVectorStoreRecordCollection<Guid, FinanceInfo>实例并进行操作。

  • serviceProvider.GetRequiredService<IVectorStoreRecordCollection<Guid,FinanceInfo>>():直接获取先前注册的特定类型的集合实例。
  • financeCollection.Display():显示集合信息。
  • financeCollection.SearchAsync("What is my budget for 2024?", top: 1):在该集合上执行搜索操作。
  • await foreach (var item in result):遍历搜索结果并显示。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet NB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前情提要
  • 使用内存向量数据库
    • 安装 NuGet 包
    • 初始化 AI Client
    • 获取 IEmbeddingGenerator 实例
    • 定义数据模型
    • 保存至向量数据库
    • 执行查询
  • 使用依赖注入
    • 注册服务
    • 获取 IVectorStore 实例
    • 获取 IEmbeddingGenerator 实例
    • 获取 IVectorSearch 实例
    • 获取 IVectorStoreRecordCollection 实例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档