From 7825979abf92f852f1e6795c57d000f94667c40a Mon Sep 17 00:00:00 2001 From: tonaerospace Date: Tue, 28 Nov 2023 00:58:08 +0000 Subject: [PATCH] update --- src/interface.jl | 73 ++++++++++++++++++++++++++++-------------------- src/type.jl | 15 +++++----- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/src/interface.jl b/src/interface.jl index 094f57f..cf1cdca 100755 --- a/src/interface.jl +++ b/src/interface.jl @@ -3,7 +3,7 @@ module interface export agentReact, agentReflex, addNewMessage, clearMessage, removeLatestMsg, conversation, writeEvaluationGuideline, - grading, analyze, selfReflext + grading, analyze, selfReflext, actor_mistral_openorca2 using JSON3, DataStructures, Dates, UUIDs, HTTP using CommUtils, GeneralUtils @@ -319,7 +319,8 @@ function planner_mistral_openorca(a::agentReflex, usermsg::String) return prompt end -function actor_mistral_openorca(a::agentReflex, usermsg::T) where {T<:AbstractString} +#WORKING try use Thought/Act/ActInput/Obs loop because some time step 2 depend on step 1 +function actor_mistral_openorca(a::agentReflex, usermsg, plan, step) """ general prompt format: @@ -359,11 +360,13 @@ function actor_mistral_openorca(a::agentReflex, usermsg::T) where {T<:AbstractSt {usermsg} <|im_end|> <|im_start|>assistant - + {plan} """ prompt = replace(prompt, "{role}" => a.roles[a.role]) prompt = replace(prompt, "{thinkingFormat}" => a.thinkingFormat[:actor]) + prompt = replace(prompt, "{step}" => step) + prompt = replace(prompt, "{plan}" => plan) toolnames = "" toollines = "" for (toolname, v) in a.tools @@ -634,22 +637,22 @@ function work(a::agentReflex, usermsg::String) respond = sendReceivePrompt(a, prompt) plan = split(respond, "<|im_end|>")[1] plan = split(plan, "Response:")[1] - _plan = replace(plan, "Plan:"=>"Plan $(a.attempt):") - logmsg = "assistant: $_plan\n" + plan = replace(plan, "Plan:"=>"Plan $(a.attempt):") + logmsg = "assistant: $plan\n" a.memory[:shortterm] *= logmsg a.thoughtlog *= logmsg - actorstate, msgToUser = actor(a, plan) + actorstate, msgToUser = actor(a, usermsg, plan) if actorstate == "chatbox" respond = msgToUser break elseif actorstate == "all steps done" println("all steps done") - #WORKING give answer to the question + respond = formulateRespond(a, a.memory[:shortterm]) a.memory[:shortterm] *= "Respond: $respond\n" - #TODO evaluate. if score < 8/10 try again. + # evaluate. if score < 8/10 try again. headerToDetect = ["user:", "assistant:", ] headers = detectCharacters(a.memory[:shortterm], headerToDetect) chunkedtext = chunktext(a.memory[:shortterm], headers) @@ -664,9 +667,10 @@ function work(a::agentReflex, usermsg::String) a.thoughtlog = "" break else # self evaluate and reflect then try again - report = analyze(a, a.memory[:shortterm]) - @show report - lessonwithcontext = selfReflext(a, report) + analysis = analyze(a, a.memory[:shortterm]) + @show analysis + + lessonwithcontext = selfReflext(a, analysis) @show lessonwithcontext a.memory[:shortterm] = "" #TODO add lesson and context into longterm memory @@ -676,7 +680,7 @@ function work(a::agentReflex, usermsg::String) @show chunkedtext push!(a.memory[:longterm], Dict(:context=>chunkedtext["Context:"], :lesson=>chunkedtext["Lesson:"])) - error(">>>>>>>>>>") + error(">>>>>>>>>") end else error("undefied condition, actorstate $actorstate $(@__LINE__)") @@ -719,7 +723,7 @@ end msgToUser = "message from assistant to user" """ -function actor(a::agentReflex, plan::T) where {T<:AbstractString} +function actor(a::agentReflex, usermsg, plan) actorState = nothing msgToUser = nothing @@ -731,28 +735,39 @@ function actor(a::agentReflex, plan::T) where {T<:AbstractString} a.step += 1 @show a.step if a.step <= totalsteps - stepdetail = extractStepFromPlan(a, plan, a.step) - prompt = actor_mistral_openorca(a, stepdetail) + # WORKING in step 2, I need to use a.memory[:shortterm] as input to actor() + prompt = actor_mistral_openorca(a, usermsg, plan, a.step) @show prompt respond = sendReceivePrompt(a, prompt) - respond = split(respond, "<|im_end|>")[1] @show respond - headerToDetect = ["Question:", "Plan:", "Thought:", "Act:", "ActInput:", "Obs:", "...", "Answer:", - "Conclusion:", "Summary:"] - headers = detectCharacters(respond, headerToDetect) + # some time LLM not generate a number after headers but I want it + if occursin("Act:", respond) + headerToDetect = ["Question:", "Plan:", "Thought:", + "Act:", "ActInput:", "Obs:", "...", + "Answer:", "Conclusion:", "Summary:"] + headers = detectCharacters(respond, headerToDetect) + respond = addStepNumber(respond, headers, a.step) + end + + respond = split(respond, "Obs $(a.step):")[1] + # add to memory - _respond = addStepNumber(respond, headers, a.step) - a.memory[:shortterm] *= _respond - a.thoughtlog *= _respond - + a.memory[:shortterm] *= respond + a.thoughtlog *= respond + headerToDetect = ["Question $(a.step):", "Plan $(a.step):", "Thought $(a.step):", + "Act $(a.step):", "ActInput $(a.step):", "Obs $(a.step):", "...", + "Answer $(a.step):", "Conclusion $(a.step):", "Summary $(a.step):"] + headers = detectCharacters(respond, headerToDetect) chunkedtext = chunktext(respond, headers) - toolname = toolNameBeingCalled(chunkedtext["Act:"], a.tools) - toolinput = chunkedtext["ActInput:"] + @show chunkedtext + toolname = toolNameBeingCalled(chunkedtext["Act $(a.step):"], a.tools) + toolinput = chunkedtext["ActInput $(a.step):"] @show toolname @show toolinput - + error(">>>>>>>>>") if toolname == "chatbox" # chat with user + #TODO donot use chatbox to respond to user respond = toolinput msgToUser = respond actorState = toolname @@ -925,8 +940,7 @@ function analyze(a, shorttermMemory::T) where {T<:AbstractString} 1. What happened? 2. List all relationships, each with cause and effect . 3. Look at each relationship, figure out why it behaved that way. - 4. Do relationships behaved differently than your expectation? If yes, why? - 5. What could you do to improve the respond? + 4. What could you do to improve the respond? <|im_end|> """ @@ -935,7 +949,6 @@ function analyze(a, shorttermMemory::T) where {T<:AbstractString} end - """ Write a lesson drawn from evaluation. Args: @@ -968,7 +981,7 @@ julia> report = julia> lesson = selfReflext(agent, report) ``` """ -function selfReflext(a, report::T) where {T<:AbstractString} +function selfReflext(a, analysis::T) where {T<:AbstractString} prompt = """ <|im_start|>system diff --git a/src/type.jl b/src/type.jl index 0d1d458..0f17593 100644 --- a/src/type.jl +++ b/src/type.jl @@ -95,15 +95,16 @@ function agentReflex( :planner=> """Use the following format: Stimulus: the input user gives to you and you must respond - Plan: first you should always think about the stimulus and the info you have thoroughly then extract and devise a step by step plan to prepare a respond (pay attention to correct numeral calculation and commonsense). + Plan: first you should always think about the stimulus and the info you have thoroughly then extract and devise a step by step plan to respond (pay attention to correct numeral calculation and commonsense). """, :actor=> - """Use the following format: - Stimulus: the input user gives to you and you must respond - Thought: your should always think about what to do (pay attention to correct numeral calculation and commonsense). - Act: the action to take that match your thought, should be one of [{toolnames}] - ActInput: the input to the action (pay attention to the tool's input) - """, + """Use the following format: + Plan: first you should always think about the stimulus and the info you have thoroughly then extract and devise a step by step plan to respond (pay attention to correct numeral calculation and commonsense). + Thought: your should always think what to do to carry out the plan's step {step} (pay attention to correct numeral calculation and commonsense). + Act: the action to take that match your thought, should be one of [{toolnames}] + ActInput: the input to the action (pay attention to the tool's input) + Obs: the result of the action + """, ), tools::Dict=Dict( :chatbox=>Dict(