入门Semantic Kernel:OneApi集成与HelloWorld

semantic,kernel,oneapi,helloworld · 浏览次数 : 0

小编点评

**代码介绍** 这是一种用于构建和使用 Semantic Kernel 的代码示例。Semantic Kernel 是一个用于 AI 模型推理的库,它可以与各种 AI 服务,包括 OpenAI 和 Azure OpenAI,一起使用。 **代码结构** 代码包含以下主要部分: 1. **类定义**:该类包含了模型 URL、请求发送器和异步发送任务的定义。 2. **`SendAsync` 方法**:该方法负责发送 HTTP 请求并处理响应。 3. **`ConfigExtensions` 类**:该类扩展了 `OpenAIConfig` 类,并定义了模型 ID 和 API key。 4. **`OpenAICustomHandler` 类**:该类实例化了 `OpenAIConfig` 并设置了模型 URL。 5. **`Kernel.CreateBuilder` 方法**:该方法用于创建 Semantic 函数的构建器。 6. **`Prompt` 类**:该类用于创建用于向模型发送问题的语义描述。 7. **`PromptStreamingAsync` 方法**:该方法用于在指定的语言中生成语义描述的异步任务。 **示例代码** 示例代码展示了如何使用 `OpenAICustomHandler` 和 `Kernel` 创建和使用 Semantic 函数。该函数可以从用户输入中推断其意图并生成相应的语义描述。 **使用示例** 假设我们想构建一个以发送电子邮件给市场团队的 Semantic 函数,我们可以按照以下步骤操作: 1. 创建一个 `OpenAICustomHandler` 实例,设置模型 URL。 2. 创建一个 `Prompt` 对象,包含用户在邮件中想要表达的内容。 3. 创建一个 `Kernel.CreateBuilder` 对象,并使用 `OpenAIChatCompletion` 创建一个语义描述器。 4. 使用 `PromptStreamingAsync` 方法生成语义描述的异步任务。 5. 在任务完成时处理生成的描述。 **总结** 这是一种使用 Semantic Kernel 构建智能应用程序的示例代码。该代码展示了如何创建和使用 Semantic 函数,以及如何将语义描述生成到用户意图中。

正文

引言

从这一章节开始正式进入我们的 Semantic Kernel 的学习之旅了。

什么是Semantic Kernel

