探索Native Plugins:开启大模型的技能之门

native,plugins · 浏览次数 : 0

小编点评

前言 上一章节我们了解了语义内核中Plugins插件的概念,并学习了如何创建 Semantic Kernel 模板插件。本章节我们将学习 Native Plugins 原生函数插件。 在 Semantic Kernel 中定义 Native Plugins 函数插件,与 gpt-3.5-turbo 在 6 月 13 日发布的 Function Calling 特别相似。这是通过增加外部函数,通过调用来增强 OpenAI 模型的能力。 在 Semantic Kernel 中定义函数插件,需要用到两个特性:KernelFunction 和 DescriptionKernelFunction。把函数标记为一个 SK 的 Native function;Description 给函数和参数以及返回值加描述,方便 LLMs 能够更好的理解。 具体使用: ```java public class WeatherPlugin { public static string GetWeather => "WeatherSearch"; [KernelFunction, Description("根据城市查询天气")] public string WeatherSearch([Description("城市名")] string city) { return "$city, 25℃,天气晴朗。"; } } Kernel.addPlugin(WeatherPlugin.ImportPluginFromType()); ``` 定义根据城市名获取美食的插件: ```java public class FinefoodPlugin { [KernelFunction, Description("根据城市获取美食推荐")] public string GetFinefoodList([Description("城市名")] string city) { return "烤鸭, 卤煮,老北京炸酱面,炒肝等"; } } kernel.ImportPluginFromObject(new FinefoodPlugin(), "GetFinefoodList"); var getWeatherFunc = kernel.Plugins.GetFunction(nameof(FinefoodPlugin), "GetFinefoodList"); var weatherContent = await getWeatherFunc.InvokeAsync(kernel, new() { [""city"] = "北京" }); Console.WriteLine(weatherContent); ``` 依赖注入举例: ```java IServiceCollection services = new ServiceCollection(); services.AddSingleton(); var rootProvider = services.BuildServiceProvider(); FinefoodPlugin finefoodPlugin = rootProvider.GetRequiredService(); kernel.ImportPluginFromObject(finefoodPlugin); ``` 根据 Kernelfunction 创建对象的实例: ```java public static KernelFunction CreateFunctionFromMethod(this Kernel kernel, Delegate method, string? functionName = null, string? description = null, IEnumerable kneernelParameterMetadata? parameters = null, KernelReturnParameterMetadata? returnParameter = null) { Verify.NotNull(kernel); Verify.NotNull(method); return KernelFunctionFactory.CreateFromMethod(method.Method, method.Target, functionName, description, parameters, returnParameter, kernel.LoggerFactory); } ``` 创建一个根据城市名获取游玩地点的插件: ```java var Kernelfunction = kernel.CreateFunctionFromMethod((string city) => { return "$city 好玩的地方有八达岭长城,故宫,恭王府等"; }, functionName: "GetTourismClassic", description: "获取城市的经典", [ new KernelParameterMetadata(name: "city") { Description = "城市名" } ]); kernel.ImportPluginFromFunctions("TourismClassicPlugin", [kernelfunction]); var getTourismClassic = kernel.Plugins.GetFunction("TourismClassicPlugin", "GetTourismClassic"); var weatherContent = await getTourismClassic.InvokeAsync(kernel, new() { [""city"] = "北京" }); Console.WriteLine(weatherContent); ``` 通过以上内容,我们可以看到在语义内核中创建 Native Plugins 原生函数插件的方法多种多样,可以根据需求采用不同的方式。希望这些内容能够帮助您更好地掌握语义内核插件的使用方法。

正文

前言

上一章节我们了解了一下Semantic KernnelPlugins插件的概念以及学习了的 Semantic Kernel 模板插件的创建,本章节我们来学习 Native Plugins 原生函数插件使用。

通过函数定义插件

在之前的章节中我们介绍过在在 Semantic Kernel 中应用 Function Calling,在文中讲解了Functioncalling的概念,以及在SK中的应用。
Semantic Kernel中定义Native Plugins 函数插件,和 gpt-3.5-turbo 在 6 月 13 日 发布的 Function Calling特别的像,这是通过增加外部函数,通过调用来增强 OpenAI 模型的能力。

在 Semantic Kernel 中定义函数插件

Semantic Kernerl 中提供了很多定义Native Plugins的扩展方法来创建插件下面介绍最常用的几种:

根据类型创建插件

  • SK源码
    public static KernelPlugin ImportPluginFromType<T>(this Kernel kernel, string? pluginName = null)
    {
        KernelPlugin plugin = CreatePluginFromType<T>(kernel, pluginName);
        kernel.Plugins.Add(plugin);
        return plugin;
    }
  • 定义Native Plugins

