引言

本教程将带你全面了解SemanticKernel,一款强大的AI开发工具包。以下内容基于实际代码示例,帮助你快速掌握使用技巧。

资源链接:

一、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开发框架具有几个独特优势:

  1. 语言灵活性:支持C#、Python、Java
  2. 开放生态:与多种LLM提供商兼容,避免供应商锁定
  3. 企业级支持:作为微软项目,具备企业级质量和支持
  4. 社区活跃:拥有活跃的开发者社区,持续改进和扩展
  5. 低入门门槛:允许开发者渐进式采用AI功能,无需一步到位

入门指南

如果你想开始使用SemanticKernel,可以按照以下步骤:

  1. 安装SDK:根据你选择的编程语言安装相应的SemanticKernel SDK
  2. 配置AI模型:连接到OpenAI、Azure OpenAI等LLM服务
  3. 创建插件:定义语义函数和原生函数
  4. 构建工作流:将函数组合成解决特定问题的工作流
  5. 集成到应用:将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());
};

执行效果:

我们使用KernelCreateBuilder创建了一个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

接下来,我们将:

  1. 构建好我们的Kernel
  2. 创建TimeInformation的一个Plugins并且提供了一个获取当前时间的Function
  3. 构建俩个对话案例,用于区分使用了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

这个是一个生成故事的提示词模板,里面提供了topiclength俩个参数,并且使用{{$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" },
}));

实现步骤:

  1. 构建Kernel
  2. 通过EmbeddedResource.Read读取嵌入的yaml模板,通过CreateFunctionFromPromptYaml创建function
  3. 使用InvokeAsync进行调用function,构建KernelArguments传递参数

执行项目得到结果:

从前,有一只聪明的小狗。
它每天帮助主人找回丢失的东西。
最终,它成了村里最受欢迎的狗狗。

结论

通过上面案例我们了解了如何定义yaml的提示词模板,并在SemanticKernel中使用它来创建和调用函数。这种方法使得提示词管理更加结构化和可维护。

总结

本教程介绍了SemanticKernel的基础知识和核心概念,并通过四个实际示例展示了如何在C#中使用SemanticKernel:

  1. 快速入门示例 - 实现流式对话输出
  2. 使用聊天完成功能 - 同步和异步对话模式
  3. 使用Plugins扩展AI能力 - 通过函数调用增强准确性
  4. 创建Yaml格式提示词模板 - 更结构化地管理提示词

通过这些示例,你应该已经掌握了SemanticKernel的基本用法,可以开始构建自己的AI增强应用程序。

