Chatterstack ist eine absolut einfache und intuitive Möglichkeit, mit den von der ChatGPT-API verwendeten „Konversations“-Variablen umzugehen und bietet Ihnen gleichzeitig erweiterte Funktionen.
Paket von pip installieren:
pip install chatterstack
Es gibt zwei Optionen für Chatterstack. Die Basisbibliothek und die erweiterte Bibliothek, die die Basis erweitert.
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 ()
Die ChatGPT-APIs verwenden „Konversations“-Variablen, um Ihre Interaktionen mit dem Bot zu verfolgen. Dies ist eine Liste von Wörterbüchern, wobei jedes Wörterbuch eine Wendung im Gespräch darstellt.
Dadurch ist Ihr Programm mit Dingen wie diesen übersät:
# 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" ])
Lächerlich.
Wenn Sie etwas Fortgeschritteneres tun möchten, wie zum Beispiel „Konversationsvariable auf maximal 8 Nachrichten beschränken“ oder „Systemnachricht immer als aktuellste Nachricht in der Konversation festlegen“ ... nun, ich erspare Ihnen den Codeausschnitt dafür diese.
Da viele Aspekte dieser Wörterbücher sehr vorhersehbar sind und wir mit ihnen meist nur eine Handvoll grundlegender Aufgaben erledigen ...
...das bedeutet, dass wir einen Großteil dieses Durcheinanders auf eine Art und Weise abstrahieren können, die die Verwendung viel intuitiver macht – und gleichzeitig im Grunde die gesamte inhärente Flexibilität beibehält! Das ist eine seltene Sache.
Dies ist ein voll funktionsfähiges Chatbot-Programm, das Chatterstack verwendet:
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 ()
Das ist das Ganze!
So würde diese Konversation im Terminal aussehen:
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]
Diese Bibliothek ist so konzipiert, dass sie intuitiv und flexibel ist, sodass Sie das Verhalten oder Aussehen auf vielfältige Weise ganz einfach ändern können, je nachdem, was Ihren Anforderungen entspricht. Hier sind einige grundlegende Beispiele für den Aufenthalt im Terminal:
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 )
Jetzt findet Ihre Konversation mit GPT-4 statt und die Konversation sieht mit der Anzahl der Token wie folgt aus:
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
Weitere Informationen zu den aktuellen Standardeinstellungen und verschiedenen Methoden zu deren Änderung finden Sie weiter unten im Abschnitt zum Senden von Nachrichten an die API
Die Methode user_input()
ist mit der Methode input()
von Python identisch, außer dass sie die Eingaben des Benutzers automatisch als korrekt formatiertes Diktat an Ihre Konversationsvariable anhängt.
convo . user_input ()
Wie oben zu sehen ist, fordert diese Methode den Benutzer standardmäßig mit „USER:“ auf, aber Sie können es nach Ihren Wünschen ändern
convo . user_input ( "Ask the bot: " )
Ask the bot:
Möglicherweise verwenden Sie das Terminal nicht.
Oder vielleicht möchten Sie die Eingabe irgendwie ändern, bevor Sie sie anhängen.
Es gibt mehrere Möglichkeiten, jede Zeichenfolgenvariable als korrekt formatiertes Diktat zur Konversation hinzuzufügen:
# 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" )
Es gibt auch .insert(), wenn Sie eine Nachricht an einem bestimmten Index hinzufügen möchten, anstatt sie an das Ende der Konversation anzuhängen:
# Here's the format
convo . insert ( index , role , content )
# example
convo . insert ( 4 , "system" , "IMPORTANT: Remember to not apologize to the user so much" )
Die Chatterstack-Methode „send_to_bot“ ist ein standardmäßiger OpenAI-API-Aufruf, aber sie ist einfacher zu verwenden und erledigt im Hintergrund eine Menge praktischer Dinge für Sie. Nennen Sie es so:
convo . send_to_bot ()
Das ist es!
Es übernimmt für Sie die Übergabe aller Standardwerte und das Anhängen der Antwort an Ihre Konversation. Es speichert auch die Token-Zählungen für Sie (und in der fortgeschrittenen Klasse noch viel mehr).
Standardmäßig verwendet Chatterstack diese Werte:
model = "gpt-3.5-turbo" ,
temperature = 0.8 ,
top_p = 1 ,
frequency_penalty = 0 ,
presence_penalty = 0 ,
max_tokens = 200
Es gibt mehrere Möglichkeiten, diese zu ändern. Wählen Sie, was für Sie am bequemsten ist.
Der naheliegendste Weg besteht darin, sie beim Aufruf einfach als Argumente zu übergeben. Wenn Sie beispielsweise GPT-4 und maximal 800 Token wünschen:
convo . send_to_bot ( model = "gpt-4" , max_tokens = 800 )
Dieser Ansatz eignet sich hervorragend, wenn Sie nur einen Anruf mit verschiedenen Werten tätigen möchten.
Wenn Sie jedoch wissen, dass Sie unterschiedliche Werte für die gesamte Konversation wünschen, können Sie diese in Großbuchstaben oben in Ihrer Datei definieren und chatterstack mit dem globals()
-Diktat wie folgt initialisieren:
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 ()
Wenn Sie schließlich nur den Standard-OpenAI-Aufruf verwenden möchten, können Sie dies trotzdem tun! Übergeben Sie ihm einfach das .list-Attribut Ihres Chatterstacks, bei dem es sich um die Rohliste der Wörterbücher handelt:
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 ,
)
Super einfach:
# Print the "content" of the last message
convo . print_last_message ()
Oder wenn Sie zuerst die Zeichenfolge formatieren möchten ...
# 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 )
Oh ja. Wir verfolgen die Token.
# 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
Es stehen verschiedene Methoden zur Verfügung, um die Reihenfolge des Gesprächs zu manipulieren. Hier sind einige davon:
# 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 )
Aber viel wichtiger: Methoden zur feinkörnigen Steuerung der Systemmeldung.
Systemnachrichten werden normalerweise für Anweisungen verwendet, und oft kann es hilfreich sein, die Anweisungen „aktueller“ in der Konversation erscheinen zu lassen. Das bedeutet, diese Nachricht zu verfolgen und zu verschieben, ohne die anderen zu stören.
# 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 )
Und mein persönlicher Favorit – im Grunde der ganze Grund, warum ich diese ganze Bibliothek geschrieben habe –
convo . set_system_lock_index ( - 1 )
Durch die Übergabe eines positiven Werts an diese Funktion wird die Systemnachricht im Index gesperrt. Immer wenn Nachrichten hinzugefügt, entfernt oder neu angeordnet werden, wird sichergestellt, dass die Systemnachricht an dieser Position bleibt (oder so nah wie möglich daran).
Wenn Sie ihm einen negativen Wert übergeben, wird Ihre Systemnachricht ab dem Ende der Konversation an den Index gebunden (das obige Beispiel würde dazu führen, dass es sich immer um die vorletzte Nachricht in der Konversation handelt).
HINWEIS: Derzeit gehen diese Methoden davon aus, dass Sie nur eine Systemmeldung haben
Drucken Sie eine formatierte Version Ihrer Konversation (ideal zum Debuggen)
convo . print_formatted_conversation
Standardmäßig wird Folgendes gedruckt:
System: You are a helpful assistant.
User: hi!
Assistant: Hi! How can I help you?
Sehen Sie sich die Gesamtstatistik Ihres Gesprächs an.
convo . summary ()
SUMMARY:
{'total_messages': 2, 'prompt_tokens': 200, 'assistant_tokens': 78, 'total_tokens': 278}
Die Chatterstack Advanced-Klasse erweitert die Basisklasse und verfügt über viel mehr integrierte Funktionen. Es ist auch leicht erweiterbar.
Warnung : Die jüngsten Änderungen am Modell scheinen diese Funktionalität beeinträchtigt zu haben. Es kann sein, dass es funktioniert oder auch nicht, wenn Sie es versuchen. Es muss wahrscheinlich neu geschrieben werden, damit Funktionsaufrufe wieder konsistent funktionieren
Sie können dem Bot jetzt sagen: „Erinnere mich daran, den Müll um 20 Uhr rauszubringen“ oder „Erinnere mich daran, den Müll in einer Stunde rauszubringen“.
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!
Der Bot kann so viele Erinnerungen verfolgen, wie Sie möchten.
Geben Sie Befehle aus der Benutzereingabe aus:
# saves the conversation to a txt file
USER: [save]
# quit the program
USER: [quit]
Standardmäßig geben Sie Befehle aus, indem Sie [
und ]
als Trennzeichen verwenden. Sie können diese jedoch beliebig ändern:
convo.open_command = "{{"
convo.close_command = "}}"
Sie können auch direkt über die Chat-Oberfläche eine beliebige Methode der Chatterstack-Klasse selbst aufrufen (oder ein beliebiges Attribut festlegen):
# 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)]
Auch wenn das erste Chat-Programmbeispiel zu Beginn dieses Repositorys auf den ersten Blick vielleicht simpel erschien, können Sie sehen, dass es wirklich alles ist, was Sie brauchen, da fast jede gewünschte Funktionalität tatsächlich aus dem Chat selbst heraus aufgerufen werden kann.
Wenn Sie Ihre eigenen Befehle schreiben möchten, stellt Chatterstack dafür eine einfache Schnittstellenklasse namens ICommand
zur Verfügung.
class ICommand :
def execute ( self ):
pass
Grundsätzlich schreiben Sie Ihren Befehl als Klasse, die von der ICommand
-Klasse erbt und über eine „execute“-Methode verfügt (was tatsächlich passieren soll, wenn Ihr Befehl aufgerufen wird).
Hier ist ein Beispiel:
class ExampleCommand ( ICommand ):
def execute ( self ):
print ( "An example command that prints this statement right here." )
Wenn Ihr Befehl Argumente benötigt, können Sie auch eine __init__
Methode hinzufügen und ihr *args
genau so übergeben:
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 )
Als letztes müssen Sie Ihrem Befehl ein Auslösewort oder eine Auslösephrase zuweisen, indem Sie es der Init -Methode in der ChatterstackAdvanced-Klasse hinzufügen.
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 )
Derzeit gibt es eine Javascript-Version von Chatterstack, aber ich habe sie noch nicht zur Verfügung gestellt, da ich Javascript nicht so gut kenne und mir nicht so sicher bin, ob es zuverlässig ist. Wenn Sie Javascript kennen und helfen möchten, lassen Sie es mich bitte wissen!