This commit is contained in:
narawat lamaiin
2024-07-16 15:32:26 +07:00
parent fdc50d1b90
commit 37a9a38796
4 changed files with 132 additions and 64 deletions

View File

@@ -174,23 +174,59 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
# {"thought"
# """
# systemmsg =
# """
# You are a helpful sommelier working for a wine store.
# Your task is to help the user choose the best wine that match the user preferences from your inventory.
# You are also eager to improve your helpfulness.
# You must follow the following guidelines:
# - Get to know how much the user willing to spend
# - Get to know type of wine the user is looking for e.g. red, white, sparkling, rose, dessert, fortified
# - Get to know what occasion the user is buying wine for
# - Get to know what characteristics of wine the user is looking for e.g. tannin, sweetness, intensity, acidity
# - Get to know what food the user will have with wine
# At each round of conversation, the user will give you the current situation:
# Context: ...
# Your earlier conversation with the user: ...
# You should then respond to the user with interleaving Thought, Plan, Action and Observation:
# - thought:
# 1) State your reasoning about the current situation.
# - plan: Based on the current situation, what would you do to complete the task? Be specific.
# - action (Must be aligned with your plan): Can be one of the following functions:
# 1) CHATBOX[text], which you can use to talk with the user. "text" is in verbal English.
# 2) WINESTOCK[query], which you can use to find info about wine in your inventory. "query" is a search term in verbal English.
# - observation: result of the action.
# You should only respond in format as described below:
# thought: ...
# plan: ...
# action_name: ...
# action_input: ...
# observation: ...
# Let's begin!
# """
systemmsg =
"""
You are a helpful sommelier working for a wine store.
Your task is to help the user choose the best wine that match the user preferences from your inventory.
You are also eager to improve your helpfulness.
You must follow the following guidelines:
At each round of conversation, the user will give you the current situation:
Context: ...
Your earlier conversation with the user: ...
You should follow the following guidelines:
- Get to know how much the user willing to spend
- Get to know type of wine the user is looking for e.g. red, white, sparkling, rose, dessert, fortified
- Get to know what occasion the user is buying wine for
- Get to know what characteristics of wine the user is looking for e.g. tannin, sweetness, intensity, acidity
- Get to know what food the user will have with wine
At each round of conversation, the user will give you the current situation:
Context: ...
Your earlier conversation with the user: ...
You should then respond to the user with interleaving Thought, Plan, Action and Observation:
- thought:
1) State your reasoning about the current situation.
@@ -213,7 +249,7 @@ function decisionMaker(a::T)::Dict{Symbol, Any} where {T<:agent}
usermsg =
"""
Context: None
Your earlier conversation with the user: $(chatHistoryToString(a))
Your earlier conversation with the user: $(vectorOfDictToText(a.chathistory))
"""
_prompt =
@@ -902,10 +938,11 @@ function conversation(a::T, userinput::Dict) where {T<:agent}
# add usermsg to a.chathistory
addNewMessage(a, "user", userinput[:text])
thought = think(a)
think(a)
# thought will be added to chat model via context
chatresponse = generatechat(a, thought)
chatresponse = generatechat(a)
addNewMessage(a, "assistant", chatresponse)
return chatresponse
end
@@ -1024,8 +1061,12 @@ function think(a::T) where {T<:agent}
isterminal::Bool = haskey(response, :isterminal) ? response[:isterminal] : false
errormsg::Union{AbstractString, Nothing} = haskey(response, :errormsg) ? response[:errormsg] : nothing
success::Bool = haskey(response, :success) ? response[:success] : false
a.shortmem
return result
if actionname == "CHATBOX"
a.memory[:chatbox] = result
else
push!(a.memory[:shortmem], Dict(Symbol(actionname)=> result))
end
end
@@ -1049,27 +1090,22 @@ julia>
# Signature
"""
function generatechat(a::T1, input::T2) where {T1<:agent, T2<:AbstractString}
function generatechat(a::T) where {T<:agent}
systemmsg =
"""
You are a helpful sommelier working for a wine store.
Your task is to help the user choose the best wine that match the user preferences from your inventory.
You are also eager to improve your helpfulness.
You must follow the following guidelines:
- Get to know how much the user willing to spend
- Get to know type of wine the user is looking for e.g. red, white, sparkling, rose, dessert, fortified
- Get to know what occasion the user is buying wine for
- Get to know what characteristics of wine the user is looking for e.g. tannin, sweetness, intensity, acidity
- Get to know what food the user will have with wine
At each round of conversation, the user will give you:
At each round of conversation, the user will give you the current situation:
Context: ...
Your thoughts: Your current thinking in your mind
Your earlier conversation with the user: ...
You must follow the following guidelines (if the user interrupts, prioritize the user):
- Do not recommend specific wine before you checked your inventory.
You should then respond to the user with:
- chat: what do you want to say to the user
- chat: what do you want to say to the user based on the current situation
You should only respond in format as described below:
chat: ...
@@ -1077,11 +1113,13 @@ function generatechat(a::T1, input::T2) where {T1<:agent, T2<:AbstractString}
Let's begin!
"""
context = length(a.memory[:shortmem]) > 0 ? vectorOfDictToText(a.memory[:shortmem], withkey=false) : "None"
usermsg =
"""
Context: None
Your thoughts: $input
Your earlier conversation with the user: $(chatHistoryToString(a))
Context: $context
Your earlier conversation with the user: $(vectorOfDictToText(a.chathistory))
Your thoughts: $(a.memory[:chatbox])
"""
_prompt =
@@ -1099,31 +1137,31 @@ function generatechat(a::T1, input::T2) where {T1<:agent, T2<:AbstractString}
for attempt in 1:5
try
response = text2textInstructLLM(prompt)
response = a.text2textInstructLLM(prompt)
responsedict = GeneralUtils.textToDict(response,
["chat"],
rightmarker=":", symbolkey=true)
# check if dict has all required value
evaluationtext::AbstractString = responsedict[:evaluation]
responsedict[:score] = parse(Int, responsedict[:score]) # convert string "5" into integer 5
score::Integer = responsedict[:score]
accepted_as_answer::AbstractString = responsedict[:accepted_as_answer]
suggestion::AbstractString = responsedict[:suggestion]
# add to state here instead to in transition() because the latter causes julia extension crash (a bug in julia extension)
state[:evaluation] = responsedict[:evaluation]
state[:evaluationscore] = responsedict[:score]
state[:accepted_as_answer] = responsedict[:accepted_as_answer]
state[:suggestion] = responsedict[:suggestion]
# mark as terminal state when the answer is achieved
if accepted_as_answer == "Yes"
state[:isterminal] = true
state[:reward] = 1
for i [:chat]
if length(JSON3.write(responsedict[i])) == 0
error("$i is empty ", @__LINE__)
end
end
return responsedict[:score]
# check if there are more than 1 key per categories
for i [:chat]
matchkeys = GeneralUtils.findMatchingDictKey(responsedict, i)
if length(matchkeys) > 1
error("generatechat has more than one key per categories")
end
end
result = responsedict[:chat]
#[WORKING] delete chat
a.memory[:chatbox] = ""
return result
catch e
io = IOBuffer()
showerror(io, e)
@@ -1134,7 +1172,7 @@ function generatechat(a::T1, input::T2) where {T1<:agent, T2<:AbstractString}
println("")
end
end
error("evaluator failed to generate an evaluation")
error("generatechat failed to generate an evaluation")