This commit is contained in:
2023-12-14 13:45:51 +00:00
parent b1c5ecfc2e
commit 7066f46504
2 changed files with 251 additions and 141 deletions

View File

@@ -234,8 +234,8 @@ function chat_mistral_openorca(a::agentReflex)
return response
end
function planner_mistral_openorca(a::agentReflex)
#WORKING
function planner_mistral_openorca(a::agentReflex, objective::T) where {T<:AbstractString}
"""
general prompt format:
@@ -263,66 +263,126 @@ function planner_mistral_openorca(a::agentReflex)
"
"""
prompt =
"""
assistant_plan_prompt =
"""
<|im_start|>system
{role}
{roleSpecificKnowledge}
{tools}
{thinkingFormat}
{context}
<|im_end|>
<|im_start|>user
{usermsg}
$(a.roles[a.role])
The info you need from the user to be able to help them selecting their best wine:
- type of food
- occasion
- user's personal taste of wine
- wine price range
- ambient temperature at the serving location
- wines we have in stock
You provide a personalized recommendation of up to two wines based on the user's info above, and you describe the benefits of each wine in detail.
You have access to the following tools:
$toollines
Use the following format:
Objective: the objective you intend to do
Plan: first you should always think about the objective, the info you need and the info you have thoroughly then extract and devise a step by step plan (pay attention to correct numeral calculation and commonsense).
p.s.1 each step should be a single action.
p.s.2 don't respond to the stimulus yet.
<|im_end|>
<|im_start|>assistant
Objective: $objective
Plan:
"""
prompt = replace(prompt, "{role}" => a.roles[a.role])
prompt = replace(prompt, "{thinkingFormat}" => a.thinkingFormat[:planner])
roleSpecificKnowledge =
"""
Info you need from the user to be able to help them selecting their best wine:
- type of food
- occasion
- user's personal taste of wine
- wine price range
- ambient temperature at the serving location
- wines we have in stock
You job is to provide a personalized recommendation of up to two wines based on the user's info above, and you describe the benefits of each wine in detail.
"""
prompt = replace(prompt, "{roleSpecificKnowledge}" => roleSpecificKnowledge)
toolnames = ""
toollines = ""
for (toolname, v) in a.tools
toolline = "$toolname: $(v[:description]) $(v[:input]) $(v[:output])\n"
toollines *= toolline
toolnames *= "$toolname,"
end
prompt = replace(prompt, "{toolnames}" => toolnames)
prompt = replace(prompt, "{tools}" => "You have access to the following tools:\n$toollines")
"""
plan = sendReceivePrompt(a, assistant_plan_prompt, temperature=0.2)
# prepare contex
context =
"""
My earlier talk with the user:
$(a.earlierConversation)
My earlier experience
$(experience(a.memory[:longterm]))
"""
prompt = replace(prompt, "{context}" => context)
# initialize short term memory
prompt = replace(prompt, "{usermsg}" => "Stimulus: $(a.memory[:shortterm]["user:"])")
return prompt
return plan
end
# function planner_mistral_openorca(a::agentReflex)
# """
# general prompt format:
# "
# <|im_start|>system
# {role}
# {tools}
# {thinkingFormat}
# <|im_end|>
# {context}
# <|im_start|>user
# {usermsg}
# <|im_end|>
# <|im_start|>assistant
# "
# Note:
# {context} =
# "
# {earlierConversation}
# {env state}
# {shortterm memory}
# {longterm memory}
# "
# """
# prompt =
# """
# <|im_start|>system
# {role}
# {roleSpecificKnowledge}
# {tools}
# {thinkingFormat}
# {context}
# <|im_end|>
# <|im_start|>user
# {usermsg}
# <|im_end|>
# <|im_start|>assistant
# Plan:
# """
# prompt = replace(prompt, "{role}" => a.roles[a.role])
# prompt = replace(prompt, "{thinkingFormat}" => a.thinkingFormat[:planner])
# roleSpecificKnowledge =
# """
# Info you need from the user to be able to help them selecting their best wine:
# - type of food
# - occasion
# - user's personal taste of wine
# - wine price range
# - ambient temperature at the serving location
# - wines we have in stock
# You job is to provide a personalized recommendation of up to two wines based on the user's info above, and you describe the benefits of each wine in detail.
# """
# prompt = replace(prompt, "{roleSpecificKnowledge}" => roleSpecificKnowledge)
# toolnames = ""
# toollines = ""
# for (toolname, v) in a.tools
# toolline = "$toolname: $(v[:description]) $(v[:input]) $(v[:output])\n"
# toollines *= toolline
# toolnames *= "$toolname,"
# end
# prompt = replace(prompt, "{toolnames}" => toolnames)
# prompt = replace(prompt, "{tools}" => "You have access to the following tools:\n$toollines")
# # prepare contex
# context =
# """
# My earlier talk with the user:
# $(a.earlierConversation)
# My earlier experience
# $(experience(a.memory[:longterm]))
# """
# prompt = replace(prompt, "{context}" => context)
# # initialize short term memory
# prompt = replace(prompt, "{usermsg}" => "Stimulus: $(a.memory[:shortterm]["user:"])")
# return prompt
# end
function actor_mistral_openorca(a::agentReflex)
"""
general prompt format:
@@ -407,7 +467,7 @@ end
julia> mqttClientSpec = (
clientName= "someclient", # name of this client
clientID= "$(uuid4())",
broker= "mqtt.yiem.ai",
broker= "mqtt.yiem.cc",
pubtopic= (imgAI="img/api/v0.0.1/gpu/request",
txtAI="txt/api/v0.1.0/gpu/request"),
subtopic= (imgAI="agent/api/v0.1.0/img/response",
@@ -441,15 +501,14 @@ function conversation(a::agentReflex, usermsg::String; attemptlimit::Int=3)
# a.earlierConversation = conversationSummary(a)
_ = addNewMessage(a, "user", usermsg)
isusetools, whattodo = isUseTools(a)
isusetools, objective = isUseTools(a)
# newinfo = extractinfo(a, usermsg)
# a.env = newinfo !== nothing ? updateEnvState(a, newinfo) : a.env
@show isusetools
#WORKING
# if isusetools # use tools before responseing
# response = work(a, usermsg)
# end
if isusetools # use tools before responseing
response = work(a, objective)
end
response = chat_mistral_openorca(a)
response = removeTrailingCharacters(response)
@@ -461,14 +520,14 @@ end
"""
Continuously run llm functions except when llm is getting Answer: or chatbox.
There are many work() depend on thinking mode.
"""
function work(a::agentReflex, usermsg::String)
""" #WORKING add plan and actor
function work(a::agentReflex, objective::T) where {T<:AbstractString}
response = nothing
error(1)
a.memory[:shortterm] = OrderedDict{String, Any}()
a.memory[:log] = OrderedDict{String, Any}()
a.memory[:shortterm]["user:"] = usermsg
a.memory[:log]["user:"] = usermsg
a.memory[:shortterm]["user:"] = objective
a.memory[:log]["user:"] = objective
a.newplan = true
while true # Work loop
@@ -570,6 +629,115 @@ function work(a::agentReflex, usermsg::String)
return response
end
# function work(a::agentReflex, usermsg::String)
# response = nothing
# a.memory[:shortterm] = OrderedDict{String, Any}()
# a.memory[:log] = OrderedDict{String, Any}()
# a.memory[:shortterm]["user:"] = usermsg
# a.memory[:log]["user:"] = usermsg
# a.newplan = true
# while true # Work loop
# # plan
# if a.attempt <= a.attemptlimit
# toolname = nothing
# toolinput = nothing
# if a.newplan == true
# a.attempt += 1
# a.step = 0
# prompt_plan = planner_mistral_openorca(a)
# println("")
# @show prompt_plan
# response = sendReceivePrompt(a, prompt_plan, max_tokens=1024)
# # sometimes LLM add not-need word I don't want
# plan = splittext(response, ["Step 1", "<|im_end|>", "Response", "Execution",
# "Result", "Recommendation", "My response"])
# # plan = replace(plan, "Plan:"=>"")
# println("")
# @show plan
# a.newplan = false
# a.memory[:shortterm]["Plan $(a.attempt):"] = plan
# a.memory[:log]["Plan $(a.attempt):"] = plan
# end
# println("")
# @show a.attempt
# # enter actor loop
# actorstate, msgToUser = actor(a)
# if actorstate == "chatbox"
# response = msgToUser
# break
# elseif actorstate == "all steps done" || actorstate == "formulateUserresponse"
# println("all steps done")
# response = formulateUserresponse(a)
# println("")
# formulatedresponse = response
# @show formulatedresponse
# a.memory[:shortterm]["response $(a.attempt):"] = response
# a.memory[:log]["response $(a.attempt):"] = response
# # evaluate. if score < 8/10 try again.
# guideline = writeEvaluationGuideline(a, a.memory[:shortterm]["user:"])
# println("")
# @show guideline
# score = grading(a, guideline, response)
# @show score
# if score >= 6 # good enough answer
# break
# else # self evaluate and reflect then try again
# analysis = analyze(a)
# println("")
# @show analysis
# lessonwithcontext = selfReflext(a, analysis)
# println("")
# @show lessonwithcontext
# newdict = OrderedDict()
# a.memory[:shortterm] = keepOnlyKeys(a.memory[:shortterm], ["user:"])
# headerToDetect = ["Lesson:", "Context:", ]
# headers = detectCharacters(lessonwithcontext, headerToDetect)
# chunkedtext = chunktext(lessonwithcontext, headers)
# a.memory[:longterm][chunkedtext["Context:"]] = chunkedtext["Lesson:"]
# a.newplan = true
# println("")
# println("RETRY $(a.attempt +1)")
# println("")
# end
# else
# error("undefied condition, actorstate $actorstate $(@__LINE__)")
# break
# end
# else
# error("attempt limit reach")
# break
# end
# end
# # good enough answer
# # communicates with user
# _ = addNewMessage(a, "assistant", response)
# return response
# end
# function work(a::agentReflex, usermsg::String)
# response = nothing

