44import pandas as pd
55from jinja2 import Environment , StrictUndefined
66
7+ from rdagent .components .knowledge_management .graph import UndirectedNode
78from rdagent .core .experiment import Experiment
89from rdagent .core .prompts import Prompts
910from rdagent .core .proposal import (
1415)
1516from rdagent .log import rdagent_logger as logger
1617from rdagent .oai .llm_utils import APIBackend
18+ from rdagent .scenarios .kaggle .experiment .kaggle_experiment import KG_SELECT_MAPPING
1719from rdagent .utils import convert2bool
1820
1921prompt_dict = Prompts (file_path = Path (__file__ ).parent .parent / "prompts.yaml" )
@@ -59,17 +61,7 @@ def generate_feedback(self, exp: Experiment, hypothesis: Hypothesis, trace: Trac
5961 Any: The feedback generated for the given experiment and hypothesis.
6062 """
6163 logger .info ("Generating feedback..." )
62- hypothesis_text = hypothesis .hypothesis
6364 current_result = exp .result
64- tasks_factors = []
65- if exp .sub_tasks :
66- tasks_factors = []
67- for task in exp .sub_tasks :
68- try :
69- task_info = task .get_task_information_and_implementation_result ()
70- tasks_factors .append (task_info )
71- except AttributeError :
72- print (f"Warning: Task { task } does not have get_task_information_and_implementation_result method" )
7365
7466 evaluation_description = None
7567 # Check if there are any based experiments
@@ -84,11 +76,6 @@ def generate_feedback(self, exp: Experiment, hypothesis: Hypothesis, trace: Trac
8476 ) # Compare with itself
8577 print ("Warning: No previous experiments to compare against. Using current result as baseline." )
8678
87- available_features = {
88- task_info : feature_shape for task_info , feature_shape in exp .experiment_workspace .data_description
89- }
90- model_code = exp .experiment_workspace .model_description
91-
9279 # Generate the user prompt based on the action type
9380 if hypothesis .action == "Model tuning" :
9481 prompt_key = "model_tuning_feedback_generation"
@@ -104,35 +91,52 @@ def generate_feedback(self, exp: Experiment, hypothesis: Hypothesis, trace: Trac
10491 .render (scenario = self .scen .get_scenario_all_desc (filtered_tag = "feedback" ))
10592 )
10693
107- last_task_and_code = None
108- if trace .hist :
109- last_task_and_code = (
110- trace .hist [- 1 ][1 ].experiment_workspace .data_description
111- if trace .hist [- 1 ][0 ].action == "Feature engineering" or trace .hist [- 1 ][0 ].action == "Feature processing"
112- else trace .hist [- 1 ][1 ].experiment_workspace .model_description
113- )
94+ sota_exp = exp .based_experiments [- 1 ] if exp .based_experiments else None
95+ assert sota_exp is not None
96+ sota_features = str (exp .based_experiments [- 1 ].experiment_workspace .data_description )
97+ sota_models = json .dumps (exp .based_experiments [- 1 ].experiment_workspace .model_description , indent = 2 )
98+ sota_result = exp .based_experiments [- 1 ].result
99+
100+ current_hypothesis = hypothesis .hypothesis
101+ current_hypothesis_reason = hypothesis .reason
102+ current_target_action = hypothesis .action
103+ current_sub_exps_to_code = {}
104+ if hypothesis .action == "Model tuning" :
105+ current_sub_exps_to_code [exp .sub_tasks [0 ].get_task_information ()] = exp .sub_workspace_list [0 ].code
106+ elif hypothesis .action == "Model feature selection" :
107+ current_sub_exps_to_code [exp .sub_tasks [0 ].get_task_information ()] = exp .experiment_workspace .code_dict [
108+ KG_SELECT_MAPPING [exp .sub_tasks [0 ].model_type ]
109+ ]
110+ else :
111+ current_sub_exps_to_code = {
112+ sub_ws .target_task .get_task_information (): sub_ws .code for sub_ws in exp .sub_workspace_list
113+ }
114+ current_sub_exps_to_code_str = json .dumps (current_sub_exps_to_code , indent = 2 )
115+ current_result = exp .result
116+
117+ last_hypothesis_and_feedback = None
118+ if trace .hist and len (trace .hist ) > 0 :
119+ last_hypothesis_and_feedback = (trace .hist [- 1 ][0 ], trace .hist [- 1 ][2 ])
114120
115121 # Prepare render dictionary
116122 render_dict = {
117- "last_hypothesis" : trace .hist [- 1 ][0 ] if trace .hist else None ,
118- "last_task_and_code" : last_task_and_code ,
119- "last_result" : trace .hist [- 1 ][1 ].result if trace .hist else None ,
120- "sota_task_and_code" : (
121- exp .based_experiments [- 1 ].experiment_workspace .data_description if exp .based_experiments else None
122- ),
123- "sota_result" : exp .based_experiments [- 1 ].result if exp .based_experiments else None ,
124- "hypothesis" : hypothesis ,
125- "exp" : exp ,
126- "model_code" : model_code , # This turn
127- "available_features" : available_features , # This turn
128- "combined_result" : combined_result , # This turn and sota
129- "hypothesis_text" : hypothesis_text , # This turn
130- "task_details" : tasks_factors , # This turn
123+ "sota_features" : sota_features ,
124+ "sota_models" : sota_models ,
125+ "sota_result" : sota_result ,
126+ "current_hypothesis" : current_hypothesis ,
127+ "current_hypothesis_reason" : current_hypothesis_reason ,
128+ "current_target_action" : current_target_action ,
129+ "current_sub_exps_to_code" : current_sub_exps_to_code_str ,
130+ "current_result" : current_result ,
131+ "combined_result" : combined_result ,
131132 "evaluation_description" : evaluation_description ,
133+ "last_hypothesis_and_feedback" : last_hypothesis_and_feedback ,
132134 }
133135
134136 usr_prompt = (
135- Environment (undefined = StrictUndefined ).from_string (prompt_dict [prompt_key ]["user" ]).render (** render_dict )
137+ Environment (undefined = StrictUndefined )
138+ .from_string (prompt_dict ["kg_feedback_generation_user" ])
139+ .render (** render_dict )
136140 )
137141
138142 response = APIBackend ().build_messages_and_create_chat_completion (
@@ -160,22 +164,29 @@ def generate_feedback(self, exp: Experiment, hypothesis: Hypothesis, trace: Trac
160164 percentile_ranking = (insert_position ) / (len (sorted_scores )) * 100
161165
162166 experiment_feedback = {
163- "current_competition " : self . scen . get_competition_full_desc () ,
164- "hypothesis_text " : hypothesis_text ,
167+ "hypothesis_text " : current_hypothesis ,
168+ "tasks_factors " : current_sub_exps_to_code ,
165169 "current_result" : current_result ,
166- "model_code" : model_code ,
167- "available_features" : available_features ,
168- "observations" : observations ,
169- "hypothesis_evaluation" : hypothesis_evaluation ,
170- "reason" : reason ,
171- "percentile_ranking" : percentile_ranking ,
172170 }
173171
174172 if self .scen .if_using_vector_rag :
173+ raise NotImplementedError ("Vector RAG is not implemented yet since there are plenty bugs!" )
175174 self .scen .vector_base .add_experience_to_vector_base (experiment_feedback )
176175 self .scen .vector_base .dump ()
177176 elif self .scen .if_using_graph_rag :
178- trace .knowledge_base .add_document (experiment_feedback , self .scen )
177+ competition_node = UndirectedNode (content = self .scen .get_competition_full_desc (), label = "competition" )
178+ hypothesis_node = UndirectedNode (content = hypothesis .hypothesis , label = hypothesis .action )
179+ exp_code_nodes = []
180+ for exp , code in current_sub_exps_to_code .items ():
181+ exp_code_nodes .append (UndirectedNode (content = exp , label = "experiments" ))
182+ if code != "" :
183+ exp_code_nodes .append (UndirectedNode (content = code , label = "code" ))
184+ conclusion_node = UndirectedNode (content = response , label = "conclusion" )
185+ all_nodes = [competition_node , hypothesis_node , * exp_code_nodes , conclusion_node ]
186+ all_nodes = trace .knowledge_base .batch_embedding (all_nodes )
187+ for node in all_nodes :
188+ if node is not competition_node :
189+ trace .knowledge_base .add_node (node , competition_node )
179190
180191 if self .scen .if_action_choosing_based_on_UCB :
181192 self .scen .action_counts [hypothesis .action ] += 1
0 commit comments