綁定到 Lua 的 OpenAI HTTP API。相容於任何支援LuaSocket http請求介面的HTTP庫。使用lapis.nginx.http
與 OpenResty 相容。
儘管這個庫是手工編寫的,但大部分文件、測試套件和 GitHub 工作流程都是由 GPT-4 完全生成的,方法是貼上整個庫的源代碼作為提示並要求生成文檔和測試。為了清晰起見和語法,對最終輸出進行了編輯(在 GPT4 難以編寫 MoonScript 的情況下)
使用 LuaRocks 安裝:
luarocks install lua-openai
local openai = require ( " openai " )
local client = openai . new ( os.getenv ( " OPENAI_API_KEY " ))
local status , response = client : chat ({
{ role = " system " , content = " You are a Lua programmer " },
{ role = " user " , content = " Write a 'Hello world' program in Lua " }
}, {
model = " gpt-3.5-turbo " , -- this is the default model
temperature = 0.5
})
if status == 200 then
-- the JSON response is automatically parsed into a Lua object
print ( response . choices [ 1 ]. message . content )
end
可以建立聊天會話實例來簡化管理與 ChatGPT API 的來回對話的狀態。請注意,聊天狀態會本地儲存在記憶體中,每個新訊息都會附加到訊息清單中,並且輸出會自動附加到下一個請求的清單中。
local openai = require ( " openai " )
local client = openai . new ( os.getenv ( " OPENAI_API_KEY " ))
local chat = client : new_chat_session ({
-- provide an initial set of messages
messages = {
{ role = " system " , content = " You are an artist who likes colors " }
}
})
-- returns the string response
print ( chat : send ( " List your top 5 favorite colors " ))
-- the chat history is sent on subsequent requests to continue the conversation
print ( chat : send ( " Excluding the colors you just listed, tell me your favorite color " ))
-- the entire chat history is stored in the messages field
for idx , message in ipairs ( chat . messages ) do
print ( message . role , message . content )
end
-- You can stream the output by providing a callback as the second argument
-- the full response concatenated is also returned by the function
local response = chat : send ( " What's the most boring color? " , function ( chunk )
io.stdout : write ( chunk . content )
io.stdout : flush ()
end )
OpenAI 允許傳送 LLM 可以根據提示決定呼叫的函數宣告清單。函數呼叫介面必須與聊天完成以及gpt-4-0613
或gpt-3.5-turbo-0613
或更高版本一起使用。
請參閱 https://github.com/leafo/lua-openai/blob/main/examples/example5.lua 以了解實現基本數學函數來計算數字列表的標準差的完整範例
以下是如何在聊天交流中使用功能的快速範例。首先,您需要使用包含一系列可用函數的functions
選項來建立聊天會話。
功能儲存在聊天物件的
functions
欄位中。如果以後的訊息需要調整功能,可以修改該欄位。
local chat = openai : new_chat_session ({
model = " gpt-3.5-turbo-0613 " ,
functions = {
{
name = " add " ,
description = " Add two numbers together " ,
parameters = {
type = " object " ,
properties = {
a = { type = " number " },
b = { type = " number " }
}
}
}
}
})
您發送的任何提示都會了解所有可用的功能,並可能要求呼叫其中的任何功能。如果回應包含函數呼叫請求,則將傳回一個物件而不是標準字串傳回值。
local res = chat : send ( " Using the provided function, calculate the sum of 2923 + 20839 " )
if type ( res ) == " table " and res . function_call then
-- The function_call object has the following fields:
-- function_call.name --> name of function to be called
-- function_call.arguments --> A string in JSON format that should match the parameter specification
-- Note that res may also include a content field if the LLM produced a textual output as well
local cjson = require " cjson "
local name = res . function_call . name
local arguments = cjson . decode ( res . function_call . arguments )
-- ... compute the result and send it back ...
end
您可以評估請求的函數和參數並將結果傳回客戶端,以便它可以使用role=function
訊息物件恢復操作:
由於 LLM 可以幻覺函數呼叫的每個部分,因此您需要進行可靠的類型驗證,以確保函數名稱和參數與您的期望相符。假設每個階段都可能失敗,包括接收參數格式錯誤的 JSON。
local name , arguments = ... -- the name and arguments extracted from above
if name == " add " then
local value = arguments . a + arguments . b
-- send the response back to the chat bot using a `role = function` message
local cjson = require " cjson "
local res = chat : send ({
role = " function " ,
name = name ,
content = cjson . encode ( value )
})
print ( res ) -- Print the final output
else
error ( " Unknown function: " .. name )
end
正常情況下,API 會等到整個回應可用後再回傳回應。根據提示,這可能需要一些時間。串流 API 可用於一次讀取一塊輸出,讓您在產生內容時即時顯示內容。
local openai = require ( " openai " )
local client = openai . new ( os.getenv ( " OPENAI_API_KEY " ))
client : chat ({
{ role = " system " , content = " You work for Streak.Club, a website to track daily creative habits " },
{ role = " user " , content = " Who do you work for? " }
}, {
stream = true
}, function ( chunk )
io.stdout : write ( chunk . content )
io.stdout : flush ()
end )
print () -- print a newline
openai
模組傳回一個包含以下欄位的表:
OpenAI
:用於向 OpenAI API 發送請求的用戶端。new
: OpenAI
的別名,用於建立 OpenAI 用戶端的新實例ChatSession
:用於使用 OpenAI API 管理聊天會話和歷史記錄的類別。VERSION = "1.1.0"
:庫的當前版本此類初始化一個新的 OpenAI API 用戶端。
new(api_key, config)
OpenAI 用戶端的建構子。
api_key
:您的 OpenAI API 金鑰。config
:配置選項的可選表,具有以下形狀:http_provider
:指定用於請求的 HTTP 模組名稱的字串,或nil
。如果未提供,程式庫將在 ngx 環境中自動使用“lapis.nginx.http”,否則使用“ssl.https”。 local openai = require ( " openai " )
local api_key = " your-api-key "
local client = openai . new ( api_key )
client:new_chat_session(...)
建立一個新的 ChatSession 實例。聊天會話是儲存聊天歷史記錄的聊天完成 API 的抽象。您可以將新訊息附加到歷史記錄中並要求從中產生完成資訊。預設情況下,完成情況會附加到歷史記錄中。
client:chat(messages, opts, chunk_callback)
向/chat/completions
端點發送請求。
messages
:訊息物件的陣列。opts
:聊天的附加選項,直接傳遞給 API(例如模型、溫度等)https://platform.openai.com/docs/api-reference/chatchunk_callback
:當stream = true
傳遞給opts
時,為解析流輸出而呼叫的函數。傳回 HTTP 狀態、回應物件和輸出標頭。如果可能,回應物件將從 JSON 解碼,否則傳回原始字串。
client:completion(prompt, opts)
向/completions
端點發送請求。
prompt
:完成的提示。opts
:完成的附加選項,直接傳遞給 API(例如模型、溫度等)https://platform.openai.com/docs/api-reference/completions傳回 HTTP 狀態、回應物件和輸出標頭。如果可能,回應物件將從 JSON 解碼,否則傳回原始字串。
client:embedding(input, opts)
向/embeddings
端點發送請求。
input
:單一字串或字串陣列opts
:完成的附加選項,直接傳遞給 API(例如模型)https://platform.openai.com/docs/api-reference/embeddings傳回 HTTP 狀態、回應物件和輸出標頭。如果可能,回應物件將從 JSON 解碼,否則傳回原始字串。
此類使用 OpenAI API 管理聊天會話和歷史記錄。通常使用new_chat_session
創建
字段messages
存儲表示聊天歷史記錄的聊天訊息數組。每個訊息對象必須符合以下結構:
role
:代表訊息發送者角色的字串。它必須是以下值之一:「system」、「user」或「assistant」。content
:包含訊息內容的字串。name
:表示訊息發送者名稱的可選字串。如果沒有提供,它應該是nil
。例如,有效的訊息物件可能如下所示:
{
role = " user " ,
content = " Tell me a joke " ,
name = " John Doe "
}
new(client, opts)
ChatSession 的建構子。
client
:OpenAI 客戶端的實例。opts
:可選的選項表。messages
:聊天訊息的初始數組functions
:函數宣告列表temperature
:溫度設定model
:使用哪種聊天完成模型,例如。 gpt-4
, gpt-3.5-turbo
chat:append_message(m, ...)
將訊息追加到聊天記錄中。
m
:訊息對象。 chat:last_message()
傳回聊天記錄中的最後一則訊息。
chat:send(message, stream_callback=nil)
將訊息附加到聊天歷史記錄並使用generate_response
觸發完成,並將回應作為字串傳回。失敗時,傳回nil
、錯誤訊息和原始請求回應。
如果回應包含function_call
,則傳回整個訊息物件而不是內容字串。您可以透過將role = "function"
物件傳遞給send
方法來傳回函數的結果
message
:訊息物件或字串。stream_callback
:(可選)啟用流輸出的函數。透過提供stream_callback
,請求將以流模式運行。此函數接收從響應中解析出的區塊。
這些區塊具有以下格式:
content
:包含助手產生的回應文字的字串。例如,一個區塊可能如下所示:
{
content = " This is a part of the assistant's response. " ,
}
chat:generate_response(append_response, stream_callback=nil)
呼叫 OpenAI API 為儲存的聊天記錄產生下一個回應。以字串形式傳回回應。失敗時,傳回nil
、錯誤訊息和原始請求回應。
append_response
:是否應將回應附加到聊天歷史記錄中(預設值:true)。stream_callback
:(可選)啟用流輸出的函數。有關stream_callback
的詳細信息,請參閱chat:send