Semantic Kernel 中定义函数插件,需要用到两个特性KernelFunctionDescription
KernelFunction特性把函数标记为一个SKNative functionDescription给函数和参数以及返回值加描述,方便LLMs能够更好的理解。

具体使用如下

public class WeatherPlugin
{
    public static string GetWeather => "WeatherSearch";

    [KernelFunction, Description("根据城市查询天气")]
    public string WeatherSearch([Description("城市名")] string city)
    {
        return $"{city}, 25℃,天气晴朗。";
    }
}
  • Kernel添加插件
kernel.ImportPluginFromType<WeatherPlugin>();

这就是刚才说的根据类型来创建SK插件

  • 调用
var getWeatherFunc = kernel.Plugins.GetFunction(nameof(WeatherPlugin), WeatherPlugin.GetWeather);
var weatherContent = await getWeatherFunc.InvokeAsync(kernel, new() { ["city"] = "北京" });
Console.WriteLine(weatherContent.ToString());
  • 输出
北京, 25℃,天气晴朗。

这是手动调用的方式当然也可以IChatCompletionService会话模式自动调用。

根据对象创建

主要用到了ImportPluginFromObject这个扩展方法

    public static KernelPlugin ImportPluginFromObject(this Kernel kernel, object target, string? pluginName = null)
    {
        KernelPlugin plugin = CreatePluginFromObject(kernel, target, pluginName);
        kernel.Plugins.Add(plugin);
        return plugin;
    }
  • 定义根据城市名获取美食的插件
public class FinefoodPlugin
{
    [KernelFunction, Description("根据城市获取美食推荐")]
    public string GetFinefoodList([Description("城市名")] string city)
    {
        return "烤鸭,卤煮,老北京炸酱面,炒肝等";
    }
}

和上一个使用 Type 注册插件是一样的操作

  • 注册并调用
    FinefoodPlugin finefoodPlugin = new();
    kernel.ImportPluginFromObject(finefoodPlugin);
    var getWeatherFunc = kernel.Plugins.GetFunction(nameof(FinefoodPlugin), "GetFinefoodList");
    var weatherContent = await getWeatherFunc.InvokeAsync(kernel, new() { ["city"] = "北京" });
    Console.WriteLine(weatherContent.ToString());
  • 输出:
烤鸭,卤煮,老北京炸酱面,炒肝等
  • 扩展
    既然 Kernel 对象提供了根据对象实例创建插件的方案,那么就可以我们最喜欢的依赖注入获取的服务做插件的实例,这一点非常的重要,在以后项目实战中很实用。

依赖注入举例

    IServiceCollection services = new ServiceCollection();
    services.AddSingleton<FinefoodPlugin>();
    var rootProvider = services.BuildServiceProvider();
    FinefoodPlugin finefoodPlugin = rootProvider.GetRequiredService<FinefoodPlugin>();
    kernel.ImportPluginFromObject(finefoodPlugin);

根据 Kernelfunction 创建对象的实例

SK 提供了几个根据 Kernelfunction 来创建Plugins的方案,这就用到Kernel对象创建 kernel functions的扩展方法。

关于Kernel Function的创建有两种常用的形式第一种是根据Prompts来创建Semantic function也可以叫Prompts function,第二种是根据 C#的Delegate来创建Kernel Function

第一种方案之前的文章中有讲过,有兴趣可以浏览一下深入学习 Semantic Kernel:创建和配置 prompts functions,这里不过多介绍。

第二种在这里我们重点讲一下,根据委托来创建Kernel Function

  • 源码一览
    public static KernelFunction CreateFunctionFromMethod(
        this Kernel kernel,
        Delegate method,
        string? functionName = null,
        string? description = null,
        IEnumerable<KernelParameterMetadata>? parameters = null,
        KernelReturnParameterMetadata? returnParameter = null)
    {
        Verify.NotNull(kernel);
        Verify.NotNull(method);

        return KernelFunctionFactory.CreateFromMethod(method.Method, method.Target, functionName, description, parameters, returnParameter, kernel.LoggerFactory);
    }

在之前的文章介绍过,所有创建Kernelfunction基本上都是利用KernelFunctionFactoryfunction工厂创建的,其实插件的创建也是一样通过KernelPluginFactory插件plugin工厂创建的。

创建一个根据城市名获取游玩地点的插件

  • 创建 Kernel Function
    var kernelfunction = kernel.CreateFunctionFromMethod((string city) => { return $"{city} 好玩的地方有八达岭长城,故宫,恭王府等"; },
        functionName: "GetTourismClassic", description: "获取城市的经典",
         [
            new KernelParameterMetadata(name:"city") {
             Description="城市名"
    }]);
  • 注册插件并调用
    kernel.ImportPluginFromFunctions("TourismClassicPlugin", [kernelfunction]);
    var getTourismClassic = kernel.Plugins.GetFunction("TourismClassicPlugin", "GetTourismClassic");
    var weatherContent = await getTourismClassic.InvokeAsync(kernel, new() { ["city"] = "北京" });
    Console.WriteLine(weatherContent.ToString());
  • 输出