Semantic Kernel是一个轻量级的开源框架,通过 Semantic Kernel 可以快速使用不同编程语言(C#/Python/Java)结合 LLMs(OpenAI、Azure OpenAI、Hugging Face 等模型) 构建智能应用,简化将人工智能(AI)集成到现有解决方案中的过程。

Semantic Kernel 的特点

  1. 模块化插件架构Semantic Kernel 提供了一个模块化的插件架构,允许开发者通过结合自定义和预定义的智能插件来解决复杂的业务问题。这种架构使得传统代码能够与智能插件无缝协作,从而简化了传统应用程序向智能化转型的过程。

  2. 多模型集成能力Semantic Kernel 支持多种 AI 模型,包括但不限于 Azure OpenAI ServiceOpenAI,以及 Hugging Face 提供的离线模型。通过 Semantic Kernel 的链接器功能,开发者可以快速地将这些 AI“大脑”集成到自己的智能应用中,大幅提升应用的智能化水平。

  3. 多样化的链接器生态系统:除了连接 AI 模型,Semantic Kernel 的链接器还支持连接向量数据库、商业软件、业务中间件等多种服务。这种多样化的链接能力,使得 Semantic Kernel 能够适应更多的业务场景,推动业务流程的智能化转型。

  4. 全面的语言兼容性Semantic Kernel 支持主流的编程语言,包括C#PythonJava。这种全面的语言支持,使得不同背景的开发者都能够轻松地利用 Semantic Kernel 来挖掘 AI 的潜力,并将其应用到自己的项目中。

  5. 低门槛的开发体验Semantic Kernel 设计注重用户体验,提供了简单易用的接口和文档。即使是 AI 领域的新手,也能够快速上手,实现零成本入门,从而降低了开发智能应用的门槛。

核心概念

Semantic Kernel基本组成

image

Semantic Kernel 中,核心概念包括:

内核(Kernel)

如果说 Semantic KernelCopilot Agent 的核心 AI 编排层,那 Kernel 对象就是 AI 编排层的核心对象。

image

从上图我们可以看出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 可以实现智能的语义理解、任务规划和智能决策,从而为用户提供更加智能、灵活和个性化的交互体验。它可以应用于各种领域,如虚拟助手、智能客服、自然语言交互系统等,为用户和企业提供更加智能和高效的解决方案。

从下面这张图可以更好的理解各核心组件之间的关系

image

Sematic Kernel 对接 OneApi

通过我们上一篇文章的,我们了解到了 OneApi,是以OpenAI的格式,所以在SK中可以使用OpenAIConnector来操作、在Semantic Kernel类库中已经默认集成。

使用 UseSecrets 存储机密信息

  • 在我们的启动项右键机密信息管理

image

配置项 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 class OpenAICustomHandler : HttpClientHandler
{
    /// <summary>
    /// 用于OpenAI或Azure OpenAI请求时重定向的模型基础URL。
    /// </summary>
    private readonly string modelUrl;
    private static readonly string[] sourceArray = ["api.openai.com", "openai.azure.com"];

    /// <summary>
    /// 使用指定的模型URL初始化<see cref="OpenAICustomHandler"/>类的新实例。
    /// </summary>
    /// <param name="modelUrl">用于OpenAI或Azure OpenAI请求的基础URL。</param>
    public OpenAICustomHandler(string modelUrl)
    {
        // 确保modelUrl不是null或空
        if (string.IsNullOrWhiteSpace(modelUrl))
            throw new 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>
    protected override async 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请求
        return await base.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 KernelPrompt TemplateCreate Semantic functionKernel 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);
await foreach (var content in streamingKernelContentsAsync)
{
    Console.WriteLine(content);
}
Console.ReadKey();

上面的代码我们通过Kernel对象用prompt创建了一个Semantic function,内容是揣测用户输入的文本意图,借助大模型的推理能力很简单的就可以做到这个功能。

Run一下

image

  • 输入
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 构建智能应用并与在线大模型进行集成。

参考文献

本文示例源代码

本文源代码

😄欢迎关注笔者公众号一起学习交流,获取更多有用的知识~

image

与入门Semantic Kernel:OneApi集成与HelloWorld相似的内容:

入门Semantic Kernel:OneApi集成与HelloWorld

引言 从这一章节开始正式进入我们的 Semantic Kernel 的学习之旅了。 什么是Semantic Kernel? Semantic Kernel是一个轻量级的开源框架,通过 Semantic Kernel 可以快速使用不同编程语言(C#/Python/Java)结合 LLMs(OpenAI

(1)semantic-kernel入门课程

(1)semantic-kernel入门课程 获取OpenAI在线API 由于在国内的限制,我们并没有办法直接访问OpenAI,所以下面的教程我们会推荐使用https://api.token-ai.cn,然后您需要在这个网站中注册一个账号,并且创建一个令牌(最好是设置无限额度和无过期时间),创建好的

Semantic Kernel入门系列:通过依赖注入管理对象和插件

前言 本章讲一下在Semantic Kernel中使用DependencyInject(依赖注入),在之前的章节我们都是通过手动创建Kernel对象来完成框架的初始化工作,今天我们用依赖注入的方式来实现。 实战 定义Native Plugins 我们用官网的LightPlugins插件来演示依赖注入

Semantic Kernel入门系列:利用Handlebars创建Prompts functions

引言 本章我们将学习通过Handlebars Prompts Template来创建Prompts functions。 什么是Handlebars? Handlebars是一个流行的 JavaScript 模板引擎,它允许你通过在 HTML 中使用简单的占位符来创建动态的 HTML。 它使用模板和

Semantic Kernel入门系列:利用YAML定义prompts functions

引言 在上一章节我们熟悉了prompts functions(提示函数)的创建,我们了解了PromptTemplateConfig中各个属性的简单使用。Semantic Kernel允许我们利用多种方式去创建prompts包括native functions,prompts functions或者也

.NET周报 【4月第3期 2023-04-15】

国内文章 Semantic Kernel 入门系列:📅 Planner 规划器 https://www.cnblogs.com/xbotter/p/semantic_kernel_introduction_planner.html 本文介绍了Semantic Kernel的一个核心能力,即实现目标

如何让其他模型也能在SemanticKernel中调用本地函数

在SemanticKernel的入门例子中: // Import packages using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.SemanticKerne

[转帖]lua入门

入门 [TOC] @date: 2018-3-18 简介 Lua的设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 作为一门过程型动态语言,Lua有着如下的特性: 变量名没有类型,值才有类型,变量名在运行时可与任何类型的值绑定; 语言只提供唯一一种数据结构,称为表(table)

[转帖]40张图入门Linux——(前端够用,运维入门)

本文主要是Linux的入门内容,利用40张思维导图从基础、操作、实用指令、组管理和权限管理、crond任务调度、Linux磁盘分区和挂载、Linux网络环境配置、进程管理、服务管理、RPM和YUM、软件安装关键点、Shell编程共十二部分着手,从而系统的了解一下Linux(基于Centos),本文的

(1)入门MasaFramework教程

(1)入门MasaFramework教程 首先了解一下MasaFramework是什么 MasaFramework是一个基于.Net6.0的后端框架, 可以被用于开发Web应用程序、WPF项目、控制台项目 其实就是MasaFramework提供了很多功能的包,很强大,对于Dapr的支持非常好,如果有