引言

上一章我们熟悉了 OpenAIfunction calling 的执行原理,这一章节我们讲解一下 function callingSemantic Kernel 的应用。

OpenAIPromptExecutionSettings跟 LLM 交互过程中,ToolCallBehavior的属性之前我们的章节有介绍过

  • ToolCallBehavior:属性用于获取或设置如何处理工具调用的行为。

          // Enable auto function calling
    OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new()
    {
    ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
    };

    1.EnableKernelFunctions:会向模型提供内核的插件函数信息,但不会自动处理函数调用请求。模型需要显式发起函数调用请求,并系统会传播这些请求给适当的处理程序来执行。

     OpenAIPromptExecutionSettings settings = new() { ToolCallBehavior = ToolCallBehavior.EnableKernelFunctions };
    var chatHistory = new ChatHistory();
    ChatMessageContent result = await chat.GetChatMessageContentAsync(chatHistory, settings, kernel);
    //手动调用
    IEnumerable<FunctionCallContent> functionCalls = FunctionCallContent.GetFunctionCalls(result);

    EnableKernelFunctions:需要通过 FunctionCallContent 手动调用

    2.AutoInvokeKernelFunctions:除了向模型提供内核的插件函数信息外,还会尝试自动处理任何函数调用请求。模型发起函数调用请求后,系统会自动执行相应的操作,并将结果返回给模型,而无需模型显式处理函数调用的过程。

模型推荐

建议使用 OpenAI 的最新模型(如 gpt-3.5-turbo-1106gpt-4-1106-preview)以获得最佳的工具调用体验。OpenAI 的最新模型通常具有更好的性能和更高的准确性,因此使用这些模型可以提高工具调用的效果。

我这里是公司提供的 Azure OpenAI 的服务,我自己通过 yarp 代理了一层做了相关服务的认证

{
"InternalAzureOpenAI": {
"Endpoint": "https://localhost:7079",
"ModelId": "gpt-35-turbo-1106",
"ApiKey": "***"
}
}

实战

接下来我们会问一下大模型当前北京的天气情况

定义 Prompts

  var template = "我想知道现在北京的天气状况?";

定义 kernel

var kernel = Kernel.CreateBuilder()
.AddAzureOpenAIChatCompletion(config.ModelId, endpoint: config.Endpoint, apiKey: config.ApiKey)
.Build();

注册 kernel function 到 plugins

定义方法

static string GetWeatherForCity(string cityName)
{
return $"{cityName} 25°,天气晴朗。";
}

为 Kernel 提供插件

 kernel.ImportPluginFromFunctions("WeatherPlugin", new[]
{
kernel.CreateFunctionFromMethod(GetWeatherForCity, "GetWeatherForCity", "获取指定城市的天气")
});

手动调用 function calling

根据上面的描述 手动处理function calling的关键实际上是ToolCallBehavior.EnableKernelFunctions参数。

  OpenAIPromptExecutionSettings settings = new OpenAIPromptExecutionSettings()
{
Temperature = 0,
ToolCallBehavior = ToolCallBehavior.EnableKernelFunctions
};

需要用到Semantic KernelIChatCompletionService的会话服务

    var chatHistory = new ChatHistory();
chatHistory.AddSystemMessage("You are a useful assistant.");
chatHistory.AddUserMessage(template);
Console.WriteLine($"User: {template}");
var chat = kernel.GetRequiredService<IChatCompletionService>();
while (true)
{
ChatMessageContent result = await chat.GetChatMessageContentAsync(chatHistory, settings, kernel);
if (result.Content is not null)
{
Console.Write(result.Content);
} IEnumerable<FunctionCallContent> functionCalls = FunctionCallContent.GetFunctionCalls(result);
if (!functionCalls.Any())
{
break;
} chatHistory.Add(result); // Adding LLM response containing function calls(requests) to chat history as it's required by LLMs. foreach (var functionCall in functionCalls)
{
try
{
FunctionResultContent resultContent = await functionCall.InvokeAsync(kernel); // Executing each function. chatHistory.Add(resultContent.ToChatMessage());
}
catch (Exception ex)
{
chatHistory.Add(new FunctionResultContent(functionCall, ex).ToChatMessage());
}
} Console.WriteLine();
}

