如何使用GPT-4o函數調用構建一個實時應用程序? 原創
本教程介紹了如何使用OpenAI最新的LLM GPT-4o通過函數調用將實時數據引入LLM。
我們在LLM函數調用指南(詳見https://thenewstack.io/a-comprehensive-guide-to-function-calling-in-llms/)中討論了如何將實時數據引入聊天機器人和代理。現在,我們將通過將來自FlightAware.com的API與新的GPT-4o模型集成,進一步探究這個概念,以便實時跟蹤航班狀態。
FlightAware的AeroAPI是一個可靠的充分利用REST的API,提供按需訪問航班跟蹤和狀態數據。它允許開發人員通過一個基于查詢的簡單系統,獲取實時、歷史或未來的航班信息。API支持基于航班標識符、飛機注冊號或機場或運營商等位置的詳細請求。它旨在以JSON格式提供精確、可操作的航空數據,支持整個航空業從航空公司到機場的運營需求。
在繼續之前,注冊FlightAware并獲得API密鑰,這對于調用REST API至關重要。免費的個人套餐足以完成本教程。
第1步:定義獲取航班狀態的函數
一旦您獲得了API密鑰,用Python創建以下函數來檢索任何航班的狀態。
import ast
import json
import random
from datetime import datetime, timedelta
import requests
import pytz
def get_flight_status(flight):
"""Returns Flight Information"""
AEROAPI_BASE_URL = "https://aeroapi.flightaware.com/aeroapi"
AEROAPI_KEY="YOUR FLIGHTAWARE API KEY"
def get_api_session():
session = requests.Session()
session.headers.update({"x-apikey": AEROAPI_KEY})
return session
def fetch_flight_data(flight_id, session):
if "flight_id=" in flight_id:
flight_id = flight_id.split("flight_id=")[1]
start_date = datetime.now().date().strftime('%Y-%m-%d')
end_date = (datetime.now().date() + timedelta(days=1)).strftime('%Y-%m-%d')
api_resource = f"/flights/{flight_id}?start={start_date}&end={end_date}"
response = session.get(f"{AEROAPI_BASE_URL}{api_resource}")
response.raise_for_status()
return response.json()['flights'][0]
def utc_to_local(utc_date_str, local_timezone_str):
utc_datetime = datetime.strptime(utc_date_str, '%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=pytz.utc)
local_timezone = pytz.timezone(local_timezone_str)
local_datetime = utc_datetime.astimezone(local_timezone)
return local_datetime.strftime('%Y-%m-%d %H:%M:%S')
session = get_api_session()
flight_data = fetch_flight_data(flight, session)
dep_key = 'estimated_out' if 'estimated_out' in flight_data and flight_data['estimated_out'] else \
'actual_out' if 'actual_out' in flight_data and flight_data['actual_out'] else \
'scheduled_out'
arr_key = 'estimated_in' if 'estimated_in' in flight_data and flight_data['estimated_in'] else \
'actual_in' if 'actual_in' in flight_data and flight_data['actual_in'] else \
'scheduled_in'
flight_details = {
'flight':flight,
'source': flight_data['origin']['city'],
'destination': flight_data['destination']['city'],
'depart_time': utc_to_local(flight_data[dep_key], flight_data['origin']['timezone']),
'arrival_time': utc_to_local(flight_data[arr_key], flight_data['destination']['timezone']),
'status': flight_data['status']
}
return json.dumps(flight_details)
flight_info = get_flight_status("EK524")
print(flight_info)
#'{"flight": "EK524", "source": "Dubai", "destination": "Hyderabad", "depart_time": "2024-05-23 22:00:00", "arrival_time": "2024-05-24 03:05:00", "status": "Scheduled"}'
雖然代碼很簡單,但還是不妨解釋一下關鍵步驟。
get_flight_status函數接受一個航班參數(假設是航班標識符),并以JSON格式返回格式化的航班詳細信息。它查詢AeroAPI以根據給定的航班標識符獲取航班數據,并確定關鍵細節的格式,比如出發地、目的地、離開時間、到達時間和狀態。
不妨看看腳本的組件:
API憑據:
AEROAPI_BASE_URL是FlightAware AeroAPI的基礎URL。
AEROAPI_KEY是用于身份驗證的API密鑰。
會話管理:
get_api_session:這個嵌套函數初始化請求。會話對象使用API密鑰設置所需的報頭,并返回會話對象。該會話將處理所有API請求。
數據獲取:
fetch_flight_data:這個函數接受flight_id和session作為參數。它使用適當的日期過濾器構造端點URL,用于獲取一天的數據,并發送GET請求以檢索航班數據。該函數處理API響應,并提取相關的航班信息。
時間轉換:
utc_to_local:根據所提供的時區字符串將UTC時間(來自API響應)轉換為本地時間。這個函數可以幫助我們獲得基于城市的到達和離開時間。
數據處理:
腳本根據估計或實際時間的可用性確定離開時間和到達時間的鍵,并返回到計劃時間。然后,它構造一個含有格式化航班詳細信息的字典。
上面的截圖顯示了我們從FlightAware API收到的從迪拜飛往海得拉巴的阿聯酋航空EK524航班的響應信息。請注意,到達和離開時間是基于城市的當地時間。
我們的目的是將該函數與GPT-4 Omni集成,使其能夠實時訪問航班跟蹤信息。
第2步:用GPT- 4o實現函數調用
不妨從導入OpenAI庫并初始化它入手。
from openai import OpenAI
client = OpenAI()
這一行創建了OpenAI類的一個實例。這個實例(客戶端)將用于與OpenAI API交互。
我們將定義一個名為tools的列表,含有一個字典,該字典指定了函數get_flight_status。該函數旨在用作OpenAI API上下文中的工具,描述參數和所需輸入。
tools = [
{
"type": "function",
"function": {
"name": "get_flight_status",
"description": "Get status of a flight",
"parameters": {
"type": "object",
"properties": {
"flight": {
"type": "string",
"description": "Flight number"
}
},
"required": ["flight"]
}
}
}
]
繁重工作在下面的函數中進行,其中LLM檢查提示以確定是否需要調用函數/工具,然后繼續生成適當的響應。
def chatbot(prompt):
# Step 1: send the conversation and available functions to the model
messages = [{"role": "user", "content": prompt}]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
tool_choice="auto"
)
response_message = response.choices[0].message
tool_calls = response_message.tool_calls
# Step 2: check if the model wanted to call a function
if tool_calls:
available_functions = {
"get_flight_status": get_flight_status,
}
messages.append(response_message)
# Step 3: send the function response to the model
for tool_call in tool_calls:
function_name = tool_call.function.name
function_to_call = available_functions[function_name]
function_args = json.loads(tool_call.function.arguments)
function_response = function_to_call(flight=function_args.get("flight"))
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
}
)
final_response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
)
return final_response
這個函數chatbot接受用戶提示,并使用OpenAI API對其進行處理。它將提示和定義的工具發送到OpenAI模型并處理響應。
通過嵌入來自用戶的提示并將其發送到OpenAI API(chat.completion .create)來創建消息。API使用指定的工具(如果適用)處理這些消息。
比如說,當我們發送提示“EK524的狀態是什么?”,GPT- 4o需要調用工具列表中提供的函數,并返回以下響應:
注意,響應包括函數(get_flight_status)和參數(EK226)。
下一步檢查是否調用了任何工具(即工具中的函數)。它使用提供的參數執行這些函數,將它們的輸出集成到對話中,并將這些更新后的信息發回到OpenAI API以進行進一步處理。
# Step 2: check if the model wanted to call a function
if tool_calls:
available_functions = {
"get_flight_status": get_flight_status,
}
messages.append(response_message)
# Step 3: send the info for each function call and function response to the model
for tool_call in tool_calls:
function_name = tool_call.function.name
function_to_call = available_functions[function_name]
function_args = json.loads(tool_call.function.arguments)
function_response = function_to_call(flight=function_args.get("flight"))
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
}
)
此時,messages列表包括原始提示、帶有函數名和變量的初始響應以及函數的實際輸出。下面的屏幕截圖顯示了含有所有要素的列表。
由于來自工具的響應附加到歷史記錄中,我們可以調用聊天完成端點,從LLM獲得最終答案。
final_response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
)
return final_response
final_response對象有我們所尋找的答案:
將提示發送給函數chatbot將返回指定航班的實時狀態。
下面是本教程的完整代碼:
from openai import OpenAI
#Initialize the environment variable OPENAI_API_KEY with your api key
client = OpenAI()
#Function is available at
https://gist.github.com/janakiramm/2143b909626f5f01d64739e3fe90c9c8
tools = [
{
"type": "function",
"function": {
"name": "get_flight_status",
"description": "Get status of a flight",
"parameters": {
"type": "object",
"properties": {
"flight": {
"type": "string",
"description": "Flight number"
}
},
"required": ["flight"]
}
}
}
]
def chatbot(prompt):
# Step 1: send the conversation and available functions to the model
messages = [{"role": "user", "content": prompt}]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
tool_choice="auto"
)
response_message = response.choices[0].message
tool_calls = response_message.tool_calls
# Step 2: check if the model wanted to call a function
if tool_calls:
available_functions = {
"get_flight_status": get_flight_status,
}
messages.append(response_message)
# Step 3: send the info for each function call and function response to the model
for tool_call in tool_calls:
function_name = tool_call.function.name
function_to_call = available_functions[function_name]
function_args = json.loads(tool_call.function.arguments)
function_response = function_to_call(flight=function_args.get("flight"))
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
}
)
final_response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
)
return final_response
res=chatbot("What's the status of EK226?")
print(res.choices[0].message.content)
我們在本教程中探討了如何通過函數調用將實時數據引入LLM。在本系列的下一部分中,我們將把GPT-4o換成Gemini Pro,以探究相同的概念,但使用不同的模型。
原文標題:How To Build a Real-Time App With GPT-4o Function Calling,作者:Janakiram MSV
鏈接:https://thenewstack.io/how-to-build-a-real-time-app-with-gpt-4o-function-calling/。
