三分鐘掌握Ollama本地DeepSeek-R1模型及其它模型在.NET應(yīng)用中的部署與應(yīng)用
Microsoft.Extensions.AI 是一個(gè)強(qiáng)大的 .NET AI 集成庫(kù),專注于為開(kāi)發(fā)者提供豐富的功能,以便在 .NET 應(yīng)用程序中輕松實(shí)現(xiàn) AI 功能的集成。通過(guò)該庫(kù),用戶可以方便地?cái)U(kuò)展和增強(qiáng)應(yīng)用程序的智能化能力。本指南將深入介紹其主要特性及具體的使用方法,幫助開(kāi)發(fā)者快速上手并充分利用 Ollama 提供的強(qiáng)大工具集。
先決條件
在開(kāi)始之前,請(qǐng)確保滿足以下條件:
- 安裝 .NET 8 SDK
- 安裝 Visual Studio 或 VS Code
- 安裝 Ollama
Nuget 安裝包
NuGet\Install-Package [Microsoft.Extensions.AI](http://Microsoft.Extensions.AI) -Version 9.3.0-preview.1.25114.11
NuGet\Install-Package Microsoft.Extensions.AI.Ollama -Version 9.3.0-preview.1.25114.11
圖片
快速開(kāi)始
模型下載
首先,使用 Ollama 下載必要的模型:
ollama pull deepseek-r1:1.5b # 聊天模型
ollama pull all-minilm:latest # 嵌入模型
基本示例集合
一、基礎(chǔ)聊天功能
using Microsoft.Extensions.AI;
namespace AppMicrosoftAI
{
internal class Program
{
static async Task Main(string[] args)
{
var endpoint = "http://localhost:11434/";
var modelId = "deepseek-r1:1.5b";
IChatClient client = new OllamaChatClient(endpoint, modelId: modelId);
var result = await client.GetResponseAsync("What is AI?");
Console.WriteLine(result.Message);
Console.ReadLine();
}
}
}
圖片
`ChatResponse` 類(lèi)的說(shuō)明:
- Choices(消息選擇列表):
- 類(lèi)型:`IList`
- 包含聊天響應(yīng)的消息列表
- 如果有多個(gè)響應(yīng)選項(xiàng),它們都會(huì)存儲(chǔ)在這個(gè)列表中
- 可以通過(guò) `Message` 屬性直接訪問(wèn)第一個(gè)選項(xiàng)
- Message(首選消息):
- 返回 `Choices` 列表中的第一條消息
- 如果沒(méi)有可用的選項(xiàng),將拋出 `InvalidOperationException`
- 使用 `[JsonIgnore]` 特性標(biāo)記,表示在 JSON 序列化時(shí)忽略
- ResponseId(響應(yīng)標(biāo)識(shí)):
- 類(lèi)型:`string`
- 聊天響應(yīng)的唯一標(biāo)識(shí)符
- ChatThreadId(聊天線程標(biāo)識(shí)):
- 類(lèi)型:`string`
- 表示聊天線程的狀態(tài)標(biāo)識(shí)符
- 在某些聊天實(shí)現(xiàn)中,可用于保持對(duì)話上下文
- 可以在后續(xù)的聊天請(qǐng)求中使用,以繼續(xù)對(duì)話
- ModelId(模型標(biāo)識(shí)):
- 類(lèi)型:`string`
- 標(biāo)識(shí)生成響應(yīng)的 AI 模型
- CreatedAt(創(chuàng)建時(shí)間):
- 類(lèi)型:`DateTimeOffset`
- 聊天響應(yīng)創(chuàng)建的時(shí)間戳
- FinishReason(完成原因):
- 類(lèi)型:`ChatFinishReason`
- 指示響應(yīng)生成停止的原因(例如:完成、達(dá)到長(zhǎng)度限制)
- Usage(使用情況):
- 類(lèi)型:`UsageDetails`
- 包含資源使用details(可能是令牌數(shù)、處理時(shí)間等)
- RawRepresentation(原始表示):
- 類(lèi)型:`object`
- 存儲(chǔ)原始的底層響應(yīng)對(duì)象
- 對(duì)調(diào)試或訪問(wèn)特定實(shí)現(xiàn)的細(xì)節(jié)很有用
- 使用 `[JsonIgnore]` 特性標(biāo)記
- AdditionalProperties(額外屬性):
- 類(lèi)型:`AdditionalPropertiesDictionary`
- 允許存儲(chǔ)未在類(lèi)中顯式定義的額外屬性
二、 對(duì)話歷史管理
using Microsoft.Extensions.AI;
namespace AppMicrosoftAI
{
internal class Program
{
static async Task Main(string[] args)
{
var endpoint = "http://localhost:11434/";
var modelId = "deepseek-r1:1.5b";
IChatClient client = new OllamaChatClient(endpoint, modelId: modelId);
List<ChatMessage> conversation =
[
new(ChatRole.System, "You are a helpful AI assistant"),
new(ChatRole.User, "What is AI?")
];
Console.WriteLine(await client.GetResponseAsync(conversation));
Console.ReadLine();
}
}
}
三、流式響應(yīng)處理
using Microsoft.Extensions.AI;
namespace AppMicrosoftAI
{
internal class Program
{
static async Task Main(string[] args)
{
var endpoint = "http://localhost:11434/";
var modelId = "deepseek-r1:1.5b";
IChatClient client = new OllamaChatClient(endpoint, modelId: modelId);
await foreach (var update in client.GetStreamingResponseAsync("什么是AI?"))
{
Console.Write(update);
}
Console.WriteLine();
Console.ReadKey();
}
}
}
圖片
圖片
中間件支持
- 緩存中間件:提供響應(yīng)緩存
- OpenTelemetry:性能監(jiān)控和追蹤
- 工具調(diào)用中間件:擴(kuò)展 AI 功能
工具調(diào)用
using System.ComponentModel;
using Microsoft.Extensions.AI;
namespace AppMicrosoftAI
{
internal class Program
{
static async Task Main(string[] args)
{
[Description("Gets the weather")]
string GetWeather() => Random.Shared.NextDouble() > 0.5 ? "It's sunny" : "It's raining";
var chatOptions = new ChatOptions
{
Tools = [AIFunctionFactory.Create(GetWeather)]
};
var endpoint = "http://localhost:11434/";
var modelId = "qwen2.5:3b";
IChatClient client = new OllamaChatClient(endpoint, modelId: modelId)
.AsBuilder()
.UseFunctionInvocation()
.Build();
Console.WriteLine(await client.GetResponseAsync("你需要雨傘嗎?", chatOptions));
Console.ReadKey();
}
}
}
使用提示緩存中間件
using System.ComponentModel;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
namespace AppMicrosoftAI
{
internal class Program
{
static async Task Main(string[] args)
{
var endpoint = "http://localhost:11434/";
var modelId = "deepseek-r1:1.5b";
var options = Options.Create(new MemoryDistributedCacheOptions());
IDistributedCache cache = new MemoryDistributedCache(options);
IChatClient client = new OllamaChatClient(endpoint, modelId: modelId)
.AsBuilder()
.UseDistributedCache(cache)
.Build();
string[] prompts = ["What is AI?", "What is .NET?", "What is AI?"];
foreach (var prompt in prompts)
{
await foreach (var message in client.GetStreamingResponseAsync(prompt))
{
Console.Write(message);
}
Console.WriteLine();
}
Console.ReadKey();
}
}
}
Middleware
using System.ComponentModel;
using System.Diagnostics;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using OpenTelemetry.Trace;
namespace AppMicrosoftAI
{
internal class Program
{
static async Task Main(string[] args)
{
var sourceName = Guid.NewGuid().ToString();
var activities = new List<Activity>();
var tracerProvider = OpenTelemetry.Sdk.CreateTracerProviderBuilder()
.AddInMemoryExporter(activities)
.AddSource(sourceName)
.Build();
[Description("Gets the weather")]
string GetWeather() => Random.Shared.NextDouble() > 0.5 ? "It's sunny" : "It's raining";
var chatOptions = new ChatOptions
{
Tools = [AIFunctionFactory.Create(GetWeather)]
};
var endpoint = "http://localhost:11434/";
var modelId = "qwen2.5:3b";
var options = Options.Create(new MemoryDistributedCacheOptions());
IDistributedCache cache = new MemoryDistributedCache(options);
IChatClient client = new OllamaChatClient(endpoint, modelId: modelId)
.AsBuilder()
.UseFunctionInvocation()
.UseOpenTelemetry(sourceName: sourceName, configure: o => o.EnableSensitiveData = true)
.UseDistributedCache(cache)
.Build();
List<ChatMessage> conversation =
[
new(ChatRole.System, "You are a helpful AI assistant"),
new(ChatRole.User, "需要帶雨傘嗎?")
];
Console.WriteLine(await client.GetResponseAsync("需要帶雨傘嗎?", chatOptions));
Console.ReadKey();
}
}
}
文本嵌入
using System.ComponentModel;
using Microsoft.Extensions.AI;
namespace AppMicrosoftAI
{
internal class Program
{
static async Task Main(string[] args)
{
var endpoint = "http://localhost:11434/";
var modelId = "all-minilm:latest";
IEmbeddingGenerator<string, Embedding<float>> generator = new OllamaEmbeddingGenerator(endpoint, modelId: modelId);
var embedding = await generator.GenerateEmbeddingVectorAsync("What is AI?");
Console.WriteLine(string.Join(", ", embedding.ToArray()));
Console.ReadKey();
}
}
}
圖片
最佳實(shí)踐
- 使用依賴注入管理 AI 客戶端
- 實(shí)現(xiàn)適當(dāng)?shù)腻e(cuò)誤處理
- 管理對(duì)話歷史
- 利用中間件增強(qiáng)功能
結(jié)論
Microsoft.Extensions.AI - Ollama 提供了強(qiáng)大、靈活的 AI 集成方案,使 .NET 開(kāi)發(fā)者能輕松構(gòu)建智能應(yīng)用程序。