引言
從這一章節開始正式進入我們的 Semantic Kernel
的學習之旅了。
什麼是Semantic Kernel
?
Semantic Kernel
是一個輕量級的開源框架,透過 Semantic Kernel
可以快速使用不同程式語言(C#/Python/Java
)結合 LLMs(OpenAI、Azure OpenAI、Hugging Face 等模型)
構建智慧應用,簡化將人工智慧(AI
)整合到現有解決方案中的過程。
Semantic Kernel
的特點
-
模組化外掛架構:
Semantic Kernel
提供了一個模組化的外掛架構,允許開發者透過結合自定義和預定義的智慧外掛來解決複雜的業務問題。這種架構使得傳統程式碼能夠與智慧外掛無縫協作,從而簡化了傳統應用程式向智慧化轉型的過程。 -
多模型整合能力:
Semantic Kernel
支援多種AI
模型,包括但不限於Azure OpenAI Service
、OpenAI
,以及Hugging Face
提供的離線模型。透過Semantic Kernel
的連結器功能,開發者可以快速地將這些AI“大腦”
整合到自己的智慧應用中,大幅提升應用的智慧化水平。 -
多樣化的連結器生態系統:除了連線
AI
模型,Semantic Kernel
的連結器還支援連線向量資料庫、商業軟體、業務中介軟體等多種服務。這種多樣化的連結能力,使得Semantic Kernel
能夠適應更多的業務場景,推動業務流程的智慧化轉型。 -
全面的語言相容性:
Semantic Kernel
支援主流的程式語言,包括C#
、Python
和Java
。這種全面的語言支援,使得不同背景的開發者都能夠輕鬆地利用Semantic Kernel
來挖掘AI
的潛力,並將其應用到自己的專案中。 -
低門檻的開發體驗:
Semantic Kernel
設計注重使用者體驗,提供了簡單易用的介面和文件。即使是AI
領域的新手,也能夠快速上手,實現零成本入門,從而降低了開發智慧應用的門檻。
核心概念
Semantic Kernel
基本組成
在 Semantic Kernel
中,核心概念包括:
核心(Kernel):
如果說 Semantic Kernel
是 Copilot Agent
的核心 AI
編排層,那 Kernel
物件就是 AI
編排層的核心物件。
從上圖我們可以看出Kernel
的核心包括:
-
配置: 包括
AI
模型、外掛、連結器等的配置資訊。 -
上下文管理:它維護應用程式的上下文資訊,確保在執行任務時,可以訪問到正確的資料和狀態。
-
服務協調:
Kernel
物件協調不同的AI
服務和外掛,確保它們能夠協同工作,完成複雜的任務。 -
執行引擎:它作為執行引擎,根據規劃器生成的計劃,排程和執行相應的操作。
外掛(Plugins)
外掛是 AI
解決方案的構建塊,它們是一組可以暴露給 AI
應用程式和 AI
服務的函式,允許它們訪問完成特定任務所需的資料。
Semantic Kernel
中的函式
Semantic Function 是用自然語言編寫的提示(Prompt
)模板,傳送給 AI
服務;而 Native Function是用 C#
或 Python
編寫的傳統函式,可以透過規劃器和函式呼叫被 AI
服務呼叫。
記憶(Memories
)
Memories
是用於儲存資料的專用外掛,它們在執行過程中為你的核心提供必要的上下文,以便你的 AI
服務能夠正常執行。
規劃器(Planners
)
規劃器
可以接收使用者的目標,並幫助我們動態生成一個包含實現該特定目標的執行步驟的計劃。規劃器使用 AI
模型根據核心中指定的函式和服務生成計劃。
透過整合這些概念和元件,Semantic Kernel
可以實現智慧的語義理解、任務規劃和智慧決策,從而為使用者提供更加智慧、靈活和個性化的互動體驗。它可以應用於各種領域,如虛擬助手、智慧客服、自然語言互動系統等,為使用者和企業提供更加智慧和高效的解決方案。
從下面這張圖可以更好的理解各核心元件之間的關係
Sematic Kernel 對接 OneApi
透過我們上一篇文章的,我們瞭解到了
OneApi
,是以OpenAI
的格式,所以在SK
中可以使用OpenAI
的Connector
來操作、在Semantic Kernel
類庫中已經預設整合。
使用 UseSecrets 儲存機密資訊
- 在我們的啟動項右鍵機密資訊管理
配置項 Json 檔案
"OneApiSpark": {
"Endpoint": "http://localhost:3000",
"ModelId": "SparkDesk-v3.5",
"ApiKey": "sk-LAYzQaWssCYYEVHP1d6a3fFa111745249e94F0364a0cF37c"
}
從 OpenAI 到本地服務的請求轉換
自定義 HttpClientHandler
用 OpenAI
或者 Azure OpenAI
的擴充套件,請求會傳送到"api.openai.com"
或者"openai.azure.com"
,這時候就需要我們透過自定的HttpClientHandler
重定向的模型基礎 URL
轉發到我們的http://localhost:3000
OneApi
的服務地址。
- 核心程式碼
public class OpenAICustomHandler : HttpClientHandler
{
/// <summary>
/// 用於OpenAI或Azure OpenAI請求時重定向的模型基礎URL。
/// </summary>
private readonly string modelUrl;
private static readonly string[] sourceArray = ["api.openai.com", "openai.azure.com"];
/// <summary>
/// 使用指定的模型URL初始化<see cref="OpenAICustomHandler"/>類的新例項。
/// </summary>
/// <param name="modelUrl">用於OpenAI或Azure OpenAI請求的基礎URL。</param>
public OpenAICustomHandler(string modelUrl)
{
// 確保modelUrl不是null或空
if (string.IsNullOrWhiteSpace(modelUrl))
throw new ArgumentException("模型URL不能為空或空白。", nameof(modelUrl));
this.modelUrl = modelUrl;
}
/// <summary>
/// 非同步傳送HTTP請求,對於OpenAI或Azure OpenAI服務的請求,將URL重定向到指定的模型URL。
/// </summary>
/// <param name="request">要傳送的HTTP請求訊息。</param>
/// <param name="cancellationToken">可以用來取消操作的取消令牌。</param>
/// <returns>表示非同步操作的任務物件。</returns>
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// 檢查請求是否針對OpenAI或Azure OpenAI服務
if (request.RequestUri != null &&
(sourceArray.Contains(request.RequestUri.Host)))
{
// 修改請求URI,以包含模型URL
request.RequestUri = new Uri(modelUrl + request.RequestUri.PathAndQuery);
}
// 呼叫基類方法實際傳送HTTP請求
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
}
Semantic Kernel HelloWorld
我們先透過一個簡單的示例學習一下 Kernel 物件的建立使用
- VS 建立控制檯專案
SK_CreateKernel
Nuget
安裝Semantic Kernel
的依賴
PM> NuGet\Install-Package Microsoft.SemanticKernel -Version 1.10.0
- 下面我們示例將藉助
Prompt
提示詞用的Semantic function
來推理一下使用者的意圖
Steps
簡單的流程可以總結為:
Build Kernel ➟ Prompt Template ➟ Create Semantic function ➟ Kernel Invoke Semantic function
var config = ConfigExtensions.FromConfig<OpenAIConfig>("OneApiSpark");
//自定義HttpClientHandler
var openAICustomHandler = new OpenAICustomHandler(config.Endpoint);
using HttpClient client = new(openAICustomHandler);
//Create Kernel
Kernel kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: config.ModelId,
apiKey: config.ApiKey,
httpClient: client)
.Build();
// 接收使用者入參
string request = Console.ReadLine()!;
// create prompt to the chat service
string prompt = "這個請求的意圖是什麼? {{$request}}";
// Create a kernel arguments object and add the request
var kernelArguments = new KernelArguments
{
{ "request", request }
};
var streamingKernelContentsAsync = kernel.InvokePromptStreamingAsync(prompt, kernelArguments);
await foreach (var content in streamingKernelContentsAsync)
{
Console.WriteLine(content);
}
Console.ReadKey();
上面的程式碼我們透過Kernel
物件用prompt
建立了一個Semantic function
,內容是揣測使用者輸入的文字意圖,藉助大模型的推理能力很簡單的就可以做到這個功能。
Run
一下
- 輸入
I want to send an email to the marketing team celebrating their recent milestone
- 輸出
這個
請求的意圖
是傳送一封
電子郵件給市場團隊
,慶祝他們最近達成
的一個重要成就。
在程式設計或自動化的上下文中,實現這個意圖可能涉及以下幾個步驟:
1. 確定市場團隊的聯絡資訊,包括電子郵件地址。
2. 編寫郵件內容,確保包含對最近里程碑的慶祝和肯定。
3.
使用適當的郵件傳送協議(如SMTP)或郵件服務API(如SendGrid, Mailgun等)來傳送郵件。
4. 確保郵件格式正確,包括主題行、正文、簽名等。
5. 測試郵件傳送功能以確保郵件能夠成功送達。
如果你需要具體的程式碼示例或進一步的幫助來實現這個功能,請提供更多的上下文或技術要求。
最後
本章介紹了 Semantic Kernel
的特點、核心概念以及與 OneApi
的對接方式,算是我們SK
學習的 HelloWorld
,展示瞭如何利用 Semantic Kernel
構建智慧應用並與線上大模型進行整合。
參考文獻
- Semantic Kernel Cookbook
- Prompting AI models with Semantic Kernel
- What is Semantic Kernel
本文示例原始碼
本文原始碼
😄歡迎關注筆者公眾號一起學習交流,獲取更多有用的知識~