Chatterstack هي طريقة بسيطة وبديهية للتعامل مع متغيرات "المحادثة" التي تستخدمها واجهة برمجة تطبيقات ChatGPT، بينما توفر لك أيضًا وظائف متقدمة.
تثبيت الحزمة من النقطة:
pip install chatterstack
هناك خياران لـ Chatterstack. المكتبة الأساسية، والمكتبة المتقدمة، التي توسع القاعدة.
import chatterstack
# The base library if you are only really concerned about mananging
# the conversation variable, it's order, and maybe tracking tokens.
convo = chatterstack . Chatterstack ()
# The advanced library allows you issuing commands from the chat input,
# gives the bot the ability to reach out to you with reminders, etc
convo = chatterstack . ChatterstackAdvanced ()
تستخدم واجهات برمجة تطبيقات ChatGPT متغيرات "المحادثة" لتتبع تفاعلاتك مع الروبوت. هذه قائمة من القواميس، حيث يمثل كل قاموس منعطفًا في المحادثة.
وهذا يترك برنامجك مليئًا بأشياء مثل هذا:
# append the bot's response to your conversation
conversation . append ({ 'role' : response . choices [ 0 ]. message . role , 'content' : response . choices [ 0 ]. message . content })
# to print the last message
print ( conversation [ - 1 ][ "content" ])
سخيف.
إذا كنت تريد القيام بأي شيء أكثر تقدمًا، مثل "الاحتفاظ بمتغير المحادثة إلى 8 رسائل كحد أقصى"، أو "جعل رسالة النظام دائمًا هي أحدث رسالة في المحادثة"... حسنًا، سأوفر لك مقتطف الشفرة لـ أولئك.
نظرًا لأن العديد من جوانب هذه القواميس يمكن التنبؤ بها بدرجة كبيرة، ونحن في أغلب الأحيان نقوم فقط بعدد قليل من المهام الأساسية معها...
...هذا يعني أنه يمكننا في الواقع التخلص من الكثير من هذه الفوضى، بطريقة تجعل استخدامها أكثر سهولة - مع الحفاظ أيضًا على كل المرونة المتأصلة! وهذا أمر نادر أن تكون قادرًا على القيام به.
هذا برنامج chatbot يعمل بكامل طاقته باستخدام chatterstack:
import chatterstack
import os
os . environ [ 'OPENAI_API_KEY' ] = 'your_api_key_here'
convo = chatterstack . Chatterstack ()
while True :
convo . user_input ()
convo . send_to_bot ()
convo . print_last_message ()
هذا هو كل شيء!
هذا ما ستبدو عليه هذه المحادثة في المحطة:
USER: hey, can you help me with something?
ASSISTANT: Sure! What would you like help with?
USER: I need to know if France has a President or a Prime Minister
ASSISTANT: France has both a President and a Prime Minister, which [... bot goes on]
تم تصميم هذه المكتبة لتكون بديهية ومرنة ، بحيث يمكنك بسهولة تغيير السلوك أو البحث، بعدة طرق، عما يناسب احتياجاتك. فيما يلي بعض الأمثلة الأساسية للبقاء في المحطة في الوقت الحالي:
while True :
# Change the user's display name
convo . user_input ( prefix = "ME: " )
# change any of the API arguments
convo . send_to_bot ( model = "gpt-4" , temperature = 1 , max_tokens = 40 )
# change the line spacing of the convo
convo . print_last_message ( prefix = "GPT: " , lines_before = 0 , lines_after = 2 )
# and let's have it print the total tokens after each turn
print ( convo . tokens_total_all )
الآن أصبحت محادثتك مع GPT-4، والمحادثة تبدو هكذا، مع عدد من الرموز المميزة:
ME: hey, can you help me with something?
GPT: Of course! I'm here to help. Please let me know what you need assistance with, and I'll do my best to help you.
28
ME: I need to know if France has a President or a Prime Minister
GPT: France has both a President and a Prime Minister. The President of France is [...bot goes on]
87
يوجد المزيد من المعلومات حول الإعدادات الافتراضية الحالية وطرق مختلفة لتغييرها أدناه في القسم الخاص بإرسال الرسائل إلى واجهة برمجة التطبيقات
طريقة user_input()
هي نفس طريقة python input()
، باستثناء أنها تقوم أيضًا بإلحاق إدخال المستخدم تلقائيًا كإملاء منسق بشكل صحيح لمتغير المحادثة الخاص بك.
convo . user_input ()
كما هو موضح أعلاه، فإن هذه الطريقة الافتراضية هي مطالبة المستخدم بـ "USER:"، ولكن يمكنك تغييرها إلى ما تريد
convo . user_input ( "Ask the bot: " )
Ask the bot:
ربما لا تستخدم المحطة.
أو ربما تريد تغيير الإدخال بطريقة ما قبل إلحاقه.
هناك عدة طرق لأخذ أي متغير سلسلة وإضافته إلى المحادثة كإملاء منسق بشكل صحيح:
# Use the .add() method. Pass it the role, then the content
convo . add ( "user" , message_string )
# or, use the role-specific methods & just pass the content
convo . add_user ( message_string )
convo . add_assistant ( "I'm a manually added assistant response" )
convo . add_system ( "SYSTEM INSTRUCTIONS - you are a helpful assistant who responds only in JSON" )
يوجد أيضًا .insert() إذا كنت تريد إضافة رسالة في فهرس محدد، بدلاً من إلحاقها بنهاية المحادثة:
# Here's the format
convo . insert ( index , role , content )
# example
convo . insert ( 4 , "system" , "IMPORTANT: Remember to not apologize to the user so much" )
تعد طريقة chatterstack "send_to_bot" بمثابة استدعاء قياسي لواجهة برمجة التطبيقات OpenAI API، ولكنها أسهل في الاستخدام وتقوم بمجموعة من الأشياء المفيدة لك في الخلفية. نسميها مثل هذا:
convo . send_to_bot ()
هذا كل شيء!
سيهتم بتمرير جميع القيم الافتراضية لك، بالإضافة إلى إلحاق الرد بمحادثتك. كما أنه يحتفظ بأعداد الرموز المميزة لك (وفي الفئة المتقدمة، أكثر من ذلك بكثير).
بشكل افتراضي، يستخدم chatterstack هذه القيم:
model = "gpt-3.5-turbo" ,
temperature = 0.8 ,
top_p = 1 ,
frequency_penalty = 0 ,
presence_penalty = 0 ,
max_tokens = 200
هناك عدة طرق لتغيير هذه. اختر ما هو أكثر ملاءمة لك.
الطريقة الأكثر وضوحًا هي تمريرها كوسائط عند إجراء المكالمة. على سبيل المثال، إذا كنت تريد رموز GPT-4 و800 كحد أقصى:
convo . send_to_bot ( model = "gpt-4" , max_tokens = 800 )
يعد هذا الأسلوب رائعًا عندما تريد إجراء مكالمة واحدة فقط ببعض القيم المختلفة.
ولكن إذا كنت تعلم أنك تريد قيمًا مختلفة للمحادثة بأكملها، فيمكنك تحديدها بالأحرف الكبيرة في الجزء العلوي من ملفك، وتهيئة chatterstack باستخدام الإملاء globals()
، مثل هذا:
MODEL = "gpt-4"
TEMPERATURE = 0.6
FREQUENCY_PENALTY = 1.25
MAX_TOKENS = 500
# initialize with 'globals()'
convo = chatterstack . Chatterstack ( user_defaults = globals ())
# and now you can just call it like this again
convo . send_to_bot ()
أخيرًا، إذا كنت تريد فقط استخدام استدعاء OpenAI المعياري، فلا يزال بإمكانك القيام بذلك! ما عليك سوى تمرير السمة .list الخاصة بـ Chatterstack، وهي القائمة الأولية للقواميس:
response = openai . ChatCompletion . create (
model = "gpt-3.5-turbo" ,
messages = convo . list , # <--- right here
temperature = 0.9 ,
top_p = 1 ,
frequency_penalty = 0 ,
presence_penalty = 0 ,
max_tokens = 200 ,
)
بسيطة للغاية:
# Print the "content" of the last message
convo . print_last_message ()
أو، إذا كنت تريد إجراء التنسيق على السلسلة أولاً...
# This represents/is the content string of the last message
convo . last_message
# So you can do stuff like this:
message_in_caps = convo . last_message . upper ()
# print the message in all upper case
print ( message_in_caps )
أوه نعم. نحن نتتبع الرموز.
# See the tokens used on the last API call
self . last_call_prompt_tokens
self . last_call_full_context_prompt_tokens
self . last_call_completion_tokens
self . last_call_tokens_all
# At any time, check the totals for the whole conversation so far
self . prompt_tokens_total
self . assistant_tokens_total
self . tokens_total_all
تتوفر طرق مختلفة للتحكم في ترتيب المحادثة، وفيما يلي بعض منها:
# Insert message at a specified index
convo . insert ( index , role , content )
# Remove N messages from the end of the list
convo . remove_from_end ( count )
# Remove N messages from the start of the list
convo . remove_from_start ( count )
ولكن الأهم من ذلك بكثير - طرق التحكم الدقيق في رسالة النظام.
يتم عادةً استخدام رسائل النظام للحصول على الإرشادات، وغالبًا ما يكون من المفيد ظهور الإرشادات "مؤخرًا" في المحادثة. مما يعني تتبع هذه الرسالة ونقلها دون تعطيل الرسائل الأخرى.
# move your system message to be the most recent message in convo
convo . move_system_to_end ()
# or second to last, etc
convo . move_system_to_end ( minus = 1 )
ومفضلي الشخصي - وهو السبب الرئيسي وراء كتابتي لهذه المكتبة بأكملها -
convo . set_system_lock_index ( - 1 )
سيؤدي تمريرها بقيمة موجبة إلى هذه الوظيفة إلى قفل رسالة النظام على الفهرس. في أي وقت تتم إضافة الرسائل أو إزالتها أو إعادة ترتيبها، سيتم التأكد من بقاء رسالة النظام في هذا الموضع (أو في أقرب وقت ممكن).
سيؤدي تمريرها بقيمة سالبة إلى قفل رسالة النظام الخاصة بك في الفهرس الذي يتم حسابه من نهاية المحادثة (المثال أعلاه سيجعلها دائمًا هي الرسالة قبل الأخيرة في المحادثة).
ملاحظة: حاليًا، تفترض هذه الطرق أن لديك رسالة نظام واحدة فقط
طباعة نسخة منسقة من محادثتك (رائعة لتصحيح الأخطاء)
convo . print_formatted_conversation
بشكل افتراضي، تتم الطباعة على النحو التالي:
System: You are a helpful assistant.
User: hi!
Assistant: Hi! How can I help you?
اطلع على الإحصائيات العامة لمحادثتك.
convo . summary ()
SUMMARY:
{'total_messages': 2, 'prompt_tokens': 200, 'assistant_tokens': 78, 'total_tokens': 278}
تعمل فئة Chatterstack Advanced على توسيع الفئة الأساسية، وتحتوي على المزيد من الوظائف المضمنة. كما أنها قابلة للتوسعة بسهولة.
تحذير : يبدو أن التغييرات الأخيرة في النموذج قد أدت إلى تعطيل هذه الوظيفة. قد يعمل أو لا يعمل عند تجربته. من المحتمل أن تتم إعادة كتابتها لاستخدام استدعاء الوظائف للعمل بشكل ثابت مرة أخرى
يمكنك الآن أن تقول للروبوت "ذكّرني بإخراج القمامة في الساعة 8 مساءً"، أو "ذكّرني بإخراج القمامة في غضون ساعة"
USER: hey, can you remind me to take the garbage out in an hour
ASSISTANT: Sure! I'll send you a reminder in an hour.
USER:
{...time passes...}
ASSISTANT: Hey! Just a quick reminder to take the garbage out!
يمكن للروبوت تتبع أي عدد من التذكيرات التي تريد إصدارها.
إصدار الأوامر من إدخال المستخدم:
# saves the conversation to a txt file
USER: [save]
# quit the program
USER: [quit]
بشكل افتراضي، يمكنك إصدار الأوامر باستخدام [
و ]
كمحددات. ولكن يمكنك تغيير هذه إلى ما تريد:
convo.open_command = "{{"
convo.close_command = "}}"
يمكنك أيضًا الاتصال بنفسك بأي أسلوب (أو تعيين أي سمة) لفئة chatterstack نفسها، مباشرة من واجهة الدردشة:
# if you want to see what is currently in the conversation history
USER: [print_formatted_conversation]
# or how many tokens you have used so far
USER: [print_total_tokens]
# you can even pass arguments to commands
USER: [set_system_lock_index(-2)]
لذلك، في حين أن مثال برنامج الدردشة الأولي في بداية هذا الريبو قد يبدو مبسطًا في البداية، يمكنك أن ترى أنه كل ما تحتاجه حقًا، حيث يمكن استدعاء أي وظيفة تريدها تقريبًا من داخل الدردشة نفسها.
إذا كنت تريد كتابة الأوامر الخاصة بك، فإن chatterstack يوفر فئة واجهة بسيطة للقيام بذلك، تسمى ICommand
.
class ICommand :
def execute ( self ):
pass
في الأساس، تكتب الأمر الخاص بك كفئة، والتي ترث من فئة ICommand
، ولها طريقة "تنفيذ" (وهو ما تريد أن يحدث بالفعل عندما يتم استدعاء الأمر الخاص بك.)
هنا مثال:
class ExampleCommand ( ICommand ):
def execute ( self ):
print ( "An example command that prints this statement right here." )
إذا كان أمرك يحتاج إلى وسيطات، فيمكنك أيضًا إضافة التابع __init__
وتمريره *args
تمامًا كما يلي:
class ExampleCommand ( ICommand ):
def __init__ ( self , * args ):
self . args = args
def execute ( self ):
print ( "Example command that print this statement with this extra stuff:" , self . args )
آخر شيء عليك القيام به هو تعيين كلمة أو عبارة تشغيل للأمر الخاص بك عن طريق إضافتها إلى أسلوب init في فئة ChatterstackAdvanced.
class ChatterstackAdvanced ( Chatterstack ):
def __init__ ( self , ...)
# ...Lots of other code here...
# This command is already in the class:
self . command_handler . register_command ( 'save' , SaveConversationCommand ( self ))
# Add your new command
self . command_handler . register_command ( "example" , ExampleCommand )
يوجد حاليًا إصدار Javascript من Chatterstack، لكنني لم أجعله متاحًا بعد لأنني لا أعرف Javascript أيضًا، ولست واثقًا جدًا من موثوقيته. إذا كنت تعرف جافا سكريبت، وترغب في المساعدة، فيرجى إبلاغي بذلك!