引言

上一章我们熟悉了 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. 如何解决python安装mysqlclient失败问题

    在使用Django等框架来操作MySQL时,实际上底层还是通过Python来操作的,首先需要安装一个驱动程序,在Python3中,驱动程序有多种选择,比如有pymysql以及mysqlclient等. ...

  2. 跨域是什么?Vue项目中你是如何解决跨域的呢?

    一.跨域是什么 跨域本质是浏览器基于同源策略的一种安全手段 同源策略(Sameoriginpolicy),是一种约定,它是浏览器最核心也最基本的安全功能 所谓同源(即指在同一个域)具有以下三个相同点 ...

  3. 【Oracle】使用PL/SQL快速查询出1-9数字

    [Oracle]使用PL/SQL快速查询出1-9数字 简单来说,直接Recursive WITH Clauses 在Oracle 里面就直接使用WITH result(参数)即可 WITH resul ...

  4. 【Oracle】Oracle常用分析函数(排名)

    Oracle常用分析函数(排名) 一般来说,遇到需要对数据进行排序的时候,可以使用分析函数,一般常用的有三个,rank,dense_rank,row_number --Oracle常用分析函数(排名) ...

  5. 五分钟学会使用 go modules(含在家办公使用技巧)

    导读:go modules 是 golang 1.11 新加的特性.如今 1.13 都已经发布了第 7 个小版本了,几乎所有大项目均已开始使用,这自然也包括 Kubernetes 生态中的众多项目.笔 ...

  6. 云钉一体:EventBridge 联合钉钉连接器打通云钉生态

    ​简介:今天,EventBridge 联合钉钉连接器,打通了钉钉生态和阿里云生态,钉钉的生态伙伴可以通过通道的能力驱动阿里云上海量的计算力. 作者:尘央 背景 "以事件集成阿里云,从 Eve ...

  7. 2018-8-10-WPF-如何画出1像素的线

    title author date CreateTime categories WPF 如何画出1像素的线 lindexi 2018-08-10 19:16:53 +0800 2018-2-13 17 ...

  8. k8s应用---持久化存储和StorageClass(10)

    一.简介: 在 k8s 中为什么要做持久化存储? 在 k8s 中部署的应用都是以 pod 容器的形式运行的,假如我们部署 MySQL.Redis 等数据库,需要 对这些数据库产生的数据做备份.因为 P ...

  9. centos7虚拟机部署netcore3.1服务供局域网访问

    如果买了亚马逊.腾讯.阿里等服务器,基本上几分钟就可以跑aspnetcore,外网访问分分钟.但是便宜点的服务器访问速度就没那么理想.这时候就需要考虑零成本的虚拟机部署了,当然这个基本都是局域网做测试 ...

  10. Ruby on Rails Active Record数据库常用操作

    目录 创建 批量插入 判断是否存在 Ruby on Rails 日期查询方法 文档地址: https://freed.gitee.io/rails-guides/active_record_query ...