Function Calling
是一个允许大型语言模型(如 GPT
)在生成文本的过程中调用外部函数或服务的功能。
Function Calling
允许我们以 JSON
格式向 LLM
模型描述函数,并使用模型的固有推理能力来决定在生成响应之前是否调用该函数。模型本身不执行函数,而是生成包含函数名称和执行函数所需的参数的 JSON
。
现在我们定义提示词像大语言模型问一下当前北京的天气?
因为
LLM
大语言模型缺乏实时数据,所以无法回答实时数据这种场景。
我们用SK
来测试一下
Console.WriteLine("===>没有设置function calling=<===");
{
var kernel = Kernel.CreateBuilder().AddAzureOpenAIChatCompletion(config.ModelId,
endpoint: config.Endpoint,
apiKey: config.ApiKey).Build();
var template = "当前北京的天气?";
Console.WriteLine($"User: {template}");
var function = kernel.CreateFunctionFromPrompt(template);
var functionResult = await function.InvokeAsync(kernel);
Console.WriteLine($"Assistant:{functionResult}");
}
输出:
User: 当前北京的天气?
Assistant:对不起,作为一个AI,我无法为你提供实时信息。你可以查看可信的天气应用或网站来获取当前北京的天气。
这时候就需要用到
LLM
的Function Calling
功能来帮助回答用户的问题
OpenAI
的 function calling
的核心是我们将Prompts
提示词和可用函数
列表一起发送给LLM
。
OpenAI Chat Completions 接口
{
"tool_choice": "auto",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "我想知道现在北京的天气状况"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "Get_Weather_For_City",
"description": "获取指定城市的天气",
"parameters": {
"type": "object",
"properties": {
"cityName": {
"type": "string",
"description": "城市名"
}
}
}
}
}
]
}
这个参数决定了模型是否应该自动选择是否调用函数。值为 "auto"
表示模型将根据情况自动决定是否调用函数。 默认情况下,如果请求中不存在任何函数,则将其设置为“none”
,则设置为“auto”
。
在 tools
部分定义了一个函数,这个函数可以被 OpenAI 的模型调用。以下是 tools
部分参数的简单解释:
type: 指定了这个工具的类型,这里是 "function"
,表示这是一个函数调用。
function: 包含函数的详细信息,是一个对象。
name: 函数的名称,这里是 "Get_Weather_For_City"
,这是调用时使用的函数名。
description: 函数的描述,这里是 "获取指定城市的天气"
,用于说明这个函数的作用。
parameters: 定义了函数调用时需要的参数,是一个对象。
type: 参数对象的类型,这里是 "object"
,表示参数是一个对象类型。
properties: 包含具体的参数定义,是一个对象,每个属性对应一个参数。
"string"
,表示参数应该是一个字符串。"城市名"
,用于解释这个参数的意义。这个 tools
部分定义了一个名为 Get_Weather_For_City
的函数,它需要一个名为 cityName
的字符串参数,用于指定想要查询天气的城市。当模型需要调用这个函数时,它将使用这个参数来获取相应的天气信息。
{
"id": "chatcmpl-9TOuIqnuMirU3BUDluCrHMTlsjz97",
"object": "chat.completion",
"created": 1716794282,
"model": "gpt-4",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_DQU6OKHWyv3HVLyWVjSRqvwZ",
"type": "function",
"function": {
"name": "Get_Weather_For_City",
"arguments": "{\n \"cityName\": \"北京\"\n}"
}
}
]
},
"logprobs": null,
"finish_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 83,
"completion_tokens": 20,
"total_tokens": 103
},
"system_fingerprint": null
}
最核心的方法是tool_calls
回参里面返回了我们需要的方法名和一个 json
参数 比如"{\n \"cityName\": \"北京\"\n}"
包含了我们的参数和值。
{
"max_tokens": 3000,
"tool_choice": "auto",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "我想知道北京的天气状况"
},
{
"role": "assistant",
"function_call": {
"name": "Get_Weather_For_City",
"arguments": "{\n \"cityName\": \"北京\"\n}"
}
},
{
"role": "function",
"name": "Get_Weather_For_City",
"content": "27度,晴朗"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "Get_Weather_For_City",
"description": "获取指定城市的天气",
"parameters": {
"type": "object",
"properties": {
"cityName": {
"type": "string",
"description": "城市名"
}
}
}
}
},
{
需要把上下文信息和function calling
的result
回答的信息传给LLM
ToolCall
上下文信息{
"role": "assistant",
"function_call": {
"name": "Get_Weather_For_City",
"arguments": "{\n \"cityName\": \"北京\"\n}"
}
}
ToolCallResponse
{
"role": "function",
"name": "Get_Weather_For_City",
"content": "27度,晴朗"
}
LLM 输出
{
"id": "chatcmpl-9TRZBqCcRMBYIojuZimio6GOpsTi4",
"object": "chat.completion",
"created": 1716804505,
"model": "gpt-4",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "北京的天气状况是27度,晴朗。"
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 133,
"completion_tokens": 19,
"total_tokens": 152
},
"system_fingerprint": null
}
到现在为止简单的function calling
的简单调用已经完成了
具体的流程可以总结为
可以看到function calling
跟大预言模型至少有两次交互的的过程
根据文档中的描述,OpenAI
的函数调用(function calling
)过程可以简化为以下几个步骤,并且可以用一个流程图来表示:
下面是一个简化的流程图,描述了上述过程:
在这个流程图中:
LLM
模型,它检查是否有函数可以调用。ToolCall
)的步骤。ToolCall
并执行相应的函数。ToolCallResponse
,即函数执行的结果。ToolCallResponse
来生成用户响应。这个流程图是基于文档内容的简化表示,实际的系统可能包含更多的细节和步骤。
本章的主要了解function calling
及其工作原理的简单介绍。在下一篇博客中,我们 x 学习在Semantic kernel
下使用使用function calling
。
参考资料
深入探讨Python中的并发编程,特别关注多线程和多进程的应用。我们将先从基本概念开始,然后通过详细举例探讨每一种机制,最后分享一些实战经验以及一种优雅的编程技巧。