From 418c543d445a80971b40a58a0bcb17b0fc00cc81 Mon Sep 17 00:00:00 2001 From: tonaerospace Date: Wed, 19 Mar 2025 11:29:31 +0700 Subject: [PATCH] update --- src/interface.jl | 148 +++++++++++++++++++++++++++++++++++++++++---- src/llmfunction.jl | 42 +++++++------ 2 files changed, 160 insertions(+), 30 deletions(-) diff --git a/src/interface.jl b/src/interface.jl index ac28967..f3c9244 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -989,15 +989,22 @@ end # Arguments - `query<:AbstractString` - a query + A natural language query in English - `executeSQL::Function` - a connection object to a database + A function that executes SQL queries against the database - `text2textInstructLLM::Function` - A function that handles communication to text2text instruct LLM service. - -# Return - - `resulttext::String` - The result of the query in English. + A function that handles communication with a text-to-text instruction-based language model + +# Keyword Arguments + - `insertSQLVectorDB::Union{Function, Nothing}=nothing` + Optional function to insert SQL queries into a vector database for future reference + - `similarSQLVectorDB::Union{Function, Nothing}=nothing` + Optional function to find similar SQL queries from a vector database + +# Returns + - `NamedTuple{(:text, :rawresponse), Tuple{Any, Any}}` + - `:text`: The query result in natural language + - `:rawresponse`: The raw database response # Example ```jldoctest @@ -1064,7 +1071,7 @@ julia> println(result) function query(query::T, executeSQL::Function, text2textInstructLLM::Function; insertSQLVectorDB::Union{Function, Nothing}=nothing, similarSQLVectorDB::Union{Function, Nothing}=nothing, - ) where {T<:AbstractString} + )::NamedTuple{(:text, :rawresponse), Tuple{Any, Any}} where {T<:AbstractString} # use similarSQLVectorDB to find similar SQL for the query sql, distance = similarSQLVectorDB(query) @@ -1095,9 +1102,128 @@ function query(query::T, executeSQL::Function, text2textInstructLLM::Function; :question=> query, ), ) + # context = Dict( + # :tablelist => listAllTable_str(executeSQL)[:result] + # ) + #XXX find a way to recreate the schema from a existing database context = Dict( - :tablelist => listAllTable_str(executeSQL)[:result] + :tablelist => + """ + Here are SQL that used to create tables in the database: + create table customer ( + customer_id uuid primary key default gen_random_uuid (), + customer_firstname varchar(128), + customer_lastname varchar(128), + customer_displayname varchar(128) not null, + customer_username varchar(128), + customer_password varchar(128), + customer_gender varchar(128), + country varchar(128), + telephone varchar(128), + email varchar(128) not null, + customer_birthdate varchar(128), + note text, + + other_attributes jsonb, + created_time timestamptz default current_timestamp, + updated_time timestamptz default current_timestamp, + description text + ); + + create table retailer ( + retailer_id uuid primary key default gen_random_uuid (), + retailer_name varchar(128) not null, + retailer_username varchar(128) not null, + retailer_password varchar(128) not null, + retailer_address text not null, + country varchar(128) not null, + contact_person varchar(128) not null, + telephone varchar(128) not null, + email varchar(128) not null, + note text, + + other_attributes jsonb, + created_time timestamptz default current_timestamp, + updated_time timestamptz default current_timestamp, + description text + ); + + create table food ( + food_id uuid primary key default gen_random_uuid (), + food_name varchar(128) not null, + country varchar(128), + spiciness integer, + sweetness integer, + sourness integer, + savoriness integer, + bitterness integer, + serving_temperature integer, + note text, + other_attributes jsonb, + + created_time timestamptz default current_timestamp, + updated_time timestamptz default current_timestamp, + description text + ); + + create table wine ( + wine_id uuid primary key default gen_random_uuid (), + seo_name varchar(128) not null, + wine_name varchar(128) not null, + winery varchar(128) not null, + vintage integer not null, + region varchar(128) not null, + country varchar(128) not null, + wine_type varchar(128) not null, + grape varchar(128) not null, + serving_temperature varchar(128) not null, + intensity integer, + sweetness integer, + tannin integer, + acidity integer, + fizziness integer, + tasting_notes text, + note text, + other_attributes jsonb, + + created_time timestamptz default current_timestamp, + updated_time timestamptz default current_timestamp, + description text + ); + + create table wine_food ( + wine_id uuid references wine(wine_id), + food_id uuid references food(food_id), + constraint wine_food_id primary key (wine_id, food_id), + + created_time timestamptz default current_timestamp, + updated_time timestamptz default current_timestamp + ); + + CREATE TABLE retailer_wine ( + retailer_id uuid references retailer(retailer_id), + wine_id uuid references wine(wine_id), + constraint retailer_wine_id primary key (retailer_id, wine_id), + price NUMERIC(10, 2), + currency varchar(3) not null, + + created_time timestamptz default current_timestamp, + updated_time timestamptz default current_timestamp + ); + + CREATE TABLE retailer_food ( + retailer_id uuid references retailer(retailer_id), + food_id uuid references food(food_id), + constraint retailer_food_id primary key (retailer_id, food_id), + price NUMERIC(10, 2), + currency varchar(3) not null, + + created_time timestamptz default current_timestamp, + updated_time timestamptz default current_timestamp + ); + """ ) + transitionargs = ( decisionMaker=decisionMaker, evaluator=evaluator, @@ -1115,7 +1241,7 @@ function query(query::T, executeSQL::Function, text2textInstructLLM::Function; LLMMCTS.runMCTS(initialstate, transition, transitionargs; horizontalSampleExpansionPhase=5, horizontalSampleSimulationPhase=2, - maxSimulationDepth=10, + maxSimulationDepth=5, maxiterations=1, explorationweight=1.0, earlystop=earlystop, @@ -1307,7 +1433,7 @@ function generatequestion(state::T1, context, text2textInstructLLM::Function; responsedict = GeneralUtils.textToDict(response, header; dictKey=dictkey, symbolkey=true) response = "Q1: " * responsedict[:q1] - println("\n~~~ SQLLLM generatequestion() ", @__FILE__, ":", @__LINE__, " $(Dates.now())") + # println("\n~~~ SQLLLM generatequestion() ", @__FILE__, ":", @__LINE__, " $(Dates.now())") pprintln(Dict(responsedict)) return response catch e diff --git a/src/llmfunction.jl b/src/llmfunction.jl index 4d5c7c9..505ddd5 100644 --- a/src/llmfunction.jl +++ b/src/llmfunction.jl @@ -36,7 +36,7 @@ julia> result = response[:result] # Signature """ function listAllTable_json(executeSQL::Function -)::NamedTuple{(:result, :success),Tuple{DataFrame,Bool}} + )::NamedTuple{(:result, :success),Tuple{DataFrame,Bool}} sql = """ SELECT @@ -788,32 +788,37 @@ function getTableNameFromSQL(sql::T, text2textInstructLLM::Function)::Vector{Str end -""" Assigns a scalar value to each new child node to be used for selec- -tion and backpropagation. This value effectively quantifies the agent's progress in task completion, -serving as a heuristic to steer the search algorithm towards the most promising regions of the tree. +""" Compare multiple solution attempts and select the most accurate one. + +This function evaluates multiple solution attempts for a given question and determines which attempt +provides the most accurate and relevant response. It uses an LLM to analyze and compare the attempts, +considering their actions and observations. # Arguments - - `state<:AbstractDict` - one of Yiem's agent - - `text2textInstructLLM::Function` - A function that handles communication to LLM service +- `question::String` + The original question or task that was attempted to be solved +- `highValueStateList::Vector{Dict}` + List of states containing different solution attempts and their results +- `text2textInstructLLM::Function` + A function that handles communication to LLM service -# Return - - `score::Integer` +# Returns +- `Integer` + The index of the selected best response (1-based indexing) # Example ```jldoctest julia> ``` -# TODO - - [] update docs - - [WORKING] implement - -# Signature +# Notes +- The function makes up to 10 attempts to get a valid response from the LLM +- Each state in highValueStateList should contain a thoughtHistory with action_input and observation +- The LLM evaluates attempts based on accuracy and relevance to the original question """ -function compareState(question::String, highValueStateList, text2textInstructLLM::Function) - println(typeof(highValueStateList)) +function compareState(question::String, highValueStateList::Vector{Dict}, + text2textInstructLLM::Function)::Integer + systemmsg = """ @@ -947,7 +952,7 @@ function compareState(question::String, highValueStateList, text2textInstructLLM return responsedict[:selected_response_number] end - error("compareState failed to generate an evaluation, Response: \n$response\n<|End of error|>", @__FILE__, ":", @__LINE__, " $(Dates.now())") + error("compareState() failed to generate an evaluation, Response: \n$response\n<|End of error|>", @__FILE__, ":", @__LINE__, " $(Dates.now())") end @@ -988,7 +993,6 @@ end - end # module llmfunction \ No newline at end of file