深入Semantic Kernel:插件开发与实践应用(进阶篇)
文章目录
- 一、引言
- 二、开发Semantic Kernel插件
- 三、实战
- 3.1 时间信息插件
- 3.2 小部件工厂插件
- 3.3 初始化Semantic Kernel实例
- 3.4 四个实战示例
- 3.4.1 模型幻觉
- 3.4.2 给模型提供时间信息
- 3.4.3 AI自动调用函数
- 3.4.4 AI自动调用和使用枚举
- 四、结论
一、引言
在上一篇入门文章《探索Semantic Kernel:开启AI编程新篇章》中,我们了解了Semantic Kernel的基础知识,包括如何创建内核实例、配置AI模型以及执行基本的AI任务。本文将作为进阶篇,重点介绍如何开发Semantic Kernel插件,并在实际应用中调用这些插件。

二、开发Semantic Kernel插件
Semantic Kernel插件是扩展AI模型功能的模块,它们可以封装特定领域的知识和功能,使得AI模型能够执行更复杂的任务。在本教程中,我们将开发两个插件:TimeInformation和WidgetFactory。
三、实战
3.1 时间信息插件
TimeInformation插件提供了一个函数,用于获取当前的UTC时间。
/// <summary>
/// 返回当前时间的插件
/// </summary>
public class TimeInformation
{[KernelFunction][Description("获取当前UTC时间")]public string GetCurrentUtcTime() => DateTime.UtcNow.ToString("R");
}
3.2 小部件工厂插件
WidgetFactory插件提供了一个函数,用于根据指定的类型和颜色创建小部件。
/// <summary>
/// 创建部件的插件
/// </summary>
public class WidgetFactory
{[KernelFunction][Description("创建指定类型和颜色的部件")]public WidgetDetails CreateWidget([Description("要创建的小部件的类型")] WidgetType widgetType, [Description("要创建的小部件颜色")] WidgetColor[] widgetColors){var colors = string.Join('-', widgetColors.Select(c => c.GetDisplayName()).ToArray());return new(){SerialNumber = $"{widgetType}-{colors}-{Guid.NewGuid()}",Type = widgetType,Colors = widgetColors};}
}
为了使插件能够处理不同的小部件类型和颜色,我们定义了两个枚举类型:WidgetType和WidgetColor。
WidgetDetails类用于存储小部件的详细信息,包括序列号、类型和颜色。
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum WidgetType
{[Description("有用的小部件。")]Useful,[Description("装饰性的小部件。")]Decorative
}[JsonConverter(typeof(JsonStringEnumConverter))]
public enum WidgetColor
{[Description("创建红色物品时使用")]Red,[Description("创建绿色物品时使用")]Green,[Description("创建蓝色物品时使用")]Blue
}public class WidgetDetails
{public string SerialNumber { get; init; }public WidgetType Type { get; init; }public WidgetColor[] Colors { get; init; }
}
/// <summary>
/// 枚举扩展方法
/// </summary>
public static class EnumExtensions
{private static readonly ConcurrentDictionary<Enum, string> DisplayNameCache = new ConcurrentDictionary<Enum, string>();/// <summary>/// 获取枚举字段值的属性。/// </summary>/// <typeparam name="T"></typeparam>/// <param name="enumValue"></param>/// <returns></returns>[UnconditionalSuppressMessage("Trimming", "IL2075", Justification = "Fields are never trimmed for enum types.")]public static T GetAttributeOfType<T>(this Enum enumValue) where T : Attribute{FieldInfo field = enumValue.GetType().GetField(enumValue.ToString(), BindingFlags.Static | BindingFlags.Public);if (field == null){return null;}return field.GetCustomAttributes<T>(inherit: false).FirstOrDefault();}/// <summary>/// 获取enum的显示名称/// </summary>/// <param name="enumValue"></param>/// <returns></returns>public static string GetDisplayName(this Enum enumValue){return DisplayNameCache.GetOrAdd(enumValue, delegate (Enum e){DisplayAttribute attributeOfType = e.GetAttributeOfType<DisplayAttribute>();return (attributeOfType != null) ? attributeOfType.Name : e.ToString();});}
}
3.3 初始化Semantic Kernel实例
#pragma warning disable SKEXP0001, SKEXP0010, SKEXP0050, SKEXP0020, ASP0000
//使用的模型
string model = "gpt-4o-mini";
//使用的openai代理地址,这里也可以使用国产模型和地址。只要是openai格式即可
string endpointKey = "https://xie.openai.com/v1";
//openai 密钥
string apiKey = "sk-";// 创建一个带有OpenAI聊天完成的内核IKernelBuilder kernelBuilder = Kernel.CreateBuilder();kernelBuilder.AddOpenAIChatCompletion(modelId: model,endpoint: new Uri(endpointKey),apiKey: apiKey);//添加打印时间信息插件kernelBuilder.Plugins.AddFromType<TimeInformation>();//添加构建颜色、类型部件插件kernelBuilder.Plugins.AddFromType<WidgetFactory>();Kernel kernel = kernelBuilder.Build();
3.4 四个实战示例
3.4.1 模型幻觉
//示例1:用一个提示来调用内核,该提示要求AI提供它无法提供的信息,并可能产生幻觉
Console.WriteLine("------------------------示例1 模型无法提供的实时信息-------------------------------");
Console.WriteLine(await kernel.InvokePromptAsync("离圣诞节还有几天?"));
Console.WriteLine();

