Привязки к HTTP API OpenAI для Lua. Совместим с любой библиотекой HTTP, поддерживающей интерфейс HTTP-запросов LuaSocket. Совместим с OpenResty с использованием lapis.nginx.http
.
Хотя эта библиотека была написана вручную, большая часть документации, набор тестов и рабочий процесс 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
Можно создать экземпляр сеанса чата, чтобы упростить управление состоянием двусторонней беседы с помощью API ChatGPT. Обратите внимание, что состояние чата сохраняется локально в памяти, каждое новое сообщение добавляется в список сообщений, а выходные данные автоматически добавляются в список для следующего запроса.
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
: клиент для отправки запросов к API OpenAI.new
: псевдоним OpenAI
для создания нового экземпляра клиента OpenAI.ChatSession
: класс для управления сеансами чата и историей с помощью API OpenAI.VERSION = "1.1.0"
: текущая версия библиотеки.Этот класс инициализирует новый клиент API OpenAI.
new(api_key, config)
Конструктор для клиента OpenAI.
api_key
: ваш ключ API OpenAI.config
: необязательная таблица параметров конфигурации следующей формы:http_provider
: строка, определяющая имя HTTP-модуля, используемого для запросов, или nil
. Если не указано иное, библиотека будет автоматически использовать «lapis.nginx.http» в среде ngx или «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, если это возможно, в противном случае возвращается необработанная строка.
Этот класс управляет сеансами чата и историей с помощью API OpenAI. Обычно создается с помощью new_chat_session
Поле messages
хранит массив сообщений чата, представляющих историю чата. Каждый объект сообщения должен соответствовать следующей структуре:
role
: строка, представляющая роль отправителя сообщения. Это должно быть одно из следующих значений: «система», «пользователь» или «помощник».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)
Вызывает API OpenAI для генерации следующего ответа для сохраненной истории чата. Возвращает ответ в виде строки. В случае неудачи возвращает nil
, сообщение об ошибке и необработанный ответ на запрос.
append_response
: следует ли добавлять ответ в историю чата (по умолчанию: true).stream_callback
: (необязательно) Функция для включения потокового вывода. Смотрите chat:send
для получения подробной информации stream_callback