引言
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