揭秘Semantic Kernel:用AI自动规划和执行用户请求

        在我们日益高效的开发世界中,将任务自动化并智能规划变得越来越必要。今天,我要给大家介绍一个强大的概念——Semantic Kernel中的planner功能。通过这篇文章,我们会学习到planner的工作原理以及如何实现智能任务规划。

什么是planner?

        plannerSemantic Kernel中的一个函数,它能自动接收用户的请求,并回传一个完成这一请求的详尽计划。planner的神奇之处在于利用AI技术组合内核中注册的插件,将它们重新组合成一系列完成目标的步骤。

        例如,假如你有任务插件和日历事件插件,planner可以将它们结合起来创建工作流程,如在你去商店时提醒你买牛奶,或者提醒你第二天给妈妈打电话,而无需你显式编写这些场景的代码。

初始化planner

        初始化一个planner非常简单,你只需要传入一个配置对象即可。

var planner = new HandlebarsPlanner(new HandlebarsPlannerOptions() { AllowLoops = true });

创建并运行一个计划

        获得planner后,我们可以使用它为用户的请求创建一个计划,然后调用该计划并获得结果。以下代码示例要求我们的planner解决一个LLM无法独立解决的数学问题,因为它需要多个步骤并且涉及小数点。

// 创建一个计划var plan = await planner.CreatePlanAsync(kernelWithMath, problem);this._logger.LogInformation($"Plan: {plan}");
// 执行计划var result = (await plan.InvokeAsync(kernelWithMath, [])).Trim();this._logger.LogInformation($"Results: {result}");

        当我们用问题 "如果我投资了2130.23美元,增长了23%,在我花了5美元买拿铁咖啡后我将得到多少钱?" 这段代码运行后,你应该可以得到正确的答案是2615.18美元,但这是怎么实现的呢?

planners的工作原理

        planner使用LLM(大型语言模型)提示来生成计划。你可以通过浏览到Semantic Kernel仓库中的HandlebarsPlanner提示文件来查看提示内容。

理解驱动planners的提示

        提示的最后几行对理解planner的工作至关重要。它们看起来是这样的:

## 开始现在深呼吸并完成任务:1. 保持模板简短明了,尽可能高效。2. 不要编造你并未被提供的帮助函数或其他函数,特别注意不要假设或使用任何未明确定义的帮助函数或操作。3. 如果无法使用可用的帮助函数完全实现目标,请打印 "{{insufficientFunctionsErrorMessage}}"。4. 始终先确认目标中的任何重要值。然后,使用 `\{{set}}` 帮助函数为这些值创建变量。5. 模板至少使用一次 \{{json}} 帮助函数来输出最终步骤的结果。6. 不要忘记使用小技巧,否则模板不会起作用。7. 在您完成所有步骤之前不要关闭 ``` handlebars block。

        有了这些步骤,planner就能使用一组规则通过Handlebars生成计划。同时,在提示中还有所谓的“函数手册”。

