生成 .NET AI 矢量搜索应用

在本快速入门中,你将创建一个 .NET 控制台应用,用于在 向量存储 上执行语义搜索,以查找用户查询的相关结果。 了解如何为用户提示生成嵌入内容,并使用这些嵌入项查询矢量数据存储。

矢量存储(或矢量数据库)在语义搜索、检索扩充生成(RAG)等任务中至关重要,以及其他需要对生成型 AI 响应进行基础支持的场景。 虽然关系数据库和文档数据库针对结构化和半结构化数据进行了优化,但矢量数据库是用来有效地存储、编制索引和管理表示为嵌入向量的数据。 因此,对矢量数据库使用的索引和搜索算法进行优化,以有效地检索可在应用程序中下游使用的数据。

关于图书馆

应用使用 Microsoft.Extensions.AIMicrosoft.Extensions.VectorData ,因此可以使用 AI 抽象而不是特定 SDK 编写代码。 AI 抽象有助于创建松散耦合的代码,使你可以通过最少的应用更改来更改基础 AI 模型。

📦 Microsoft.Extensions.VectorData.Abstractions 是一个 .NET 库,与语义内核和更广泛的 .NET 生态系统协作开发,为与矢量存储交互提供统一的抽象层。 Microsoft.Extensions.VectorData.Abstractions 中的抽象为库作者和开发人员提供以下功能:

  • 对向量存储执行 create-read-update-delete (CRUD)操作。
  • 在向量库中使用向量与文本检索。

注释

Microsoft.Extensions.VectorData.Abstractions 库目前为预览版。

先决条件

先决条件

创建应用

完成以下步骤以创建可执行以下作的 .NET 控制台应用:

  • 通过为数据集生成嵌入内容来创建和填充向量存储。
  • 为用户提示生成嵌入内容。
  • 使用用户提示嵌入查询矢量存储。
  • 显示矢量搜索的相关结果。
  1. 在计算机上的空目录中,使用 dotnet new 命令创建新的控制台应用:

    dotnet new console -o VectorDataAI
    
  2. 将目录更改为应用文件夹:

    cd VectorDataAI
    
  3. 安装所需的包:

    dotnet add package Azure.Identity
    dotnet add package Azure.AI.OpenAI
    dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease
    dotnet add package Microsoft.Extensions.VectorData.Abstractions --prerelease
    dotnet add package Microsoft.SemanticKernel.Connectors.InMemory --prerelease
    dotnet add package Microsoft.Extensions.Configuration
    dotnet add package Microsoft.Extensions.Configuration.UserSecrets
    dotnet add package System.Linq.AsyncEnumerable
    

    以下列表描述了应用中的每个包 VectorDataAI

    dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease
    dotnet add package Microsoft.Extensions.VectorData.Abstractions --prerelease
    dotnet add package Microsoft.SemanticKernel.Connectors.InMemory --prerelease
    dotnet add package Microsoft.Extensions.Configuration
    dotnet add package Microsoft.Extensions.Configuration.UserSecrets
    dotnet add package System.Linq.AsyncEnumerable
    

    以下列表描述了应用中的每个包 VectorDataAI

  4. 在 Visual Studio Code 中打开应用(或所选编辑器)。

    code .
    

创建 AI 服务

  1. 若要预配 Azure OpenAI 服务和模型,请完成 创建和部署 Azure OpenAI 服务资源 文章中的步骤。

  2. 在终端或命令提示符下,导航到项目目录的根目录。

  3. 运行以下命令为示例应用配置 Azure OpenAI 终结点和模型名称:

    dotnet user-secrets init
    dotnet user-secrets set AZURE_OPENAI_ENDPOINT <your-Azure-OpenAI-endpoint>
    dotnet user-secrets set AZURE_OPENAI_GPT_NAME <your-Azure-OpenAI-model-name>
    

配置应用

  1. 从终端或命令提示符导航到 .NET 项目的根目录。

  2. 运行以下命令,将 OpenAI API 密钥配置为示例应用的机密:

    dotnet user-secrets init
    dotnet user-secrets set OpenAIKey <your-OpenAI-key>
    dotnet user-secrets set ModelName <your-OpenAI-model-name>
    

注释

对于模型名称,需要指定文本嵌入模型,例如 text-embedding-3-smalltext-embedding-3-large 为后面的部分中的矢量搜索生成嵌入内容。 有关嵌入模型的详细信息,请参阅 Embeddings

