引言

上一章我们熟悉了 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. k8s之存储卷local PV

    一.简介 local能够作为PV使用的本地存储卷. local卷插件用于将本地存储设备(如磁盘.分区或目录) 配置为卷. hostPath卷在Pod被重建后可能被调试至其它节点而无法再次使用此前的数据 ...

  2. 重新整理 mysql 基础篇—————表锁和全局锁[六]

    前言 锁从大的方面可以分为: 1.全局锁 2.表锁 3.行锁 正文 全局锁 全局锁就是对整个数据加上读锁. 在mysql 中,加入全局锁的命令就是: Flush tables with read lo ...

  3. C3P0反序列化链分析

    前言 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.使用它的开源项目有Hibernate.Spring等.之前有接触到过,但是没有深入了解 ...

  4. Mac 上fiddler与charles 抓包https 小程序请求 内容

    为什么选择charles 之前讲过<wireshark使用教程及过滤语法总结--血泪史的汇聚>, 很强大,但是很难用. fiddler 很好用,之前mac 上面没有,现在有了 fiddle ...

  5. 如何把jQuery对象转成DOM对象?OR DOM对象转化成jQuery对象

    如何把jQuery对象转成DOM对象? 参考:https://www.imooc.com/code/8110 利用数组下标的方式读取到jQuery中的DOM对象 <div>元素一</ ...

  6. anconda配置tensorflow环境

    一.anconda的安装 1.进入Anaconda官网并按照电脑配置选择合适的安装包 Anaconda官网:https://www.anaconda.com/ 点击进入 不同的三个版本,分别是wind ...

  7. 平行云CEO 李岩:CloudXR ,开启通往元宇宙的通道

    ​简介:一端是算力无穷的云,这也是 CloudXR 的精髓所在. ​ 图:2022阿里云视觉计算私享会现场 5月11日,在"2022阿里云视觉计算私享会"上,平行云CEO李岩为大家 ...

  8. 深度 | 从DevOps到BizDevOps, 研发效能提升的系统方法

    ​简介:研发效能提升不知从何下手.一头雾水?阿里资深技术专家一文为你揭秘研发效能提升的系统方法. ​ 注:本文是对云栖大会何勉分享内容的整理 这几年"研发效能"一直是热词,很多组织 ...

  9. 2019-9-27-微软的-P2P-下载方式

    title author date CreateTime categories 微软的 P2P 下载方式 lindexi 2019-09-27 09:44:44 +0800 2019-09-27 09 ...

  10. Ubuntu 20.04版本安装k8s控制节点与控制节点升级

    一.环境配置 服务器配置:2核4G IP:192.168.10.23 主机名:master4将改主机加入此 集群 # 1.修改主机名 hostnamectl set-hostname master4 ...