引言
Function Calling
是一個允許大型語言模型(如 GPT
)在生成文字的過程中呼叫外部函式或服務的功能。
Function Calling
允許我們以 JSON
格式向 LLM
模型描述函式,並使用模型的固有推理能力來決定在生成響應之前是否呼叫該函式。模型本身不執行函式,而是生成包含函式名稱和執行函式所需的引數的 JSON
。
function calling 執行原理
現在我們定義提示詞像大語言模型問一下當前北京的天氣?
因為
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 API 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": "城市名"
}
}
}
}
}
]
}
核心引數解釋
tool_choice:
這個引數決定了模型是否應該自動選擇是否呼叫函式。值為 "auto"
表示模型將根據情況自動決定是否呼叫函式。 預設情況下,如果請求中不存在任何函式,則將其設定為“none”
,則設定為“auto”
。
tools
在 tools
部分定義了一個函式,這個函式可以被 OpenAI 的模型呼叫。以下是 tools
部分引數的簡單解釋:
-
type: 指定了這個工具的型別,這裡是
"function"
,表示這是一個函式呼叫。 -
function: 包含函式的詳細資訊,是一個物件。
-
name: 函式的名稱,這裡是
"Get_Weather_For_City"
,這是呼叫時使用的函式名。 -
description: 函式的描述,這裡是
"獲取指定城市的天氣"
,用於說明這個函式的作用。 -
parameters: 定義了函式呼叫時需要的引數,是一個物件。
-
type: 引數物件的型別,這裡是
"object"
,表示引數是一個物件型別。 -
properties: 包含具體的引數定義,是一個物件,每個屬性對應一個引數。
- cityName: 這是一個引數的名稱,表示城市名稱。
- type: 此引數的型別,這裡是
"string"
,表示引數應該是一個字串。 - description: 引數的描述,這裡是
"城市名"
,用於解釋這個引數的意義。
- type: 此引數的型別,這裡是
- cityName: 這是一個引數的名稱,表示城市名稱。
-
-
這個 tools
部分定義了一個名為 Get_Weather_For_City
的函式,它需要一個名為 cityName
的字串引數,用於指定想要查詢天氣的城市。當模型需要呼叫這個函式時,它將使用這個引數來獲取相應的天氣資訊。
function calling 輸出
{
"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
)過程可以簡化為以下幾個步驟,並且可以用一個流程圖來表示:
- 使用者提出問題。
- 系統接收到問題,並檢查是否有可用的函式可以呼叫。
- 如果有,系統會生成一個工具呼叫請求(ToolCall),併傳送給應用程式。
- 應用程式執行請求的函式,並返回結果。
- 系統將函式的響應(ToolCallResponse)傳送回 LLM 模型。
- LLM 模型使用這個響應來生成最終的使用者響應。
下面是一個簡化的流程圖,描述了上述過程:
在這個流程圖中:
- A 代表使用者。
- B 是使用者提出的問題。
- C 是
LLM
模型,它檢查是否有函式可以呼叫。 - D 是生成工具呼叫(
ToolCall
)的步驟。 - E 是應用程式,它接收
ToolCall
並執行相應的函式。 - F 是應用程式返回的
ToolCallResponse
,即函式執行的結果。 - G 是 LLM 模型,它使用
ToolCallResponse
來生成使用者響應。 - H 是最終接收到使用者響應的使用者。
這個流程圖是基於文件內容的簡化表示,實際的系統可能包含更多的細節和步驟。
最後
本章的主要了解function calling
及其工作原理的簡單介紹。在下一篇部落格中,我們 x 學習在Semantic kernel
下使用使用function calling
。
參考資料
openai-function-calling