GoalChain เป็นเฟรมเวิร์กที่เรียบง่ายแต่มีประสิทธิภาพในการเปิดใช้งานโฟลว์การสนทนาที่มุ่งเน้นเป้าหมายสำหรับการโต้ตอบระหว่างมนุษย์กับ LLM และ LLM-LLM
pip install goalchain
มานำเข้าคลาส Field
, ValidationError
, Goal
และ GoalChain
ซึ่งเป็นพื้นฐานสำหรับโฟลว์การสนทนา
from goalchain import Field , ValidationError , Goal , GoalChain
ในตัวอย่างนี้ เราจะสร้างผู้ช่วย AI ซึ่งมีเป้าหมายเพื่อรวบรวมข้อมูลจากลูกค้าเกี่ยวกับคำสั่งซื้อผลิตภัณฑ์ที่ต้องการ เรากำหนดข้อมูลที่จะรวบรวมโดยใช้วัตถุ Field
ภายใน ProductOrderGoal
ซึ่งเป็นลูกของ Goal
:
นอกจากนี้เรายังกำหนดเครื่องมือตรวจสอบปริมาณ (หลังจากพิมพ์ประเภทเป็น int) ValidationError
ใช้เพื่อส่งข้อความแสดงข้อผิดพลาดกลับไปยังการสนทนา ข้อความเหล่านี้ควรเป็นข้อความที่มนุษย์สามารถอ่านได้
format_hint
เป็นคำใบ้ประเภทภาษาธรรมชาติสำหรับเอาต์พุตโหมด JSON ของ LLM
def quantity_validator ( value ):
try :
value = int ( value )
except ( ValueError , TypeError ):
raise ValidationError ( "Quantity must be a valid number" )
if value <= 0 :
raise ValidationError ( "Quantity cannot be less than one" )
if value > 100 :
raise ValidationError ( "Quantity cannot be greater than 100" )
return value
class ProductOrderGoal ( Goal ):
product_name = Field ( "product to be ordered" , format_hint = "a string" )
customer_email = Field ( "customer email" , format_hint = "a string" )
quantity = Field ( "quantity of product" , format_hint = "an integer" , validator = quantity_validator )
ในกรณีที่ลูกค้าเปลี่ยนใจ เรามาสร้างคลาสย่อย Goal
อีกคลาสที่เรียกว่า OrderCancelGoal
เราจะขอเหตุผลเพิ่มเติมสำหรับการยกเลิกคำสั่งซื้อที่กำลังดำเนินอยู่ของลูกค้า ด้วยการระบุว่าฟิลด์นั้นเป็น "(ไม่บังคับ)" ในคำอธิบาย LLM จะรู้ว่าไม่จำเป็นต้องบรรลุเป้าหมาย
class OrderCancelGoal ( Goal ):
reason = Field ( "reason for order cancellation (optional)" , format_hint = "a string" )
โปรดทราบว่าชื่อออบเจ็กต์ฟิลด์ เช่น product_name
จะถูกส่งโดยตรงไปยังพรอมต์ LLM และดังนั้นจึงเป็นส่วนหนึ่งของงานวิศวกรรมพร้อมต์ เช่นเดียวกับสตริงอื่นๆ
โดยพื้นฐานแล้ว คลาสที่เรากำหนดนั้นเหมือนกับแบบฟอร์มที่ลูกค้ากรอก แต่ไม่มีคำแนะนำ มาเพิ่มสิ่งเหล่านั้นด้วยการยกตัวอย่างคลาสเป็นวัตถุ
product_order_goal = ProductOrderGoal (
label = "product_order" ,
goal = "to obtain information on an order to be made" ,
opener = "I see you are trying to order a product, how can I help you?" ,
out_of_scope = "Ask the user to contact sales team at [email protected]"
)
order_cancel_goal = OrderCancelGoal (
label = "cancel_current_order" ,
goal = "to obtain the reason for the cancellation" ,
opener = "I see you are trying to cancel the current order, how can I help you?" ,
out_of_scope = "Ask the user to contact the support team at [email protected]" ,
confirm = False
)
เรากำหนด
opener
เริ่มต้น - สิ่งที่ผู้ช่วย AI จะใช้โดยไม่ได้ป้อนข้อมูลล่วงหน้า ธง confirm
จะกำหนดว่าผู้ช่วย AI จะขอการยืนยันหรือไม่เมื่อมีข้อมูลที่จำเป็นทั้งหมดที่กำหนดโดยใช้ออบเจ็กต์ Field
มันเป็น True
โดยค่าเริ่มต้น เราไม่ต้องการการยืนยันสำหรับเป้าหมายการยกเลิกคำสั่งซื้อ เนื่องจากเป็นการยืนยันในตัวอยู่แล้ว
ต่อไปเราต้องเชื่อมโยงเป้าหมายเข้าด้วยกัน
product_order_goal . connect ( goal = order_cancel_goal ,
user_goal = "to cancel the current order" ,
hand_over = True ,
keep_messages = True )
user_goal
เป็นอีกหนึ่งคำสั่ง "ถึง ... " หากไม่มี hand_over=True
เจ้าหน้าที่ AI จะตอบกลับด้วย opener
กระป๋อง การตั้งค่าเป็น True
ช่วยให้การสนทนาดำเนินไปอย่างราบรื่น บางครั้งคุณอาจต้องการคำตอบสำเร็จรูป แต่บางครั้งก็ไม่ต้องการ
keep_messages=True
หมายความว่า order_cancel_goal
จะได้รับประวัติการสนทนาทั้งหมดกับ product_order_goal
มิฉะนั้นจะถูกล้างข้อมูล ขอย้ำอีกครั้งว่าบางครั้งอาจต้องการล้างประวัติการสนทนา เช่น เมื่อจำลองบุคลิกของ AI ที่แตกต่างกัน
พิจารณาความเป็นไปได้ของลูกค้าที่ไม่แน่ใจจริงๆ เราควรให้ทางเลือกแก่พวกเขาในการ "ยกเลิกการยกเลิก"
order_cancel_goal . connect ( goal = product_order_goal ,
user_goal = "to continue with the order anyway" ,
hand_over = True ,
keep_messages = True )
เมื่อถึงจุดหนึ่ง คุณอาจสงสัยว่าคุณสามารถสร้างเป้าหมายโดยไม่มีวัตถุ Field
ได้หรือไม่ คุณสามารถ! เป้าหมายดังกล่าวเป็นเป้าหมายการกำหนดเส้นทางที่กำหนดไว้เฉพาะการเชื่อมต่อที่มีเท่านั้น สิ่งนี้มีประโยชน์เช่นในระบบเมนูวอยซ์เมล
คุณอาจสงสัยว่าคุณสามารถเชื่อมโยงเป้าหมายเข้ากับเป้าหมายได้หรือไม่ คุณสามารถ! สิ่งนี้มีประโยชน์ เช่น เมื่อใช้ confirm=False
กับอ็อบเจ็กต์การสืบทอด Goal
ซึ่งคุณต้องการอินพุตผู้ใช้ตามลำดับของความหลากหลายบางอย่าง
คุณยังสามารถเชื่อมต่อแบบลูกโซ่ได้ เช่น goal.connect(...).connect(...).connect(...)
สุดท้ายนี้ ลองใช้ GoalChain
เพื่อกำหนดเป้าหมายเริ่มต้นและทดสอบผู้ช่วยฝ่ายขาย AI ของเรากันดีกว่า!
goal_chain = GoalChain ( product_order_goal )
โปรดทราบว่าแต่ละเป้าหมายสามารถใช้ LLM API แยกต่างหากตามที่ LiteLLM เปิดใช้งาน และหากคุณได้ตั้งค่าตัวแปรสภาพแวดล้อมที่จำเป็น คุณสามารถใช้โมเดลใดก็ได้จากผู้ให้บริการโมเดลที่รองรับ
โมเดลเริ่มต้นคือ "gpt-4-1106-preview"
นั่นคือ:
product_order_goal = ProductOrderGoal (...
model = "gpt-4-1106-preview" ,
json_model = "gpt-4-1106-preview"
)
คุณยังสามารถส่งผ่านพารามิเตอร์ทั่วไปของ LiteLLM ได้โดยใช้ params
เช่น:
product_order_goal = ProductOrderGoal (...
model = "gpt-4-1106-preview" ,
json_model = "gpt-4-1106-preview" ,
params = { "temperature" : 1.5 , "max_tokens" : 10 }
)
คุณยังสามารถใช้ params
เพื่อเรียกโมเดลในเครื่องโดยใช้ VLLM
เมื่อใช้โมเดล "gpt-4-1106-preview"
เริ่มต้น อย่าลืมตั้งค่าตัวแปรสภาพแวดล้อม OPENAI_API_KEY
import os
os . environ [ "OPENAI_API_KEY" ] = "sk-ABC..."
หมายเหตุ: รหัสจนถึงขณะนี้มีอยู่เป็นส่วนสำคัญ วางลงในสมุดบันทึก Jupyter โดยนำหน้าด้วย !pip install goalchain
เพื่อเริ่มต้นด้วยตัวอย่างสดด้านล่าง
โดยปกติแล้วผู้ใช้จะแจ้งตัวแทน AI ก่อน แต่หากไม่เป็นเช่นนั้น เราจะเรียก get_response
โดยไม่มีอาร์กิวเมนต์ใดๆ หรือใช้ None
เป็นอาร์กิวเมนต์:
goal_chain . get_response ()
{'type': 'message',
'content': 'Great choice! Could you please provide me with your email address to proceed with the order?',
'goal': <__main__.ProductOrderGoal at 0x7f8c8b687110>}
GoalChain ส่งคืน dict
ที่มีประเภทของการตอบกลับ ( message
หรือ data
) เนื้อหาของการตอบกลับ (ตอนนี้เป็นเพียงการตอบกลับสำเร็จรูปของเรา) และอ็อบเจ็กต์การสืบทอด Goal
ปัจจุบัน
ลองสอบถามผู้ช่วย AI ของเราเกี่ยวกับการซื้อที่เป็นไปได้
goal_chain . get_response ( "Hi, I'd like to buy a vacuum cleaner" )
{'type': 'message',
'content': 'Great! Could you please provide your email address so we can send the confirmation of your order?',
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
ผู้ช่วย AI กำลังทำงานเพื่อให้บรรลุเป้าหมายปัจจุบัน และรวบรวมข้อมูลที่จำเป็นสำหรับคำสั่งซื้อ
goal_chain . get_response ( "Sure, it is [email protected]" )
{'type': 'message',
'content': 'Thank you, John. Which model of vacuum cleaner would you like to order?',
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
goal_chain . get_response ( "The 2000XL model" )
{'type': 'message',
'content': 'How many of the 2000XL model would you like to order?',
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
มาทดสอบกันว่าผู้ช่วย AI ของเราสามารถรองรับการยกเลิกคำสั่งซื้อปัจจุบันได้หรือไม่
goal_chain . get_response ( "Actually I changed my mind, cancel this order" )
{'type': 'message',
'content': 'Of course, I can assist with that. Could you please tell me the reason for the cancellation?',
'goal': <__main__.OrderCancelGoal at 0x7ff0fb275650>}
มันได้ผล โปรดทราบว่าเป้าหมายที่ส่งคืนขณะนี้เป็นประเภท OrderCancelGoal
เราเปลี่ยนเป้าหมายแล้ว มาทดสอบว่าเราสามารถเปลี่ยนกลับได้หรือไม่
goal_chain . get_response ( "Actually, yeah, I would like to buy the vacuum cleaner" )
{'type': 'message',
'content': 'Understood. How many of the 2000XL model would you like to order?',
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
เรากลับมาที่ ProductOrderGoal
goal_chain . get_response ( "1 please" )
{'type': 'message',
'content': 'To confirm, you would like to order one 2000XL vacuum cleaner and the order will be sent to [email protected], is that correct?',
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
ผู้ช่วย AI ยืนยันคำสั่งซื้อของเรา หากเราไม่ชอบพฤติกรรมนี้ เราจะใช้ confirm=False
มาดูกันว่าผู้ช่วยจะตอบสนองต่อคำค้นหาที่อยู่นอกขอบเขตอย่างไร
goal_chain . get_response ( "Is it a good vacuum cleaner? What do you think?" )
{'type': 'message',
'content': "For product reviews and additional information, I recommend contacting our sales team at [email protected]. They can help with your inquiries. Meanwhile, can you please confirm if you'd like to proceed with the order for one 2000XL vacuum cleaner to [email protected]?",
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
ผู้ช่วย AI นำเราไปยังกล่องจดหมายของทีมขายตามที่กำหนดไว้ก่อนหน้านี้ และย้ำการยืนยันอีกครั้ง
แต่มาโยนลูกบอลโค้งกันเถอะ...
goal_chain . get_response ( "Ok, I'd actually like to make that an order of 500" )
{'type': 'message',
'content': "Just to clarify, you'd like to order 500 units of the 2000XL vacuum cleaner, with the order confirmation sent to [email protected]. Is that correct?",
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
goal_chain . get_response ( "Yes" )
{'type': 'message',
'content': 'I’m sorry, but I need to inform you that the quantity cannot be greater than 100 for an order. If you would like to proceed with an order within this limit, please let me know.',
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
เครื่องมือตรวจสอบที่เราใช้ให้ข้อมูลที่เพียงพอแก่ผู้ช่วย AI เพื่อชี้แจงว่าเหตุใดจึงไม่สามารถประมวลผลปริมาณนี้ผ่านข้อความ ValidationError
โปรดทราบว่า GoalChain จะตรวจสอบความถูกต้องของอินพุตเมื่อ Goal
เสร็จสมบูรณ์แล้วเท่านั้น ด้วยเหตุผลด้านประสิทธิภาพของโทเค็นและประสิทธิภาพ หากคุณต้องการตรวจสอบอินพุตทันที คุณมีสองตัวเลือก:
ใช้ Goal
ที่มีเพียง Field
เดียว และ confirm=False
เชื่อมโยงเป้าหมายเหล่านี้แทนที่จะใช้หลายช่องใน Goal
เดียว
ใช้ soft-prompt เช่น quantity = Field("quantity of product (no more than 100)", format_hint="an integer")
วิธีการนี้ไม่สามารถป้องกันความผิดพลาดได้ ดังนั้นจึงยังคงแนะนำให้ใช้เครื่องมือตรวจสอบความถูกต้อง อย่างไรก็ตามผู้ใช้จะได้รับการตอบรับทันที
มาทำออร์เดอร์ให้เสร็จกันเถอะ
goal_chain . get_response ( "Alright, I'll guess I'll just go with 1" )
{'type': 'message',
'content': 'To confirm, you would like to order one 2000XL vacuum cleaner and the order will be sent to [email protected], is that correct?',
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
goal_chain . get_response ( "That's right" )
{'type': 'data',
'content': {'customer_email': '[email protected]',
'product_name': '2000XL',
'quantity': 1},
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
เนื้อหาที่ส่งคืนเป็นพจนานุกรมที่แยกวิเคราะห์จากเอาต์พุตของโหมด JSON ของ LLM คีย์คือชื่ออินสแตนซ์ฟิลด์ของเรา ตอนนี้เราสามารถใช้ข้อมูลเพื่อดำเนินการบางอย่างได้ เช่น ประมวลผลลำดับเครื่องดูดฝุ่น 2000XL สมมุติของเรา
โปรดทราบว่าในความเป็นจริง หากคุณกำลังสร้างระบบดังกล่าว คุณจะต้องตั้งเป้าหมายการค้นหาผลิตภัณฑ์โดยเฉพาะ เพื่อไม่ให้มีชื่อผลิตภัณฑ์ที่กำหนดเองหรือไร้ความหมาย
มาส่งคำยืนยันของเราว่าคำสั่งซื้อได้รับการประมวลผลผ่าน simulate_response
แล้ว นอกจากนี้ เรายังใช้ rephrase = True
เพื่อเรียบเรียงเอาต์พุตใหม่ ซึ่งจะปรากฏเป็นธรรมชาติมากขึ้นในกรณีที่ลูกค้าโต้ตอบกับเป้าหมายบ่อยครั้ง
goal_chain . simulate_response ( f"Thank you for ordering from Acme. Your order will be dispatched in the next 1-3 business days." , rephrase = True )
{'type': 'message',
'content': 'We appreciate your purchase with Acme! Rest assured, your order will be on its way within the next 1 to 3 business days.',
'goal': <__main__.ProductOrderGoal at 0x7ff0fb283090>}
ณ จุดนี้ เราอาจสิ้นสุดเซสชันหรือเชื่อมต่อกลับไปยังเมนูหรือเป้าหมายการกำหนดเส้นทางเพื่อรับข้อมูลเพิ่มเติม
หากคุณต้องการปรับแต่งหรือสนับสนุน GoalChain หรือรายงานปัญหาใดๆ โปรดไปที่หน้า GitHub