3.4.2 给模型提供时间信息
//示例2:使用模板提示调用内核,该提示调用插件并显示结果
Console.WriteLine("------------------------示例2 使用插件结合问题,给模型提供时间信息--------------------------------");
Console.WriteLine(await kernel.InvokePromptAsync("当前时间为: {{TimeInformation.GetCurrentUtcTime}}。 离圣诞节还有几天?"));
Console.WriteLine();

3.4.3 AI自动调用函数
//示例3:使用提示符调用内核,并允许AI自动调用函数
#pragma warning disable SKEXP0001 // 类型仅用于评估,在将来的更新中可能会被更改或删除。取消此诊断以继续。OpenAIPromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
#pragma warning restore SKEXP0001 // 类型仅用于评估,在将来的更新中可能会被更改或删除。取消此诊断以继续。Console.WriteLine("------------------------示例3 模型自动评估是否调用函数获取时间--------------------------------");Console.WriteLine(await kernel.InvokePromptAsync("离圣诞节还有几天?解释你的想法。", new(settings)));Console.WriteLine();

3.4.4 AI自动调用和使用枚举
//示例4:用提示符调用内核,并允许AI自动调用使用枚举的函数
Console.WriteLine("------------------------示例4 模型自动调用函数生成对应颜色组件- -----------------------------");
Console.WriteLine("--------------------示例4.1红色----------------------------");
//因枚举中有红色,AI自动识别并创建红色组件
Console.WriteLine(await kernel.InvokePromptAsync("为我创建一个红色小部件。", new(settings)));
Console.WriteLine();Console.WriteLine("--------------------示例4.2浅绿色----------------------------");//因枚举中有绿色,AI自动识别并创建绿色组件Console.WriteLine(await kernel.InvokePromptAsync("为我创建一个浅绿色小部件。", new(settings)));Console.WriteLine();Console.WriteLine("--------------------示例4.3蓝色----------------------------");//因枚举中有蓝色,AI自动识别并创建蓝色组件Console.WriteLine(await kernel.InvokePromptAsync("为我创建一个蓝色小部件。", new(settings)));Console.WriteLine();// 因枚举中没有紫色,AI会告知用户只能在系统提供的三种颜色中选取Console.WriteLine("--------------------示例4.4紫色----------------------------");Console.WriteLine(await kernel.InvokePromptAsync("为我创建一个紫色小部件。", new(settings)));


