引言
從這一章節開始正式進入我們的 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
本文示例源代碼
本文源代碼
😄歡迎關注筆者公眾號一起學習交流,獲取更多有用的知識~