在我们日益高效的开发世界中,将任务自动化并智能规划变得越来越必要。今天,我要给大家介绍一个强大的概念——Semantic Kernel中的planner
功能。通过这篇文章,我们会学习到planner
的工作原理以及如何实现智能任务规划。
什么是planner?
planner
是Semantic 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
,发挥它的强大能力来解决你的问题。