北京 好玩的地方有八达岭长城,故宫,恭王府等

扩展

上面介绍的都是在Sk中创建Native Plugins常用的方法,还有一些用法,比如

  • ImportPluginFromApiManifestAsync OpenAPI 功能相关
  • ImportPluginFromOpenAIAsync 通过 OpenAI 的 ChatGPT 格式为 OpenAI 插件创建一个插件
  • CreatePluginFromOpenApiAsync 从 OpenAPI v3 端点创建插件
  • ImportPluginFromGrpcFile 从 gRPC 文档导入
  • 其他

最后

本章我们学习了在 Semantic Kernel 中使用 Native Plugins 原生函数插件的方法,包括通过函数定义插件和根据对象创建插件的步骤。我们探讨了不同的创建插件的方式,以及如何注册插件并进行调用。通过这些方法,我们可以扩展 Semantic Kernel 的功能,增强模型的能力。

参考文献

示例代码

本文源代码

与探索Native Plugins:开启大模型的技能之门相似的内容:

探索Native Plugins:开启大模型的技能之门

前言 上一章节我们了解了一下Semantic Kernnel中Plugins插件的概念以及学习了的 Semantic Kernel 模板插件的创建,本章节我们来学习 Native Plugins 原生函数插件使用。 通过函数定义插件 在之前的章节中我们介绍过在在 Semantic Kernel 中应

探索Semantic Kernel内置插件:深入了解ConversationSummaryPlugin的应用

前言 经过前几章的学习我们已经熟悉了Semantic Kernel 插件的概念,以及基于Prompts构造的Semantic Plugins和基于本地方法构建的Native Plugins。本章我们来讲解一下在Semantic Kernel 中内置的一些插件,让我们避免重复造轮子。 内置插件 Sem

[转帖]探索惊群 ①

https://wenfh2020.com/2021/09/25/thundering-herd/ 惊群比较抽象,类似于抢红包 😁。它多出现在高性能的多进程/多线程服务中,例如:nginx。 探索惊群 系列文章将深入 Linux (5.0.1) 内核,透过 多进程模型 去剖析惊群现象、惊群原理、惊

探索Semantic Kernel内置插件:深入了解HttpPlugin的应用

前言 上一章我们熟悉了Semantic Kernel中的内置插件和对ConversationSummaryPlugin插件进行了实战,本章我们讲解一下另一个常用的内置插件HttpPlugin的应用。 上一章对ConversationSummaryPlugin总结进行了调整之后,顺便给Semantic

基于 Cloudflare Workers 和 cloudflare-docker-proxy 搭建镜像加速服务

本文主要介绍了如何基于 Cloudflare Workers 和 cloudflare-docker-proxy 搭建 dockerhub、gcr、quay 等镜像加速服务。 最近,受限于各种情况,部分主流镜像站都关了,为了能够正常使用,建议自己搭建一个加速器。 写文之前,也已经部署好了一个,可以直

探索Web Components

这篇文章介绍了Web Components技术,它允许开发者创建可复用、封装良好的自定义HTML元素,并直接在浏览器中运行,无需依赖外部库。通过组合HTML模板、Shadow DOM、自定义元素和HTML imports,Web Components增强了原生DOM的功能,提高了组件化开发的封装性和...

从零开始写 Docker(十八)---容器网络实现(下):为容器插上”网线“

本文为从零开始写 Docker 系列第十八篇,利用 linux 下的 Veth、Bridge、iptables 等等相关技术,构建容器网络模型,为容器插上”网线“。 完整代码见:https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实

从零开始写 Docker(十七)---容器网络实现(中):为容器插上”网线“

本文为从零开始写 Docker 系列第十七篇,利用 linux 下的 Veth、Bridge、iptables 等等相关技术,构建容器网络模型,为容器插上”网线“。 完整代码见:https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实

探索Semantic Plugins:开启大模型的技能之门

前言 在之前的章节中我们或多或少的已经接触到了 Semantic Kernel 的 Plugins,本章我们讲详细介绍如何使用插件。 Semantic Kernel 的一大特点是拥有强大的插件,通过结合自定义/预定义的插件解决智能业务的问题。让传统的代码和智能插件一起工作灵活地接入到应用场景简化传统

从零开始写 Docker(十六)---容器网络实现(上):为容器插上”网线”

本文为从零开始写 Docker 系列第十六篇,利用 linux 下的 Veth、Bridge、iptables 等等相关技术,构建容器网络模型,为容器插上”网线“。