赞
踩
Semantic Kernel是一个开源的SDK,可以轻松构建能够调用现有代码的代理程序。作为一个高度可扩展的SDK,可以使用Semantic Kernel与来自OpenAI、Azure OpenAI、Hugging Face等的模型进行结合。通过将现有的C#、Python和Java代码与这些模型结合,可以构建能够回答问题和自动化流程的代理程序。Semantic Kernel是代理程序堆栈的核心,支持插件扩展性、协同编排、基础模型和基础设施。它还提供了内置的模板、链式和规划能力,可以轻松构建自定义的插件和应用程序。通过Semantic Kernel,您可以将现有的代码与Al模型结合,实现对现实世界的调用,而不受特定Al模型提供商的限制。
框架在使用中,使用planner去规划流程,通过native function/semantic function执行实际业务逻辑, Memory进行知识库搜索完成业务调用。
planner是一个函数,它接收用户的请求并返回一个计划,告诉如何完成这个请求。它使用人工智能技术将注册在内核中的插件进行混合和匹配,以将它们重新组合成一系列步骤,完成一个目标。使用planner,你可以创建原子函数,以一种开发者可能没有想到的方式使用它们。例如,如果你有任务和日历事件插件,planner可以将它们组合起来,以完成像"明天给我妈妈打电话"这样的请求,而无需显式编写处理这些情况的代码。
如下所示,通过HandlebarsPlanner创建计划,并直接执行,可以达到将复杂的任务拆解为精细的子任务并逐步执行以便完成最终任务效果
var planner = new HandlebarsPlanner(new HandlebarsPlannerOptions() { AllowLoops = true });
// 创建计划
var plan = await planner.CreatePlanAsync(kernelWithMath, problem);
this._logger.LogInformation($"Plan: {plan}");
// 执行计划
var result = (await plan.InvokeAsync(kernelWithMath, [])).Trim();
this._logger.LogInformation($"Results: {result}");
SK框架中的Function主要分为两部分:Semantic Function和Native Function。 Semantic Function是在Semantic Kernel中定义的函数,用来处理语义相关操作。主要通过Prompt来创建。而Native Function是本地函数,可以进行复杂的计算逻辑或Web调用等原生函数操作。通过结合Semantic Function和Native Function,可以将大模型的语言能力和原生代码能力相结合,赋予大模型执行业务调用的能力。
Semantic Function主要通过Prompt创建,SK本身提供了一些示例的skill,如文本总结的Summary Skill。官方也提供了标准的Semantic Function创建Prompt示例:
using Microsoft.SemanticKernel.SemanticFunctions; // ⚠️ Semantic Function的核心就是prompt⚠️ // 这里偷懒,使用Semantic Kernel官方样例库里面的的Summary Skill var prompt = """ [SUMMARIZATION RULES] DONT WASTE WORDS USE SHORT, CLEAR, COMPLETE SENTENCES. DO NOT USE BULLET POINTS OR DASHES. USE ACTIVE VOICE. MAXIMIZE DETAIL, MEANING FOCUS ON THE CONTENT [BANNED PHRASES] This article This document This page This material [END LIST] Summarize: Hello how are you? +++++ Hello Summarize this {{$input}} +++++ """; // 使用扩展方法在Kernel上注册一个SemanticFunction // prompt 是Semantic Function的核心,如何设计一个好的prompt是成功构建Semantic Function的关键所在,也是未来LLM AI 应用中的重要内容 // PromptTemplateConfig 用于配置prompt 模板的相关参数 // functionName 是自定义的功能名称[可选] // skillName 是自定义的技能名称[可选] var summaryFunction = kernel.CreateSemanticFunction(prompt,new PromptTemplateConfig());
可以注意到的是在prompt中,有一个变量参数 {{$input}},这是SK的默认输入参数,用于注入需要处理的用户输入,这样的格式用于预防Prompt Injection,这就是另外一个话题了。
Native Function是指原生函数,在函数上使用KernelFunction标注
[KernelFunction, Description("查询用户的充值和到账情况相关信息")]
public string QueryCharge()
{
//调用webapi获取充值信息
var baseUrl = _configuration.GetValue<string>("CallbackUrl", "https://www.mytest.com/api.aspx?");
var httpClient = HttpClientFactory.Create();
var url = $"{baseUrl}param=&state=1";
var result = httpClient.GetStringAsync(url).Result;
var jsonResult = JsonSerializer.Deserialize<ApiResult>(result);
if (jsonResult.StatusCode != 200) return jsonResult.Description;
return jsonResult.ResponseObject.First().Info;
//return "通过查询,用户最近有2笔充值,详情如下XXXXX";
//return "通过查询,用户最近未充值或者付费。";
}
memory提供了上下文的能力。通过Embedding服务将内容向量化,并从数据源中进行向量搜索,已期获得相关的结果。当拥有庞大的知识库/上下文/参考资料时,结合Embedding进行搜索,并提取相关内容给大模型,达到减小token消耗,精准获得相关结果的效果
示例:
var questions = new[] { "what is my name?", "where do I live?", "where is my family from?", "where have I travelled?", "what do I do for work?", }; foreach (var q in questions) { var response = await kernel.Memory.SearchAsync(MemoryCollectionName, q).FirstOrDefaultAsync(); Console.WriteLine(q + " " + response?.Metadata.Text); } // output /* what is my name? My name is Andrea where do I live? I currently live in Seattle and have been living there since 2005 where is my family from? My family is from New York where have I travelled? I visited France and Italy five times since 2015 what do I do for work? I currently work as a tourist operator */
参考资料:
微软SemanticKernel官方文档: https://learn.microsoft.com/zh-cn/semantic-kernel/overview/
博客园SK入门教程: https://www.cnblogs.com/xbotter/p/semantic_kernel_introduction_llm.html
SK开发日志: https://devblogs.microsoft.com/semantic-kernel/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。