Skip to content

Commit efedddf

Browse files
RolandMinruiXu
andauthored
feat: add drafting pipeline (#832)
* init commit * add drafting prompt * complete the drafting * remove scenario problems from proposal * rename prompts_drafting.yaml * fix bug * fix DSHypothesis print bug * add failed drafting exp to prompt * fix small bug * use get_task_information() for task design * resolve all comments * add problem_desc to pesudo hypothesis --------- Co-authored-by: Xu <[email protected]>
1 parent a3d5473 commit efedddf

File tree

8 files changed

+180
-66
lines changed

8 files changed

+180
-66
lines changed

rdagent/scenarios/data_science/dev/prompts.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ exp_feedback:
4141
- Begin your `reasoning` with `[Experiment Analysis]`, clearly stating why the current experiment's result surpasses or falls short compared to the SOTA.
4242
- NOTES:
4343
- The experiments focus on the comparison of the final ensemble results (Don't reject the results because they are still not perfect)
44-
44+
- If the `ensemble` score does not exceed the best individual mode or single fold, it is still acceptable unless the gap is significant.
4545
Step 4: Analyze Code With Similar validation Results
4646
- If the current `ensemble` validation score is similar to the SOTA `ensemble` validation score, give the decision based on the comparison between the current experiment and SOTA.
4747
- The current code should replace the best result if the code is:

rdagent/scenarios/data_science/proposal/exp_gen/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
from rdagent.core.utils import import_class
44
from rdagent.scenarios.data_science.experiment.experiment import DSExperiment
55
from rdagent.scenarios.data_science.proposal.exp_gen.base import DSHypothesis, DSTrace
6-
from rdagent.scenarios.data_science.proposal.exp_gen.draft import DSDraftExpGen
6+
from rdagent.scenarios.data_science.proposal.exp_gen.draft import (
7+
DSDraftExpGen,
8+
DSDraftV2ExpGen,
9+
)
710
from rdagent.scenarios.data_science.proposal.exp_gen.proposal import (
811
DSProposalV1ExpGen,
912
DSProposalV2ExpGen,
@@ -29,6 +32,9 @@ def gen(self, trace: DSTrace, selection: tuple[int, ...] = (-1,)) -> DSExperimen
2932
if DS_RD_SETTING.proposal_version not in ["v1", "v2"]:
3033
return import_class(DS_RD_SETTING.proposal_version)(scen=self.scen).gen(trace=trace)
3134

35+
if trace.sota_experiment() is None:
36+
return DSDraftV2ExpGen(scen=self.scen).gen(trace=trace)
37+
3238
if DS_RD_SETTING.coder_on_whole_pipeline:
3339
return DSProposalV2ExpGen(scen=self.scen).gen(trace=trace, pipeline=True)
3440

rdagent/scenarios/data_science/proposal/exp_gen/base.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ def __init__(
1313
self,
1414
component: COMPONENT,
1515
hypothesis: str = "",
16-
reason: str = "",
17-
concise_reason: str = "",
18-
concise_observation: str = "",
19-
concise_justification: str = "",
20-
concise_knowledge: str = "",
21-
problem_name: str = "",
22-
problem_desc: str = "",
16+
reason: str | None = None,
17+
concise_reason: str | None = None,
18+
concise_observation: str | None = None,
19+
concise_justification: str | None = None,
20+
concise_knowledge: str | None = None,
21+
problem_name: str | None = None,
22+
problem_desc: str | None = None,
2323
problem_label: Literal["SCENARIO_PROBLEM", "FEEDBACK_PROBLEM"] = "FEEDBACK_PROBLEM",
2424
) -> None:
2525
super().__init__(

rdagent/scenarios/data_science/proposal/exp_gen/draft.py

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import json
2-
from typing import TYPE_CHECKING
2+
from typing import TYPE_CHECKING, Dict
33

44
from rdagent.app.data_science.conf import DS_RD_SETTING
55
from rdagent.components.coder.data_science.ensemble.exp import EnsembleTask
66
from rdagent.components.coder.data_science.feature.exp import FeatureTask
77
from rdagent.components.coder.data_science.model.exp import ModelTask
8+
from rdagent.components.coder.data_science.pipeline.exp import PipelineTask
89
from rdagent.components.coder.data_science.raw_data_loader.exp import DataLoaderTask
910
from rdagent.components.coder.data_science.workflow.exp import WorkflowTask
1011
from rdagent.core.proposal import ExpGen, Hypothesis
@@ -116,3 +117,77 @@ def gen(
116117
# exp.experiment_workspace.inject_code_from_folder(last_successful_exp.experiment_workspace.workspace_path)
117118
exp.experiment_workspace.inject_code_from_file_dict(last_successful_exp.experiment_workspace)
118119
return exp
120+
121+
122+
class DSDraftV2ExpGen(ExpGen):
123+
def task_gen(
124+
self,
125+
scenario_desc: str,
126+
scen_problems: dict,
127+
component_desc: str,
128+
drafting_trace_desc: str,
129+
) -> DSExperiment:
130+
scen_problems_text = ""
131+
for i, (problem_name, problem_dict) in enumerate(scen_problems.items()):
132+
scen_problems_text += f"## Problem Name: {problem_name}\n"
133+
scen_problems_text += f"- Problem Description: {problem_dict['problem']}\n\n"
134+
sys_prompt = T(".prompts_drafting:task_draft.system").r(
135+
task_spec=T(f"scenarios.data_science.share:component_spec.Pipeline").r(),
136+
component_desc=component_desc,
137+
)
138+
user_prompt = T(".prompts_drafting:task_draft.user").r(
139+
scenario_desc=scenario_desc,
140+
scen_problems=scen_problems_text,
141+
drafting_trace_desc=drafting_trace_desc,
142+
)
143+
response = APIBackend().build_messages_and_create_chat_completion(
144+
user_prompt=user_prompt,
145+
system_prompt=sys_prompt,
146+
json_mode=True,
147+
json_target_type=Dict[str, str],
148+
)
149+
task_dict = json.loads(response)
150+
task_design = task_dict.get("task_design", "Description not provided")
151+
task = PipelineTask(name="Workflow", description=task_design)
152+
153+
# we use a pesudo hypothesis here
154+
pesudo_hypothesis = DSHypothesis(
155+
component=task_component,
156+
hypothesis="This is a pesudo hypothesis for drafting the first competition implementation. Your result should not be influenced by this hypothesis.",
157+
problem_name="This is a pesudo problem name for drafting. The corresponding problem description includes several problem together.",
158+
problem_desc=scen_problems_text,
159+
)
160+
exp = DSExperiment(pending_tasks_list=[[task]], hypothesis=pesudo_hypothesis)
161+
return exp
162+
163+
def gen(self, trace: DSTrace) -> DSExperiment:
164+
# Prepare
165+
last_exp = trace.last_exp()
166+
if not isinstance(last_exp, DSExperiment):
167+
eda_output = None
168+
else:
169+
eda_output = last_exp.experiment_workspace.file_dict.get("EDA.md", None)
170+
171+
component_desc = T("scenarios.data_science.share:component_description_in_pipeline").r()
172+
scenario_desc = trace.scen.get_scenario_all_desc(eda_output=eda_output)
173+
drafting_trace_desc = T("scenarios.data_science.share:describe.drafting_trace").r(
174+
exp_and_feedback_list=trace.experiment_and_feedback_list_after_init(return_type="all"),
175+
)
176+
177+
# Step 1: Identify Scenario Problems
178+
sys_prompt = T(".prompts_drafting:scenario_problem.system").r()
179+
user_prompt = T(".prompts_drafting:scenario_problem.user").r(scenario_desc=scenario_desc)
180+
response = APIBackend().build_messages_and_create_chat_completion(
181+
user_prompt=user_prompt,
182+
system_prompt=sys_prompt,
183+
json_mode=True,
184+
json_target_type=Dict[str, Dict[str, str]],
185+
)
186+
scen_problems = json.loads(response)
187+
188+
# Step 2: Design Task
189+
return self.task_gen(
190+
scenario_desc=scenario_desc,
191+
scen_problems=scen_problems,
192+
drafting_trace_desc=drafting_trace_desc,
193+
)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
scenario_problem:
2+
system: |-
3+
{% include "scenarios.data_science.share:scen.role" %}
4+
The user is creating a Kaggle competition implementation iteratively and this is the first iteration. You will be given the Kaggle competition scenario.
5+
Your task is to analyze the given information and extract the **Scenario Problems** from the given materials to aid the implementation.
6+
7+
## Scenario Problems
8+
### Definition
9+
Scenario problems are specific, context-dependent challenges arising from a competition's dataset or domain. They fall into two categories:
10+
1. Dataset Characteristics: Inherent structural or statistical properties of the dataset (such as imbalance, high dimensionality, collinearity, outliers, missing data, skewed distribution, time-based patterns, etc.).
11+
2. Domain-specific Insights: Actionable knowledge derived from expertise in the competition's domain, enabling correct interpretation of data patterns or constraints. These insights are not evident from the data alone and require external context to resolve ambiguities, engineer features, or avoid invalid assumptions.
12+
13+
### Specification
14+
1. The problem should be specific and fine-grained. Avoid general or vague statements.
15+
2. The problem should technical or methodological. Focus on design and implementation flaws.
16+
3. The problem should be strictly aligned with the improvement of target metric. **IF THE PROBLEM IS SOLVED, THEN THE TARGET METRIC WILL IMPROVE**.
17+
18+
### Output Format
19+
For each of the identified problem, you should strictly adhere to the following JSON schema. Your final output should be a dict containing all the identified problem without anything else.
20+
{
21+
"problem name 1": {
22+
"problem": "Description of the first issue in no more than three sentences.",
23+
"reason": "Brief explanation of why this is a problem, based on evidence from provided materials in no more than three sentences."
24+
},
25+
"problem name 2": {
26+
"problem": "Description of the second issue in no more than three sentences.",
27+
"reason": "Brief explanation of why this is a problem, based on evidence from provided materials in no more than three sentences."
28+
}
29+
}
30+
31+
user: |-
32+
# Scenario Description
33+
{{ scenario_desc }}
34+
35+
36+
task_draft:
37+
system: |-
38+
{% include "scenarios.data_science.share:scen.role" %}
39+
The user is creating a Kaggle competition implementation iteratively and this is the first iteration.
40+
You will be given a competition scenario and a list of identified scenario problems from the given competition scenario.
41+
In addition, if there are any previous failed experiments, you will receive the task designs and failures. Please read them carefully to have a better understanding.
42+
Your role is to design a very detailed task with specific steps and instructions to implement competition solution and address identifed scenario problems. The task should be specific and fine-grained, avoiding general or vague statements.
43+
44+
# Task Design
45+
## Task Specification
46+
{{ task_spec }}
47+
48+
## Task Design Guidelines
49+
Here are guidelines **YOU MUST FOLLOW** in your task design:
50+
1. The task should be concise with several steps each only in a few sentences.
51+
2. DO NOT write any code in the task description.
52+
3. DO NOT use any pharases like "for example" or "eg.," in the task description. Clearly give a decision (such as the specific method or model name) in the task description.
53+
4. DO NOT use vague statements like "choose a proper model" or "optimize the pipeline". Instead, specify the exact step and task to be made.
54+
5. Your task design should try to cover **ALL** the identified scenario problems. DO NOT include any conflicting ideas in the task design. If there are conflicting ideas due to conflicting identified problems, prioritize the most impactful or feasible option. If multiple solutions exist for a problem, select the most impactful or feasible option only. DO NOT include any conflicting ideas in the task description.
55+
6. Carefully read and analyze the previous failed experiments if any so that no similar mistakes will be made in your task design. Remember to put the lessons you learned from previous experiments in the new task design.
56+
57+
## Task Output Format:
58+
Design a specific and detailed Pipeline task based on the given competition scenario and scenario problems. The output should be detailed enough to directly implement the corresponding code.
59+
The output should follow JSON format. The schema is as follows:
60+
{
61+
"task_design": "A precise and comprehensive description of the main workflow script (`main.py`).",
62+
}
63+
64+
user: |-
65+
# Scenario Description
66+
{{ scenario_desc }}
67+
68+
# Identified Scenario Problems
69+
{{ scen_problems }}
70+
71+
# Previous Failed Experiments
72+
{{ drafting_trace_desc }}

rdagent/scenarios/data_science/proposal/exp_gen/prompts_v2.yaml

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,3 @@
1-
scenario_problem:
2-
system: |-
3-
{% include "scenarios.data_science.share:scen.role" %}
4-
You will be given the scenario description and the current SOTA implementation and feedback.
5-
Your task is to analyze the given information and extract the **Scenario Problems** from the given materials.
6-
7-
## Scenario Problems
8-
### Definition
9-
Scenario problems are specific, context-dependent challenges arising from a competition's dataset or domain. They fall into two categories:
10-
1. Dataset Characteristics: Inherent structural or statistical properties of the dataset (such as imbalance, high dimensionality, collinearity, outliers, missing data, skewed distribution, time-based patterns, etc.).
11-
2. Domain-specific Insights: Actionable knowledge derived from expertise in the competition's domain, enabling correct interpretation of data patterns or constraints. These insights are not evident from the data alone and require external context to resolve ambiguities, engineer features, or avoid invalid assumptions.
12-
13-
### Specification
14-
{{ problem_spec }}
15-
16-
### Core Analysis Dimensions
17-
1. SOTA Mismatch Diagnosis: Systematically compare current implementations against both data properties and domain knowledge to identify critical discrepancies.
18-
2. Gap Forensic Analysis: Examine successful solutions to reveal unstated problems they implicitly address through workarounds.
19-
3. Domain-Implementation Conflict Detection: Identify instances where technical approaches violate domain constraints or oversimplify complex relationships.
20-
21-
### Output Format
22-
{{ problem_output_format }}
23-
24-
user: |-
25-
# Scenario Description
26-
{{ scenario_desc }}
27-
28-
# Current SOTA Implementation
29-
{{ sota_exp_desc }}
30-
311
feedback_problem:
322
system: |-
333
{% include "scenarios.data_science.share:scen.role" %}
@@ -81,12 +51,15 @@ hypothesis_gen:
8151
2. Lessons from Previous Experiments
8252
- For persistent problems, analyze why prior hypotheses and solutions failed.
8353
- Incorporate evidence from past failures/successes to justify the hypothesis.
54+
- If previous experiments failed due to time/memory constraints, prioritize changes on efficiency.
8455
3. Actionable Changes
85-
- If the problem relates to time/memory constraints, suggest smaller model sizes or alternative algorithms with reduced complexity.
56+
- If the problem relates to time/memory constraints, consider smaller model sizes or alternative algorithms with reduced complexity.
8657
- If the problem involves underperforming models, propose removing or replacing models with significantly worse performance.
8758
- If the problem relates to hyperparameter tuning, recommend a specific method or strategy for tuning.
59+
4. Priority Note on Time/Memory Constraints
60+
- If time/memory constraints exist, they must be prioritized above all other problems. In such cases, do not response any other problems in the response dictionary.
8861
{% if enable_idea_pool %}
89-
4. Idea Reference
62+
5. Idea Reference
9063
- Each idea is a method, technique or trick that contributes to high performance from other competition implementation under similar problem. You are free to use them as an inspiration for your hypothesis proposal.
9164
{% endif %}
9265

rdagent/scenarios/data_science/proposal/exp_gen/proposal.py

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -224,23 +224,6 @@ def _f(user_prompt):
224224

225225

226226
class DSProposalV2ExpGen(ExpGen):
227-
def identify_scenario_problem(self, scenario_desc: str, sota_exp_desc: str) -> Dict:
228-
sys_prompt = T(".prompts_v2:scenario_problem.system").r(
229-
problem_spec=T(".prompts_v2:specification.problem").r(),
230-
problem_output_format=T(".prompts_v2:output_format.problem").r(),
231-
)
232-
user_prompt = T(".prompts_v2:scenario_problem.user").r(
233-
scenario_desc=scenario_desc,
234-
sota_exp_desc=sota_exp_desc,
235-
)
236-
response = APIBackend().build_messages_and_create_chat_completion(
237-
user_prompt=user_prompt,
238-
system_prompt=sys_prompt,
239-
json_mode=True,
240-
json_target_type=Dict[str, Dict[str, str]],
241-
)
242-
return json.loads(response)
243-
244227
def identify_feedback_problem(self, scenario_desc: str, exp_feedback_list_desc: str, sota_exp_desc: str) -> Dict:
245228
sys_prompt = T(".prompts_v2:feedback_problem.system").r(
246229
problem_spec=T(".prompts_v2:specification.problem").r(),
@@ -457,20 +440,14 @@ def gen(self, trace: DSTrace, pipeline: bool = False) -> DSExperiment:
457440
)
458441

459442
# Step 1: Identify problems
460-
scen_problems = self.identify_scenario_problem(
461-
scenario_desc=scenario_desc,
462-
sota_exp_desc=sota_exp_desc,
463-
)
464-
for problem_name in scen_problems:
465-
scen_problems[problem_name]["label"] = "SCENARIO_PROBLEM"
466443
fb_problems = self.identify_feedback_problem(
467444
scenario_desc=scenario_desc,
468445
exp_feedback_list_desc=exp_feedback_list_desc,
469446
sota_exp_desc=sota_exp_desc,
470447
)
471448
for problem_name in fb_problems:
472449
fb_problems[problem_name]["label"] = "FEEDBACK_PROBLEM"
473-
all_problems = {**scen_problems, **fb_problems}
450+
all_problems = fb_problems
474451

475452
# Step 1.5: Sample ideas from idea pool
476453
if DS_RD_SETTING.enable_knowledge_base:

rdagent/scenarios/data_science/share.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,18 @@ describe: # some template to describe some object
7979
Reason: {{ exp_and_feedback[1].reason }}
8080
{% endfor %}
8181
{% endif %}
82+
83+
drafting_trace: |-
84+
{% if exp_and_feedback_list|length == 0 %}
85+
No previous drafting experiments available.
86+
{% else %}
87+
{% for exp_and_feedback in exp_and_feedback_list %}
88+
## Drafting Experiment {{ loop.index }}
89+
Task Design: {{ exp_and_feedback[0].pending_tasks_list[0][0].get_task_information() }}
90+
Failure: {{ exp_and_feedback[1].reason }}
8291
92+
{% endfor %}
93+
{% endif %}
8394
8495
scen: # customizable
8596
role: |-

0 commit comments

Comments
 (0)