update
This commit is contained in:
+152
-35
@@ -64,36 +64,14 @@ end
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia> config = Dict(
|
||||
"mqttServerInfo" => Dict(
|
||||
"description" => "mqtt server info",
|
||||
"port" => 1883,
|
||||
"broker" => "mqtt.yiem.cc"
|
||||
),
|
||||
"externalservice" => Dict(
|
||||
"text2textinstruct" => Dict(
|
||||
"mqtttopic" => "/loadbalancer/requestingservice",
|
||||
"description" => "text to text service with instruct LLM",
|
||||
"llminfo" => Dict(
|
||||
"name" => "llama3instruct"
|
||||
)
|
||||
),
|
||||
)
|
||||
)
|
||||
julia> result = decisionMaker(agent)
|
||||
|
||||
julia> output_thoughtDict = Dict(
|
||||
"thought_1" => "The customer wants to buy a bottle of wine. This is a good start!",
|
||||
"action_1" => Dict{String, Any}(
|
||||
"action"=>"CHAT_BOX",
|
||||
"input"=>"What occasion are you buying the wine for?"
|
||||
),
|
||||
"observation_1" => ""
|
||||
)
|
||||
OrderedDict{String, Any} with 4 entries:
|
||||
"plan" => "The user provided an image of a sparkling white wine (Asolo Prosecco Bella Principessa from Italy) and requested a search for similar wines in the inventory. According to store guidelines, I must st…
|
||||
"action_name" => "CHECK_WINE"
|
||||
"action_input" => "Sparkling white wine from Italy"
|
||||
"action_result" => "1) winery: Terrazze dell Etna, wine_name: Rose Brut.
|
||||
```
|
||||
- [] update docstring
|
||||
- [] use customerinfo
|
||||
- [] user storeinfo
|
||||
|
||||
"""
|
||||
function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
) where {T<:agent}
|
||||
@@ -164,7 +142,6 @@ function decisionMaker(a::T; recentevents::Integer=20, maxattempt=10
|
||||
think, response = GeneralUtils.extractthink(response)
|
||||
response = String(split(response, ", observation")[1]) # in case LLM generate observation key which it isn't supposed to
|
||||
response = strip(response)
|
||||
@show response
|
||||
|
||||
responsedict = nothing
|
||||
if occursin(requiredKeys[2], response)
|
||||
@@ -371,6 +348,148 @@ function evaluator(a::T1, timeline, decisiondict, evaluateecontext
|
||||
end
|
||||
error("Evaluator failed to generate an evaluation, Response: \n$response\n<|End of error|>")
|
||||
end
|
||||
# function evaluator(a::T1, timeline, decisiondict, evaluateecontext
|
||||
# ) where {T1<:agent}
|
||||
|
||||
# systemmsg =
|
||||
# """
|
||||
# <Your role>
|
||||
# - You are a master sommelier of an online wine store.
|
||||
# </Your role>
|
||||
# <Situation>
|
||||
# - Under your supervision, a trainee sommelier is engaging with a store customer. Each time the customer speaks, the trainee will assess the situation, determine the next course of action, and pause to await your guidance before proceeding.
|
||||
# </Situation>
|
||||
# <Your mission>
|
||||
# - Improve a trainee sommelier decision based on the store policy and guidelines while ensuring seamless interactions between the trainee and customers.
|
||||
# </Your mission>
|
||||
# <At each round of conversation, you will be given the following information>
|
||||
# - trajectory: A conversation between your trainee and the customer that have occurred up until now
|
||||
# - evaluatee_context: The context that evaluatee use to make a decision
|
||||
# - evaluatee_decision: The decision made by the evaluatee, consists of the following elements:
|
||||
# "plan" is the trainee's plan
|
||||
# "action_name" is the name of the action taken, which can be one of the available tool name.
|
||||
# "action_input" is the input to the action.
|
||||
# </At each round of conversation, you will be given the following information>
|
||||
# <You must follow the following policy>
|
||||
# - Use only infomation provided by the store policy and guidelines as a bedrocks for your response.
|
||||
# </You must follow the following policy>
|
||||
# <You should follow the following guidelines>
|
||||
# - The trainee's plan, action_name, and action_input must be logically consistent
|
||||
# - The trainee's action_input should be in a proper format as specified by the tools.
|
||||
# - The trainee's action name and action input should make sense. For example, if the trainee isn't finished talking, he shouldn't use the END_CONVER_GUIDELINE tool.
|
||||
# </You should follow the following guidelines>
|
||||
# <You should then respond to the user with>
|
||||
# 1) trajectory_evaluation: Analyze the trajectory of a solution to answer the user's original question.
|
||||
# - Evaluate the correctness of each section and the overall trajectory based on the given question.
|
||||
# - Provide detailed reasoning and analysis, focusing on the latest thought, action, and observation.
|
||||
# - Incomplete trajectory are acceptable if the thoughts and actions up to that point are correct, even if the final answer isn't reached.
|
||||
# - Do not generate additional thoughts or actions.
|
||||
# 2) decision_evaluation:
|
||||
# - Examine how the trainee's decisions align with the store's policies and guidelines before proceeding.
|
||||
# 3) suggestion: Based store policy and guidelines, provide a suggestion for the immediate decision step only.
|
||||
# 4) approval: Can be "yes" or "no". "no" if the suggestion contradict the trainee's decision; otherwise, it is "yes".
|
||||
|
||||
# </You should then respond to the user with>
|
||||
# <You should only respond in JSON format as described below>
|
||||
# {
|
||||
# "trajectory_evaluation": "...",
|
||||
# "decision_evaluation": "...",
|
||||
# "suggestion": "...",
|
||||
# "approval": "...",
|
||||
# }
|
||||
# </You should only respond in format as described below>
|
||||
|
||||
# Let's begin!
|
||||
# """
|
||||
# requiredKeys = [:trajectory_evaluation, :decision_evaluation, :approval, :suggestion]
|
||||
# errornote = "N/A"
|
||||
|
||||
# for attempt in 1:10
|
||||
# evaluateecontext = replace(evaluateecontext, "<context>" => "")
|
||||
# evaluateecontext = replace(evaluateecontext, "</context>" => "")
|
||||
|
||||
# context =
|
||||
# """
|
||||
# <context>
|
||||
# <trajectory>
|
||||
# $timeline
|
||||
# </trajectory>
|
||||
# <evaluatee_context>
|
||||
# $evaluateecontext
|
||||
# </evaluatee_context>
|
||||
# <evaluatee_decision>
|
||||
# {plan: $(decisiondict["plan"]), action_name: $(decisiondict["action_name"]), action_input: $(decisiondict["action_input"])}
|
||||
# </evaluatee_decision>
|
||||
# P.S. $errornote
|
||||
# </context>
|
||||
# """
|
||||
|
||||
# unformatPrompt =
|
||||
# [
|
||||
# Dict("name" => "system", "text" => systemmsg),
|
||||
# ]
|
||||
|
||||
# # put in model format
|
||||
# prompt = GeneralUtils.formatLLMtext(unformatPrompt, a.llmFormatName)
|
||||
# # add info
|
||||
# prompt = prompt * context
|
||||
|
||||
# response = a.context.text2textInstructLLM(prompt; senderId=a.id)
|
||||
# response = GeneralUtils.deFormatLLMtext(response, a.llmFormatName)
|
||||
# response = GeneralUtils.remove_french_accents(response)
|
||||
# # response = replace(response, '$'=>"USD")
|
||||
# think, response = GeneralUtils.extractthink(response)
|
||||
|
||||
# responsedict = nothing
|
||||
# try
|
||||
# responsedict = copy(JSON.parsefile(response))
|
||||
# catch
|
||||
# println("\nERROR YiemAgent generatechat() failed to parse response: $response", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
# continue
|
||||
# end
|
||||
|
||||
# # check whether all answer's key points are in responsedict
|
||||
# ispass, errormsg = checkAgentResponse_JSON(responsedict, requiredKeys)
|
||||
# if !ispass
|
||||
# errornote = errormsg
|
||||
# println("\nERROR YiemAgent evaluator() $errornote --(not qualify response)> $responsedict", @__FILE__, ":", @__LINE__, " $(Dates.now())\n")
|
||||
# continue
|
||||
# end
|
||||
|
||||
# # if accepted_as_answer ∉ ["yes", "no"] # [PENDING] add errornote into the prompt
|
||||
# # error("generated accepted_as_answer has wrong format")
|
||||
# # end
|
||||
|
||||
# println("\nEvaluator() ", @__FILE__, ":", @__LINE__, " $(Dates.now())")
|
||||
# pprintln(Dict(responsedict))
|
||||
|
||||
# # # read sessionId
|
||||
# # sessionid = a.id
|
||||
# # # save to filename ./log/decisionlog.txt
|
||||
# # println("saving SQLLLM evaluator() to disk")
|
||||
# # filename = "agent_evaluator_log_$(sessionid[:id]).json"
|
||||
# # filepath = "/appfolder/app/log/$filename"
|
||||
# # # check whether there is a file path exists before writing to it
|
||||
# # if !isfile(filepath)
|
||||
# # decisionlist = [responsedict]
|
||||
# # println("Creating file $filepath")
|
||||
# # open(filepath, "w") do io
|
||||
# # JSON.pretty(io, decisionlist)
|
||||
# # end
|
||||
# # else
|
||||
# # # read the file and append new data
|
||||
# # decisionlist = copy(JSON.parsefile(filepath))
|
||||
# # push!(decisionlist, responsedict)
|
||||
# # println("Appending new data to file $filepath")
|
||||
# # open(filepath, "w") do io
|
||||
# # JSON.pretty(io, decisionlist)
|
||||
# # end
|
||||
# # end
|
||||
|
||||
# return responsedict
|
||||
# end
|
||||
# error("Evaluator failed to generate an evaluation, Response: \n$response\n<|End of error|>")
|
||||
# end
|
||||
|
||||
|
||||
""" Chat with llm.
|
||||
@@ -406,11 +525,10 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj
|
||||
|
||||
# find text in usermsg
|
||||
usertext = nothing
|
||||
text_position = nothing
|
||||
for (i, d) in enumerate(userinput["content"])
|
||||
if d["type"] == "text"
|
||||
d["text"] = GeneralUtils.remove_french_accents(d["text"])
|
||||
usertext = d["text"]
|
||||
text_position = i
|
||||
end
|
||||
end
|
||||
|
||||
@@ -419,7 +537,6 @@ function conversation(a::sommelier; userinput::Union{Dict{String, Any}, JSON.Obj
|
||||
return "Okay. What shall we talk about?"
|
||||
else
|
||||
@info "YiemAgent conversation() 2" @__LINE__
|
||||
userinput["content"][text_position]["text"] = GeneralUtils.remove_french_accents(usertext)
|
||||
# add usermsg to a.chathistory but how do I handle images?
|
||||
addNewMessage(a, "user", userinput; maximumMsg=maximumMsg)
|
||||
|
||||
@@ -504,7 +621,7 @@ function think(a::T)::NamedTuple{(:thoughtdict, :result_raw), Tuple{OrderedDict,
|
||||
# a.memory[:recap] = generateSituationReport(a, a.context["text"2textInstructLLM]; skiprecent=0)
|
||||
thoughtdict = decisionMaker(a)
|
||||
@info "YiemAgent think() 1" @__LINE__
|
||||
pprintln(thoughtdict)
|
||||
# pprintln(thoughtdict)
|
||||
|
||||
result_raw = nothing
|
||||
if thoughtdict["action_name"] ∈ ["CHAT_BOX"]
|
||||
@@ -657,7 +774,7 @@ function generatechat(a::T; recentevents::Integer=20, maxattempt=10
|
||||
- Once the user has selected their wine, if you haven't already, ask the user whether they need any further assistance. Do not offer any additional services.
|
||||
- Only end the conversation when the user explicitly intends to do so. When ending, ensure a polite farewell and an invitation to return in the future.
|
||||
- Spicy foods should be paired only with light red wines.
|
||||
- We do not sell organic, sustainable, gluten-free, and sulfite-free wine. Inform the user imediately if they are looking for these types of wines. Do not sell our wines as such.
|
||||
- We do not sell organic, sustainable, gluten-free, and sulfite-free wine. Inform the user immediately if they are looking for these types of wines. Do not sell our wines as such.
|
||||
- Gift box, gift card, and custom messages are available. Inform the user to contact our sales team.
|
||||
|
||||
# store_guidelines
|
||||
@@ -834,7 +951,7 @@ end
|
||||
# - Once the user has selected their wine, if you haven't already, ask the user whether they need any further assistance. Do not offer any additional services.
|
||||
# - Only end the conversation when the user explicitly intends to do so. When ending, ensure a polite farewell and an invitation to return in the future.
|
||||
# - Spicy foods should be paired only with light red wines.
|
||||
# - We do not sell organic, sustainable, gluten-free, and sulfite-free wine. Inform the user imediately if they are looking for these types of wines. Do not sell our wines as such.
|
||||
# - We do not sell organic, sustainable, gluten-free, and sulfite-free wine. Inform the user immediately if they are looking for these types of wines. Do not sell our wines as such.
|
||||
# - Gift box, gift card, and custom messages are available. Inform the user to contact our sales team.
|
||||
# </store_policy>
|
||||
# <store_guidelines>
|
||||
|
||||
Reference in New Issue
Block a user