الارتباطات بـ OpenAI HTTP API لـ 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
يمكن إنشاء مثيل جلسة محادثة لتبسيط إدارة حالة المحادثة ذهابًا وإيابًا باستخدام 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) حتى تصبح الاستجابة بأكملها متاحة قبل إرجاع الاستجابة. اعتمادا على الموجه، قد يستغرق هذا بعض الوقت. يمكن استخدام واجهة برمجة التطبيقات المتدفقة لقراءة المخرجات قطعة واحدة في كل مرة، مما يسمح لك بعرض المحتوى في الوقت الفعلي عند إنشائه.
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
لإنشاء مثيل جديد لعميل OpenAIChatSession
: فئة لإدارة جلسات الدردشة والسجل باستخدام OpenAI API.VERSION = "1.1.0"
: الإصدار الحالي من المكتبةتقوم هذه الفئة بتهيئة عميل OpenAI API جديد.
new(api_key, config)
مُنشئ لعميل OpenAI.
api_key
: مفتاح OpenAI API الخاص بك.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 جديد. جلسة الدردشة هي فكرة عن واجهة برمجة تطبيقات إكمال الدردشة التي تخزن سجل الدردشة. يمكنك إلحاق رسائل جديدة بالسجل وطلب إنشاء الإكمالات منه. افتراضيًا، يتم إلحاق الإكمال بالمحفوظات.
client:chat(messages, opts, chunk_callback)
يرسل طلبًا إلى نقطة النهاية /chat/completions
.
messages
: مجموعة من كائنات الرسالة.opts
: خيارات إضافية للدردشة، يتم تمريرها مباشرة إلى واجهة برمجة التطبيقات (على سبيل المثال، النموذج، ودرجة الحرارة، وما إلى ذلك) https://platform.openai.com/docs/api-reference/chatchunk_callback
: دالة يتم استدعاؤها لإخراج الدفق المُحلل عندما يتم تمرير stream = true
إلى opts
.إرجاع حالة HTTP وكائن الاستجابة ورؤوس الإخراج. سيتم فك تشفير كائن الاستجابة من JSON إن أمكن، وإلا فسيتم إرجاع السلسلة الأولية.
client:completion(prompt, opts)
يرسل طلبًا إلى نقطة النهاية /completions
.
prompt
: المطالبة بالإكمال.opts
: خيارات إضافية للإكمال، يتم تمريرها مباشرة إلى واجهة برمجة التطبيقات (على سبيل المثال، النموذج، ودرجة الحرارة، وما إلى ذلك) https://platform.openai.com/docs/api-reference/completionsإرجاع حالة HTTP وكائن الاستجابة ورؤوس الإخراج. سيتم فك تشفير كائن الاستجابة من JSON إن أمكن، وإلا فسيتم إرجاع السلسلة الأولية.
client:embedding(input, opts)
يرسل طلبًا إلى نقطة النهاية /embeddings
.
input
: سلسلة واحدة أو مجموعة من السلاسلopts
: خيارات إضافية للإكمال، يتم تمريرها مباشرة إلى واجهة برمجة التطبيقات (على سبيل المثال، النموذج) https://platform.openai.com/docs/api-reference/embeddingsإرجاع حالة HTTP وكائن الاستجابة ورؤوس الإخراج. سيتم فك تشفير كائن الاستجابة من JSON إن أمكن، وإلا فسيتم إرجاع السلسلة الأولية.
يدير هذا الفصل جلسات الدردشة والسجل باستخدام OpenAI API. يتم إنشاؤه عادةً باستخدام new_chat_session
تقوم messages
الميدانية بتخزين مجموعة من رسائل الدردشة التي تمثل سجل الدردشة. يجب أن يتوافق كل كائن رسالة مع البنية التالية:
role
: سلسلة تمثل دور مرسل الرسالة. ويجب أن تكون إحدى القيم التالية: "النظام" أو "المستخدم" أو "المساعد".content
: سلسلة تحتوي على محتوى الرسالة.name
: سلسلة اختيارية تمثل اسم مرسل الرسالة. إذا لم يتم تقديمه، فيجب أن يكون nil
.على سبيل المثال، قد يبدو كائن الرسالة الصالح كما يلي:
{
role = " user " ,
content = " Tell me a joke " ,
name = " John Doe "
}
new(client, opts)
مُنشئ جلسة الدردشة.
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
: ما إذا كان يجب إلحاق الرد بسجل الدردشة (الافتراضي: صحيح).stream_callback
: (اختياري) وظيفة لتمكين إخراج التدفق. راجع chat:send
للحصول على تفاصيل حول stream_callback