引言
本教程將帶你全面了解SemanticKernel,一款強大的AI開發工具包。以下內容基于實際代碼示例,幫助你快速掌握使用技巧。
資源鏈接:
- 教程代碼倉庫:https://github.com/AIDotNet/SemanticKernel.Samples
- QQ交流群:
961090189 - 微信交流群(加微):
wk28u9123456789 - 飛書交流群:點擊加入
- 原文地址:https://ycnv7u8vf1o3.feishu.cn/docx/WezYdjrckoqhU3xNXbEcL3Ubn2b?from=from_copylink
一、SemanticKernel簡介
SemanticKernel是一種輕型開源開發工具包,可用于輕松生成AI代理并將最新的AI模型集成到C#、Python或Java代碼庫中。它充當一個高效的中間件,可實現企業級解決方案的快速交付。
作為連接AI模型與傳統編程的橋梁,SemanticKernel讓你可以:
- 無縫集成OpenAI、Azure OpenAI和Hugging Face等LLM服務
- 將AI能力與傳統編程邏輯和外部服務結合
- 構建復雜的AI工作流,解決實際業務問題
SemanticKernel的核心理念
SemanticKernel建立在幾個關鍵概念之上:
1. 插件(Plugins)架構
SemanticKernel的插件系統是其最強大的特性之一。這些插件有兩種主要類型:
- 語義函數(Semantic Functions):使用自然語言指令(提示詞)定義的函數,由AI模型執行
- 原生函數(Native Functions):使用傳統編程語言(如C#、Python、Java等)編寫的函數
這種雙重架構允許開發者創建混合解決方案,在需要精確控制的地方使用傳統代碼,在需要創造性和靈活性的地方使用AI能力。
2. Memory與Planner
SemanticKernel提供了先進的Memory和Planner組件:
- SemanticKernelMemory:使應用能夠存儲和檢索信息,實現類似長期記憶的功能
- Planner:可以自動將復雜任務分解為更小的步驟,并安排它們的執行順序
3. 可組合性
SemanticKernel的設計鼓勵組件重用和組合,使開發者能夠:
- 將簡單功能組合成更復雜的工作流
- 創建可復用的插件庫
- 構建模塊化且可擴展的AI應用架構
實際應用案例
SemanticKernel在各種場景中展現出強大的實用價值:
- 內容創作助手:自動生成、總結和修改文本內容
- 個人知識管理:智能組織和檢索文檔與知識
- 客戶服務自動化:構建能理解客戶需求并提供個性化幫助的智能系統
- 數據分析輔助:將自然語言查詢轉換為數據查詢,并生成見解報告
- 流程自動化:創建能理解非結構化數據并執行復雜任務的智能工作流
技術優勢
SemanticKernel相比其他AI開發框架具有幾個獨特優勢:
- 語言靈活性:支持C#、Python、Java
- 開放生態:與多種LLM提供商兼容,避免供應商鎖定
- 企業級支持:作為微軟項目,具備企業級質量和支持
- 社區活躍:擁有活躍的開發者社區,持續改進和擴展
- 低入門門檻:允許開發者漸進式采用AI功能,無需一步到位
入門指南
如果你想開始使用SemanticKernel,可以按照以下步驟:
- 安裝SDK:根據你選擇的編程語言安裝相應的SemanticKernel SDK
- 配置AI模型:連接到OpenAI、Azure OpenAI等LLM服務
- 創建插件:定義語義函數和原生函數
- 構建工作流:將函數組合成解決特定問題的工作流
- 集成到應用:將SemanticKernel集成到你的應用程序中
二、SemanticKernel入門篇
1. 快速開始第一個示例
獲取OpenAI在線API
由于在國內的限制,我們并沒有辦法直接訪問OpenAI,所以下面的教程我們會推薦使用 https://api.token-ai.cn,然后您需要在這個網站中注冊一個賬號,并且創建一個令牌(最好是設置無限額度和無過期時間),創建好的令牌我們保存好,下面的基礎教程入門會用到,這個令牌是用于代替OpenAI的原有的令牌。
創建項目
-
打開
Visual Studio 2022,然后創建一個名稱為TokenAI的控制臺項目

-
右鍵新建的項目,然后點擊
管理 NuGet 程序包

-
搜索
Semantic Kernel,并且選擇包括預覽版,然后選擇安裝Microsoft.SemanticKernel,

-
實現Stream式對話輸出
打開Program.cs,輸入以下代碼:
using Microsoft.SemanticKernel;
#pragma warning disable SKEXP0010
var kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion("gpt-4.1-mini", new Uri("https://api.token-ai.cn/v1"),
"您的密鑰")
.Build();
await foreach (var item in kernel.InvokePromptStreamingAsync("您好,我是TokenAI"))
{
Console.Write(item.ToString());
};
執行效果:

我們使用Kernel的CreateBuilder創建了一個Kernel對象,并且在這個對象中存在InvokePromptStreamingAsync方法,這個方法提供了OpenAI的一個Stream的對話接口,并且我們添加了AddOpenAIChatCompletion添加了自定義的模型和我們的代理網站的key地址。
2. 使用聊天完成對話示例
首先給我們的控制臺項目安裝SK包
dotnet add package Microsoft.SemanticKernel
然后我們構建一個簡單的Kernel,和ChatCompletion:
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
#pragma warning disable SKEXP0010
var kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion("gpt-4o", new Uri("https://api.token-ai.cn/v1"),
"您的密鑰")
.Build();
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
ChatHistory history = [];
history.AddUserMessage("Hello, how are you?");
// 使用同步對話
var response = await chatCompletionService.GetChatMessageContentAsync(
history,
kernel: kernel
);
Console.WriteLine(response.Content);
// 使用異步對話
await foreach (var item in chatCompletionService.GetStreamingChatMessageContentsAsync(
history,
kernel: kernel
))
{
Console.Write(item.Content);
}
效果如圖,同步對話會一次性返回,異步對話會一點點返回,適合不同場景的對話,同步對話完整的響應會更快,但是復雜的業務可能等待很長時間導致請求超時,所以不同場景使用不同模式。

3. 開始使用Plugins
創建項目
首先給我們的控制臺項目安裝SK包
dotnet add package Microsoft.SemanticKernel
接下來,我們將:
- 構建好我們的Kernel
- 創建
TimeInformation的一個Plugins并且提供了一個獲取當前時間的Function - 構建倆個對話案例,用于區分使用了Function和沒有使用function的區別
using System.ComponentModel;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
#pragma warning disable SKEXP0010
var kernelBuilder = Kernel.CreateBuilder()
.AddOpenAIChatCompletion("gpt-4.1-mini", new Uri("https://api.token-ai.cn/v1"),
"您的密鑰");
kernelBuilder.Plugins.AddFromType<TimeInformation>();
var kernel = kernelBuilder.Build();
// 用提示符調用SK,要求AI提供它無法提供的信息,并可能產生幻覺
Console.WriteLine(await kernel.InvokePromptAsync("離圣誕節還有幾天?"));
OpenAIPromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
// 用提示符調用內核,并允許AI自動調用函數
Console.WriteLine(await kernel.InvokePromptAsync("離圣誕節還有幾天?解釋你的想法", new(settings)));
class TimeInformation
{
[KernelFunction]
[Description("獲取當前時間幫助用戶解決時區不準確。")]
public string GetCurrentUtcTime() => DateTime.UtcNow.ToString("R");
}
執行控制臺得到如下效果:
今天是2024年4月27日,離圣誕節(12月25日)還有242天。
今天是2025年4月27日,距離圣誕節(12月25日)還有大約8個月,即大約242天左右。因此,現在離圣誕節還有很多天。
第一條內容是沒有執行function得到的結果,完全不準確。
第二條內容是執行了function的結果,得到了當前時間得到了準確的結果。
結論
通過以上步驟,我們可以看到:
- 沒有執行函數時,AI生成的回答不準確,無法提供實際的時間信息。
- 執行函數后,AI能夠準確獲取當前時間,并提供相應的計算結果。
4. 創建Yaml格式的提示詞模板
這一篇的教程我們將講解如何定義yaml格式的提示詞模板并且使用,下面我們需要安裝一下倆個包:
dotnet add package Microsoft.SemanticKernel
dotnet add package Microsoft.SemanticKernel.Yaml
創建目錄Resources在目錄下創建GenerateStory.yaml文件,然后打開文件:
name: GenerateStory
template: |
將一個關于 {{$topic}} 的故事生成一個長度為 {{$length}} 的故事。
template_format: semantic-kernel
description: 生成關于某個主題的故事的函數。
input_variables:
- name: topic
description: 故事的主題。
is_required: true
- name: length
description: 故事中的句子數。
is_required: true
output_variable:
description: 生成的故事。
execution_settings:
default:
temperature: 0.6
這個是一個生成故事的提示詞模板,里面提供了topic和length倆個參數,并且使用{{$topic}}的格式插入到模板中。
然后我們還需要將GenerateStory.yaml文件設置成嵌入資源,將下面配置復制到項目當中:
<ItemGroup>
<None Remove="Resources\GenerateStory.yaml" />
<EmbeddedResource Include="Resources\GenerateStory.yaml" />
</ItemGroup>
然后還需要創建一個讀取嵌入資源的方法,創建EmbeddedResource.cs,打開文件:
/// <summary>
/// 提供從程序集中讀取嵌入資源的功能。
/// 此類設計用于訪問嵌入在同一程序集中的基于文本的資源。
/// 它根據名稱檢索指定資源文件的內容,并將其作為字符串返回。
/// </summary>
public static class EmbeddedResource
{
private static readonly string? s_namespace = typeof(EmbeddedResource).Namespace;
internal static string Read(string fileName)
{
// Get the current assembly. Note: this class is in the same assembly where the embedded resources are stored.
Assembly assembly =
typeof(EmbeddedResource).GetTypeInfo().Assembly ??
throw new InvalidOperationException($"[{s_namespace}] {fileName} assembly not found");
// Resources are mapped like types, using the namespace and appending "." (dot) and the file name
var resourceName = $"{s_namespace}." + fileName;
using Stream resource =
assembly.GetManifestResourceStream(resourceName) ??
throw new InvalidOperationException($"{resourceName} resource not found");
// Return the resource content, in text format.
using var reader = new StreamReader(resource);
return reader.ReadToEnd();
}
}
現在可以打開我們的Program.cs:
using Microsoft.SemanticKernel;
using Samples4;
#pragma warning disable SKEXP0010
var kernelBuilder = Kernel.CreateBuilder()
.AddOpenAIChatCompletion("gpt-4.1-mini", new Uri("https://api.token-ai.cn/v1"),
"您的密鑰");
var kernel = kernelBuilder.Build();
var generateStoryYaml = EmbeddedResource.Read("Resources.GenerateStory.yaml");
var function = kernel.CreateFunctionFromPromptYaml(generateStoryYaml);
// Invoke the prompt function and display the result
Console.WriteLine(await kernel.InvokeAsync(function, arguments: new()
{
{ "topic", "Dog" },
{ "length", "3" },
}));
實現步驟:
- 構建Kernel
- 通過EmbeddedResource.Read讀取嵌入的yaml模板,通過CreateFunctionFromPromptYaml創建function
- 使用InvokeAsync進行調用function,構建
KernelArguments傳遞參數
執行項目得到結果:
從前,有一只聰明的小狗。
它每天幫助主人找回丟失的東西。
最終,它成了村里最受歡迎的狗狗。
結論
通過上面案例我們了解了如何定義yaml的提示詞模板,并在SemanticKernel中使用它來創建和調用函數。這種方法使得提示詞管理更加結構化和可維護。
總結
本教程介紹了SemanticKernel的基礎知識和核心概念,并通過四個實際示例展示了如何在C#中使用SemanticKernel:
- 快速入門示例 - 實現流式對話輸出
- 使用聊天完成功能 - 同步和異步對話模式
- 使用Plugins擴展AI能力 - 通過函數調用增強準確性
- 創建Yaml格式提示詞模板 - 更結構化地管理提示詞
通過這些示例,你應該已經掌握了SemanticKernel的基本用法,可以開始構建自己的AI增強應用程序。
浙公網安備 33010602011771號