Semantic Kernel 入门系列:📅 Planner 计划管理

Semantic Kernel 的一个核心能力就是实现“目标导向”的AI应用。
目标导向
“目标导向”听起来是一个比较高大的词,但是却是实际生活中我们处理问题的基本方法和原则。
顾名思义,这种方法的核心就是先确定目标,然后在寻找实现目标的方法和步骤。这对于人来说的是很自然的事情,但是对于机器则不然。一大堆的指令和控制逻辑其实都是在完成另外一种产出导向的结果。所有的流程和过程都需要提前预定义好,然后期待一个结果的产出。
如今,借助 LLM AI 的力量,我们可以轻松的实现目标导向的过程。
在 Semantic Kernel中,Planner就用于这项工作。
我们可以提前准备好所需的Skill,根据设定好的最终目标,通过Planner,可以将目标分解为需要执行的任务列表,并且可以指定好对应的参数传递,然后逐个任务执行,从而实现最终目标。
做好技能准备
为了让LLM AI更好的理解我们所提供的技能,需要明确地配置好每个技能本身的描述和参数描述。
对于的Semantic Function来说,可以在config.json中配置。以下是一个Translate的配置。
需要注意的就是 description 和 input 参数,最终会成为的LLM是否选择使用的判断标准。而这一切都是基于语义化的理解。
{
"schema": 1,
"type": "completion",
"description": "Translate the input into the specified language",
"completion": {
"max_tokens": 256,
"temperature": 0.0,
"top_p": 0.0,
"presence_penalty": 0.0,
"frequency_penalty": 0.0
},
"input": {
"parameters": [
{
"name": "input",
"description": "input text",
"defaultValue": ""
},
{
"name":"language",
"description":"the specified language",
"defaultValue":"English"
}
]
}
}
对于Native Function ,可以使用特性进行声明,其实 SKFunction 中用于添加Function的描述, SKFunctionContextParameter 用于添加参数的说明。
public class EmailSKill {
[SKFunction("Send email conten to receiver")]
[SKFunctionContextParameter(Name ="content", Description = "email content")]
[SKFunctionContextParameter(Name ="receiver", Description = "the email address of receiver")]
public void SendTo(SKContext context){
var email = context["content"];
var receiver = context["receiver"];
Console.WriteLine(
$"""
mail to: {receiver}
{email}
""");
}
}
准备好技能之后,就可以将这些技能导入到Kernel中,准备后续时候。
作为示例,这里导入了三个功能:
MySkill.WriteText: 文案写作MySkill.Translate:文本翻译email.SendTo: 邮件发送
使用Planner
然后我们就可以开始使用 Planner了。
Planner本身也是 Semantic Kernel中的一个Skill,融合了Semantic Function 和 Native Function。
和通常的Skill一样,导入 PlannerSkill 后即可使用。
var planner = kernel.ImportSkill(new PlannerSkill(kernel),"plan");
指定好任务目标。
var goal = "The PowerBlog is about to release a new product, please write a chinese press release about the new product and send it to mail@example.com";
然后就可以执行 CreatePlan 创建一个Plan。
var plan = await kernel.RunAsync(goal,planner["CreatePlan"]);
此时可以使用Plan.PathString查看当前的任务编排。
Plan所有状态的结果都会保存在Context中,所以可以通过 context.Variables.ToPlan() 方法获取Plan对象。
plan.Variables.ToPlan().PlanString.Dump("Create Plan");
/*
<goal>
The PowerBlog is about to release a new product, please write a chinese press release about the new product and send it to mail@example.com
</goal>
<plan>
<function.MySkill.WriteText input="The PowerBlog is about to release a new product" setContextVariable="PRESS_RELEASE"/>
<function.MySkill.Translate input="$PRESS_RELEASE" language="Chinese" setContextVariable="TRANSLATED_PRESS_RELEASE"/>
<function.email.SendTo content="$TRANSLATED_PRESS_RELEASE" receiver="mail@example.com"/>
</plan>
*/
创建好了 Plan 就可以使用 ExecutePlan 执行了。
由于每次只能执行一个Function,所以我们需要通过循环来执行所有Function。
同时根据Plan的状态,判断是否执行成功,是否执行完成。
Plan 有两种状态,一种是 IsSuccessful ,表示当前的Plan是否执行成功。
另一个是 IsComplete,表示整个Plan是否执行完成。
async Task<SKContext> ExecutePlanAsync(IKernel kernel, SKContext plan)
{
var executionResults = plan;
while (!executionResults.Variables.ToPlan().IsComplete)
{
var result = await kernel.RunAsync(executionResults.Variables, planner["ExecutePlan"]);
var planResult = result.Variables.ToPlan();
if (planResult.IsSuccessful)
{
if (planResult.IsComplete)
{
break;
}
}
else
{
break;
}
executionResults = result;
}
return executionResults;
}
var result = await ExecutePlanAsync(kernel,plan);
// output:
/*
mail to: mail@example.com
介绍PowerBlog——专为企业和企业家设计的终极博客平台。我们的新产品旨在帮助您轻松创建、管理和优化博客内容。
PowerBlog是为想要创建与竞争对手不同的专业博客的企业和企业家完美的解决方案。通过我们的直观用户界面,您可以快速创建和管理博客文章,优化SEO内容,并跟踪博客的性能。
我们的新产品还包括强大的功能,如自动内容策划、社交媒体整合和分析工具。通过这些功能,您可以轻松监控博客的性能,并就内容策略做出明智的决定。
PowerBlog是为想要创建与竞争对手不同的专业博客的企业和企业家完美的解决方案。通过我们的直观用户界面,您可以快速创建和管理博客文章,优化SEO内容,并跟踪博客的性能。
我们很高兴向客户提供这款新产品,期待帮助您创建一个成功的博客。今天就注册,开始创建与竞争对手不同的内容吧。
*/
最后根据状态判断Plan最后执行是否成功,并从plan.Result 中获取最后的输出结果。
if(!result.Variables.ToPlan().IsSuccessful) {
result.Variables.ToPlan().Result.Dump("Complete!");
}else {
result.Variables.ToPlan().Result.Dump("Error");
}
/*
:Complete!:
介绍PowerBlog——专为企业和企业家设计的终极博客平台。我们的新产品旨在帮助您轻松创建、管理和优化博客内容。
PowerBlog是为想要创建与竞争对手不同的专业博客的企业和企业家完美的解决方案。通过我们的直观用户界面,您可以快速创建和管理博客文章,优化SEO内容,并跟踪博客的性能。
我们的新产品还包括强大的功能,如自动内容策划、社交媒体整合和分析工具。通过这些功能,您可以轻松监控博客的性能,并就内容策略做出明智的决定。
PowerBlog是为想要创建与竞争对手不同的专业博客的企业和企业家完美的解决方案。通过我们的直观用户界面,您可以快速创建和管理博客文章,优化SEO内容,并跟踪博客的性能。
我们很高兴向客户提供这款新产品,期待帮助您创建一个成功的博客。今天就注册,开始创建与竞争对手不同的内容吧。
*/
至此,我们就掌握了Semantic Kernel 当前所有的核心概念和基本使用方法。
参考资料:
- Planner in Semantic Kernel | Microsoft Learn
- semantic-kernel/05-using-the-planner.ipynb at main · microsoft/semantic-kernel · GitHub
- What is Semantic Kernel? | Microsoft Learn
Semantic Kernel 入门系列:📅 Planner 计划管理的更多相关文章
- linux入门系列13--磁盘管理之RAID、LVM技术
前一篇文章学习了磁盘分区.格式化.挂载等相关知识,本文将讲解RAID和LVM技术. 磁盘管理操作主要是运维人员用的较多,如果只是单纯的开发人员,可以先略过本文.但是在很多小公司里往往都是一人多用,运维 ...
- linux入门系列12--磁盘管理之分区、格式化与挂载
前面系列文章讲解了VI编辑器.常用命令.防火墙及网络服务管理,本篇将讲解磁盘管理相关知识. 本文将会介绍大量的Linux命令,其中有一部分在"linux入门系列5--新手必会的linux命令 ...
- linux入门系列6--软件管理之rpm和yum仓库
前面系列文章中,我们对vi编辑器和46个基本命令进行了介绍,本文将演示在centos7下使用RPM和YUM安装和管理软件. 一.RPM软件包管理器 1.1 RPM背景介绍 RPM(RedHat P ...
- linux入门系列9--用户管理及文件权限控制
前面文章分享了Linux下常用命令以及Shell编程相关知识,本节继续学习Linux用户管理及文件权限控制. Linux是多用户多任务操作系统,具有很好的稳定性和安全性.既然是多用户,那就意味 ...
- linux入门系列10--firewalld防火墙管理
上一篇文章学习了用户及文件相关权限,本篇继续学习防火墙技术. 防火墙作为公网与内网之间的保护屏障,对系统至关重要.防火墙又分为硬件防火墙和软件防火墙,主要功能都是依据设置的策略对穿越防火墙的流量进行过 ...
- linux入门系列14--ssh服务及主机远程管理
通过前面十余篇文章的介绍,相信已经初步入门Linux本地管理的基本方法了,后续的文章将介绍Linux中常用的服务部署以及如何为外部提供相应的服务. 系列文章第三篇"linux入门系列3--l ...
- linux入门系列18--Web服务之Apache服务2
接上一篇文章,在了解Apache基本配置以及SELinux相关知识后,继续演示Apache提供的虚拟主机功能以及访问控制方式. 如果还没看上一篇的建议先查看后再来,上篇文章"linux入门系 ...
- ABP入门系列(9)——权限管理
ABP入门系列目录--学习Abp框架之实操演练 源码路径:Github-LearningMpaAbp 完成了简单的增删改查和分页功能,是不是觉得少了点什么? 是的,少了权限管理.既然涉及到了权限,那我 ...
- HBase编程 API入门系列之create(管理端而言)(8)
大家,若是看过我前期的这篇博客的话,则 HBase编程 API入门系列之put(客户端而言)(1) 就知道,在这篇博文里,我是在HBase Shell里创建HBase表的. 这里,我带领大家,学习更高 ...
- Linux入门到放弃之八《任务计划管理》
任务计划管理 1.每周一下午5:50将/data目录下的所有目录和文件归档并压缩为:backup.tar.gz 放在/home/backup目录下. 先新建/data目录,并在目录中随意生成几个文件 ...
随机推荐
- vscode 一些扩展的推荐(前端)
- `Auto Rename Tag`:成对修改 HTML 标签名 - `Bracket Pair Colorizer`:括号匹配高亮 - `Color Highlight`:显示颜色代码的颜色 - ...
- 数字子串的和 str2int
UVA1673 这道题可以用广义后缀自动机,不过陈锋老师给我们讲了一个巧妙地方法,使得这道题可以用普通的后缀自动机做. 题目大意: 给出NNN个完全由数字组成的字符串.计算将这个NNN的字符串的所有子 ...
- css怪异现象合集
一.margin上塌陷解决方案(无中生有的margin-top): 1.父级元素设置padding-top:1px;//最不靠谱的解决方案 2.父级元素设置 overflow: hidden; 或者 ...
- Asp.net zero项目框架和配置
- GFF2GTF.py2
import sys inFile = open(sys.argv[1],'r') for line in inFile: #skip comment lines that start with th ...
- 京东薅羊毛脚本-Docker
一.安装好docker,然后创建容器: 注1:如果是旁路由,建议用--network host \代替-p 5678:5678 \这一行. 注2:如果想要看到lxk0301大佬的js脚本,并且重新部署 ...
- Apache Ranger系列六:Submarine Spark Security Plugin安装(0.6.0版本)
参考 https://submarine.apache.org/zh-cn/docs/0.6.0/userDocs/submarine-security/spark-security/ 从ranger ...
- week3题解
1.寄包柜 看到题目最容易想到开二位数组 但数据量过大,因此需要map #include <bits/stdc++.h> using namespace std; map<int,m ...
- GitHub远程仓库与本地仓库链接问题
git clone ...时,Failed to connect to 127.0.0.1 port 1080: Connection refused 步骤1------git查看: 查询动态代理 g ...
- VSCode 快捷键,简化操作
一. 区域代码快捷键 1. 折叠所有 折叠所有区域代码的快捷: ctrl + k ctrl + 0 ; 展开所有折叠区域代码的快捷:ctrl +k ctrl + J ; 2. 按层 ...