添加应用代码

  1. 使用以下属性向项目添加新类 CloudService

    using Microsoft.Extensions.VectorData;
    
    namespace VectorDataAI;
    
    internal class CloudService
    {
        [VectorStoreKey]
        public int Key { get; set; }
    
        [VectorStoreData]
        public string Name { get; set; }
    
        [VectorStoreData]
        public string Description { get; set; }
    
        [VectorStoreVector(
            Dimensions: 384,
            DistanceFunction = DistanceFunction.CosineSimilarity)]
        public ReadOnlyMemory<float> Vector { get; set; }
    }
    

    Microsoft.Extensions.VectorData 属性,例如 VectorStoreKeyAttribute,会影响在向量存储中使用时每个属性的处理方式。 该 Vector 属性存储生成的嵌入,表示 Description 值在矢量搜索中的语义含义。

  2. Program.cs 文件中,添加以下代码以创建描述云服务集合的数据集:

    List<CloudService> cloudServices =
    [
        new() {
                Key = 0,
                Name = "Azure App Service",
                Description = "Host .NET, Java, Node.js, and Python web applications and APIs in a fully managed Azure service. You only need to deploy your code to Azure. Azure takes care of all the infrastructure management like high availability, load balancing, and autoscaling."
        },
        new() {
                Key = 1,
                Name = "Azure Service Bus",
                Description = "A fully managed enterprise message broker supporting both point to point and publish-subscribe integrations. It's ideal for building decoupled applications, queue-based load leveling, or facilitating communication between microservices."
        },
        new() {
                Key = 2,
                Name = "Azure Blob Storage",
                Description = "Azure Blob Storage allows your applications to store and retrieve files in the cloud. Azure Storage is highly scalable to store massive amounts of data and data is stored redundantly to ensure high availability."
        },
        new() {
                Key = 3,
                Name = "Microsoft Entra ID",
                Description = "Manage user identities and control access to your apps, data, and resources."
        },
        new() {
                Key = 4,
                Name = "Azure Key Vault",
                Description = "Store and access application secrets like connection strings and API keys in an encrypted vault with restricted access to make sure your secrets and your application aren't compromised."
        },
        new() {
                Key = 5,
                Name = "Azure AI Search",
                Description = "Information retrieval at scale for traditional and conversational search applications, with security and options for AI enrichment and vectorization."
        }
    ];
    
  3. 创建和配置 IEmbeddingGenerator 实现以将请求发送到嵌入 AI 模型:

    // Load the configuration values.
    IConfigurationRoot config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
    string endpoint = config["AZURE_OPENAI_ENDPOINT"];
    string model = config["AZURE_OPENAI_GPT_NAME"];
    
    // Create the embedding generator.
    IEmbeddingGenerator<string, Embedding<float>> generator =
        new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
            .GetEmbeddingClient(deploymentName: model)
            .AsIEmbeddingGenerator();
    

    注释

    DefaultAzureCredential 从本地工具中搜寻身份验证凭据。 需要将 Azure AI Developer 角色分配给用于登录到 Visual Studio 或 Azure CLI 的帐户。 有关详细信息,请参阅使用 .NET 向 Azure AI 服务进行身份验证

    // Load the configuration values.
    IConfigurationRoot config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
    string model = config["ModelName"];
    string key = config["OpenAIKey"];
    
    // Create the embedding generator.
    IEmbeddingGenerator<string, Embedding<float>> generator =
        new OpenAIClient(new ApiKeyCredential(key))
          .GetEmbeddingClient(model: model)
          .AsIEmbeddingGenerator();
    
  4. 使用云服务数据创建和填充向量存储。 使用 IEmbeddingGenerator 实现为云服务数据中的每个记录创建和分配嵌入向量:

    // Create and populate the vector store.
    var vectorStore = new InMemoryVectorStore();
    VectorStoreCollection<int, CloudService> cloudServicesStore =
        vectorStore.GetCollection<int, CloudService>("cloudServices");
    await cloudServicesStore.EnsureCollectionExistsAsync();
    
    foreach (CloudService service in cloudServices)
    {
        service.Vector = await generator.GenerateVectorAsync(service.Description);
        await cloudServicesStore.UpsertAsync(service);
    }
    

    嵌入是每个数据记录语义含义的数字表示形式,这使得它们与矢量搜索功能兼容。

  5. 为搜索查询创建嵌入,并使用它在向量存储上执行矢量搜索:

    // Convert a search query to a vector
    // and search the vector store.
    string query = "Which Azure service should I use to store my Word documents?";
    ReadOnlyMemory<float> queryEmbedding = await generator.GenerateVectorAsync(query);
    
    IAsyncEnumerable<VectorSearchResult<CloudService>> results =
        cloudServicesStore.SearchAsync(queryEmbedding, top: 1);
    
    await foreach (VectorSearchResult<CloudService> result in results)
    {
        Console.WriteLine($"Name: {result.Record.Name}");
        Console.WriteLine($"Description: {result.Record.Description}");
        Console.WriteLine($"Vector match score: {result.Score}");
    }
    
  6. 使用 dotnet run 命令运行应用:

    dotnet run
    

    应用输出矢量搜索的顶部结果,这是与原始查询最相关的云服务。 可以修改查询以尝试不同的搜索方案。

清理资源

如果不再需要它们,请删除 Azure OpenAI 资源和模型部署。

  1. Azure 门户中,导航到 Azure OpenAI 资源。
  2. 选择 Azure OpenAI 资源,然后选择 删除

后续步骤