Microsoft.Extensions.AI 初探

mingupupup發表於2024-11-20

.NET Conf上的介紹

在今年的.NET Conf上Steve Sanderson帶來了題為“AI Building Blocks - A new, unified AI layer”的演講。該演講的主要內容如下:

“大多數.NET應用程式可以透過AI功能變得更加強大和高效,例如語義搜尋、自動分類、摘要生成、翻譯、資料提取,甚至是基於聊天的助手。但直到現在,.NET本身還沒有統一的AI概念表示標準,因此開發者需要組合使用許多不相關的API。Microsoft.Extensions.AI解決了這個問題,提供了一組新的AI服務標準API,包括在本地工作站上執行或作為託管服務的大型語言模型(LLMs),並整合了文字嵌入、向量儲存等功能。在本次演講中,我們將展示這些新的標準抽象如何讓你組合多個服務,並且這些服務可以隨著時間的推移輕鬆替換和更改,以及如何在更高階的場景中接入內部機制。透過本次演講,你將能夠開始在自己的應用程式中實驗新的AI功能。”

youtube地址:https://www.youtube.com/watch?v=qcp6ufe_XYo&list=PLdo4fOcmZ0oXeSG8BgCVru3zQtw_K4ANY&index=3

Steve Sanderson介紹了以下幾種應用場景:

image-20241120094958717

Microsoft.Extensions.AI介紹

2024年10月8日,Luis Quintanilla在.NET Blog上釋出了題為“Introducing Microsoft.Extensions.AI Preview – Unified AI Building Blocks for .NET”的文章介紹了Microsoft.Extensions.AI Preview。

文章地址:https://devblogs.microsoft.com/dotnet/introducing-microsoft-extensions-ai-preview/

“Microsoft.Extensions.AI 是一組由 .NET 生態系統中的開發者(包括 Semantic Kernel 團隊)共同開發的核心 .NET 庫。這些庫提供了一層統一的 C# 抽象層,用於與 AI 服務進行互動,例如小型和大型語言模型(SLM 和 LLM)、嵌入內容以及中介軟體。”

img

“目前,我們的重點是建立抽象概念,這些抽象概念可以由各種服務實現,並且都遵循相同的核心理念。我們不打算釋出針對任何特定服務提供商的API。我們的目標是在.NET生態系統中充當一個統一的層,使開發者能夠選擇他們喜歡的框架和庫,同時確保在整個生態系統中的無縫整合和協作。”

Microsoft.Extensions.AI的優勢

Microsoft.Extensions.AI 提供了一個統一的 API 抽象,用於 AI 服務,類似於我們在日誌記錄和依賴注入(DI)抽象方面的成功。我們的目標是提供標準的實現,用於快取、遙測、工具呼叫和其他常見任務,這些實現可以與任何提供商相容。

核心優勢有以下幾點:

統一API:為將AI服務整合到.NET應用程式提供了一致的API和約定。
靈活性:允許.NET庫作者使用AI服務而無需繫結特定提供商,使其適應任何提供商。
易用性:使.NET開發人員能夠使用相同的底層抽象嘗試不同的包,在整個應用程式中保持單一API。
元件化:簡化了新增新功能的過程,並促進了應用程式的元件化和測試。

Microsoft.Extensions.AI簡單實踐

使用Microsoft.Extensions.AI可以看Nuget包的介紹。

地址:https://www.nuget.org/packages/Microsoft.Extensions.AI.Abstractions/9.0.0-preview.9.24556.5

先簡單的以OpenAI為例,然後考慮到在國內使用OpenAI不便,再介紹一下如何接入相容OpenAI格式的大語言模型提供商。

簡單的對話:

string OPENAI_API_KEY = "sk-sssss...";

IChatClient client =
 new OpenAIClient(OPENAI_API_KEY)
.AsChatClient(modelId: "gpt-4o-mini");

var response = await client.CompleteAsync("你是誰?");

Console.WriteLine(response.Message);

效果:

image-20241120101114704

我比較關心的是Function Calling的功能,來簡單嘗試一下:

string OPENAI_API_KEY = "sk-sssss...";

[Description("Get the current time")]
 string GetCurrentTime() => DateTime.Now.ToString();

 IChatClient client = new ChatClientBuilder()
     .UseFunctionInvocation()
     .Use(new OpenAIClient(OPENAI_API_KEY).AsChatClient(modelId: "gpt-4o-mini"));

 var response = client.CompleteStreamingAsync(
     "現在幾點了?",
     new() { Tools = [AIFunctionFactory.Create(GetCurrentTime)] });

 await foreach (var update in response)
 {
     Console.Write(update);
 }

效果:

image-20241120101404123

成功獲取到了當前的時間。

由於在國內使用OpenAI不方便,而且國內也有很多大模型提供商都是相容OpenAI格式的,因此現在以國內的模型提供商為例,進行說明。

我以矽基流動為例,上面還有一些額度。

簡單對話:

 OpenAIClientOptions openAIClientOptions = new OpenAIClientOptions();
 openAIClientOptions.Endpoint = new Uri("https://api.siliconflow.cn/v1");

 // SiliconCloud API Key
 string mySiliconCloudAPIKey = "sk-lll...";


 OpenAIClient client = new OpenAIClient(new ApiKeyCredential(mySiliconCloudAPIKey),  openAIClientOptions);
 IChatClient chatClient = client.AsChatClient("Qwen/Qwen2.5-72B-Instruct-128K");
 var response = await chatClient.CompleteAsync("你是誰?");
 Console.WriteLine(response.Message);

效果:

image-20241120101803488

函式呼叫:

 OpenAIClientOptions openAIClientOptions = new OpenAIClientOptions();
 openAIClientOptions.Endpoint = new Uri("https://api.siliconflow.cn/v1");

 // SiliconCloud API Key
 string mySiliconCloudAPIKey = "sk-lll...";

  [Description("Get the current time")]
  string GetCurrentTime() => DateTime.Now.ToString();

  IChatClient client = new ChatClientBuilder()
      .UseFunctionInvocation()
      .Use(new OpenAIClient(new ApiKeyCredential(mySiliconCloudAPIKey), openAIClientOptions).AsChatClient("Qwen/Qwen2.5-72B-Instruct-128K"));

  var response = await client.CompleteAsync(
      "現在幾點了?",
      new() { Tools = [AIFunctionFactory.Create(GetCurrentTime)] });

  Console.Write(response);

image-20241120102258535

也成功進行函式呼叫,獲取到了當前的時間。

會發現其實和SemanticKernel很像,Steve Sanderson也坦言這些是從SemanticKernel“畢業”的東西,更多用例可由讀者自行探索。