输出

=====>手动function calling
User: 我想知道现在北京的天气状况? Assistant:现在北京的天气是晴朗,气温为25°C。

自动调用 function calling

和手动的区别就是上面描述的OpenAIPromptExecutionSettings配置的ToolCallBehavior属性值不同

  OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new OpenAIPromptExecutionSettings()
{
Temperature = 0,
ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions
};

自动function calling从本质上来讲是隐藏了跟大模型多次交互的逻辑,有Semantic Kernel框架自动帮我们调用

核心代码

    var chatHistory = new ChatHistory();
chatHistory.AddSystemMessage("You are a useful assistant.");
chatHistory.AddUserMessage(template);
Console.WriteLine($"User: {template}");
var chatService = kernel.GetRequiredService<IChatCompletionService>();
var result = await chatService.GetChatMessageContentAsync(chatHistory, openAIPromptExecutionSettings, kernel);
Console.Write("Assistant:" + result.ToString());

输出

=====>自动function calling
User: 我想知道现在北京的天气状况?
Assistant:北京现在的天气状况是晴朗,气温为25°C。

最后

在本章中,我们探讨了在 OpenAIfunction callingSemantic Kernel 中的应用。通过对 ToolCallBehavior 属性的设置,我们可以灵活地控制工具调用的行为,从手动调用到自动调用,为用户提供了更加便捷和高效的体验。

建议在实践中使用 OpenAI 的最新模型(如 gpt-3.5-turbo-1106gpt-4-1106-preview)以获得最佳的工具调用效果。同时,通过合理配置 OpenAIPromptExecutionSettings 中的参数,可以更好地适配不同的场景和需求。

希望本章内容能够帮助您更深入地理解 function callingSemantic Kernel 中的运用,为您的项目和应用带来更多可能性和创新。

示例代码

本文源代码

深入探讨Function Calling:在Semantic Kernel中的应用实践的更多相关文章

  1. Semantic Kernel 入门系列:🥑Memory内存

    了解的运作原理之后,就可以开始使用Semantic Kernel来制作应用了. Semantic Kernel将embedding的功能封装到了Memory中,用来存储上下文信息,就好像电脑的内存一样 ...

  2. Semantic Kernel 入门系列:🍋Connector连接器

    当我们使用Native Function的时候,除了处理一些基本的逻辑操作之外,更多的还是需要进行外部数据源和服务的对接,要么是获取相关的数据,要么是保存输出结果.这一过程在Semantic Kern ...

  3. Semantic Kernel 入门系列:📅 Planner 计划管理

    Semantic Kernel 的一个核心能力就是实现"目标导向"的AI应用. 目标导向 "目标导向"听起来是一个比较高大的词,但是却是实际生活中我们处理问题的 ...

  4. OpenStack环境中的NFV实践

    原文链接:http://www.99cloud.net/html/2016/jiuzhouyuanchuang_1103/250.html 在开始实践之前我们首先需要了解一些NFV概念和术语. NFV ...

  5. Semantic Kernel 入门系列:💬Semantic Function

    如果把提示词也算作一种代码的话,那么语义技能所带来的将会是全新编程方式,自然语言编程. 通常情况下一段prompt就可以构成一个Semantic Function,如此这般简单,如果我们提前可以组织好 ...

  6. Semantic Kernel 入门系列:💾Native Function

    语义的归语义,语法的归语法. 基础定义 最基本的Native Function定义只需要在方法上添加 SKFunction 的特性即可. using Microsoft.SemanticKernel. ...

  7. Linux kernel中常见的宏整理

    0x00 宏的基本知识 // object-like #define 宏名 替换列表 换行符 //function-like #define 宏名 ([标识符列表]) 替换列表 换行符 替换列表和标识 ...

  8. Semantic Kernel 入门系列:🔥Kernel 内核和🧂Skills 技能

    理解了LLM的作用之后,如何才能构造出与LLM相结合的应用程序呢? 首先我们需要把LLM AI的能力和原生代码的能力区分开来,在Semantic Kernel(以下简称SK),LLM的能力称为 sem ...

  9. Semantic Kernel 入门系列:🥑突破提示词的限制

    无尽的上下文 LLM的语言理解和掌握能力在知识内容的解读和总结方面提供了强大的能力. 但是由于训练数据本身来自于公共领域,也就注定了无法在一些小众或者私有的领域能够足够的好的应答. 因此如何给LLM ...

  10. Semantic UI中的验证控件的事件的使用

    1.Semantic UI中的验证控件,功能挺不错的,中文官网的文档写的都比较详细了,我再这里就不再进行重复了,主要是想说一下它的事件的使用方法,这个可能有部分朋友刚开始接触的时候不太了解 注意看这几 ...

