在SK 最新的1.51.0 发布后,ITextEmbeddingGenerationService
被标记为[Obsolete]
,进而推荐直接使用IEmbeddingGenerator
,本篇文章将介绍具体的食用指南。
使用向量搜索,需要使用以下NuGet包,其中:
#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。为方便演示,我这边使用的是Azure OpenAI 的模型进行嵌入。大家可以按需切换其他AI 服务提供商的模型。
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客户端。
AzureOpenAIClient
实例,用于与Azure OpenAI服务进行交互。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?”的嵌入向量。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
属性的值会被自动转换为向量。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
属性自动生成向量。// 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 包:
#r "nuget:Microsoft.Extensions.DependencyInjection"
#r "nuget:Microsoft.SemanticKernel.Connectors.Qdrant,*-*"
以上代码指定了使用依赖注入所需的NuGet包。
Microsoft.Extensions.DependencyInjection
:提供依赖注入相关的核心功能。
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();
以上代码演示了如何使用依赖注入来注册服务。
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()
:构建服务提供程序,用于后续获取已注册的服务实例。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()
:显示获取到的集合信息。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()
:显示生成的嵌入结果。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)
:遍历搜索结果并显示。// 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)
:遍历搜索结果并显示。