OpenAI API進階-Function Calling實現插件!
Function Calling介紹
Function Calling是什么
OpenAI Chat API官方文檔:Chat API[1]
Function Calling官方介紹:Function Calling[2]
圖片
開發者現在可以向 gpt-4-0613 和 gpt-3.5-turbo-0613 描述函數,并讓模型智能地選擇輸出一個包含調用這些函數參數的 JSON 對象。這是一種更可靠地將 GPT 的功能與外部工具和 API 相連接的新方法。
這些模型經過了微調,既可以檢測到何時需要調用函數(根據用戶的輸入),又可以回復符合函數簽名的 JSON。函數調用使開發者能夠更可靠地從模型中獲得結構化數據。例如,開發者可以:
- 利用外部工具調用的聊天機器人(如 ChatGPT 插件)來回答問題
將查詢如“Email Anya看看她下周五是否想喝咖啡”轉換為像 send_email(to: string, body: string) 這樣的函數調用,或者將“波士頓的天氣如何?”轉換為 get_current_weather(location: string, unit: 'celsius' | 'fahrenheit')。
- 將自然語言轉換為 API 調用或數據庫查詢
將“這個月我的前十位客戶是誰?”轉換為內部 API 調用,如 get_customers_by_revenue(start_date: string, end_date: string, limit: int),或者將“Acme 公司上個月下了多少訂單?”轉換為使用 sql_query(query: string) 的 SQL 查詢。
- 從文本中提取結構化數據
定義一個名為 extract_people_data(people: [{name: string, birthday: string, location: string}]) 的函數,以提取在維基百科文章中提到的所有人物。
這些用例通過我們的 /v1/chat/completions 端點中的新 API 參數 functions 和 function_call 得以實現,開發者可以通過 JSON Schema 描述函數,并可選擇要求模型調用特定函數。
一句戶解釋就是:我們可以把自己的函數集成到GPT里了
Function Calling解決什么問題
Function Calling本質上就是插件!
插件功能相當于給OpenAI增加了一個武器庫,開發者可以隨意給它安裝武器提升它的能力。
數據實時性問題
圖片
問他langchain是什么?由于訓練集是截止2021年的,他會回答不知道。但是有了Function Callling,我們就可以寫一個函數集成谷歌/百度搜索API,給GPT加上聯網能力,這樣就借助搜索引擎的能力支持了數據的動態更新。
跟已有系統集成問題
圖片
問他今天天氣如何?由于ChatGPT數據集是離線的,無法滿足獲取實時天氣的需求。但是有了Function Calling,我們可以編寫一個函數來調用天氣獲取的API,從而獲取實時天氣信息,然后再與大模型的對話能力進行自然語言交互。
Function Calling如何使用
使用介紹
與普通chat對話的區別是增加了兩個額外參數
- functions: 聲明自定義函數庫
- funcion_call: 控制大模型什么時機使用通Function Calling功能
圖片
普通代碼:
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages
)
Function calling:
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages,
# 增加額外兩個參數
functinotallow=functions,
function_call="auto", # auto is default, but we'll be explicit
)
實時天氣查詢實踐
整體要經過兩次的OpenAI Chat接口調用。
調用流程
1.定義函數
定義本地函數get_current_weather實現從API拉取,這里直接寫一個簡單對參數輸出進行模擬。
然后按照OpenAI的文檔要求格式定義get_current_weather的接口函數的json參數。
2.第一次調用接口
返回大模型分析出的函數名稱和參數。
結果如下:
{
"id": "chatcmpl-8EIYxuSvhxmvYRE2UZI19fodbhXGv",
"object": "chat.completion",
"created": 1698418639,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"function_call": {
"name": "get_current_weather",
"arguments": "{\n \"location\": \"Boston, MA\",\n \"unit\": \"celsius\"\n}"
}
},
"finish_reason": "function_call"
}
],
"usage": {
"prompt_tokens": 86,
"completion_tokens": 26,
"total_tokens": 112
}
}
3.調用本地函數
獲取返回值,進行本地python方法調用
4.第二次調用接口
將第一次接口的返回值message與本地函數調用的接口拼裝起來,然后再次調用接口。
結果如下:
{
"role": "assistant",
"content": "The weather in Boston today is 20 degrees Celsius."
}
代碼實現
完整代碼鏈接:Fuction Calling 示例[3]
# function_calling.py
import openai
import json
openai.api_key = 'sk-NYsoG3VBKDiTuvdtC969F95aFc4f45379aD3854a93602327'
openai.api_base = "https://key.wenwen-ai.com/v1"
# 1. 定義函數
# 1.1 定義模擬獲取天氣的本地函數
def get_current_weather(location, unit):
# Call the weather API
return f"It's 20 {unit} in {location}"
# 1.2 定義函數字典方便調用
function_dict = {
"get_current_weather": get_current_weather,
}
# 1.3 定義chat接口需要的函數
functions = [
{
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
}
]
# 2. 第一次調用chat接口,返回的是函數調用的提示
messages = [
{"role": "user", "content": "What's the weather like in Boston today with celsius?"}]
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages,
functinotallow=functions,
function_call="auto", # auto is default, but we'll be explicit
)
print(completion)
# 3. 從結果接口的結果中獲取函數調用的參數 進行本地函數調用
# 3.1 獲取函數調用的參數
response_message = completion.choices[0].message
function_name = response_message["function_call"]["name"]
function_args = json.loads(response_message["function_call"]["arguments"])
# 3.2 調用本地函數
function_response = function_dict.get(function_name)(**function_args)
# 3.3 將本地函數的結果作為chat接口的輸入
messages.append(response_message)
messages.append({
"role": "function",
"name": function_name,
"content": function_response,
})
# 4. 第二次調用chat接口,返回的是chat的最終結果
completion_final = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages,
)
print(completion_final.choices[0].message)
上面的代碼中的key是我自己維護的,免費給大家使用,代碼可以直接運行!
python3.9 function_calling.py
參考資料
[1]Chat API: https://platform.openai.com/docs/api-reference/chat
[2]Function Calling: https://openai.com/blog/function-calling-and-other-api-updates
[3]Fuction Calling 示例: https://github.com/hehan-wang/openai-demo/blob/main/function_calling.py