随机推荐

  1. 树模型-C4.5

    C4.5: ID3的改进版本 首先,C4.5和ID3一样都是多叉树,重点是连续特征处理+特征选择的方式不同. ID3算法存在的不足, 在C4.5里面有了改进 有那些改进 不能处理连续特征的问题 C4. ...

  2. Python 爬虫进阶五之多线程的用法

    Python 爬虫进阶五之多线程的用法 作者 崔庆才   发表于 2016-11-03   分类于 Python   阅读次数: 60553   本文字数: 7.5k   阅读时长 ≈ 7 分钟 前言 ...

  3. sql 语句系列(众数中位数与百分比)[八百章之第十五章]

    众数 众数就是出现最多的那个数. select sal,count(*) as cnt from emp where DEPTNO=20 group by sal 通过分组把他们的行数计算出来.那么最 ...

  4. redis 简单整理——客户端管理[十六]

    前言 简单介绍一下客户端管理. 正文 Redis提供了客户端相关API对其状态进行监控和管理,这个一般有很多工具了,看看就好,没有必要去细看.

  5. Error:A problem occurred configuring project ':app'.

    前言 因为部门需要用到另外一个部门的库,而另外一个部门是c++部门,这种声音视频算法java做不了的. 如果是因为有引入c++库产生的这个问题,那么基本上你需要肯定你安装了ndk,如果没有安装那么会报 ...

  6. Web前端 -- ES6

    ES标准中不包含 DOM 和 BOM的定义,只涵盖基本数据类型.关键字.语句.运算符.内建对象.内建函数等通用语法. 本部分只学习前端开发中ES6的最少必要知识,方便后面项目开发中对代码的理解. 1. ...

  7. .NET开源强大、易于使用的缓存框架 - FusionCache

    前言 缓存在程序中扮演着提升性能.降低资源消耗.改善用户体验等重要角色,是构建高效.可伸缩.稳定的系统不可或缺的重要组成部分.今天大姚给大家分享一款.NET开源(基于MIT license).强大.易 ...

  8. 力扣633(java&python)-平方数之和(中等)

    题目: 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例 1: 输入:c = 5输出:true解释:1 * 1 + 2 * 2 = 5示例 2: 输 ...

  9. 力扣686(java)-重复叠加字符串匹配(中等)

    题目: 给定两个字符串 a 和 b,寻找重复叠加字符串 a 的最小次数,使得字符串 b 成为叠加后的字符串 a 的子串,如果不存在则返回 -1. 注意:字符串 "abc" 重复叠加 ...

  10. DataX在数据迁移中的应用

    简介: DataX在数据迁移中的应用 1. DataX定义 首先简单介绍下datax是什么.DataX是阿里巴巴集团内被广泛使用的离线数据同步工具/平台,实现包括 MySQL.Oracle.SqlSe ...