GoalChain은 인간-LLM 및 LLM-LLM 상호 작용을 위한 목표 지향적 대화 흐름을 가능하게 하는 간단하지만 효과적인 프레임워크입니다.
pip install goalchain
대화 흐름의 기초가 되는 Field
, ValidationError
, Goal
및 GoalChain
클래스를 가져오겠습니다.
from goalchain import Field , ValidationError , Goal , GoalChain
이 예에서는 고객이 원하는 제품 주문에 대한 정보를 수집하는 것을 목표로 하는 AI 도우미를 만듭니다. Goal
의 하위 항목인 ProductOrderGoal
내의 Field
객체를 사용하여 수집할 정보를 정의합니다.
또한 수량에 대한 유효성 검사기를 정의합니다(int로 유형 캐스팅한 후). ValidationError
는 오류 메시지를 대화로 다시 전달하는 데 사용됩니다. 이러한 메시지는 사람이 읽을 수 있어야 합니다.
format_hint
는 LLM의 JSON 모드 출력에 대한 자연어 유형 힌트입니다.
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 )
고객이 마음을 바꾸는 경우 OrderCancelGoal
이라는 또 다른 Goal
하위 클래스를 만들어 보겠습니다. 진행 중인 주문을 고객이 취소하는 선택적 이유를 요청합니다. 설명에서 필드가 "(선택 사항)"임을 지정함으로써 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
은 또 다른 "to ..." 명령문입니다. 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
개체 없이 골을 넣을 수 있는지 궁금해했을 수도 있습니다. 당신은 할 수 있습니다! 이러한 목표는 연결로만 정의된 라우팅 목표입니다. 이는 예를 들어 음성 메일 메뉴 시스템에 유용합니다.
목표를 목표 자체에 연결할 수 있는지 궁금할 수도 있습니다. 당신은 할 수 있습니다! 이는 예를 들어 다양한 순차적 사용자 입력이 필요한 Goal
상속 개체와 함께 confirm=False
사용할 때 유용합니다.
체인 연결도 가능합니다(예: goal.connect(...).connect(...).connect(...)
마지막으로 GoalChain
사용하여 초기 목표를 설정하고 AI 영업 도우미를 테스트해 보겠습니다!
goal_chain = GoalChain ( product_order_goal )
각 목표는 LiteLLM에 의해 활성화된 별도의 LLM API를 사용할 수 있으며, 필수 환경 변수가 설정된 경우 지원되는 모델 제공자의 모든 모델을 사용할 수 있습니다.
기본 모델은 "gpt-4-1106-preview"
입니다. 즉,
product_order_goal = ProductOrderGoal (...
model = "gpt-4-1106-preview" ,
json_model = "gpt-4-1106-preview"
)
params
사용하여 LiteLLM 공통 매개변수를 전달할 수도 있습니다. 예를 들면 다음과 같습니다.
product_order_goal = ProductOrderGoal (...
model = "gpt-4-1106-preview" ,
json_model = "gpt-4-1106-preview" ,
params = { "temperature" : 1.5 , "max_tokens" : 10 }
)
VLLM을 사용하여 로컬 모델을 호출하기 위해 params
사용할 수도 있습니다.
기본 "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은 응답 유형( message
또는 data
), 응답 내용(지금은 미리 준비된 응답) 및 현재 Goal
상속 개체가 포함된 dict
반환합니다.
잠재적 구매에 대해 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
완료된 후에만 입력을 검증합니다. 진행하면서 입력의 유효성을 검사하려면 다음 두 가지 옵션이 있습니다.
Field
하나만 있는 Goal
사용하고, confirm=False
사용하세요. 단일 Goal
에서 여러 필드를 사용하는 대신 이러한 목표를 연결하세요.
소프트 프롬프트를 사용하세요(예: 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>}
반환된 콘텐츠는 LLM JSON 모드의 출력에서 구문 분석된 사전입니다. 키는 필드 인스턴스 이름입니다. 이제 데이터를 사용하여 가상의 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 페이지를 방문하세요.