This commit is contained in:
narawat lamaiin
2024-12-10 13:13:36 +07:00
parent d0262124d3
commit debd663f44
2 changed files with 104 additions and 48 deletions

View File

@@ -133,7 +133,7 @@ function decisionMaker(state::T1, context, text2textInstructLLM::Function,
systemmsg = systemmsg =
""" """
You are a helpful assistant that get the data from a database to satisfy the user's query. You are a helpful assistant that find the data from a database to satisfy the user's query.
You are also eager to improve your helpfulness. You are also eager to improve your helpfulness.
At each round of conversation, the user will give you the current situation: At each round of conversation, the user will give you the current situation:
@@ -146,12 +146,12 @@ function decisionMaker(state::T1, context, text2textInstructLLM::Function,
You should consider the following guidelines: You should consider the following guidelines:
- Do not create any table in the database - Do not create any table in the database
- Start only with the infomation the the query.
- Column name can be the same in different tables. Refer to column comments to get more details by using TABLEINFO function - Column name can be the same in different tables. Refer to column comments to get more details by using TABLEINFO function
- A junction table can be used to link tables together. Another use case is for filtering data. - A junction table can be used to link tables together. Another use case is for filtering data.
- If you can't find a single table that can be used to answer the user's query, try joining multiple tables to see if you can obtain the answer. - If you can't find a single table that can be used to answer the user's query, try joining multiple tables to see if you can obtain the answer.
- If you are unable to find the requested information, kindly inform the user, "The current data in our database does not provide the specific answer to your query". - If you are unable to find the requested information, kindly inform the user, "The current data in our database does not provide the specific answer to your query".
- Text information in the database usually stored in lower case. If your search returns empty, try using lower case to search. - Text information in the database usually stored in lower case. If your search returns empty, try using lower case to search.
- Do not use backticks (`). Use double quotes instead.
You should then respond to the user with interleaving Understanding, Reasoning, Plan, Action: You should then respond to the user with interleaving Understanding, Reasoning, Plan, Action:
1) Understanding: 1) Understanding:
@@ -224,7 +224,60 @@ function decisionMaker(state::T1, context, text2textInstructLLM::Function,
<|start_header_id|>assistant<|end_header_id|> <|start_header_id|>assistant<|end_header_id|>
""" """
try # try
# response = text2textInstructLLM(prompt)
# # textToDict() search for action_input
# responsedict = GeneralUtils.textToDict(response,
# ["Understanding", "Reasoning", "Plan", "Action_name", "Action_input", "Observation"],
# rightmarker=":", symbolkey=true, lowercasekey=true)
# delete!(responsedict, :observation)
# # [WORKING] remove backticks Error occurred: MethodError: no method matching occursin(::String, ::Vector{String})
# if occursin("```", responsedict[:action_input])
# responsedict[:action_input] =
# GeneralUtils.extract_triple_backtick_text(responsedict[:action_input])
# end
# toollist = ["TABLEINFO", "GETDATA"]
# if responsedict[:action_name] ∉ toollist
# error("SQL decisionMaker() didn't use the given functions ", @__FILE__, " ", @__LINE__)
# end
# for i in toollist
# if occursin(i, responsedict[:action_input])
# error("Action_name is in action_input which is not allowed.")
# end
# end
# for i ∈ [:understanding, :reasoning, :plan, :action_name, :action_input]
# if length(JSON3.write(responsedict[i])) == 0
# error("$i is empty ", @__FILE__, " ", @__LINE__)
# end
# end
# # check if there are more than 1 key per categories
# for i ∈ [:understanding, :reasoning, :plan, :action_name, :action_input]
# matchkeys = GeneralUtils.findMatchingDictKey(responsedict, i)
# if length(matchkeys) > 1
# error("DecisionMaker has more than one key per categories")
# end
# end
# state[:decisionMaker] = responsedict
# return responsedict
# 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("\n~~~ SQLLLM decisionMaker() Attempt $attempt. Error occurred: $errorMsg\n$st ", @__FILE__, " ", @__LINE__)
# println("")
# end
response = text2textInstructLLM(prompt) response = text2textInstructLLM(prompt)
# textToDict() search for action_input # textToDict() search for action_input
@@ -234,7 +287,7 @@ function decisionMaker(state::T1, context, text2textInstructLLM::Function,
delete!(responsedict, :observation) delete!(responsedict, :observation)
# remove backticks # [WORKING] remove backticks Error occurred: MethodError: no method matching occursin(::String, ::Vector{String})
if occursin("```", responsedict[:action_input]) if occursin("```", responsedict[:action_input])
responsedict[:action_input] = responsedict[:action_input] =
GeneralUtils.extract_triple_backtick_text(responsedict[:action_input]) GeneralUtils.extract_triple_backtick_text(responsedict[:action_input])
@@ -268,15 +321,6 @@ function decisionMaker(state::T1, context, text2textInstructLLM::Function,
state[:decisionMaker] = responsedict state[:decisionMaker] = responsedict
return responsedict return responsedict
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("\n~~~ SQLLLM decisionMaker() Attempt $attempt. Error occurred: $errorMsg\n$st ", @__FILE__, " ", @__LINE__)
println("")
end
end end
error("DecisionMaker failed to generate a thought ", response) error("DecisionMaker failed to generate a thought ", response)
end end
@@ -945,7 +989,9 @@ function query(query::T, executeSQL::Function, text2textInstructLLM::Function;
extracted = resultState[:thoughtHistory][latestKey] extracted = resultState[:thoughtHistory][latestKey]
# add to vectorDB only if the answer is achieved and the state is terminal # add to vectorDB only if the answer is achieved and the state is terminal
if addSQLVectorDB !== nothing && resultState[:isterminal] == true if addSQLVectorDB !== nothing && resultState[:isterminal] == true &&
resultState[:rawresponse] !== nothing
addSQLVectorDB(resultState[:thoughtHistory][:question], sql) addSQLVectorDB(resultState[:thoughtHistory][:question], sql)
end end
@@ -1017,7 +1063,7 @@ function generatequestion(state::T1, context, text2textInstructLLM::Function;
systemmsg = systemmsg =
""" """
You are a helpful assistant that generate multiple questions about the current situation. You are a SQL expert that generate multiple questions about the current situation.
At each round of conversation, the user will give you the current situation: At each round of conversation, the user will give you the current situation:
User query: ... User query: ...
@@ -1035,6 +1081,9 @@ function generatequestion(state::T1, context, text2textInstructLLM::Function;
3) Some information can be accessed by joining multiple tables. 3) Some information can be accessed by joining multiple tables.
4) Do not generate any question or comments at the end. 4) Do not generate any question or comments at the end.
You should consider the following guidelines:
- When querying data in the database, start with broad search terms and refine your query later for more precise results.
You should then respond to the user with: You should then respond to the user with:
1) Understanding: 1) Understanding:
- State your understanding about the current situation. - State your understanding about the current situation.
@@ -1052,6 +1101,13 @@ function generatequestion(state::T1, context, text2textInstructLLM::Function;
A3: ... A3: ...
... ...
Here are some examples:
Q: What information in the hints is not necessary based on the query?
A: Country is not specified in the query thus it should not be included in an SQL
Q: How can I modify a SQL example to fit my specific query needs?
A: ...
Let's begin! Let's begin!
""" """

View File

@@ -613,7 +613,7 @@ function SQLexecution(executeSQL::Function, sql::T
tablesize = size(df) tablesize = size(df)
row, column = tablesize row, column = tablesize
if row == 0 # if 0 row if row == 0 # if 0 row
error("The resulting table has 0 row. Possible causes: 1) You might be searching in the wrong place 2) There could be a typo in your search query.") error("The resulting table has 0 row. Possible causes: 1) Your search criteria might be too specific. Relaxing some conditions could yield better results. Remember, you can always refine your search later. 2) There could be a typo in your search query. 3) You might be searching in the wrong place.")
elseif column > 30 elseif column > 30
error("SQL execution failed. An unexpected error occurred. Please try again.") error("SQL execution failed. An unexpected error occurred. Please try again.")
end end