This commit is contained in:
narawat lamaiin
2024-08-04 17:32:07 +07:00
parent d86468c6c8
commit 3a5c0f188a
2 changed files with 117 additions and 82 deletions

View File

@@ -213,7 +213,7 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
systemmsg =
"""
You are an website-based polite sommelier working for an online wine store. You are currently talking with the user.
Your task is to help the user choose the best wine that match the user preferences from your inventory.
Your task is to help the user choose the best wine from your inventory that matches their tastes.
Definitions:
"observation" is result of the preceding immediate action.
@@ -224,11 +224,9 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
You MUST follow the following guidelines:
- Generally speaking, your inventory has some wines from France, the United States, Australia, Spain, and Italy but you won't know which wines are in stock until you check your inventory.
- Use the "ask the user's preferences, then check inventory" strategy to help the user, as there are many wines in the inventory.
- Check inventory before recommending or suggesting wines to the user.
- Only recommending wine from your inventory.
- Use the "get to know the user's preferences, then check inventory" strategy to help the user, as there are many wines in the inventory.
- After recommending wine to the user, ask if there is anything else you can help with, but do not offer any additional services. If the user doesn't need anything else, say thank you and goodbye.
- Do not offer the user to try wine as you are internet-based agent.
- Do not ask the user about wine's flavors
You should follow the following guidelines as you see fit:
- If the user interrupts, prioritize the user.
@@ -248,14 +246,14 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
Good query example: black car, a stereo, 200 mile range, electric motor.
Good query example: How many car brand are from Asia?
- action_input: input to the action
- recommending_wine: Are you recommending wines to the user? Can be "Yes" or "No"
- mentioning_wine: Are you mentioning specific wine name to the user? Can be "Yes" or "No"
You should only respond in format as described below:
thought: ...
plan: ...
action_name: ...
action_input: ...
recommending_wine: ...
mentioning_wine: ...
Let's begin!
"""
@@ -270,31 +268,33 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
chathistory = vectorOfDictToText(a.chathistory)
checkinventory_flag = ""
usermsg =
"""
Context: $context
Your conversation with the user: $chathistory)
$checkinventory_flag
"""
response = nothing # placeholder for show when error msg show up
_prompt =
[
Dict(:name=> "system", :text=> systemmsg),
Dict(:name=> "user", :text=> usermsg)
]
for attempt in 1:10
usermsg =
"""
Context: $context
Your conversation with the user: $chathistory)
$checkinventory_flag
"""
_prompt =
[
Dict(:name=> "system", :text=> systemmsg),
Dict(:name=> "user", :text=> usermsg)
]
# put in model format
prompt = GeneralUtils.formatLLMtext(_prompt, "llama3instruct")
prompt *=
"""
<|start_header_id|>assistant<|end_header_id|>
"""
# put in model format
prompt = GeneralUtils.formatLLMtext(_prompt, "llama3instruct")
prompt *=
"""
<|start_header_id|>assistant<|end_header_id|>
"""
response = nothing # store for show when error msg show up
for attempt in 1:10
try
response = a.text2textInstructLLM(prompt)
responsedict = GeneralUtils.textToDict(response,
["thought", "plan", "action_name", "action_input", "recommending_wine"],
["thought", "plan", "action_name", "action_input", "mentioning_wine"],
rightmarker=":", symbolkey=true)
if responsedict[:action_name] ["CHATBOX", "CHECKINVENTORY"]
@@ -308,7 +308,7 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
end
# check if there are more than 1 key per categories
for i [:thought, :plan, :action_name, :action_input, :recommending_wine]
for i [:thought, :plan, :action_name, :action_input, :mentioning_wine]
matchkeys = GeneralUtils.findMatchingDictKey(responsedict, i)
if length(matchkeys) > 1
error("DecisionMaker has more than one key per categories")
@@ -316,20 +316,22 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
end
println("")
println("--> Yiem decisionMaker ", @__FILE__, " ", @__LINE__)
println("--> Yiem decisionMaker() ", @__FILE__, " ", @__LINE__)
pprintln(responsedict)
# check if LLM recommend wine before checking inventory
isMemEmpty = isempty(a.memory[:shortmem])
if occursin("Yes", responsedict[:recommending_wine]) && isMemEmpty &&
if occursin("Yes", responsedict[:mentioning_wine]) && isMemEmpty &&
responsedict[:action_name] != "CHECKINVENTORY"
checkinventory_flag = "You must check your inventory before recommending wine to the user."
checkinventory_flag = "Note: You must check your inventory before recommending wine to the user."
error( "You must check your inventory before recommending wine")
else
checkinventory_flag = ""
end
delete!(responsedict, :recommending_wine)
delete!(responsedict, :mentioning_wine)
return responsedict
return responsedict
catch e
io = IOBuffer()
showerror(io, e)
@@ -1220,7 +1222,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
systemmsg =
"""
You are an website-based polite sommelier working for an online wine store.
Your task is to help the user choose the best wine that match the user preferences from your inventory.
Your task is to help the user choose the best wine from your inventory that matches their tastes.
At each round of conversation, the user will give you the current situation:
Context: ...
@@ -1228,47 +1230,50 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
Your current thoughts in your mind: ...
You must follow the following guidelines:
- You won't know which wines are in stock until you check your inventory.
- Only recommending (suggesting) wine from your inventory.
- Your thoughts matter.
- Do not offer the user to try wine as you are internet-based agent.
- Do not ask the user about wine's flavors
You should then respond to the user with:
- chat: what do you want to say to the user based on the current situation
- mentioning_wine: Are you mentioning specific wine name to the user? Can be "Yes" or "No"
You should only respond in format as described below:
chat: ...
mentioning_wine: ...
Let's begin!
"""
context_1 = length(memory[:shortmem]) > 0 ? vectorOfDictToText(memory[:shortmem], withkey=false) : "None"
_chathistory = vectorOfDictToText(chathistory)
usermsg =
"""
Context: $context_1
Your earlier conversation with the user: $_chathistory)
Your thoughts: $(memory[:chatbox])
"""
_prompt =
[
Dict(:name=> "system", :text=> systemmsg),
Dict(:name=> "user", :text=> usermsg)
]
# put in model format
prompt = GeneralUtils.formatLLMtext(_prompt, "llama3instruct")
prompt *=
"""
<|start_header_id|>assistant<|end_header_id|>
"""
chathistory = vectorOfDictToText(chathistory)
checkinventory_flag = ""
response = nothing # placeholder for show when error msg show up
for attempt in 1:5
usermsg =
"""
Context: $context_1
Your earlier conversation with the user: $chathistory)
Your thoughts: $(memory[:chatbox])
$checkinventory_flag
"""
_prompt =
[
Dict(:name=> "system", :text=> systemmsg),
Dict(:name=> "user", :text=> usermsg)
]
# put in model format
prompt = GeneralUtils.formatLLMtext(_prompt, "llama3instruct")
prompt *=
"""
<|start_header_id|>assistant<|end_header_id|>
"""
try
response = text2textInstructLLM(prompt)
responsedict = GeneralUtils.textToDict(response,
["chat"],
responsedict = GeneralUtils.textToDict(response,["chat", "mentioning_wine"],
rightmarker=":", symbolkey=true)
for i [:chat]
@@ -1285,6 +1290,21 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
end
end
println("")
println("--> generatechat() ", @__FILE__, " ", @__LINE__)
pprintln(responsedict)
# check if LLM recommend wine before checking inventory
isMemEmpty = isempty(memory[:shortmem])
if occursin("Yes", responsedict[:mentioning_wine]) && isMemEmpty
checkinventory_flag = "Note: You must check your inventory before recommending wine to the user."
error( "You must check your inventory before recommending wine")
else
checkinventory_flag = ""
end
delete!(responsedict, :mentioning_wine)
result = responsedict[:chat]
return result