This commit is contained in:
narawat lamaiin
2024-08-17 22:32:16 +07:00
parent e1592f9d8e
commit 9d805fb3e7
3 changed files with 198 additions and 43 deletions

View File

@@ -1283,7 +1283,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
Your goal is: Recommend the best wines from your inventory that align with the user's preferences.
Your responsibility includes:
1) Convey your thoughts to the user
1) Given the situation, convey your thoughts to the user
At each round of conversation, you will be given the current situation:
Your conversation with the user: ...
@@ -1297,7 +1297,7 @@ function generatechat(memory::Dict, chathistory::Vector, text2textInstructLLM::F
- Focus on the latest conversation.
You should then respond to the user with:
1) chat: Given the current situation, what will you say to the user?
1) chat: Given the situation, convey your thoughts to the user
2) 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:
@@ -1398,13 +1398,58 @@ end
function generatequestion(a, text2textInstructLLM::Function)::String
# systemmsg =
# """
# You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
# Your goal is: Help the user select the best wines from your inventory that align with the user's preferences.
# Your responsibility includes:
# 1) Self questioning about the current situation
# 2) Thanks the user when they are done choosing wines and invite them to comeback next time
# Your responsibility does not include:
# 1) Processing sales orders or engaging in any other sales-related activities.
# At each round of conversation, you will be given the current situation:
# Your conversation with the user: ...
# Context: ...
# You must follow the following guidelines:
# - Your question should be specific, self-contained and not require any additional context.
# - Do not generate any question or comments at the end.
# - Once the user has selected their wine, ask the user if they need any further assistance. Do not offer any additional services. If the user doesn't need any further assistance, say goodbye and invite them to come back next time.
# You should follow the following guidelines:
# - Focus on the latest conversation.
# - Do not ask the user about wine's flavor e.g. floral, citrusy, nutty or some thing similar as these terms cannot be used to search the database.
# - All wines in your inventory are always in stock.
# You should then respond to the user with:
# 1) Reasoning: State your detailed reasoning of the current situation
# 2) Q: Based on the current situation, ask yourself at least two, but no more than five, questions about what you need to do to achieve the goal.
# 3) A: Based on the current situation, answer to yourself the best you can
# You must only respond in format as described below:
# Reasoning: ...
# Q 1: ...
# A 1: ...
# Q 2: ...
# A 2: ...
# Q 3: ...
# A 3: ...
# ...
# Let's begin!
# """
systemmsg =
"""
You are a helpful assistant acting as a polite, website-based sommelier for an online wine store.
Your goal is: Help the user select the best wines from your inventory that align with the user's preferences.
Your goal includes:
1) Help the user select the best wines from your inventory that align with the user's preferences.
Your responsibility includes:
1) Self questioning about the current situation
1) Ask yourself what to do about the current situation
2) Thanks the user when they are done choosing wines and invite them to comeback next time
Your responsibility does not include:
@@ -1426,8 +1471,16 @@ function generatequestion(a, text2textInstructLLM::Function)::String
You should then respond to the user with:
1) Reasoning: State your detailed reasoning of the current situation
2) Q: Based on the current situation, ask yourself at least two, but no more than five, questions about what you need to do to achieve the goal.
3) A: Based on the current situation, answer to yourself the best you can
2) Q: Given the situation, "ask yourself" about the situation at least two, but no more than five, questions.
3) A: Given the situation, "answer to yourself" the best you can
Here are some examples:
Q: The user is asking for a cappuccino. Do I have it at my cafe?
A: No I don't.
Q: Since I don't have a cappuccino but I have a Late, should I ask if they are okay with that?
A: Yes, I should.
Q: Are they allergic to milk?
A: Since they mentioned a cappuccino before, I think they are not allergic to milk.
You must only respond in format as described below:
Reasoning: ...
@@ -1497,7 +1550,6 @@ function generatequestion(a, text2textInstructLLM::Function)::String
error("generatequestion failed to generate a thought ", response)
end
function generateSituationReport(a, text2textInstructLLM::Function)::Dict
# systemmsg =
@@ -1523,23 +1575,24 @@ function generateSituationReport(a, text2textInstructLLM::Function)::Dict
systemmsg =
"""
You are the assistant being in the given events.
Your task is to writes a summary of each event.
Your task is to writes a summary for each event.
At each round of conversation, you will be given the situation:
Total events: number of events you need to summarize.
Events timeline: ...
Context: ...
You should then respond to the user with:
event: a detailed summary of each event without exaggerated details.
event: a detailed summary for each event without exaggerated details.
You must only respond in format as described below:
event 1: ...
event 2: ...
event_1: ...
event_2: ...
...
Here are some examples:
event 1: The user ask me about where to buy a toy.
event 2: I told the user to go to the store at 2nd floor.
event_1: The user ask me about where to buy a toy.
event_2: I told the user to go to the store at 2nd floor.
Let's begin!
"""
@@ -1559,6 +1612,7 @@ function generateSituationReport(a, text2textInstructLLM::Function)::Dict
for attempt in 1:10
usermsg =
"""
Total events: $(length(a.memory[:events]))
Events timeline: $timeline
$errornote
"""
@@ -1576,27 +1630,129 @@ function generateSituationReport(a, text2textInstructLLM::Function)::Dict
<|start_header_id|>assistant<|end_header_id|>
"""
try
response = text2textInstructLLM(prompt)
# responsedict = GeneralUtils.textToDict(response,
# ["summary", "presented", "selected"],
# rightmarker=":", symbolkey=true)
# println("--> generateSituationReport ", @__FILE__, " ", @__LINE__)
pprintln(response)
return Dict(:recap=>response)
catch e
io = IOBuffer()
showerror(io, e)
errorMsg = String(take!(io))
st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
println("")
println("Attempt $attempt. Error occurred: $errorMsg\n$st")
println("")
response = text2textInstructLLM(prompt)
# responsedict = GeneralUtils.textToDict(response,
# ["summary", "presented", "selected"],
# rightmarker=":", symbolkey=true)
# println("--> generateSituationReport ", @__FILE__, " ", @__LINE__)
pprintln(response)
eventcount = count("event_", response)
if eventcount < length(a.memory[:events])
errornote = "Note: You need to summarize every events."
println("the summary covers $eventcount/$(length(a.memory[:events])) ", @__FILE__, " ", @__LINE__)
else
return Dict(:recap=> response)
end
end
error("generateSituationReport failed to generate a thought ", response)
end
# function generateSituationReport(a, text2textInstructLLM::Function)::Dict
# # systemmsg =
# # """
# # You are a helpful assistant in the given timeline.
# # You task is to writes a situational report on the current situation.
# # At each round of conversation, you will be given the current situation:
# # Timeline: ...
# # Context: ...
# # You should then respond to the user with:
# # 1) report: State your detailed situational report on the current situation.
# # 2) wine_selected: Indicates whether the user selected wine. It can be the name of the selected wine or "None"
# # You must only respond in format as described below:
# # report: ...
# # wine_selected: ...
# # Let's begin!
# # """
# systemmsg =
# """
# You are the assistant being in the given events.
# Your task is to writes a summary of each event.
# At each round of conversation, you will be given the situation:
# Events timeline: ...
# Context: ...
# You should then respond to the user with:
# event: a detailed summary of each event without exaggerated details.
# You must only respond in format as described below:
# event 1: ...
# event 2: ...
# ...
# Here are some examples:
# event 1: The user ask me about where to buy a toy.
# event 2: I told the user to go to the store at 2nd floor.
# Let's begin!
# """
# timeline = ""
# for (i, event) in enumerate(a.memory[:events])
# if event[:outcome] === nothing
# timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue])\n"
# else
# timeline *= "$i) $(event[:subject])> $(event[:action_or_dialogue]) $(event[:outcome])\n"
# end
# end
# errornote = ""
# response = nothing # store for show when error msg show up
# for attempt in 1:10
# usermsg =
# """
# Events timeline: $timeline
# $errornote
# """
# _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,
# # ["summary", "presented", "selected"],
# # rightmarker=":", symbolkey=true)
# # println("--> generateSituationReport ", @__FILE__, " ", @__LINE__)
# pprintln(response)
# eventcount = count("event", response)
# if eventcount < length(a.memory[:events])
# error("the summary is missing some events ", @__FILE__, " ", @__LINE__)
# end
# return Dict(:recap=>response)
# catch e
# io = IOBuffer()
# showerror(io, e)
# errorMsg = String(take!(io))
# st = sprint((io, v) -> show(io, "text/plain", v), stacktrace(catch_backtrace()))
# println("")
# println("Attempt $attempt. Error occurred: $errorMsg\n$st")
# println("")
# end
# end
# error("generateSituationReport failed to generate a thought ", response)
# end