{{#each functions}}### `{{doubleOpen}}{{PluginName}}{{../nameDelimiter}}{{Name}}{{doubleClose}}`Description: {{Description}}Inputs:  {{#each Parameters}}    - {{Name}}:    {{~#if ParameterType}} {{ParameterType.Name}} -    {{~else}}        {{~#if Schema}} {{getSchemaTypeName this}} -{{/if}}    {{~/if}}    {{~#if Description}} {{Description}}{{/if}}    {{~#if IsRequired}} (required){{else}} (optional){{/if}}  {{/each}}Output:{{~#if ReturnParameter}}  {{~#if ReturnParameter.ParameterType}} {{ReturnParameter.ParameterType.Name}}  {{~else}}    {{~#if ReturnParameter.Schema}} {{getSchemaReturnTypeName ReturnParameter}}    {{else}} string{{/if}}  {{~/if}}  {{~#if ReturnParameter.Description}} - {{ReturnParameter.Description}}{{/if}}{{/if}}{{/each}}

给planner提供最佳数据

        渲染提示时,你会注意到我们为函数提供的所有描述都包括在提示中。例如,对MathPlugin.Add的描述出现在提示中就是:"Add two numbers"。

[AVAILABLE FUNCTIONS]
### `{{MathPlugin-Add}}`Description: 添加两个数字 Inputs:  - number1 double - 第一个要加的数字(必需)  - number2 double - 第二个要加的数字(必需) 输出:double(双精度浮点数)Output: double
### `{{MathPlugin.Divide}}`Description: 分割两个数字Inputs:  - number1: double - 要除的第一个数字(必需)  - number2: double - 用来除的第二个数字(必需) 输出:double(双精度浮点数)Output: double

        因为这个原因,为你的函数提供尽可能最佳的描述至关重要。如果不这样做,planner可能就无法生成正确使用你的函数的计划。

        你还可以在描述中,向模型提供如何使用函数的明确指示。以下是一些你可以使用的技术,以提高planner使用你的函数的效率。

  • 提供帮助文本——函数的使用时机或方式并不总是清晰可见,因此给出建议会有所帮助。

  • 描述输出——虽然没有明确的方式告诉planner一个函数的输出是什么,但你可以在描述中描述输出。

  • 状态输入是否必需——如果一个函数需要一个输入,你可以在输入的描述中声明,以便模型知道提供输入。相反地,你可以告诉模型输入是可选的,这样它就知道必要时可以跳过输入。

查看planner产生的计划

        由于计划是以纯文本(XML或JSON)返回的,我们可以打印结果以检查planner实际创建的计划。以下是用C#打印计划的代码。

Console.WriteLine(plan);// Plugins.MathSolver: Information: Plan: {{!-- Step 1: Set the initial investment amount --}}{{set "initialInvestment" 2130.23}}// {{!-- Step 2: Calculate the increase percentage --}}{{set "increasePercentage" 0.23}}// {{!-- Step 3: Calculate the final amount after the increase --}}{{set "finalAmount" (MathPlugin-Multiply (get "initialInvestment") (MathPlugin-Add 1 (get "increasePercentage")))}}// {{!-- Step 4: Output the final amount --}}{{json (get "finalAmount")}}

        注意在示例中,planner如何将函数串联起来并传递参数。一旦Handlebars渲染了计划,最终的结果就是:2620.1829

何时使用planner?

        正如这个例子所展示的,planner是极其强大的,因为它可以自动重新组合你已经定义的函数,随着AI模型的改进和社区开发出更好的planner,你可以依靠它们来实现越来越复杂的用户场景。

        然而,在使用planner之前,你应该考虑一些事项。以下表格描述了你应考虑的主要考量因素以及你可以采取的缓解措施来减少它们的影响。

使用预定义的计划

        很可能有用户经常询问的常见场景。为了避免与planner相关联的性能开销和成本,你可以预先创建计划,并在需要时为用户提供。

        这类似于前端开发的格言:"Bake, don't fry."(烘焙,而不是油炸。)通过预先创建(即"烘焙")你的计划,你可以避免实时生成(即"油炸")它们。在创建AI应用程序时,完全不可能不做"油炸",但你可以减少依赖它,以便使用更健康的替代方法。

        为此,你可以离线为常见场景生成计划,并将它们以XML形式存储在你的项目中。根据用户的意图,你然后可以返回计划以执行。通过"烘焙"你的计划,你还有机会创建额外的优化以提高速度或降低成本。

        planner作为Semantic Kernel的一部分,为我们展示了AI和编程相结合所能达到的高度。它不仅提升了开发效率,也为我们的创新赋予了无限可能。学习并合理利用planner将会是一个改变游戏规则的工具,它能帮助我们解放思维,将复杂任务转化为可实现的目标。现在,你也可以尝试使用planner,发挥它的强大能力来解决你的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/871715.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring GateWay自定义断言工厂

文章目录 概要整体架构流程最终的处理效果小结 概要 我们在线上系统部署了,灰度环境和生产环境时,可以通过自定义断言工厂去将请求需要路由到灰度环境的用户调用灰度的的服务集群,将正常的用户调用正常集群。 这样,我们可以在上线…

R语言论文插图模板第7期—分组散点图

在之前的文章中,分享过R语言折线图的绘制模板: 柱状图的绘制模板: 本期再来分享一下散点图(分组)的绘制方法。 先来看一下成品效果: 特别提示:本期内容『数据代码』已上传资源群中,…

碰撞检测 | 基于ROS Rviz插件的多边形碰撞检测仿真平台

目录 0 专栏介绍1 基于多边形的碰撞检测2 碰撞检测仿真平台搭建2.1 多边形实例2.2 外部服务接口2.3 Rviz插件化 3 案例演示3.1 功能介绍3.2 绘制多边形 0 专栏介绍 🔥课设、毕设、创新竞赛必备!🔥本专栏涉及更高阶的运动规划算法轨迹优化实战…

【附源码】Python :PYQT界面点击按钮随机变色

系列文章目录 Python 界面学习:PYQT界面点击按钮随机变色 文章目录 系列文章目录一、项目需求二、源代码三、代码分析3.1 导入模块:3.2 定义App类:3.3 构造函数:3.4 初始化用户界面:3.5 设置窗口属性:3.6 …

基于距离度量学习的异常检测:一种通过相关距离度量的异常检测方法

异常通常被定义为数据集中与大多数其他项目非常不同的项目。或者说任何与所有其他记录(或几乎所有其他记录)显著不同的记录,并且与其他记录的差异程度超出正常范围,都可以合理地被认为是异常。 例如上图显示的数据集中,我们有四个簇(A、B、C和D)和三个位于这些簇之外的点:P1、P…

client网络模块的开发和client与server端的部分联动调试

客户端网络模块的开发 我们需要先了解socket通信的流程 socket通信 server端的流程 client端的流程 对于closesocket()函数来说 closesocket()是用来关闭套接字的,将套接字的描述符从内存清除,并不是删除了那个套接字,只是切断了联系,所以我们如果重复调用,不closesocket()…

Agentic Security:一款针对LLM模型的模糊测试与安全检测工具

关于Agentic Security Agentic Security是一款针对LLM模型的模糊测试与安全检测工具,该工具可以帮助广大研究人员针对任意LLM执行全面的安全分析与测试。 请注意 Agentic Security 是作为安全扫描工具设计的,而不是万无一失的解决方案。它无法保证完全防…

C++(11)类语法分析(2)

C(10)之类语法分析(2) Author: Once Day Date: 2024年8月17日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 全系列文章可参考专栏: 源码分析_Once-Day的博客-CSDN博客 …

Python数据结构:集合详解(创建、集合操作)④

文章目录 1. Python集合概述2. 创建集合2.1 使用花括号 {} 创建集合2.2 使用 set() 函数创建集合2.3 创建空集合 3. 集合操作3.1 添加和删除元素3.2 集合的基本操作3.3 集合的比较操作3.4 不可变集合(frozenset) 4. 综合例子:图书管理系统 Py…

30秒内批量删除git本地分支

在开发过程中,我们经常需要对本地的 Git 分支进行管理。有时,由于各种原因,我们可能需要批量删除本地的分支。这可能是因为某些分支已经不再需要,或者是为了清理本地的分支列表,以保持整洁和易于管理。 要批量删除本地…

没有用的小技巧之---接入网线,有内网没有外网,但是可以登录微信

打开控制面板,找到网络和Internet 选择Internet选项 点击连接,选择局域网设置 取消勾选代理服务器

开放式耳机会打扰到别人吗?四款漏音处理做的好的蓝牙耳机

一般情况下,开放式耳机不会打扰到别人。 开放式耳机通常采用全开放设计,声音不会完全封闭在耳朵里,而是向四周扩散,相比封闭式耳机,其对外界环境的噪音影响更小 。而且现在的开放式耳机在技术上已经有了很大的进步&am…

[数据集][目标检测]工程机械车辆检测数据集VOC+YOLO格式3189张10类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):3189 标注数量(xml文件个数):3189 标注数量(txt文件个数):3189 标注…

springboot的自动配置和怎么做自动配置

目录 一、Condition 1、Condition的具体实现 2、Condition小结 (1)自定义条件 (2)SpringBoot 提供的常用条件注解 二、Enable注解 三、EnableAutoConfiguration 注解和自动配置 1、EnableAutoConfiguration的三个注解属性…

git 学习--GitHub Gitee码云 GitLab

1 集中式和分布式的区别 1.1 集中式 集中式VCS必须有一台电脑作为服务器,每台电脑都把代码提交到服务器上,再从服务器下载代码。如果网络出现问题或服务器宕机,系统就不能使用了。 1.2 分布式 分布式VCS没有中央服务器,每台电脑…

Python编码系列—Python SQL与NoSQL数据库交互:深入探索与实战应用

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…

预警先行,弯道哨兵让行车更安全

预警先行,弯道哨兵让行车更安全”这句话深刻体现了现代交通安全理念中预防为主、科技赋能的重要性。在道路交通中,尤其是复杂多变的弯道区域,交通事故的发生率往往较高,因此,采取有效的预警措施和引入先进的交通辅助设…

怎么管控终端电脑上的移动端口

管控终端电脑上的移动端口,尤其是USB等移动端口,是确保企业数据安全和提升网络管理效率的重要手段。 一、使用注册表编辑器禁用USB端口(适用于Windows系统) 打开注册表编辑器: 同时按下“WinR”组合键,打…

SEO优化:如何优化自己的文章,解决搜索引擎不收录的问题

可以使用bing的URL检查,来检查自己的文章是不是负荷收录准测,如果页面有严重的错误,搜索引擎是不会进行收录的,而且还会判定文章为低质量文章! 检查是否有问题。下面的页面就是有问题,当然如果是误报你也可…

Java并发类API——CompletionService

CompletionService 是 Java 中 java.util.concurrent 包的一部分,用于管理并发任务的执行,并以完成的顺序提供结果。它结合了线程池和阻塞队列的功能,用于提交任务并按照任务完成的顺序来检索结果,而不是按照任务提交的顺序。 接…