Chatterstack เป็นวิธีที่ง่ายและใช้งานง่ายในการจัดการตัวแปร "การสนทนา" ที่ใช้โดย ChatGPT API ในขณะเดียวกันก็ให้ฟังก์ชันขั้นสูงแก่คุณด้วย
ติดตั้งแพ็คเกจจาก pip:
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 API ใช้ตัวแปร "การสนทนา" เพื่อติดตามการโต้ตอบของคุณกับบ็อต นี่คือรายการพจนานุกรม โดยแต่ละพจนานุกรมจะแสดงถึงจุดเปลี่ยนในการสนทนา
สิ่งนี้ทำให้โปรแกรมของคุณเต็มไปด้วยสิ่งต่าง ๆ เช่นนี้:
# 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 ข้อความ" หรือ "ทำให้ข้อความของระบบเป็นข้อความล่าสุดในการสนทนาเสมอ"... ฉันจะสำรองข้อมูลโค้ดสำหรับ เหล่านั้น.
เนื่องจากพจนานุกรมเหล่านี้มีหลายแง่มุมที่สามารถคาดเดาได้อย่างมาก และเรามักจะทำงานพื้นฐานเพียงไม่กี่อย่างกับพจนานุกรมเหล่านั้น...
...ซึ่งหมายความว่าเราสามารถขจัดความยุ่งเหยิงนี้ออกไปได้จริง ๆ ในลักษณะที่ทำให้ใช้งานง่ายขึ้นมาก - ขณะเดียวกันก็รักษาความยืดหยุ่นโดยธรรมชาติเอาไว้ด้วย! นั่นเป็นสิ่งที่หายากที่จะทำได้
นี่เป็นโปรแกรมแชทบอทที่ทำงานได้อย่างสมบูรณ์โดยใช้ 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
มีข้อมูลเพิ่มเติมเกี่ยวกับค่าเริ่มต้นปัจจุบันและวิธีการต่างๆ ในการเปลี่ยนแปลงด้านล่างในส่วนเกี่ยวกับการส่งข้อความไปยัง API
เมธอด user_input()
เหมือนกับเมธอด python input()
ยกเว้นแต่ว่าจะผนวกอินพุตของผู้ใช้เป็น dict ที่มีรูปแบบถูกต้องต่อท้ายตัวแปรการสนทนาของคุณโดยอัตโนมัติ
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()
dict เช่นนี้
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 ขยายคลาสพื้นฐานและมีฟังก์ชันการทำงานในตัวอีกมากมาย นอกจากนี้ยังสามารถขยายได้อย่างง่ายดาย
คำเตือน : การเปลี่ยนแปลงล่าสุดของโมเดลดูเหมือนจะทำให้ฟังก์ชันการทำงานนี้เสียหาย มันอาจจะหรืออาจจะไม่ทำงานเมื่อคุณลอง มีแนวโน้มว่าจะต้องเขียนใหม่เพื่อใช้การเรียกฟังก์ชันเพื่อให้ทำงานอย่างต่อเนื่องอีกครั้ง
ตอนนี้คุณสามารถบอกบอทได้ว่า "เตือนฉันให้เอาขยะออกไปตอน 20.00 น." หรือ "เตือนให้ฉันเอาขยะออกไปในหนึ่งชั่วโมง"
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)]
ดังนั้น แม้ว่าตัวอย่างโปรแกรมแชทเริ่มต้นในช่วงเริ่มต้นของ repo นี้อาจดูเรียบง่ายในตอนแรก คุณจะเห็นว่านี่คือทั้งหมดที่คุณต้องการจริงๆ เนื่องจากฟังก์ชันเกือบทั้งหมดที่คุณต้องการสามารถเรียกใช้จากภายในแชทได้จริง
หากคุณต้องการเขียนคำสั่งของคุณเอง chatterstack มีคลาสอินเทอร์เฟซที่เรียบง่ายให้ดำเนินการดังกล่าว เรียกว่า ICommand
class ICommand :
def execute ( self ):
pass
โดยพื้นฐานแล้ว คุณเขียนคำสั่งของคุณเป็นคลาส ซึ่งสืบทอดมาจากคลาส ICommand
และมีเมธอด "execute" (ซึ่งเป็นสิ่งที่คุณต้องการให้เกิดขึ้นจริงเมื่อมีการเรียกใช้คำสั่งของคุณ)
นี่คือตัวอย่าง:
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 )
ขณะนี้มี Chatterstack เวอร์ชัน Javascript แต่ฉันยังไม่ได้เผยแพร่เพราะฉันไม่รู้จัก Javascript เช่นกัน และฉันไม่ค่อยมั่นใจในความน่าเชื่อถือ หากคุณรู้จัก Javascript และต้องการความช่วยเหลือ โปรดแจ้งให้เราทราบ!