View File

@@ -445,6 +445,16 @@ function extractWineAttributes_1(a::T1, input::T2)::String where {T1<:agent, T2<
end
end
# check if region is mentioned in the input
if !occursin("NA", responsedict[:region]) && !occursin(responsedict[:region], input)
if attempt < maxattempt
errornote = "You are halucinating, $(responsedict[:region]) is not mentioned in the input"
error("$(responsedict[:region]) is not mentioned in the input")
else
responsedict[:region] = "NA"
end
end
responsedict[:flavors] = replace(responsedict[:flavors], "notes"=>"")
delete!(responsedict, :reasoning)
delete!(responsedict, :tasting_notes)

View File

@@ -19,14 +19,6 @@ msgMeta = GeneralUtils.generate_msgMeta(
replyTopic = config[:servicetopic][:mqtttopic] # ask frontend reply to this instance_chat_topic
)
# commConfig = Dict(
# :mqttServerInfo=> config[:mqttServerInfo],
# :receivemsg=> Dict(
# :prompt=> config[:servicetopic][:mqtttopic], # topic to receive prompt i.e. frontend send msg to this topic
# ),
# :externalservice=> config[:externalservice],
# )
function executeSQL(sql::T) where {T<:AbstractString}
DBconnection = LibPQ.Connection("host=192.168.88.12 port=5432 dbname=yiem_wine_assistant user=yiem password=yiem@Postgres_0.0")
result = LibPQ.execute(DBconnection, sql)
@@ -56,15 +48,12 @@ function text2textInstructLLM(prompt::String)
)
)
_response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg)
_response = GeneralUtils.sendReceiveMqttMsg(outgoingMsg; timeout=120)
response = _response[:response][:text]
return response
end
# Instantiate an agent
a = YiemAgent.sommelier(
text2textInstructLLM,
@@ -88,7 +77,7 @@ end
main()
"""
I'm joining a graduation party this evening. I have unlimited budget and I'm ok with wines in all price range. I want a bottle of full bodied, dry white wine from the U.S.
I'm joining a graduation party this evening. I want a bottle of full bodied, dry white wine from the U.S. and I'm ok with all price range.
Well, the party is small casual with close friends and no food serving.
I'm open to suggestion since I have no specific idea about wine.