引言
从这一章节开始正式进入我们的
Semantic Kernel
的学习之旅了。
什么是
Semantic Kernel
?
Semantic Kernel
是一个轻量级的开源框架,通过
Semantic Kernel
可以快速使用不同编程语言(
C#/Python/Java
)结合
LLMs(OpenAI、Azure OpenAI、Hugging Face 等模型)
构建智能应用,简化将人工智能(
AI
)集成到现有解决方案中的过程。
Semantic Kernel
的特点
模块化插件架构 :
Semantic Kernel
提供了一个模块化的插件架构,允许开发者通过结合自定义和预定义的智能插件来解决复杂的业务问题。这种架构使得传统代码能够与智能插件无缝协作,从而简化了传统应用程序向智能化转型的过程。多模型集成能力 :
Semantic Kernel
支持多种AI
模型,包括但不限于Azure OpenAI Service
、OpenAI
,以及Hugging Face
提供的离线模型。通过Semantic Kernel
的链接器功能,开发者可以快速地将这些AI「大脑」
集成到自己的智能应用中,大幅提升应用的智能化水平。多样化的链接器生态系统 :除了连接
AI
模型,Semantic Kernel
的链接器还支持连接向量数据库、商业软件、业务中间件等多种服务。这种多样化的链接能力,使得Semantic Kernel
能够适应更多的业务场景,推动业务流程的智能化转型。全面的语言兼容性 :
Semantic Kernel
支持主流的编程语言,包括C#
、Python
和Java
。这种全面的语言支持,使得不同背景的开发者都能够轻松地利用Semantic Kernel
来挖掘AI
的潜力,并将其应用到自己的项目中。低门槛的开发体验 :
Semantic Kernel
设计注重用户体验,提供了简单易用的接口和文档。即使是AI
领域的新手,也能够快速上手,实现零成本入门,从而降低了开发智能应用的门槛。
核心概念
Semantic Kernel
基本组成
在
Semantic Kernel
中,核心概念包括:
内核(Kernel) :
如果说
Semantic Kernel
是
Copilot Agent
的核心
AI
编排层,那
Kernel
对象就是
AI
编排层的核心对象。
从上图我们可以看出
Kernel
的核心包括:
配置
: 包括
AI
模型、插件、链接器等的配置信息。
上下文管理 :它维护应用程序的上下文信息,确保在执行任务时,可以访问到正确的数据和状态。
服务协调
:
Kernel
对象协调不同的
AI
服务和插件,确保它们能够协同工作,完成复杂的任务。
执行引擎 :它作为执行引擎,根据规划器生成的计划,调度和执行相应的操作。
插件(Plugins)
插件是
AI
解决方案的构建块,它们是一组可以暴露给
AI
应用程序和
AI
服务的函数,允许它们访问完成特定任务所需的数据。
Semantic Kernel
中的函数
Semantic Function
是用自然语言编写的提示(
Prompt
)模板,发送给
AI
服务;而
Native Function
是用
C#
或
Python
编写的传统函数,可以通过规划器和函数调用被
AI
服务调用。
记忆(
Memories
)
Memories
是用于存储数据的专用插件,它们在执行过程中为你的内核提供必要的上下文,以便你的
AI
服务能够正常运行。
规划器(
Planners
)
规划器
可以接收用户的目标,并帮助我们动态生成一个包含实现该特定目标的执行步骤的计划。规划器使用
AI
模型根据核心中指定的函数和服务生成计划。
通过整合这些概念和组件,
Semantic Kernel
可以实现智能的语义理解、任务规划和智能决策,从而为用户提供更加智能、灵活和个性化的交互体验。它可以应用于各种领域,如虚拟助手、智能客服、自然语言交互系统等,为用户和企业提供更加智能和高效的解决方案。
从下面这张图可以更好的理解各核心组件之间的关系
Sematic Kernel 对接 OneApi
通过我们上一篇文章的,我们了解到了
OneApi
,是以
OpenAI
的格式,所以在
SK
中可以使用
OpenAI
的
Connector
来操作、在
Semantic Kernel
类库中已经默认集成。
使用 UseSecrets 存储机密信息
在我们的启动项右键机密信息管理
配置项 Json 文件
"OneApiSpark": {
"Endpoint": "http://localhost:3000",
"ModelId": "SparkDesk-v3.5",
"ApiKey": "sk-LAYzQaWssCYYEVHP1d6a3fFa111745249e94F0364a0cF37c"
}
从 OpenAI 到本地服务的请求转换
自定义 HttpClientHandler
用
OpenAI
或者
Azure OpenAI
的扩展,请求会发送到
"api.openai.com"
或者
"openai.azure.com"
,这时候就需要我们通过自定的
HttpClientHandler
重定向的模型基础
URL
转发到我们的
http://localhost:3000
OneApi
的服务地址。
核心代码
public classOpenAICustomHandler : HttpClientHandler
{
///<summary>
/// 用于OpenAI或Azure OpenAI请求时重定向的模型基础URL。
///</summary>
privatereadonlystring modelUrl;
privatestaticreadonlystring[] sourceArray = ["api.openai.com", "openai.azure.com"];
///<summary>
/// 使用指定的模型URL初始化<see cref="OpenAICustomHandler"/>类的新实例。
///</summary>
///<param name="modelUrl">用于OpenAI或Azure OpenAI请求的基础URL。</param>
publicOpenAICustomHandler(string modelUrl)
{
// 确保modelUrl不是null或空
if (string.IsNullOrWhiteSpace(modelUrl))
thrownew ArgumentException("模型URL不能为空或空白。", nameof(modelUrl));
this.modelUrl = modelUrl;
}
///<summary>
/// 异步发送HTTP请求,对于OpenAI或Azure OpenAI服务的请求,将URL重定向到指定的模型URL。
///</summary>
///<param name="request">要发送的HTTP请求消息。</param>
///<param name="cancellationToken">可以用来取消操作的取消令牌。</param>
///<returns>表示异步操作的任务对象。</returns>
protectedoverrideasync Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// 检查请求是否针对OpenAI或Azure OpenAI服务
if (request.RequestUri != null &&
(sourceArray.Contains(request.RequestUri.Host)))
{
// 修改请求URI,以包含模型URL
request.RequestUri = new Uri(modelUrl + request.RequestUri.PathAndQuery);
}
// 调用基类方法实际发送HTTP请求
returnawaitbase.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
}
Semantic Kernel HelloWorld
我们先通过一个简单的示例学习一下 Kernel 对象的创建使用
VS 创建控制台项目
SK_CreateKernel
Nuget
安装
Semantic Kernel
的依赖
PM> NuGet\Install-Package Microsoft.SemanticKernel -Version 1.10.0
下面我们示例将借助
Prompt
提示词用的
Semantic function
来推理一下用户的意图
Steps
简单的流程可以总结为:
Build Kernel ➟ Prompt Template ➟ Create Semantic function ➟ Kernel Invoke Semantic function
var config = ConfigExtensions.FromConfig<OpenAIConfig>("OneApiSpark");
//自定义HttpClientHandler
var openAICustomHandler = new OpenAICustomHandler(config.Endpoint);
using HttpClient client = new(openAICustomHandler);
//Create Kernel
Kernel kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: config.ModelId,
apiKey: config.ApiKey,
httpClient: client)
.Build();
// 接收用户入参
string request = Console.ReadLine()!;
// create prompt to the chat service
string prompt = "这个请求的意图是什么? {{$request}}";
// Create a kernel arguments object and add the request
var kernelArguments = new KernelArguments
{
{ "request", request }
};
var streamingKernelContentsAsync = kernel.InvokePromptStreamingAsync(prompt, kernelArguments);
awaitforeach (var content in streamingKernelContentsAsync)
{
Console.WriteLine(content);
}
Console.ReadKey();
上面的代码我们通过
Kernel
对象用
prompt
创建了一个
Semantic function
,内容是揣测用户输入的文本意图,借助大模型的推理能力很简单的就可以做到这个功能。
Run
一下
输入
I want to send an email to the marketing team celebrating their recent milestone
输出
这个
请求的意图
是发送一封
电子邮件给市场团队
,庆祝他们最近达成
的一个重要成就。
在编程或自动化的上下文中,实现这个意图可能涉及以下几个步骤:
1. 确定市场团队的联系信息,包括电子邮件地址。
2. 编写邮件内容,确保包含对最近里程碑的庆祝和肯定。
3.
使用适当的邮件发送协议(如SMTP)或邮件服务API(如SendGrid, Mailgun等)来发送邮件。
4. 确保邮件格式正确,包括主题行、正文、签名等。
5. 测试邮件发送功能以确保邮件能够成功送达。
如果你需要具体的代码示例或进一步的帮助来实现这个功能,请提供更多的上下文或技术要求。
最后
本章介绍了
Semantic Kernel
的特点、核心概念以及与
OneApi
的对接方式,算是我们
SK
学习的
HelloWorld
,展示了如何利用
Semantic Kernel
构建智能应用并与在线大模型进行集成。
参考文献
Semantic Kernel Cookbook [1]
Prompting AI models with Semantic Kernel [2]
What is Semantic Kernel [3]
本文示例源代码
本文源代码 [4]
参考资料
[1]
Semantic Kernel Cookbook:
https://github.com/microsoft/SemanticKernelCookBook/blob/main/README.zh-cn.md
Prompting AI models with Semantic Kernel:
https://learn.microsoft.com/en-us/semantic-kernel/prompts/your-first-prompt?tabs=Csharp
What is Semantic Kernel:
https://systenics.ai/blog/2023-12-11-what-is-semantic-kernel/
本文源代码:
https://github.com/Dong-Ruipeng/SK-WorkBook