.NET AI从0开始入门 SemanticKernel 从基础到实践的更多相关文章

  1. 设正整数n的十进制表示为n=ak……a1a0(0<=ai<=9,0<=i<=k,ak!=0),n的个位为起始数字的数字的正负交错之和T(n)=a0+a1+……+(-1)kak,证明:11|n的充分必要条件是11|T(n);(整除理论1.1.2))

    设正整数n的十进制表示为n=ak……a1a0(0<=ai<=9,0<=i<=k,ak!=0),n的个位为起始数字的数字的正负交错之和T(n)=a0+a1+……+(-1)kak, ...

  2. DWR3.0框架入门(2) —— DWR的服务器推送

    DWR3.0框架入门(2) —— DWR的服务器推送 DWR 在开始本节内容之前,先来了解一下什么是服务器推送技术和DWR的推送方式.   1.服务器推送技术和DWR的推送方式   传统模式的 Web ...

  3. 《vue.js2.0从入门到放弃》学习之路

    原文地址: Vue.js2.0从入门到放弃---入门实例(一):http://blog.csdn.net/u013182762/article/details/53021374 Vue.js2.0从入 ...

  4. 【转】Zabbix 3.0 从入门到精通(zabbix使用详解)

    [转]Zabbix 3.0 从入门到精通(zabbix使用详解) 第1章 zabbix监控 1.1 为什么要监控 在需要的时刻,提前提醒我们服务器出问题了 当出问题之后,可以找到问题的根源   网站/ ...

  5. ExtJs 6.0+快速入门,ext-bootstrap.js文件的分析,各版本API下载

    ExtJS6.0+快速入门+API下载地址 ExtAPI 下载地址如下,包含各个版本 http://docs.sencha.com/misc/guides/offline_docs.html 1.使用 ...

  6. 新手嘛,先学习下 Vue2.0 新手入门 — 从环境搭建到发布

    Vue2.0 新手入门 — 从环境搭建到发布 转自:http://www.runoob.com/w3cnote/vue2-start-coding.html 具体文章详细就不搬了,步骤可过去看,我这就 ...

  7. 【数据库】7.0 MySQL入门学习(七)——MySQL基本指令:帮助、清除输入、查询等

    1.0 help == ? 帮助指令,查询某个指令的解释.用法.说明等.详情参考博文: [数据库]6.0 MySQL入门学习(六)——MySQL启动与停止.官方手册.文档查询 https://www. ...

  8. 【数据库】4.0 MySQL入门学习(四)——linux系统环境下MySQL安装

    1.0 我的操作系统是CentOS Linux release 7.6.1810  (Core) 系统详细信息如下: Linux version 3.10.0-957.1.3.el7.x86_64 ( ...

  9. 【数据库】3.0 MySQL入门学习(三)——Windows系统环境下MySQL安装

    1.0 我的操作系统是window10 专业版 64位.,不过至少windows7以上系统都是一样的. 关于MySQL如何下载,请参考博文: [数据库]2.0 如何获得MySQL以及MySQL安装 h ...

  10. 01.普通抖音新手如何从0开始入门3个月做到粉丝100w+

    普通抖音新手如何从0开始入门3个月做到粉丝100w+ 今年以来,明显感觉抖音很火,大有干掉微信,取代淘宝,京东的感觉,如今年轻人,一周7天有7天要玩抖音,所以说未来不可估量. 如是,2019春节以后, ...

随机推荐

  1. 操作系统发展历史与Linux

    操作系统发展历史与Linux 随着计算机技术的迅猛发展,操作系统作为计算机系统的核心软件,经历了从单一到多样.从封闭到开放的演变过程.从最初的批处理系统,到分时操作系统的兴起,再到个人计算机操作系统的 ...

  2. [SDOI2008] Sandy的卡片 题解

    讲一种自认为最暴力的方法. 首先肯定还是用差分的思想,对于每一张卡片进行重新标号,在卡片串与卡片串中插入特殊字符,然后找重复了 \(n\) 次的子串. 这里我们对于每一个子串开一个大小为 \(n\) ...

  3. Typecho如何去掉/隐藏index.php

    Typecho后台设置永久链接后,会在域名后加上index.php,很多人都接受不了.例如如下网址:https://www.jichun29.cn/index.php/archives/37/,但我们 ...

  4. vue - [03] Hello World~

    题记部分 (1)选择一个合适的目录,然后进入终端,执行:vue create account-manager (2)切换目录到account-manager,执行npm run serve启动开发服务 ...

  5. JavaGUI - [01] 常见API

    题记部分 一.Component 作为基类,提供了如下常用的方法来设置组件的大小.位置.可见性等. setLocation(int x,int y) 设置组件的位置 setSize(int width ...

  6. Flume - [02] Spooling Directory Source

    一.概述   可以通过将文件放入磁盘上的 "Spooldir" 目录中来获取数据.此源会监视指定目录中的新文件,并在新文件出现时解析新文件中的事件.事件解析逻辑是可插入的.在将指定 ...

  7. Elasticsearch7.8搭建(Windows版本单节点、Linux版本单节点、集群,)

    The Elastic Stack, 包括 Elasticsearch.Kibana.Beats 和 Logstash(也称为 ELK Stack).能够安全可靠地获取任何来源.任何格式的数据,然后实 ...

  8. echarts柱形图给X轴坐标类目添加点击事件

    在项目中遇到这么个需求要在柱形图上的x轴添加点击事件,当点击对应x轴文字的时候要弹出模态框展示子图表 根据echarts的Api给图表实例绑定点击事件 myChartInstance?.on('cli ...

  9. Ubuntu如何下载nvidia驱动和Cuda Toolkit

    Ubuntu如何下载nvidia驱动和Cuda Toolkit 前言 ‍ 手快不小心把 nvidia​ 的某个东西删除了,现在不得不全部卸载后再重新安装了. 我再也不敢在不确认内容的情况下,确认删除了 ...

  10. 微信小程序云函数

    小程序开发云环境设置 注意事项 每一个云函数都是一个独立的 nodeJS 项目.所以每个云函数下都有 package.json 文件 错误 前端操作数据库 1 指引 2 新建集合 3 新增记录 4 查 ...