View File

@@ -363,12 +363,19 @@ end
# return thinkingmode
# end
#WORKING
""" Determine from a user message whether an assistant need to use tools.
Arguments:
a, one of ChatAgent's agent.
Return:
1. true/false # is LLM going to use tools
2. objective # what LLM going to do
"""
function isUseTools(a::agentReflex)
# response = chat_mistral_openorca(a)
toollines = ""
for (toolname, v) in a.tools
if toolname ["chatbox"]
@@ -396,81 +403,16 @@ function isUseTools(a::agentReflex)
# if LLM mentions any tools, use Plan/Thought/Act loop
isusetool = false
result = sendReceivePrompt(a, prompt, temperature=0.2)
objective = sendReceivePrompt(a, prompt, temperature=0.2)
for (toolname, v) in a.tools
if occursin(toolname, result)
if occursin(toolname, objective)
isusetool = true
break
end
end
@show result
plan = "N/A"
if isusetool
# toollines = ""
# for (toolname, v) in a.tools
# if toolname ∉ [""]
# toolline = "$toolname: $(v[:description]) $(v[:input]) $(v[:output])\n"
# toollines *= toolline
# end
# end
# assistant_objective_prompt =
# """
# <|im_start|>system
# $(a.roles[a.role])
# The info you need from the user to be able to help them selecting their best wine:
# - type of food
# - occasion
# - user's personal taste of wine
# - wine price range
# - ambient temperature at the serving location
# - wines we have in stock
# You provide a personalized recommendation of up to two wines based on the user's info above, and you describe the benefits of each wine in detail.
# You have access to the following tools:
# $toollines
# Your conversation with the user:
# $conversation
# Use the following format:
# Objective: From your conversation with the user, ask yourself what do you need to do now?
# <|im_end|>
# """
# result_objective = sendReceivePrompt(a, assistant_objective_prompt, temperature=0.2)
# @show result_objective
assistant_plan_prompt =
"""
<|im_start|>system
$(a.roles[a.role])
The info you need from the user to be able to help them selecting their best wine:
- type of food
- occasion
- user's personal taste of wine
- wine price range
- ambient temperature at the serving location
- wines we have in stock
You provide a personalized recommendation of up to two wines based on the user's info above, and you describe the benefits of each wine in detail.
You have access to the following tools:
$toollines
Use the following format:
Objective: the objective you intend to do
Plan: first you should always think about the objective, the info you need and the info you have thoroughly then extract and devise a step by step plan (pay attention to correct numeral calculation and commonsense).
p.s.1 each step should be a single action.
p.s.2 don't respond to the stimulus yet.
<|im_end|>
<|im_start|>assistant
Objective: $result
Plan:
"""
plan = sendReceivePrompt(a, assistant_plan_prompt, temperature=0.2)
@show plan
end
return isusetool, plan
@show objective
return isusetool, objective
end
@@ -650,7 +592,7 @@ julia> agent.messages = [Dict(:role=> "user", :content=> "Hi there."),
julia> messagesToString(agent.messages)
"<|im_start|>user: Hi there.\n<|im_end|><|im_start|>assistant: Hello! How can I assist you today?\n<|im_end|>"
```
""" #WORKING
"""
function messagesToString(messages::AbstractVector{T}; addressAIas="assistant") where {T<:AbstractDict}
conversation = ""
if length(messages)!= 0
@@ -681,7 +623,7 @@ function messagesToString(messages::AbstractVector{T}; addressAIas="assistant")
return conversation
end
#WORKING
function messagesToString_nomark(messages::AbstractVector{T}; addressAIas="assistant") where {T<:AbstractDict}
conversation = ""
if length(messages)!= 0