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

推荐订阅源

WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
腾讯CDC
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
N
Netflix TechBlog - Medium
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
GbyAI
GbyAI
B
Blog
F
Fortinet All Blogs
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
Google Developers Blog
A
About on SuperTechFans
C
Check Point Blog
Microsoft Security Blog
Microsoft Security Blog
MyScale Blog
MyScale Blog
B
Blog RSS Feed

博客园 - 冠军

Keep alive 分析 SSRS Reporting Service 日志 [翻译] 感谢 Avalonia, .NET MAUI 即将来到 Linux 和浏览器端 多区域一致性:鱼与熊掌兼得! Microsoft Agent Framework (预览) 入门:让所有的开发者轻松创建 AI Agents 使用 AI app 模板扩展来创建基于订制数据进行聊天的 .NET AI 应用 真正的 .NET 单文件发布与构建 Microsoft.Extensions.AI 库 OfficeRuntime.storage 适配 oidc-client.js 中的 WebStorageStateStore 翻译:基于 OAuth2 在 Web 服务中使用 MailKit Microsoft.Extensions.VectorData.Abstractions 入门 使用 PdfPig 处理 PDF 文档 使用 Any CPU构建 .NET 8 应用会支持 32 位吗? 使用 NATS CLI NATS: 使用 work-queue Stream NATS: Pull Consumers in JetStream .NET 单文件执行程序拆解器 SingleFileExtractor .NET Aspire Apps 集成测试 ASCII 与 Unicode 中的引号
基于本地 Llama 生成 .NET AI 矢量搜索应用
冠军 · 2025-06-28 · via 博客园 - 冠军

本文使用运行在本地的 llama 来实现 AI 向量搜索。它使用 OllamaSharp 访问本地的 llama 中运行的模型。

注意:OllamaSharp 5.2.3 可以工作, 但是 OllamaSharp 5.0.4 不行。
会抛出异常:System.MissingMethodException: Method not found: 'Microsoft.Extensions.AI.ChatClientMetadata Microsoft.Extensions.AI.IChatClient.get_Metadata()'.

先决条件

  • .NET 8.0 SDK 或者更高版本

使用的 NuGet 包

<ItemGroup>
  <PackageReference Include="Microsoft.Extensions.AI.Abstractions" Version="9.6.0" />
  <PackageReference Include="Microsoft.Extensions.VectorData.Abstractions" Version="9.6.0" />
  <PackageReference Include="Microsoft.SemanticKernel.Connectors.InMemory" Version="1.58.0-preview" />
  <PackageReference Include="OllamaSharp" Version="5.2.3" />
  <PackageReference Include="System.Linq.AsyncEnumerable" Version="10.0.0-preview.5.25277.114" />
</ItemGroup>

创建应用

1. 创建控制台应用

dotnet new console -o VectorDataAI

2. 将应用目录设为当前目录

cd VectorDataAI

3. 安装所需的 NuGet 包

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

示例所涉及的 NuGet 包:

  • Microsoft.Extensions.AI.Abstractions, 为大模型提供 AI 抽象
  • Microsoft.Extensions.VectorData.Abstractions, 启用对矢量存储的 Create-Read-Update-Delete (CRUD) 和搜索操作
  • OllamaSharp, 提供针对 Ollama 的实现支持
  • Microsoft.SemanticKernel.Connectors.InMemory, 供内存中矢量存储类来保存可查询矢量数据记录。

编写代码

1. 创建数据映射类

创建 CloudService.cs 代码文件,其中定义了数据映射。

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; }
}

这里的 VectorStoreVector 特性标志用来存储生成的向量,它表示 Description 中文本的语义含义。

2. 创建示例数据

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. 基于 OllamaSharp 创建使用 Ollama 的向量生成器实例

OllamaApiClient 实现了 3 个接口:

  • IOllamaApiClient
  • IChatClient
  • IEmbeddingGenerator<string, Embedding>

可以直接将 OllamaApiClient 转型为 IEmbeddingGenerator<string, Embedding> 引用。

var uri = "http://localhost:11434";
string model = "deepseek-r1:1.5b";

var client = new OllamaApiClient(uri, model);

// Create the embedding generator.
IEmbeddingGenerator<string, Embedding<float>> generator =
            client as IEmbeddingGenerator<string, Embedding<float>>;

Console.WriteLine($"Using Ollama API at {uri} with model {model}");

4. 使用向量生成器创建并存储向量

首先,创建内存中的向量存储。然后,在内存中的向量存储中创建名为 cloudServices 的向量集合。
最后,使用向量生成器将 Description 中内容向量化并存储。

// 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?";
Console.WriteLine($"Querying: {query}");
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
Hello, World!
Using Ollama API at http://localhost:11434 with model deepseek-r1:1.5b
Querying: Which Azure service should I use to store my Word documents?
Name: Microsoft Entra ID
Description: Manage user identities and control access to your apps, data, and resources.
Vector match score: 0.8528178930282593

完整代码

using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using VectorDataAI;
using OllamaSharp;
using OllamaSharp.Models;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.InMemory;

// See https://aka.ms/new-console-template for more information
class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine("Hello, World!");

        List<CloudService> cloudServices = new List<CloudService>
        {
            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."
            }
        };

        var uri = "http://localhost:11434";
        string model = "deepseek-r1:1.5b";

        var client = new OllamaApiClient(uri, model);

        // Create the embedding generator.
        IEmbeddingGenerator<string, Embedding<float>> generator =
            client as IEmbeddingGenerator<string, Embedding<float>>;

        Console.WriteLine($"Using Ollama API at {uri} with model {model}");

        // 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);
        }

        // 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?";
        Console.WriteLine($"Querying: {query}");
        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}");
        }
    }
}

执行结果

Hello, World!
Using Ollama API at http://localhost:11434 with model deepseek-r1:1.5b
Querying: Which Azure service should I use to store my Word documents?
Name: Microsoft Entra ID
Description: Manage user identities and control access to your apps, data, and resources.
Vector match score: 0.8528178930282593

这个文档已经过时!
https://learn.microsoft.com/zh-cn/dotnet/ai/quickstarts/build-vector-search-app?pivots=openai