四、结论
通过开发和调用Semantic Kernel插件,我们可以将自定义功能和业务逻辑集成到AI模型中,从而创建更加强大和灵活的应用程序。这些插件不仅可以提高开发效率,还可以帮助我们更好地控制AI模型的行为。
在下一篇文章中,我们将探讨如何将Semantic Kernel与其他技术栈和服务集成,以构建更加强大和全面的AI解决方案。
参考资料:
微软文档:https://learn.microsoft.com/en-us/semantic-kernel/overview/
Github:https://github.com/microsoft/semantic-kernel
相关文章:
深入Semantic Kernel:插件开发与实践应用(进阶篇)
文章目录 一、引言二、开发Semantic Kernel插件三、实战3.1 时间信息插件3.2 小部件工厂插件3.3 初始化Semantic Kernel实例3.4 四个实战示例3.4.1 模型幻觉3.4.2 给模型提供时间信息3.4.3 AI自动调用函数3.4.4 AI自动调用和使用枚举 四、结论 一、引言 在上一篇入门文章《探索…...
基于SpringBoot+Vue+Uniapp的植物园管理小程序系统(2024最新,源码+文档+远程部署+讲解视频等)
3. 论文参考 4. 项目运行截图 5. 技术框架 5.1 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不是配置文件。Spring …...
2024zzuacm新生选拔赛第一场
2024zzuacm新生选拔赛第一场https://ac.nowcoder.com/acm/contest/92409 python代码源自我有异议症QAQ A - 降智视频 题意 起初有n个数都在丁丁手中,进行如下操作k次: 豆豆从丁丁手中拿走标号为奇数的数。对丁丁的其他的数进行重新标号。 问进行k次…...
IP地址如何支持远程办公?
由于当今社会经济的飞速发展,各个方向的业务都不免接触到跨省、跨市以及跨国办公的需要,随之而来的远程操作的不方便,加载缓慢,传输文件时间过长等困难,如何在万里之外实现远程办公呢?我们以以下几点进行阐…...
spring 集合注入格式
数组 List Set Map properties 案例 package org.example.dao.impl;import org.example.dao.BookDao;import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set;public class BookDaoImpl implements BookDao {private int[] array;p…...
基于Zabbix进行服务器运行情况监测
文章目录 引言I Zabbix主要构成下载并安装Zabbix被监控主机安装zabbix agent创建被监控主机报警设置II 常见问题cannot use database "zabbix": its "users" table is empty (is this the Zabbix proxy database?)重置 Zabbix Web 界面密码Zabbix agent i…...
Github优质项目推荐 - 第五期
文章目录 Github优质项目推荐 - 第五期一、【localsend】,47.5k stars - 附近设备文件互传二、【Pake】,29.9k stars - 网页变成桌面应用三、【laravel-crm】,10.7k stars - CRM 解决方案四、【localstack】,55.7k stars - 本地 A…...
Java_ EE (网络编程)
网络编程基本概念: 计算机网络计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。从其…...
Qt子线程运行报错error: undefined reference to `excelThread::conversionFinished()‘
如标题所示,笔者试图在子线程中使用基于GUI的对话框,而基于GUI的对话框需要在主线程(也称为GUI线程)中运行,在子线程中不能直接用,需要使用信号与槽机制,将请求发送到主线程,然后在主…...
VSCode 使用 EmmyLua 对lua进行调试
时间:2024年10月 其他:win10,EmmyLua v0.8.20 参考:https://blog.csdn.net/ShenHaoDeHao/article/details/140268354 有几个概念搞清楚就好理解了。一般开发中,我们编写的lua文件由宿主程序的来解析、执行࿱…...
neovim ubuntu中WARNING No clipboard tool found
我在vnc远程的ubuntu中做个临时开发,发现neovim无法复制文字,于是我:checkhealth查看了一下,测试结果如下: WARNING No clipboard tool found. Clipboard registers (" and "*) will not work.ADVICE::help clipboard …...
1882B - Sets and Union
题意就是有n个集合,对n个集合做并集得到 S S S, 现在抽n个集合中的集合做交集得到 T T T,问如何做让 S ≠ T S\neq T ST,并且让 T T T尽可能大。 这道题如果数据大一些做不了,但是数字大小只在50之间,并且集合的大小50,n大小50…...
thinkphp阿里云发送短信验证码,存储到缓存中完成手机号验证
源码demo下载地址 https://download.csdn.net/download/hanzhuhuaa/89865893 或者也可以在文章中查看demo源码 ↓ 第一步安装阿里云 SDK 您可以使用 Composer 来安装阿里云的 SDK。在项目目录中运行: composer require alibabacloud/sdk第二步发送短信 namespace app\api\c…...
题目解析:1423. 可获得的最大点数
题目解析:1423. 可获得的最大点数 > Problem: 1423. 可获得的最大点数 题目描述: 你有一个整数数组 cardPoints,表示排成一行的几张卡牌的点数。你每次可以从这排卡牌的 开头或末尾 拿一张卡牌,最终你需要正好拿 k 张卡牌。目…...
【MySQL】数据库的操作
文章目录 一、查看数据库(显示所有的数据库)二、使用数据库二、创建数据库字符集编码(为数据进行编码然后保存)校验(排序)规则(如何对数据进行排序)推荐这样创建数据库: …...
Spring Boot读取resources目录下文件(打成jar可用),并放入Guava缓存
1、文件所在位置: 2、需要Guava依赖: <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>23.0</version></dependency>3、启动时就读取放入缓存的代码…...
rsync 数据镜像同步服务笔记
1. rsync概述 定义:rsync是一款数据镜像备份工具,支持快速完全备份和增量备份,支持本地复制与远程同步。镜像指两份完全相同的数据备份.特点: 支持整个目录树和文件系统的更新;可选择性地保留符号链接、文件属性、权限…...
【layui】多文件上传组件实现
插件预览效果: 需要引入layui的脚本文件layui.js和样式文件layui.css html代码: <div class"layui-input-block"><div class"layui-upload-list"><table class"layui-table"><colgroup><col…...
多维最短路
D-最短?路径_牛客小白月赛102 (nowcoder.com) #include <bits/stdc.h> #define int long long using namespace std; const int N1e6; struct node {int x;int y;int z;bool operator>(const node& other) const {return x> other.x;} }; signed m…...
设计模式03-装饰模式(Java)
4.4 装饰模式 1.模式定义 不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。 2.模式结构 抽象构件角色 :定义一个抽象接口以规范准备接收附加责任的对象。客户端可以方便调用装饰类和被装饰类…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
