• Semantic Kernel 入门系列:💾Native Function


    image
    语义的归语义,语法的归语法。

    基础定义

    最基本的Native Function定义只需要在方法上添加 SKFunction 的特性即可。

    using Microsoft.SemanticKernel.SkillDefinition;
    using Microsoft.SemanticKernel.Orchestration;
    namespace MySkillsDirectory;
    public class MyCSharpSkill
    {
    [SKFunction("Return the first row of a qwerty keyboard")]
    public string Qwerty(string input)
    {
    return "qwertyuiop";
    }
    [SKFunction("Return a string that's duplicated")]
    public string DupDup(string text)
    {
    return text + text;
    }
    }

    默认情况下只需要传递一个string 参数就行,如果需要多个参数的话,和Semantic Function一样,也是使用Context,不过这里传进去是 SKContext。在方法上使用 SKFunctionContextParameter声明一下参数,可以提供一定的说明,同时的有需要的话,可以设置参数的默认值。

    using Microsoft.SemanticKernel.SkillDefinition;
    using Microsoft.SemanticKernel.Orchestration;
    namespace MySkillsDirectory;
    public class MyCSharpSkill
    {
    [SKFunction("Return a string that's duplicated")]
    public string DupDup(string text)
    {
    return text + text;
    }
    [SKFunction("Joins a first and last name together")]
    [SKFunctionContextParameter(Name = "firstname", Description = "Informal name you use")]
    [SKFunctionContextParameter(Name = "lastname", Description = "More formal name you use")]
    public string FullNamer(SKContext context)
    {
    return context["firstname"] + " " + context["lastname"];
    }
    }

    调用的时候,一样使用 ContextVariables.

    using Microsoft.SemanticKernel;
    using Microsoft.SemanticKernel.Orchestration;
    using MySkillsDirectory;
    // ... instantiate a kernel as myKernel
    var myContext = new ContextVariables();
    myContext.Set("firstname","Sam");
    myContext.Set("lastname","Appdev");
    var myCshSkill = myKernel.ImportSkill ( new MyCSharpSkill(), "MyCSharpSkill");
    var myOutput = await myKernel.RunAsync(myContext,myCshSkill["FullNamer"]);
    Console.WriteLine(myOutput);

    当然异步的方法也是支持的。这样的话,就可以处理一些像是网络请求,数据库访问、文件读写等操作了。

    using Microsoft.SemanticKernel.SkillDefinition;
    using Microsoft.SemanticKernel.Orchestration;
    public class MyCSharpSkill
    {
    [SKFunction("Return the first row of a qwerty keyboard")]
    public string Qwerty(string input)
    {
    return "qwertyuiop";
    }
    [SKFunction("Return the second row of a qwerty keyboard")]
    [SKFunctionName("Asdfg")]
    public async Task<string> AsdfgAsync(string input)
    {
    await ...do something asynchronous...
    return "asdfghjkl";
    }

    这里针对 AsdfgAsync 添加了一个 SKFunctionName 的特性,主要是为了使Function name 好看一些,避免 MyCSharpSkill.AsdfgAsync 这样。

    混合调用

    和 Semantic Function中能够调用 Native Function一样,在 Native Function也可以调用Semantic Function,其中主要使用的还是 SKContext.

    using Microsoft.SemanticKernel.SkillDefinition;
    using Microsoft.SemanticKernel.Orchestration;
    namespace MySkillsDirectory;
    public class MyCSharpSkill
    {
    [SKFunction("Tell me a joke in one line of text")]
    [SKFunctionName("TellAJokeInOneLine")]
    public async Task<string> TellAJokeInOneLineAsync(SKContext context)
    {
    // Fetch a semantic function previously loaded into the kernel
    ISKFunction joker1 = context.Func("funSkill", "joker");
    // OR Fetch a semantic function previously loaded into the kernel
    ISKFunction joker2 = context.Skills.GetSemanticFunction("funSkill", "joker");
    var joke = await joker1.InvokeAsync();
    return joke.Result.ReplaceLineEndings(" ");
    }
    }

    这里并没有限制是 Semantic Function 还是Native Function,所以甚至可以完全使用Native Function编排技能调用,除了参数的定义和提取有些费劲以外,其他的几乎没什么问题,毕竟返回值都是string,这也就贯彻了Text is the universal wire protocol,即便是代码也得将就一下。

    一些核心技能

    Semantic Kernel 中大部分的能力都是有技能提供的,例如Semantic Kernel的一个核心组件Planner,其实就是一个Semantic Skill,另外官方提供了一些Core SKill,基本是日常比较常用的。具体可以参考https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/SemanticKernel/CoreSkills

    image

    和自行定义的Native Function一样的,只需要使用ImportSkill就行了

    using Microsoft.SemanticKernel.CoreSkills;
    // ( You want to instantiate a kernel and configure it first )
    myKernel.ImportSkill(new TimeSkill(), "time");
    const string ThePromptTemplate = @"
    Today is: {{time.Date}}
    Current time is: {{time.Time}}
    Answer to the following questions using JSON syntax, including the data used.
    Is it morning, afternoon, evening, or night (morning/afternoon/evening/night)?
    Is it weekend time (weekend/not weekend)?";
    var myKindOfDay = myKernel.CreateSemanticFunction(ThePromptTemplate, maxTokens: 150);
    var myOutput = await myKindOfDay.InvokeAsync();
    Console.WriteLine(myOutput);

    至此,Semantic Kernel 的基础能力就学习得差不多了。


    参考资料:

    1. https://learn.microsoft.com/en-us/semantic-kernel/howto/nativefunctions
    2. https://learn.microsoft.com/en-us/semantic-kernel/howto/coreskills
    3. https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/SemanticKernel/CoreSkills
  • 相关阅读:
    daml和xaml
    Docker
    创建vue3工程
    git及dbc的学习
    (二十六)大数据实战——kafka集群之Kraft模式安装与部署
    8.3 NtGlobalFlag
    对rust语言的一些理解
    入门四认识HTML
    Dapr 证书过期了怎么办? 别慌,有救!
    [硬件基础]-快速了解PWM
  • 原文地址:https://www.cnblogs.com/xbotter/p/semantic_kernel_introduction_native_function.html