Compare commits

...

405 Commits

Author SHA1 Message Date
you-n-g f075824a16 chore: release 0.6.0
Release-As: 0.6.0
2025-06-26 22:32:15 +08:00
you-n-g 5c5508c8cc fix: add async to direct_exp_gen avoid infinite loop (#992)
* refactor: convert direct_exp_gen to async and enforce parallel limit

* fix bug

* change coroutine function position

* fix fin_quant's direct_exp_gen

* format with isort

---------

Co-authored-by: Bowen Xian <xianbowen@outlook.com>
Co-authored-by: SunsetWolf <Lv.Linlang@hotmail.com>
2025-06-26 22:10:52 +08:00
xuangu-fang a5c5c7172b feat: async mechanism for multi-trace (#981)
* start to work on multi-trace + async

* init ver of async-multi-tarce, to test

* add eng-ver log

* complete version of async+ mul-trace

* debug

* fix bug on         DS_RD_SETTING.get()

* update

* fix bug + simplif the usage of async in multi-trace

* fix mini bug of arg_name

* Move local_selection into class Experiment & clean the code
2025-06-26 15:49:47 +08:00
you-n-g 58b5cc1458 fix: refine prompt (#987)
* refactor: rename failed_exp_and_feedback_list to include _after_sota suffix

* refactor: merge prompts_v3 into prompts_v2 and update references
2025-06-26 12:08:31 +08:00
Xu Yang 80d81c8ea9 support tar in dataset & fix a small bug in loop (#986)
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-06-25 15:32:37 +08:00
XianBW 1b762ceddd fix LLM log bug (#985) 2025-06-25 10:38:20 +08:00
Tim ed84b6b0a3 chore: merge with more trace (#982)
* merge support more traces
* use feedback from all traces
2025-06-24 10:47:45 +08:00
you-n-g 46367e15f5 fix: refine details (#979)
* feat: add parquet preview and extract common DataFrame preview logic

* refactor: improve error messages, prompts, regex, and session loading

* lint
2025-06-23 10:38:27 +08:00
Yuante Li 0859b9f3a2 fix: fix a bug and update the docs (#978) 2025-06-20 10:58:14 +08:00
Copilot e03fca3206 fix: docker container cleanup to prevent accumulation and system slowdown (#975)
* Initial plan for issue

* Fix Docker container cleanup issue by using try-finally block

Co-authored-by: peteryang1 <25981102+peteryang1@users.noreply.github.com>

* Fix additional Docker container leaks in health_check and GPU test functions

Co-authored-by: peteryang1 <25981102+peteryang1@users.noreply.github.com>

* Remove temporary test files and finalize Docker container cleanup fix

Co-authored-by: peteryang1 <25981102+peteryang1@users.noreply.github.com>

* Refactor container cleanup code to reduce duplication as requested in review feedback

Co-authored-by: peteryang1 <25981102+peteryang1@users.noreply.github.com>

* Refactor container cleanup to use shared function and always stop before remove

Co-authored-by: peteryang1 <25981102+peteryang1@users.noreply.github.com>

* fix CI

* Fix mypy type checking errors for Docker container cleanup

Co-authored-by: peteryang1 <25981102+peteryang1@users.noreply.github.com>

* fix CI

* Remove unnecessary _cleanup_container wrapper method in DockerEnv class

Co-authored-by: peteryang1 <25981102+peteryang1@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: peteryang1 <25981102+peteryang1@users.noreply.github.com>
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-06-19 18:32:50 +08:00
Xu Yang 977136f1f3 fix: merge datascience v3 and v2 (#974)
* add coder version

* merge cooder and feedback prompts

* align v2 and v3 proposal prompts

* fix a small bug

* fix a bug

* fix another bug

* support both function calling and json mode in v2 proposal

* fix minor bug

* reformat

* remove proposal v3

* fix a small bug in json mode

* fix CI

* remove tmp file

* remove v3 check

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-06-19 13:25:10 +08:00
you-n-g bf9efe127d chore: release 0.5.0
Release-As: 0.5.0
2025-06-18 15:08:11 +08:00
Yuante Li 243d5259f7 docs: update readme for v0.5.0 release (#973) 2025-06-18 14:49:24 +08:00
Linlang dd10ddf9fd fix: main bug (#938)
* feat: parameterize cache paths with USER to avoid conflicts

* guide for missing training_hyperparameters

* guidance for  KeyError: 'concise_reason'

* fixed three bugs in the test

* fix general_model task bug

* fixed some bugs in the med_model scenario

* delete comments

* format with black

* fix mypy error

* fix ruff error

* fix isort error

* sync code

* revert cache_path code

* revert cache_path code

* delete data mining scenario

* fix factor report loop

* fix LiteLLMAPIBackend log_llm_chat_content setting

* refine fin factor report scenario

* remove unused LogColors

* fix UI

* remove medical scenario docs

* change **kaggle** to **data_science**

* remove default dataset_path in create_debug_data

* remove KAGGLE_SETTINGS in kaggle_crawler

* limit litellm versions

* reformat with black

* change README

* fix_data_science_docs

* make hypothesis observations string

* Hiding old versions of kaggle docs

* hidding kaggle agent docs

---------

Co-authored-by: Young <afe.young@gmail.com>
Co-authored-by: Bowen Xian <xianbowen@outlook.com>
Co-authored-by: yuanteli <1957922024@qq.com>
2025-06-18 14:35:45 +08:00
Yuante Li a619ff999b refactor: refactor RD-Agent(Q) configuration files (#972)
* refactor rdagent(q) conf files

* fix

* fix ci
2025-06-18 12:28:29 +08:00
Tim c215e735c2 fix: use simple stdout and stderr (#966)
* use simple stdout and stderr
* add live_output config in LocalConf
2025-06-18 11:54:27 +08:00
Yuante Li 0c219b81e0 docs: update the documentation for custom dataset (#969) 2025-06-18 10:58:28 +08:00
Tim 9f793d58b3 fix: get_metric_direction for aerial-cactus-identification (#970) 2025-06-17 18:06:38 +08:00
Yuante Li f0deace7a7 docs: add readme for custom data in R&D Agent DS scenario (#968) 2025-06-17 16:29:07 +08:00
Tim 682f657637 chore: break when loop_n runs out (#964)
* raise loop termination in execute_loop

* add SENTINEL
2025-06-17 15:46:38 +08:00
Yuante Li af5898211b refactor: add custom data setting for data science scene (#967)
* add custom data setting for the data science scene

* fix ci?

* fix ci

* add custom data as an example

* fix ci

* add package

* fix test_import ci error
2025-06-17 14:55:11 +08:00
XianBW 1a1e88c47c fix: log info (#965)
* fix log caller_info

* make env info beauty
2025-06-16 19:52:44 +08:00
amstrongzyf 9890bb4b00 docs: update explanation for separate config use in litellm (#958)
* docs: update explanation for separate config use in litellm

* docs: update default backend to `rdagent.oai.backend.LiteLLMAPIBackend`

* docs: update .rst format

* Update installation_and_configuration.rst
2025-06-13 18:32:39 +08:00
XianBW 5a3a2bf2be chore: remove redundant tag in old scenarios (#917)
* remove state.times in old ui

* remove "r" tag

* remove "d" tag

* remove "ef" tag

* remove "init" tag

* fix CI

* remove old tag in app UI

* fix bugs

* fix CI

* some updates

* filter tags
2025-06-13 17:49:58 +08:00
you-n-g 77e9f186d5 fix: add missing semicolon after chmod in env shell command (#955) 2025-06-12 21:02:07 +08:00
you-n-g 2187081905 feat: replace hard-coded cache paths with dynamic cache_path config (#952)
* feat: replace hard-coded cache paths with dynamic cache_path config

* style: reorder wait_retry import and format chmod list

* refactor: pass workspace_path to chmod command and use DockerConf check
2025-06-12 17:44:31 +08:00
Xu Yang 698f89e07c print out the qlib data generation error message to help user find the problem (#954)
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-06-12 17:34:51 +08:00
you-n-g 304d3fad2e feat: parallel loop running based on asyncio (#932)
* refactor: split workflow into pkg, add WorkflowTracker & wait_retry

* feat: add async LoopBase with parallel workers and step semaphores

* fix: replace pickle with dill and run blocking tasks via joblib wrapper

* feat: add log format settings, dynamic parallelism & pickle-based snapshot

* fix: default step semaphore to 1 and avoid subprocess when single worker

* merge bowen's changes

* merge tim's changes

* refactor: extract component task mapping, add conditional logger setup

* lint

* refactor: add type hints and safer remain_time metric logging in workflow

* lint

* fix: allow BadRequestError to be pickled via custom copyreg reducer

* fix: stop loop when LoopTerminationError is raised in LoopBase

* lint

* refactor: make log tag context-local using ContextVar for thread safety

* feat: add subproc_step flag and helper to decide subprocess execution

* fix: use ./cache path and normalize relative volume bind paths

* fix: reset loop_idx to 0 on loop restart/resume to ensure correct flow

* fix: avoid chmod on cache and input dirs in Env timeout wrapper

* fix: skip chmod on 'cache' and 'input' dirs using find -prune

* fix: restrict chmod to immediate mount dirs excluding cache/input

* fix: chmod cache and input dirs alongside their contents after entry run

* fix: guard chmod with directory checks for cache and input

* fix: prefix mount_path in chmod command for cache/input dirs

* fix: drop quotes from find exclude patterns to ensure chmod executes

* fix: skip chmod on cache/input directories to avoid warning spam

* feat: support string volume mappings and poll subprocess stdout/stderr

* support remove symbolic link

* test: use dynamic home path and code volume in LocalEnv local_simple

* fix: skip trace and progress update when loop step is withdrawn

* refactor: add clean_workspace util and non-destructive workspace backup

* fix: preserve symlinks when backing up workspace with copytree

* fix: prevent AttributeError when _pbar not yet initialized in LoopBase

* perf: replace shutil.copytree with rsync for faster workspace backup

* fix: cast log directory Path to str in tar command of data science loop

* fix: use portable 'cp -r -P' instead of rsync for workspace backup

* fix: add retry and logging to workspace backup for robustness

* refactor: extract backup_folder helper and reuse in DataScienceRDLoop

* fix: propagate backup errors & default _pbar getattr to avoid error

* fix the division by zero bug

* refactor: execute RD loops via asyncio.run and add necessary imports

* lint

* lint

* lint

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
2025-06-12 11:44:14 +08:00
xuangu-fang ba76063069 feat: enable to set different version of idea-proposal for multi traces (#895)
* fix the logic of kb-inject, allow different verion

* set more flexiable proposal-version change for multi-tarce

* auto-lint

* fix the divede-zero-bug in a trival way

* keep the dump imp. first, update in next version

* use get_sub_trace_count() to get trace_num_count

* fix the conern case bug of divide-zero

* update corner case

* fix the bug

* auto-lint

* fis the bug

* fix the logic bug in max_sota_filter

* fix bug of old version of self.exp_gen.gen

* update the reset_exp_gen_version

* use get_parent_exps to replace all  collect_all_ancestors

* auto lint

* fix the bug of reset_exp_gen_version

* fix bug: update V3's old hypothesis_rank

* trival patch on gap of V3 & V2

* make dump patch to unify proposal_V3's dentify_problems

* auto-lint

* fix the bug of sub_trace_count
2025-06-11 23:13:30 +08:00
Haoran Pan d18271275e docs: update llm setting guidance and "REASONING_THINK_RM" description (#943)
* update llm setting guidance and "REASONING_THINK_RM" description

* remove deprecated backend in readme
2025-06-11 15:45:22 +08:00
Tim a4986c415c fix: 'DSProposalV2ExpGen' object has no attribute 'COMPONENT_TASK_MAP… (#950)
* fix: 'DSProposalV2ExpGen' object has no attribute 'COMPONENT_TASK_MAPPING'
* chore: add get_component function
2025-06-09 21:49:46 +08:00
Jensen Lee 155675d4bf fix: filter system metadata dirs and init missing DSTrace attribute (#946)
* fix: filter system metadata dirs and init missing DSTrace attribute

* style:pre-commit
2025-06-07 19:44:23 +08:00
you-n-g 15e3ba9004 docs: Update README.md (#948) 2025-06-07 15:24:25 +08:00
Yuante Li 671771a626 docs: update document for RD-Agent(Q) (#940) 2025-06-07 14:41:02 +08:00
Tim 63ba3296dd chore: continue to read output (#945) 2025-06-07 13:22:56 +08:00
Linlang 805f337fc4 chore: add a rdagent server with UI & logger storage refinement(#553)
* change_log_object

* lint code

* delete comments

* change_log_object

* change_log_object

* fix import test error

* update code

* update code

* fix bugs

* skip mypy error

* skip mypy error

* skip mypy error

* Start the flask server before running the demo.

* achieve front and back interaction

* fix github-advanced-security comments

* fix github-advanced-security comments

* tmp ignore

* fix CI

* move some logic

* change format

* adjust logic

* log2json changes

* tmp

* fix

* fix bug

* refine log2json between 5 scenarios

* fix

* refine codes

* fix logic

* use localhost

* add loop & all_duration param for old scenario startup

* merge control logic

* add README for server ui api

* update README

* reuse code in logger

* add loop_n and all_duration param

* fix upload

* ui server now use port in setting

* fix port setting

* fix port setting

* fix mypy check

* refine logger and log storage

* fix ruff error

* fix CI

* refine logger, loop, storage

* bind one FileStorage with one logger

* not truncate log storage

* refine LoopBase.load(), use `checkout` instead of `output_path` and `do_truncate`

* clear session folder when loading loop to run

* move component info init step to ExpGen Class

* Update rdagent/utils/workflow.py

* move truncate_session function to LoopBase class

* add checkout param for other scenarios

* fix bug

* move WebStorage to UI

* change web_storage name

* add randomname to requirements

* add typer

* fix requirements

---------

Co-authored-by: WinstonLiyte <1957922024@qq.com>
Co-authored-by: Bowen Xian <xianbowen@outlook.com>
Co-authored-by: you-n-g <you-n-g@users.noreply.github.com>
2025-06-06 18:52:19 +08:00
you-n-g bdaa376569 chore: update load add & (#944) 2025-06-06 16:58:09 +08:00
Haoran Pan de6b7f7648 feat: update prompt to improve json respond format of some LLM models (#928)
* update prompt to improve json respond format of some LLM models

* fix

* fix

---------

Co-authored-by: WinstonLiyte <1957922024@qq.com>
2025-06-06 11:49:40 +08:00
Tim 5bb5722921 fix: conda error information (#941)
* test with conda error

* reformat
2025-06-06 11:45:48 +08:00
XianBW 1a61d51fa8 change qlib install method (#937) 2025-06-05 11:40:46 +08:00
XianBW 2b7e0c4bd0 refine debug window logic (#936) 2025-06-05 11:29:37 +08:00
XianBW 311c2bf977 fix detect scenario logic (#935) 2025-06-05 11:19:09 +08:00
XianBW 50702e254e some update (#934) 2025-06-05 10:56:54 +08:00
Tim 543fb2c1ef fix: ds trace (#929)
* fix: remove_ansi_codes
* chore: rename function
2025-06-04 18:30:29 +08:00
Tim 51a5247285 feat: merge selectively (#888)
* chore: avoid incorporate changes
best as sota
merge hypothesis
fix: max_retrieve_num after decision
chore: select last experiments and feedbacks
* add the set_current_selection before the exp_gen when merging
add trace.NEW_ROOT
fix: no scen_prob_multiplier
fix: use regex with timeout
chore: hypothesis_rank with selected_idx
chore: define is_parent in proposal
chore: rename collect_all_ancestors to get_parent_exps
---------

Co-authored-by: you-n-g <you-n-g@users.noreply.github.com>
Co-authored-by: Young <afe.young@gmail.com>
Co-authored-by: Xu <v-xuminrui@microsoft.com>
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-06-04 14:46:47 +08:00
you-n-g a1843a9c4e feat: log reaching max time limit before breaking CoSTEER evolution (#921) 2025-06-03 12:51:56 +08:00
Yuante Li b1029cbd5a docs: update README for RD-Agent(Q) (#913) 2025-05-30 12:28:52 +08:00
you-n-g 0611a0846a fix: default cost to NaN when calculation fails in LiteLLM backend (#912)
* fix: default cost to NaN when calculation fails in LiteLLM backend

* lint

* lint
2025-05-29 22:58:29 +08:00
you-n-g 4974277f1c feat: add last_exp_fb to DSTrace and update feedback retrieval usage (#910)
* feat: add last_exp_fb to DSTrace and update feedback retrieval usage

* fix: use trace.last_exp_fb for previous trial feedback description
2025-05-29 20:32:06 +08:00
Tim a7c6fca8b4 chore: withdraw for policy error (#907)
* chore: withdraw for policy error

Co-authored-by: you-n-g <you-n-g@users.noreply.github.com>

* Apply suggestions from code review
2025-05-29 17:23:06 +08:00
Tim 1091d5ea29 fix: use trace count as index (#909) 2025-05-29 16:52:37 +08:00
XianBW 63ebdb5ada fix loop_num calc logic (#911) 2025-05-29 16:40:57 +08:00
Yuante Li d6ce70b551 feat: add RD-Agent-Quant scenario (#838)
* fix model input shape bug and costeer_model bug

* fix a bug

* fix a bug in docker result extraction

* a system-level optimization

* add a filter of stdout

* update

* add stdout to model

* model training_hyperparameters update

* quant scenario

* update some quant settings

* llm choose action

* Thompson Sampling Bandit for action choosing

* refine both scens

* add trace messages for quant scen

* fix some bugs

* fix some bugs

* update

* update

* update

* fix

* fix

* fix

* update for merge

* fix ci

* fix some bugs

* fix ci

* fix ci

* fix ci

* fix ci

* refactor

* default qlib4rdagent local env downloading

* fix ci

* fix ci

* fix a bug

* fix ci

* fix: align all prompts on template (#908)

* use template to render all prompts

* fix CI

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>

* add fin_quant in cli

* fix a bug

* fix ci

* fix some bugs

* refactor

* remove the columns in hypothesis if no value generated in this column

* fix a bug

* fix ci

* fix conda env

* add qlib gitignore

* remove existed qlib folder & install torch in qlib conda

* fix workspace ui in feedback

* align model config in coder and runner in docker or conda

* fix CI

* fix CI

---------

Co-authored-by: Xu Yang <peteryang@vip.qq.com>
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-05-29 16:16:51 +08:00
Haoran Pan 628deade72 feat: enhance compatibility with more LLM models (#905)
* add try-except to avoid retry when using completion_cost

* feat: add JSON prompt injection and think tag removal handling

* refactor: simplify cost handling in LiteLLM backend and clean up style

* docs: clarify purpose of reasoning_think_rm in LLMSettings

* refactor: remove unused *args and redundant cost assignment

---------

Co-authored-by: Young <afe.young@gmail.com>
2025-05-29 15:21:34 +08:00
Roland Minrui 29c245c6e3 fix: fix the problems weights bug (#898)
* fix the problems weights bug

* refactor: remove DSExpGen

* update problems weights calculation

* update problems weights calculation

* remove the selection parameter from exp_gen

* v2 support draft

* v3 also support decomposition

* make the identify_problems an independent function

* fix minor bug

* reformat

* rename exp_num to weighted_exp_num

* add the set_current_selection before the exp_gen when merging

* reformat

* fix wrong selection

* refactor: drop selection arg from ExpGen.gen and DS merge generators

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
Co-authored-by: Young <afe.young@gmail.com>
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-05-28 11:14:37 +08:00
amstrongzyf 2e39700eeb docs: add docstring for confusing columns in logs dir (#902)
* Docs updated

docs: add docstring for confusing columns in ds-summary

* update

* update black format
2025-05-27 20:54:32 +08:00
Roland Minrui 370adbfa1e fix: refine feedback prompt (#901)
* feedback observation must base on evidence

* avoid too strong constrain

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
2025-05-27 19:41:23 +08:00
Tim dbaf70ce57 chore: add kill after for timeout (#899) 2025-05-27 12:02:22 +08:00
Haoran Pan 3c6f9ef76d docs: update guidance for running mle-bench (#896)
* update guidance for running mle-bench

* ci issue

* Update guidance for setting kaggle api
2025-05-26 17:43:43 +08:00
XianBW 0109b044a0 add select_best param for log.ui.utils.compare tool function (#897) 2025-05-23 18:32:31 +08:00
Yuante Li 5a62b47e95 fix: fix the bug in the regular expression matching for stdout (#890) 2025-05-23 14:13:31 +08:00
Tim 5b47c0ab5c feat: raise policy violation (#894) 2025-05-22 16:54:34 +08:00
xuangu-fang 3e60749f70 fix: fix the bug of Exceed-LLM-Context in online merge of multi-tarce (#892)
* set constrains on max_sota_retrieved, fix logis on identical problem

* fix: only Auto SOTA selector use max_sota_retrieved_num

* set max_sota_retrieved_num=10 by default

* minor update

* auto lint
2025-05-22 16:10:00 +08:00
you-n-g cfa5f382aa docs: update paper report (#893)
* doc: update paper report

* Update README.md

* Update README.md

* Update README.md
2025-05-22 15:37:34 +08:00
Yuge Zhang 9ea44be5f8 feat: new proposal (structured outputs) prompts (#887)
* some initial modifications

* first prompt

* refine prompts

* isolate to v3 exp gen

* Revert prompts

* Add hypothesis

* task gen prompt

* minor updates

* minor updates

* update proposal

* Move the pydantic schema upfront to avoid loading error

* Update first prompts

* New prompt

* Update prompt

* Update data folder

* .

* Revert changes

* support v3 in pipeline and feedback

* sort imports

* black format

* Update rdagent/scenarios/data_science/dev/prompts.yaml

Co-authored-by: you-n-g <you-n-g@users.noreply.github.com>

---------

Co-authored-by: Xu Yang <peteryang@vip.qq.com>
Co-authored-by: you-n-g <you-n-g@users.noreply.github.com>
2025-05-22 15:08:33 +08:00
XianBW 37e9912ac0 chore: organize the tool functions related to trace and summary (#889)
* provide get metric direction in kaggle_crawler.py

* move utils function

* move statistics logic

* fix CI

* fix CI

* fix CI

* fix CI

* move some tool functions

* fix CI

* move curves win

* add compare tool

* change function name

* fix CI
2025-05-21 17:20:31 +08:00
xuangu-fang bc9cee49ba feat: multi-trace online merge (#886)
* prompt: highlight overfitting rist in AutoSOTAexpSelector

* set online merge time in conf

* online multi-trace merge with time-limit policy

* fix typo

* feat: allow soft-knowledge-base + multi_trace

* fix: improve file tree and _walk symlink handling (#877)

* refactor: improve file tree and _walk symlink handling

* remove unused code

* lint

* prompt: highlight overfitting rist in AutoSOTAexpSelector

* set online merge time in conf

* online multi-trace merge with time-limit policy

* fix typo

* feat: allow soft-knowledge-base + multi_trace

* auto-lint

* put the multi-trace related config together

---------

Co-authored-by: you-n-g <you-n-g@users.noreply.github.com>
2025-05-19 17:59:42 +08:00
Linlang 763dff1596 fix mypy check dependence error (#885) 2025-05-18 15:15:32 +08:00
XianBW fe11ee92e6 chore: ui bug fix (#884)
* bug fix

* bug fix

* test ci

* bug fix

* ci fix

* ci fix
2025-05-18 11:08:41 +08:00
XianBW 2c11752a54 chore: log storage refine (#883)
* log storage change

* fix bug

* fix ci
2025-05-16 18:29:59 +08:00
you-n-g 7aea9a27dc fix: use fallback messages for missing submission and scores files (#882) 2025-05-16 14:39:47 +08:00
Linlang 0c97fe4ae7 update_QR_code_url (#881) 2025-05-16 14:13:40 +08:00
you-n-g 586349af36 fix: update DS env setup with competition volume and timeout (#878)
* refactor: update DS env setup with competition volume and timeout

* refactor: update volume mapping and timeout based on run type
2025-05-16 02:05:15 +08:00
you-n-g 5b3f5f66cf fix: improve file tree and _walk symlink handling (#877)
* refactor: improve file tree and _walk symlink handling

* remove unused code

* lint
2025-05-16 00:11:25 +08:00
Xu Yang 69e5c3a7de doc: small typo in README (#876) 2025-05-15 21:40:39 +08:00
cslwqxx b76abe839b Update README.md (#875) 2025-05-15 21:32:20 +08:00
Xu Yang c8c8e26812 add multi trace results (#873)
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-05-15 20:29:52 +08:00
XianBW 42ea6f106b fix debug_tpl and debug_llm saving method(#874) 2025-05-15 18:37:51 +08:00
you-n-g 7742a9e759 docs: update README.md (#871) 2025-05-14 11:32:23 +08:00
you-n-g 8acd24a016 chore: news MLE-bench release (#870)
* docs: add MLE-bench details to README

* docs: update README with revised MLE-bench description and leaderboard

* docs: update RD-Agent text and add trial info in README

* Update README.md

* Update README.md

* update by M

* update format

* Add documents

* docs: update RD-Agent references to R&D-Agent

* docs: update README with MLE-Bench complexity level details
2025-05-14 11:21:13 +08:00
you-n-g 54465d6e82 feat: add competition level filter and extract constants to utils (#869)
* feat: add competition level filter and extract constants to utils

* lint
2025-05-12 21:56:57 +08:00
Roland Minrui 90f6c94d3e fix coder bug (#868)
Co-authored-by: Xu <v-xuminrui@microsoft.com>
2025-05-12 17:20:26 +08:00
Tim 7f4e5096e8 chore: custom data refine (#864)
* chore: print up to 100 columns in simple mode

* fix: check content for model dump

* chore: add show_nan_columns config
2025-05-10 17:02:12 +08:00
you-n-g a294bc74e0 feat: truncate by time (#863)
* refactor: move session file lookup logic to folder utils module

* print more info

* lint
2025-05-10 00:42:59 +08:00
xuangu-fang e71d8f6c3c feat: advanced checkpoint selectors (#790)
* rebase selection code

* bug-free run: checkpoint selection and dynamic EDA loading

* add prototypes of various selectors, to imp. and test later

* fix EDA write bug

* imp SOTA-Jump policy

* fix small bug

* allow to set different selector by .env

* add always-win selector

* add init length for AlwaysWinCKPSelector

* add back_jump selector

* auto lint

* add sota_exp_to_submit attribute; change the name of ckp_selector and sota-selector

* fix bug

* auto lint

* working on auto sota selector

* add subtrace counter

* fix bug, remove unuse selector

* add auto sota selector

* auto lint

* fix bug

* fix small logic bug

* add logging

* add inject_diverse feat

* auto lint

* capable to None-select

* feat: add hypothesis_gen config and ExpGen2TraceAndMerge functionality

* refactor: use dynamic import for experiment generator instantiation

* feat: add BestValidSelector for improved SOTA experiment selection

* runnable twin-trace version

* fix logic error of trace-merge

* auto lint

* use import_class to set selector,

* auto-lint

---------

Co-authored-by: Young <afe.young@gmail.com>
2025-05-09 15:38:25 +08:00
Xu Yang 5c7cdf298c fix: typo in workflow (#861) 2025-05-09 13:29:36 +08:00
Xu Yang 8a0a0fa3c4 feat: log api status to mlflow (#860)
* log api status to mlflow to frontend tracking

* fix CI

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-05-09 12:20:49 +08:00
Xu Yang 69c630e983 make timeout fail a hyper parameter (#859)
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-05-08 21:30:44 +08:00
XianBW ad12fccb61 change method of cut log trace (#858) 2025-05-08 21:07:33 +08:00
Roland Minrui 9986b5f9ce fix: refine the time/memory constraints prompt in hypothesis proposal (#856)
* refine prompt

* refine the wording

* add ratelimit retry to align with the suggested wait seconds

* add max retry to 0

* don't delete hist

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-05-08 21:05:07 +08:00
Linlang eb1cefb202 fix: fixed CI execution failures caused by document builds (#857)
* fixed CI execution failures caused by document builds

* add comments
2025-05-08 20:35:13 +08:00
XianBW 4f5cce0607 add cache for summary, remove workspace dependency when generate summary (#854) 2025-05-08 12:24:48 +08:00
you-n-g 495063c385 fix: adjust ds_trace lookup and add stderr redirect to mlebench command (#853)
* fix: adjust ds_trace lookup and add stderr redirect to mlebench command

* style: reformat SOTA experiment lookup in ds_trace.py

* feat: add DS_RD_SETTING pipeline to MergeExpGen success message
2025-05-08 02:40:49 +08:00
Xu Yang 318acb4922 fix: trace list but (#852) 2025-05-07 21:28:24 +08:00
XianBW 8340ab5d09 add aide.py (#851) 2025-05-07 19:59:40 +08:00
Xu Yang 22a0c7fe56 feat: revert draft stage into a soft decay in hypothesis selection (#849)
* revert drafting

* update hypothesis rank logic

* prioritize time constraint in task design

* refine trace_desc and feedback problem prompt

* refine experiment_and_feedback_list_after_init

* fix DSHypothesis default parameter and print logic

* refine the selection weight

* merge simple_trace and trace

* refine weight and prompt

* refine sample logic

* fix CI

* robust code

---------

Co-authored-by: WinstonLiyte <1957922024@qq.com>
Co-authored-by: Xu <v-xuminrui@microsoft.com>
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-05-07 19:05:50 +08:00
Tim 02534cfd88 chore: dump test data (#850)
* debug path for model dump
* update prompt
2025-05-07 17:24:50 +08:00
you-n-g 9a8426f373 fix: non-exist variable test_eval.py (#847) 2025-05-07 04:36:00 +08:00
you-n-g 6eef7517ad fix: wrong variable test_eval.py (#846) 2025-05-07 04:17:57 +08:00
XianBW 29a14e1e22 fix bug (#845) 2025-05-06 18:15:20 +08:00
Tim 6f9843a7df feat: custom data (#810)
* custom data

* fix: simplify competition check and log local description file

* no sample data

* feat: add test evaluation module with error handling support

* fix: update eval path to use eval_sub_dir and add valid_check TODO

* refactor: add MLETestEval check to conditionally run grading steps

* avoid blank stdout

* valid in testeval

* rename test.csv to avoid conflict

* Support Disabling sample submission

* refactoring

* fix: remove DS_KAGGLE_DATA and update prompt instructions

* add try for grade

* ignore submission

* fix: remove tee from eval command and warn about pipeline exit code detection

* optional to use raw description

* support old data

* add execution result to stdout

* add metric to raw description

* custom data explain

* add debug_path

* rst update

---------

Co-authored-by: Young <afe.young@gmail.com>
2025-05-06 16:00:13 +08:00
XianBW aa97d5a09d chore: ui change (#844)
* ui change

* ui change
2025-05-06 11:34:21 +08:00
you-n-g 6b7988fba1 feat: refine merge (#842)
* feat: add search_type param and customize success trial desc

* docs: simplify trial descriptions in share.yaml

* lint
2025-05-04 23:17:58 +08:00
you-n-g 93303873d0 fix: adapting UI to mock trace (#841)
* fix: return first index if 'SOTA Exp Score (valid)' is empty

* feat: add get_state_data_range helper for loops and slider bounds

* fix: exclude batch embedding tag from log filtering

* feat: add feedback support in sota_experiment and adjust merge flow

* fix: use fb function for merging experiments

* style: remove extra whitespace and reformat code
2025-05-04 15:51:32 +08:00
Xu Yang d0e3fc1573 fix new draft bugs (#840) 2025-04-30 18:53:27 +08:00
Haoran Pan cbedbc7d54 feat: reanalyze competition info & pipeline coding evaluator prompt (#837)
* update coding evaluator prompt similar to feedback

* reanaylyzing competition description when three sonsecutive coding failures

* update reanalyzing competition implementation

* fix bug

* update prompts and reanalyze

* fix bugs

* ci issue

* improve some code

* fix CI

---------

Co-authored-by: Xu Yang <peteryang@vip.qq.com>
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-04-30 17:36:35 +08:00
Roland Minrui 03040de35f 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 <v-xuminrui@microsoft.com>
2025-04-30 16:25:32 +08:00
you-n-g a73f2dbc12 feat: trace merging (#836)
* feat: runnalbe -- add exp_gen_cls param, get_leaves and merge exp gen functionalities

* fix: remove unused scenario_desc and update YAML task labels

* feat: override selection and update merge task description

* lint

* lint

* lint

* lint

* lint

* fix: log competition setting to enable mle_summary

* fix name error
2025-04-29 09:30:45 +08:00
Xu Yang 45931b1012 when restart with kb and different pkl path, we need to initialize the kb from json file (#835) 2025-04-28 15:51:51 +08:00
Tim 6c179442bf chore: log cost object (#829) 2025-04-25 19:26:08 +08:00
Xu Yang 8affbf89a9 add pipeline to hypothesis spec (#828) 2025-04-25 18:29:14 +08:00
Roland Minrui 8968ab8c9a feat: propose hypothesis across multiple parts in pipeline (#827)
* refine hypothesis for pipeline

* refine component selection prompt

* update feedback prompt

* remove feat_eng in pipeline coding

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
Co-authored-by: Xu Yang <peteryang@vip.qq.com>
2025-04-25 17:17:53 +08:00
Xu Yang c89321f5a2 fix: add time to timer when api timeout bug (#826)
* If not use the session stored timer, need to replace it with the default timer

* when api timeout, add the waiting time to timer
2025-04-25 10:50:27 +08:00
Xu Yang d6990a12b8 If not use the session stored timer, need to replace it with the default timer (#825) 2025-04-25 00:39:31 +08:00
Yuante Li 86e05e6d35 fix: fix a bug in docker result extraction (#824)
* fix a bug in docker result extraction
2025-04-24 19:02:38 +08:00
XianBW fda5c281a8 can set reasoning_effor=None in chat_model_map (#823) 2025-04-24 18:47:24 +08:00
XianBW 4f2a915da5 feat: using different chat model in different part (#822)
* using model in the chat_model_map in one tag

* add replace timer to DS loop

* fix CI

* fix CI

* add more custom config in chat_model_map

* fix CI

* fix CI

* fix CI

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-04-24 18:22:51 +08:00
Yuante Li ff99e4dc2c fix: fix model input shape bug and costeer_model bug (#821)
* fix model input shape bug and costeer_model bug

* fix a bug
2025-04-24 12:48:25 +08:00
Xu Yang c5beaeeaf8 fix: update runner max loop to 1 in DS scenario (#820) 2025-04-23 19:15:29 +08:00
Yuante Li 82b037cb63 fix: fix some minor bugs in qlib scenario (#817)
* fix some bugs

* fix a bug

* fix a bug in qlib frontend

* fix ci

* fic ci

* fix qlib Dockerfile
2025-04-23 18:48:02 +08:00
Haoran Pan 456ed100a0 update qrcode (#818) 2025-04-23 16:12:48 +08:00
Yuante Li 0798c05cb7 fix: improve eval alignment check (e.g. small-scale finetuning) (#802)
* fix

* fix
2025-04-22 18:47:24 +08:00
Xu Yang 7dbffc516d feat: add mlflow logger in RD loop to log (#815)
* add mlflow logger in DS loop

* fix CI

* fix CI

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-04-22 01:23:40 +08:00
Xu Yang 4509d92ea7 feat: archive python and csv files in workspace to maintain results (#814)
* archive workspace also

* remove non python csv and md files in workspace to avoid big workspace dump

* FIX ci
2025-04-21 16:34:29 +08:00
XianBW 19bb2e740e fix: align competion_full_desc and scenario_all_desc, remove redundant info in problems proposal (#808)
* align competition desc & scenario desc string

* remove competition_desc when having used scenario_desc in problem gen

* fix bug

* remove redundant competition desc in naive expgen

* improve proposal prompt

* modify phrase

---------

Co-authored-by: Xu Yang <peteryang@vip.qq.com>
2025-04-18 16:48:26 +08:00
XianBW 2fea82bee7 add select lite and select best button (#809) 2025-04-18 16:28:31 +08:00
Xu Yang c68b597069 fix: bug fix in timer start (#807) 2025-04-18 16:16:28 +08:00
Xu Yang bbb9d36f77 fix: bug in problem identification (#806) 2025-04-18 15:46:11 +08:00
Roland Minrui e44bb2dcc1 feat: idea pool integrated to exp_gen & add timer to RD-Agent & pause-resume to RD-loops (#795)
* update all code

* update all code

* dump knowledge base

* rename the tag

* add timer to RD-Agent

* fix CI

* fix CI

* use batch embedding

* fix a small bug

* fix prompt bug

* feat: add pause resume to handle K8S cluster pause (#804)

* add resume to cluster running

* fix non-pickle problem

* fix a small bug

* fix a small bug

* avoid shutil move error

* refine the logic

* move knowledge base out of session

* avoid mistake information to pipeline coding

* avoid load and dump in steps

* archive the right folder

* small improvement

* avoid restart when timer is already started

* fix CI

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>

---------

Co-authored-by: Xu Yang <peteryang@vip.qq.com>
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
Co-authored-by: Xu <v-xuminrui@microsoft.com>
2025-04-18 14:01:03 +08:00
Linlang 08fc2dcef3 chore: modify kaggle docs & Adding ds_loop at program entry (#786)
* modify kaggle docs

* optimise code based on comments

* Update docs/scens/kaggle_agent.rst

* fix docs build error

---------

Co-authored-by: you-n-g <you-n-g@users.noreply.github.com>
2025-04-17 22:02:49 +08:00
you-n-g c2759a2a0a refactor: use remove_eda_part for EDA cleanup, fix diff eval (#800) 2025-04-17 16:19:26 +08:00
Linlang 05092c5c5b update wechat qrcode (#798) 2025-04-16 21:39:56 +08:00
XianBW d9cee55063 fix retry when hypothesis gen (#796) 2025-04-16 19:01:46 +08:00
you-n-g fe3337d6ff refactor: use dynamic input path and update template loader (#792)
* refactor: use dynamic input path and update template loader

* fix: update include syntax for data source in prompts.yaml

* add customization path

* docs: update prompts for ensemble scoring and metric direction

* chore: remove obsolete data_science/share.yaml file
2025-04-16 18:11:46 +08:00
Xu Yang 90f6fde3d4 feat: raise error when timeout in api call (#793)
* small change to try catch in backend

* fix CI

* add timeout tolerance to 3
2025-04-16 13:50:20 +08:00
you-n-g 0e3dcc2d8d feat: refine prompt (#760)
* style: Simplify language and improve clarity in prompts and share.yaml

* style: Update prompt wording for clarity in raw_data_loader

* style: Simplify conditional logic in task_gen system prompt

* refactor: Update prompts and proposal for component output format handling

* fix: Correct grammar and add clarification in prompts.yaml

* feat: Include coding guidelines in data science component prompts

* lint
2025-04-16 09:35:30 +08:00
you-n-g aedd0a0f72 fix: update metric direction to return bool (#791) 2025-04-15 17:10:31 +08:00
Roland Minrui 214da4826f fix: add wait_retry to exp_gen v2 (#783)
* add wait retry to v2

* format

* fix a bug

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
Co-authored-by: yuanteli <1957922024@qq.com>
2025-04-14 11:02:45 +08:00
you-n-g f25d729a02 fix: import path of T (#787)
* feat: add DocDev for auto-generating workspace documentation

* fix: update markdown instructions in tpl.yaml

* feat: add enable_doc_dev flag and conditionally call DocDev

* refactor: update T import and prompt keys for DocDev

* fix: update include path for MarkdownOut template

* fix: update file search, README injection, and brief prompt text

* docs: update prompt to only introduce models

* lint
2025-04-13 10:21:24 +08:00
Yuante Li 773b7ac439 fix: fix competition metric direction (#784) 2025-04-11 16:25:30 +08:00
Yuante Li 19dd259165 refactor: refactor feedback logic and fix bug in task_gen (#782)
* task gen refine & feedback refine

* fix

* refine feedback logic

* fix a bug

* fix

* fix

* fix ci
2025-04-11 15:52:52 +08:00
you-n-g ab52e1b65c feat: add DocDev for auto-generating workspace documentation (#781)
* feat: add DocDev for auto-generating workspace documentation

* fix: update markdown instructions in tpl.yaml

* feat: add enable_doc_dev flag and conditionally call DocDev
2025-04-10 20:12:21 +08:00
Xu Yang 959f2fa076 still assign five component to pipeline (#780) 2025-04-10 18:30:32 +08:00
Tim f06e6986c8 chore: fit more competition (#723)
1. Remove potential <code> tags from the generated code.
2. Use return codes in data_loader, feature, and model.
3. Configure the debug timeout.
2025-04-10 17:56:57 +08:00
Tim b5631b9f78 feat: pull image with progress (#777)
pull image with progress
2025-04-10 12:00:27 +08:00
you-n-g b662f45021 feat: dump model (#776)
* feat: add model dump flag and multi-evaluator support

* tmp code

* refactor: update evaluator feedback and FBWorkspace types

* feat: add get_clear_ws_cmd and CPU count in Docker environment

* feat: Add model dump check level and enhance evaluator functionality

fix data type bug

* fix: Ensure required files exist before model dump evaluation

* refactor: streamline prompt and file checks in model dump evaluation

* fix: add assertions and reorder file reads in model dump evaluator

* feat: remove EDA part from evaluation output

* docs: update dump_model guidelines and eval prompt to include template

* style: reformat multiline dicts and lists in conf and eval files

* fix: add DOTALL flag to EDA removal regex
2025-04-09 23:24:12 +08:00
XianBW 92d007e179 ui updates (#778) 2025-04-09 20:11:00 +08:00
you-n-g c40f22361c refactor: update MLEBench submission validation logic in runner and eval (#769)
* refactor: Update MLEBench submission validation logic in runner and eval

* lint

* Delete docs/scens/data_science.rst

* fix: update variable name in feedback prompt

* define a variable: submission_check_out

* fix: update submission check handling for MLE data

* refactor: reformat if condition for clarity

---------

Co-authored-by: Linlang <Lv.Linlang@hotmail.com>
2025-04-09 13:34:48 +08:00
Linlang e22fb84fb3 update wechat qrcode (#775) 2025-04-09 12:23:38 +08:00
XianBW 80c5eb209e catch llm_data pkl read exception (#774) 2025-04-09 12:21:54 +08:00
xuangu-fang 67114540b1 feat: checkpoint selection (#744)
* rebase selection code

* bug-free run: checkpoint selection and dynamic EDA loading

* add prototypes of various selectors, to imp. and test later

* fix EDA write bug

* move selector to from proposal.py tp seletc.py

* auto lint

* fix line-too-long typos

* aligh the design of "selection", rm extra instance check

* make auto-lint

* add non-trival selector: SOTAjump
2025-04-09 09:42:30 +08:00
Xu Yang 8517eb4a18 fix: update feedback.py (#772) 2025-04-08 23:35:11 +08:00
Xu Yang a16c79e45b small bug fix in feedback (#771) 2025-04-08 22:17:47 +08:00
XianBW ce23e1c30b chore: data science scenario UI updates (#770)
* fix some pandas warning

* fix load time logic

* optimize load_time logic

* fix CI

* fix bug
2025-04-08 19:33:20 +08:00
Xu Yang 92e7932126 add rule-based eval to speed up the whole process (#768) 2025-04-08 17:27:21 +08:00
Yuante Li 31752bb8f0 feat: merge failed and successful traces together (#766)
* merge failed and successful traces together

* delete the task description from the trace display

* prune unnecessary info for the proposal stage
2025-04-08 17:04:55 +08:00
Yuante Li 7372d1011e feat: add reviewer in feedback (#765) 2025-04-08 16:20:13 +08:00
XianBW a918f941dd add hypothesis table (#764) 2025-04-07 20:16:37 +08:00
XianBW dee11fbd9c fix: duplicate model names test in pipeline coder & runner (#763)
* add model name duplicate test in pipeline costeer

* fix ci
2025-04-07 19:06:42 +08:00
you-n-g 0dcc990bd4 fix: Set PYTHONPATH in env.run_ret_code call in FBWorkspace class (#755) 2025-04-07 18:15:33 +08:00
XianBW 3f41e868b3 chore: data science scenario UI updates (#757)
* ui changes

* add ours vs medal threshold

* add success loop statistic of components

* show times info

* UI updates

* summary selected

* change colors

* fix CI

* add stat hours param for `mle_summary.py --summary` command

* add 24h summary button

* fix CI

* add logger info for dockerEnv/condaEnv running time
2025-04-07 16:24:27 +08:00
Roland Minrui fac39e5588 remove buggy info in hypothesis rank (#762)
Co-authored-by: Xu <v-xuminrui@microsoft.com>
2025-04-07 14:09:36 +08:00
Xu Yang fce5342ad4 pretrained & validation alignment (#761) 2025-04-07 13:29:41 +08:00
you-n-g 44ada185f4 feat: add naive experiment generator and update proposal configurations (#759)
* feat: Add naive experiment generator and update proposal configurations

* lint

* lint
2025-04-07 13:01:29 +08:00
Yuante Li 6818ada2cf fix: fix some minor bugs (#758) 2025-04-04 23:54:54 +08:00
Yuante Li 11e8acc88b feat: add a check for whether values in score_df are NaN (#756)
* add a check for whether values in score_df are NaN

* fix ci

* change raise to assert
2025-04-04 22:44:55 +08:00
you-n-g 9415113e01 feat: add reasoning_effort parameter to LiteLLMAPIBackend and LLMSett… (#754)
* feat: Add reasoning_effort parameter to LiteLLMAPIBackend and LLMSettings

* style: Use consistent quotation marks for reasoning_effort literals
2025-04-04 19:37:40 +08:00
Xu Yang d3414ea07d fix: task_gen for better understanding (#752) 2025-04-04 17:09:26 +08:00
Tim 8bd2714814 feat: joblib cache (#749)
* cache function

* fix test

* bin cache

* fix test

* fix test

* fix test

* cache for different source

* cache for localenv

* remove unnecessary log

* reformat

* remove unrelated modify
2025-04-04 12:08:18 +08:00
Tim 200764d38b workflow entrypoint check (#748) 2025-04-04 12:07:46 +08:00
you-n-g c1c1342a9e chore(main): release 0.4.0 (#454)
Release-As: 0.4.0
2025-04-04 11:51:31 +08:00
Linlang 756dfba53f fix: fix kaggle templates path error (#747)
* fix kaggle templates path error

* add env.py dependence

* reformat with lint
2025-04-04 11:20:33 +08:00
Xu Yang 1f0032bc50 fix when score is a string (#750) 2025-04-03 23:48:38 +08:00
Roland Minrui 9eded6faa8 feat: add hypothesis guidelines and rule-based ranking (#746)
* 1. add hypothesis guidelines 2. add weighted scoring

* fix CI & speed up exp_gen

* random but reproduciable choice on hypothesis

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
Co-authored-by: Xu Yang <peteryang@vip.qq.com>
2025-04-03 18:48:28 +08:00
you-n-g 8783781daa refactor: Improve data handling and representation in eval tests and prompts (#740) 2025-04-03 13:53:25 +08:00
Roland Minrui da8fbcf4ee feat: add pipeline coder (#742)
* init commit

* limit problem numbers

* ensemble lower case

* add runtime and spec to coder

* submission check notice

* sub EDA in sample execution

* avoid lightgbm

* add time limit to scenario

* rephrase the submission check

* give positive feedback when facing warning in check

* ENABLE FEEDBACK

* fix feedback bug

---------

Co-authored-by: Xu Yang <peteryang@vip.qq.com>
2025-04-03 13:00:11 +08:00
Linlang 22ed8b522b fix: fix KeyError direct_exp_gen (#735)
* fix KeyError direct_exp_gen

* fix KeyError direct_exp_gen

* fix fin_factor fetch data error
2025-04-03 12:01:10 +08:00
Haoran Pan 7fc5e73f76 fix: replace func "len()" in ensemble test code to support various data type (#739)
* replace len with def get_length

* update get_length implementation
2025-04-02 19:52:54 +08:00
Yuante Li e30768969d feat: add describe_data_folder_v2 (#738)
* add describe_data_folder_v2

* fix ci

* fix

* add packages
2025-04-02 19:38:43 +08:00
Xu Yang bc8e9dc23a costeer max loop as hyperp & skip workflow in eval (#737) 2025-04-02 14:18:42 +08:00
Roland Minrui 1474478768 feat: new exp gen v2 implementation (#725)
* first framework commit

* idea proposal v2

Co-authored-by: Roland Minrui <RolandMinrui@users.noreply.github.com>

* fix a small bug in v1

* fix a small bug

* add problem to DShypothesis

* use exp gen as unified interface

* merge yuante's code into pr

* fix a small bug in draft

* update all minrui's code

* small update

* fix small bug & remove useless code

* fix return type

* fix CI

---------

Co-authored-by: Xu Yang <peteryang@vip.qq.com>
Co-authored-by: Roland Minrui <RolandMinrui@users.noreply.github.com>
Co-authored-by: Xu <v-xuminrui@microsoft.com>
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-04-02 13:37:47 +08:00
you-n-g 260b563710 feat: loader prompt & simplify YAML loading and update data loader specifications (#736)
* refactor: Simplify YAML loading and update data loader specifications

* docs: Add comment explaining FunctionLoader usage in tpl.py

* lint

* lint
2025-04-01 22:36:25 +08:00
XianBW 3ef0b21350 chore: split dsapp to pages & add llm_logs showing (#733)
* split dsapp to pages & add llm_logs showing

* some changes

* small bug

* add time info

* do not test UI in test_import

* cache stdout
2025-04-01 20:55:10 +08:00
you-n-g 473b9000b9 feat: update prompts and descriptions for data science components (#731)
* docs: Update prompts and descriptions for data science components

* chore: Remove outdated comments from conf.py

* feat: Add metric_name attribute to DataScienceScen class

* style: Update description in prompts.yaml and reorder metric_name init

* docs: Update prompts.yaml with feature engineering guidelines
2025-04-01 20:54:42 +08:00
Yuante Li 00b31fa752 fix: fix a bug in regular expression exception processing (#734)
* fix a bug in regular expression exception precessing

* fix ci

* fix
2025-04-01 16:54:05 +08:00
Haoran Pan cc8ae7e1f0 update wechat group qrcode (#732) 2025-03-31 19:20:04 +08:00
Yuante Li 752de9dc67 feat: add a tool to enable saving workspace files into a specific folder (#728)
* add a tool to enable saving workspace files into a specific folder

* fix

* fix
2025-03-28 16:22:27 +08:00
you-n-g a99276d59b feat: track and log accumulated completion cost in LiteLLMAPIBackend (#727)
* feat: Track and log accumulated completion cost in LiteLLMAPIBackend

* refactor: Use variable for retry count and update import formatting

* lint

* fix: Allow chat_max_tokens to be None in LLMSettings

* feat: Add logging for LiteLLM settings and finish reason in cost calculation
2025-03-28 12:24:19 +08:00
XianBW 450571e86e fix: add metric name check for valid scores (#724)
* update metric_name

* fix some bugs

* add an evaluation in workflow

* add an evalution in runner

* fix ci

* test change

* fix CI

---------

Co-authored-by: TPLin22 <tplin2@163.com>
Co-authored-by: yuanteli <1957922024@qq.com>
2025-03-27 19:36:57 +08:00
XianBW 7fc9e18a71 feat: make spec optional (#719)
* feat: Add spec_enabled configuration for data science settings

* make spec alternative

* change spec logic in exp_gen

* remove some general texts

* align

---------

Co-authored-by: Young <afe.young@gmail.com>
Co-authored-by: yuanteli <1957922024@qq.com>
2025-03-27 17:17:41 +08:00
you-n-g 031d264957 docs: Add note on running Docker without sudo in installation guides (#721) 2025-03-27 10:28:06 +08:00
Linlang 6da6fb5ee5 refactor: remove unused code and update documentation in CoSTEER module (#720)
* refactor: Remove unused code and update documentation in CoSTEER module

* fix mypy error

* fix black error

---------

Co-authored-by: Young <afe.young@gmail.com>
2025-03-26 22:48:01 +08:00
Haoran Pan 525b1a2136 update wechat qrcode (#718) 2025-03-25 22:23:33 +08:00
XianBW 61813cba67 chore: update data science scenario UI (#717)
* UI changes

* remove hardcode

* fix CI
2025-03-21 18:11:06 +08:00
Hamza Bouajila b33be5ed5b docs: add contributing guidelines for rdagent (#710)
* docs: add contributing guidelines for RD-Agent

* docs: update contributing guide to include CI checks before pull requests and refrer to it in the home page README
2025-03-21 15:56:13 +08:00
Haoran Pan 6b856e2217 docs: update readme and installation guide for litellm backend addition (#703)
* docs: Update README and installation guide for LiteLLM backend addition

* docs: update LiteLLM Backend configuration guide

* remove and add some llm settings docs

* CI Issue

* CI Issue

* update docs

---------

Co-authored-by: Young <afe.young@gmail.com>
2025-03-21 14:55:30 +08:00
Linlang f5f3e050ab fix: fix docs build error (#711)
* fix docs build error

* delete test code

* add comments
2025-03-21 14:44:35 +08:00
you-n-g 9a43e15bf4 feat: Add line length limit to shrink_text function and settings (#715) 2025-03-21 00:41:52 +08:00
XianBW 251800396d add task type logger tag in coding (#714) 2025-03-20 19:15:37 +08:00
Yuante Li 5f3e382248 fix: fix a bug in ensemble test script (#713)
* fix a bug in ensemble test script

* fix

* add a comment
2025-03-20 17:35:39 +08:00
Yuante Li fa0dbb69fe fix: fix a bug in progress_bar filter (#712)
* fix a bug in progress_bar filter

* fix
2025-03-20 16:02:09 +08:00
Linlang f1e4e9900c fix docs build error (#709) 2025-03-20 11:39:19 +08:00
Haoran Pan 203be39ad6 docs: update wechat community qrcode (#704) 2025-03-19 20:17:41 +08:00
XianBW 60b66aa6c9 change only model codes in model coder (#707) 2025-03-19 19:37:26 +08:00
XianBW b91471181c fix coverage using method (#706) 2025-03-19 19:00:53 +08:00
Yuante Li a48abf4a84 fix: clarify an ambiguous explanation (#705) 2025-03-19 17:57:04 +08:00
Yuante Li 5b14779f69 feat: add cross validation to workflow (#700) 2025-03-19 17:56:42 +08:00
you-n-g 8ea8817e7d fix: default emb model (#702)
* fix: Remove incorrect prefix from default embedding model name

* refactor: Consolidate model settings in LLMSettings class
2025-03-19 12:27:45 +08:00
Yuante Li fd747fe741 fix: align components' name (#701) 2025-03-19 11:27:43 +08:00
Linlang b666397786 fix: fix combined_factors_df.pkl not loading in docker (#697)
* Fix combined_factors_df.pkl not loading in docker

* change combined factors file type

* change qlib commit id
2025-03-18 18:36:21 +08:00
XianBW 31381743f7 feat: out spec change for o1-preview (#666)
* add not_json batcheditout

* ensemble out_spec change

* feature out_spec change

* model out_spec change

* workflow out_spec change

* runner debugger out_spec change

* filter_progress_bar return format fix

* data_loader and spec out_spec change

* show finish_reason in llm log

* json_mode fix

* remove hardcode

* fix CI

* fix grammer

* complete PythonBatchEditOut logic

---------

Co-authored-by: yuanteli <1957922024@qq.com>
2025-03-18 17:43:44 +08:00
Yuante Li e564b418e1 fix: fix some description errors in direct_exp_gen (#698)
* fix some description errors in direct_exp_gen

* delete an unused module
2025-03-18 16:21:59 +08:00
Ikko Eltociear Ashimine d1031ed24d refactor: update evolving_strategy.py (#686)
implmentation -> implementation
2025-03-18 16:15:08 +08:00
XianBW d66c045115 fix: add check when retrying gen model codes (#699)
* add check when retrying gen model codes

* fix CI
2025-03-18 15:59:34 +08:00
Yuante Li 7b3473cf30 feat: add model removal and adjust some framework logic (#681)
* prune model task

* add component_description

* add model removal logic to component, hypo, and task gen

* fix ci

* adjust coder to meet the requirement of model removal

* fix and refine the logic of model removal

* add model removal logic in model_eval

* fix ci

* fix ci

* prune some unnecessary codes
2025-03-18 14:42:53 +08:00
XianBW 1d6e97cb99 fix preds_dict's keys (#695) 2025-03-17 23:33:17 +08:00
XianBW 3d7b2b4567 fix: runner COSTEER evaluator (#693)
* fix scores.csv and submission.csv check in runner eval

* add coverage check info in running COSTEER feedback

* feedback value fix
2025-03-17 23:12:59 +08:00
Yuante Li b8a699a0df fix: fix a minor bug (#694) 2025-03-17 21:43:26 +08:00
Jake Roggenbuck 93b41c1414 fix: change devault to default (#688) 2025-03-17 21:28:13 +08:00
Yuante Li bb91201dd2 fix: fix a bug related to model_name in ensemble (#692)
* fix a bug related to model_name in ensemble

* refine
2025-03-17 21:23:57 +08:00
XianBW e0ae91b497 validate and update 'final_decision' before init CosTeerFeedback (#691) 2025-03-17 19:53:09 +08:00
Yuante Li b20692cbd4 fix: fix an error in model_coder prompt (#690) 2025-03-17 15:38:39 +08:00
cslwqxx 78e2665617 Update README.md (#689) 2025-03-17 14:11:34 +08:00
you-n-g 40f2b8f98b doc: Update README.md new (#679) 2025-03-16 22:34:29 +08:00
XianBW b033215ca9 fix: add force parameter for cache_with_pickle & using cache when get kaggle leaderboard (#687)
* use kaggleApi latest edition

* add 'force' for cache_with_pickle, use cache when getting kaggle leaderboard
2025-03-16 00:50:17 +08:00
XianBW 1f4432c39b fix PythonAgentOut extract (#685) 2025-03-14 21:12:10 +08:00
XianBW a9f0fd9786 fix: rich.print error when some control char in output (#684)
* fix rich.print error when some control char in output

* change conda env info printing

* fix import
2025-03-14 21:03:46 +08:00
XianBW 05bf05ca49 fix running part timeout (#683) 2025-03-14 17:56:41 +08:00
XianBW 9bba28093c check 'ensemble' in scores.csv in workflow eval (#682) 2025-03-14 17:40:06 +08:00
Roland Minrui 3519b718ea feat: add constraint labels for semantic search (#680)
* add constraint labels for semantic search

* reformat

* reformat

* reformat

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
2025-03-14 16:08:29 +08:00
XianBW cde173688b timeout message adjustment for Run Env (#677) 2025-03-13 16:57:10 +08:00
Yuante Li 68668d7a5b feat: display LLM prompt (#676)
* log llm prompt

* fix

* fix log llm messages problem

---------

Co-authored-by: Bowen Xian <xianbowen@outlook.com>
2025-03-13 15:57:17 +08:00
XianBW 55b914fe22 fix: save only one mle_score pkl for a running exp (#675)
* save only one mle_score pkl for a running exp

* fix_CI
2025-03-13 14:55:13 +08:00
XianBW b2c1b68d51 fix: mle_score save problem (#674)
* fix mle_score save problem

* fix CI
2025-03-12 20:54:05 +08:00
XianBW 14270354d1 change default to False of 'do_truncate' (#673) 2025-03-12 20:21:34 +08:00
XianBW 7b981cbf09 save mle_score to log folder with 'mle_score' tag (#672) 2025-03-12 19:40:23 +08:00
you-n-g 27596473c7 fix: correct the configuration inheritance relationship (#671)
* fix: Correct the configuration inheritance relationship

* lint
2025-03-12 18:49:00 +08:00
Roland Minrui 14421c6cde fix: return 1D embedding if create_embedding receive a string input (#670)
* return single dimension embedding for string input of create_embedding

* Update base.py

* fix

* fix

* fix

* fix

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
2025-03-12 16:10:33 +08:00
you-n-g 918b0b0d43 feat: condaenv & full docker env (#668)
* use conda to run kaggle and mlebench code

* refactor: Simplify environment configuration and execution logic

* add setting to use local env in ds

* refine dockerfile

* fix: Move MLEBDockerEnv initialization inside conditionals &  fix condaenv

* refactor: reformat code for better readability and consistency

* feat: add conda env to all envs.

* fix: fix bugs when run loop

* refactor: Simplify DockerEnv configuration in mle_summary.py

* fix image bug

* style: reformat code for better readability and consistency

* change commit

* feat: Add entrypoint script for sing_docker scenario in rdagent

* refactor: add Any type hints and comments for clarity in env.py

* feat: Create log directory if it doesn't exist in entrypoint script

* feat: Add debug mode and list root directory in entrypoint script

* fix: Remove specific branch checkout in Dockerfile for RD-Agent

* fix: Add competition argument to loop.py script execution

* fix: Correct directory navigation and dependency installation in entrypoint.sh

* fix: Correct user ownership assignment in entrypoint script

* refactor: Comment out redundant log copying to RD_OUTPUT_DIR

* fix: Unset LOG_TRACE_PATH to prevent log contamination in entrypoint.sh

---------

Co-authored-by: Xu Yang <peteryang@vip.qq.com>
2025-03-12 11:36:28 +08:00
Yuante Li 4cd20a464d feat: add rank into report (mle_summary) (#665)
* add rank into report (mle_summary)

* fix CI

* fix
2025-03-10 15:25:38 +08:00
Haoran Pan 1c628c6c1a update qrcode 25/03/07 (#664) 2025-03-07 17:59:49 +08:00
you-n-g a55af6fa00 fix: target json type & round (#662)
* refactor: Rename direct_exp_gen to json_target_type in DSExpGen class

* fix type

* fix: Adjust loop iterations and update json_target_type for nested dicts
2025-03-05 22:46:43 +08:00
you-n-g 824390e33c fix: direct_exp_gen to json_target_type in DSExpGen class (#661)
* refactor: Rename direct_exp_gen to json_target_type in DSExpGen class

* fix type
2025-03-05 22:27:46 +08:00
you-n-g 2171e99416 fix: fix ExtendedSettingsConfigDict does not work (#660)
* refactor: Replace ExtendedSettingsConfigDict with SettingsConfigDict

* lint

* lint
2025-03-05 18:30:02 +08:00
Haoran Pan b6ad5a6ed3 avoid selecting the same components too many times (#654) 2025-03-05 13:12:08 +08:00
Haoran Pan b49505be8e feat: variable printing tool of data_science coder testing (#658)
* update debug_info printing

* refine infomation printing

* update ensemble evaluator prompt

* substitute repr with reprlib.repr

* strip comments
2025-03-05 13:08:30 +08:00
Roland Minrui 2ed6ec53d9 feat: add do_truncate control for the load function (#656)
feat: add do_truncate control for the load function (#656)
2025-03-04 15:18:36 +08:00
Tim 30b52d7d57 scores.csv should not be rewritten (#653) 2025-02-28 19:56:20 +08:00
Haoran Pan d753daf758 update Wechat group QR code (#652) 2025-02-28 15:39:52 +08:00
Xu Yang 74cfc5b906 feat: add type checker to api backend & align litellm and old backend (#647)
* move cache auto continue and retry to all api backend

* add type checker to json mode output

* fix CI

* feat: Add json_mode handling and streaming support in chat completion function

* lint

* fix a bug when returning a dict which value could contain int or bool

* remove litellm

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>
Co-authored-by: Young <afe.young@gmail.com>
2025-02-28 15:13:43 +08:00
you-n-g 58910d2ce6 docs: Add guidelines for competition participation in prompts.yaml (#651) 2025-02-28 10:40:14 +08:00
XianBW bd258fe970 fix workflow eval logic (#650) 2025-02-27 22:07:20 +08:00
Yuante Li 68bf5665f0 fix: fix some bugs (ensemble output, HPO, model tuning) (#648) 2025-02-27 18:28:13 +08:00
Xu Yang a57e625b17 feat: add eda to data science scenario (#639)
* add eda to data science scenario

* fix CI
2025-02-26 22:35:44 +08:00
Xu Yang d7da15c826 feat: add max time config to costeer in data science (#645)
* add max time config to costeer

* fix a small bug

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-02-26 18:36:51 +08:00
Yuante Li ac7c2155e4 fix: clarify cross_validation (#644) 2025-02-26 17:52:30 +08:00
you-n-g bccf5aed8a fix: Set default value for 'entry' parameter in Env.run method (#643) 2025-02-26 16:51:38 +08:00
Tim 5bb73ff6cb chore: sample unique labels (#642)
* sample unique labels

* reformat
2025-02-26 15:24:39 +08:00
Roland Minrui b772fe2191 load code from file dict instead of folder (#641)
Co-authored-by: Xu <v-xuminrui@microsoft.com>
2025-02-26 14:21:28 +08:00
XianBW 28f072da31 change ensemble metric prompt's code tips (#640) 2025-02-26 11:40:25 +08:00
XianBW 34e143cd66 fix: avoid try-except in ensemble eval prompts (#637)
* avoid try-except in prompts

* remove try-except limit from coder prompt

* add no try-except criteria in ensemble eval
2025-02-25 23:06:41 +08:00
Tim e73db7e0d7 ignore new numeric type (#638) 2025-02-25 18:20:14 +08:00
Xu Yang f120341c9c fix: qlib and other scenario bugs (#636)
* fix qlib and other scenario bugs

* bug fix
2025-02-25 12:06:07 +08:00
XianBW 54cd73eb85 fix: add ensemble test, change to "use cross-validation if possible" in workflow spec (#634)
* change to "use cross-validation if possible" in workflow spec

* Limit the evaluation indicator to only one

* add metric tips

* string change
2025-02-24 20:28:32 +08:00
Yuante Li 20bd55c3a5 fix: fix a bug in initial tasks (#635)
* fix a bug in initial tasks

* fix ci
2025-02-24 20:23:54 +08:00
you-n-g 403d7fcf80 feat: Make system prompt role customizable in LLM settings (#632) 2025-02-23 00:52:30 +08:00
Yuante Li f5761b1f2d feat: improve the framework's ability to adaptively adjust the model (#629) 2025-02-21 22:46:14 +08:00
Xu Yang d4ade36184 refine component choosing part (#630) 2025-02-21 18:35:36 +08:00
Roland Minrui 982b43e4fd feat: add output_path to load function of LoopBase (#628)
* feat: add output_path to load from checkpoint function

* add default value to output_path

* sort import

* sort imports

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
2025-02-21 16:46:58 +08:00
Yuante Li b64ab18caa fix: fix a bug in cross validation (#618)
* fix a bug in cross_validation

* fix cross-validation prompt position

* fix

* fix

* append all error messages and full traceback details in execution

---------

Co-authored-by: Bowen Xian <xianbowen@outlook.com>
2025-02-20 16:18:40 +08:00
Yuante Li 433594297a fix: fix some bugs in workflow unit test (#624)
* fix some bugs in workflow unit test

* fix ci
2025-02-20 15:42:17 +08:00
you-n-g dff89d2950 refactor: add run_ret_code method and update run method to use it (#623)
* refactor: Add run_ret_code method and update run method to use it

* feat: Add kwargs support to run methods and test for run_ret_code

* fix: preserve exit code after chmod in DockerEnv entry command

* chore: Change file permissions from 755 to 644 in env_tpl directory

* refactor: Return execution code and update evaluator logic

* lint

* refactor: Use MappingProxyType for running_extra_volume in DockerEnv methods

* lint
2025-02-20 00:42:10 +08:00
Xu Yang 0bd8366254 several bug fix (#621) 2025-02-19 22:03:39 +08:00
XianBW 2222897b3f fix: change ensemble test (#622)
* change ensemble test

* remove redundant info

* fix bug

* add model name duplication check in ensemble test

* change text
2025-02-19 21:26:09 +08:00
XianBW fc5f295de7 fix: move docker timeout message to __run() (#620)
* move docker timeout msg to __run()

* fix CI
2025-02-19 19:09:52 +08:00
Haoran Pan 05c7712770 update qrcode (#616) 2025-02-19 13:44:40 +08:00
you-n-g 1737aff7c9 fix: Runnable on first complete & Rename method to next_incomplete_component for clarity (#615) 2025-02-19 01:00:25 +08:00
Yuante Li 464222094f add a check for the name of ensemble's score in scores.csv (#614) 2025-02-18 22:24:11 +08:00
you-n-g 42d15623ca fix: move next_component_required logic to DSTrace class and accurate implement (#612)
* refactor: Move next_component_required logic to DSTrace class

* lint
2025-02-18 21:56:32 +08:00
Haoran Pan 6c20263e2e fix: sota comparison logic (#608)
* concat sota and current result

* fix the bug in current_exp's score vs sota's score

* fix ci

---------

Co-authored-by: yuanteli <1957922024@qq.com>
2025-02-18 20:43:28 +08:00
XianBW 50e637f9cd add PYTHONUNBUFFERED=1 for docker env (#613) 2025-02-18 20:07:49 +08:00
Roland Minrui 1605cddb40 feat: add loop_n parameter to the main loop (#611)
* add loop_n parameter to main loop

* complete the loop_n

---------

Co-authored-by: Xu <v-xuminrui@microsoft.com>
2025-02-18 19:22:52 +08:00
Xu Yang 75e496d461 fix restart bug (#609) 2025-02-18 15:39:34 +08:00
you-n-g 9fcd5d473e refactor: replace Evaluator with CoSTEEREvaluator in eva_utils.py (#607)
* refactor: Replace Evaluator with CoSTEEREvaluator in eva_utils.py

* fix bug

---------

Co-authored-by: Linlang <Lv.Linlang@hotmail.com>
2025-02-18 13:38:13 +08:00
Xu Yang 5f1c814355 fix: a small bug in exp_gen (#606) 2025-02-17 22:40:05 +08:00
Yuante Li 21d88f38d0 fix: fix some minor bugs and add AutoML & cross-validation (#604)
* fix some complex sentences

* add AutoML in model and cross-validation in workflow
2025-02-17 19:14:50 +08:00
Tim fd27842a98 print head for txt files and shuffle when sample (#603) 2025-02-17 18:44:26 +08:00
Xu Yang bddb5eb935 fix: docker error will trigger retry and data science runner loop set to 3 (#602)
* docker error will trigger retry
data science runner loop set to 3

* fix CI
2025-02-17 17:36:05 +08:00
you-n-g ffc85936f1 refactor: refactor core framework to better propogate feedbacks (#599)
* refactor: Update type annotations and remove unused class in evolving modules

* refactor: Simplify evolving agent and feedback handling in CoSTEER module

* lint & CI

* mypy

* ruff for core

* mypy

* refactor: remove unnecessary comments and update feedback handling logic

* refactor: Add prev_task_feedback parameter to evolving strategies

* feat: Clear folder before extracting zip file in DockerEnv

* fix: Correct retrieval of last experiment from history
2025-02-16 01:40:44 +08:00
Tim 241c05ccac chore: print txt info (#600)
* print head for txt files

* update sample
2025-02-14 19:16:28 +08:00
Xu Yang 50e020b75d fix: auto continue small bug (#598) 2025-02-14 17:03:57 +08:00
Yuante Li d1c005ff6d fix: fix a bug in proposal (add last loop's exception to last task desc) (#596)
* fix a bug in proposal (add last loop's exception to last task desc)

* fix
2025-02-14 16:36:49 +08:00
Xu Yang 96ee62c7a2 small bugs in cache rerun (#597) 2025-02-14 16:24:26 +08:00
Yuante Li c321ebfbcb fix: fix some bugs in the ensemble component (#595)
* allow the LLM in the ensemble to focus on the significance of metrics

* fix a bug in feedback

* prun spec

* fix a bug in ensemble

* delete unnecessary prompts

* fix the logic in spec

* generalize dataset split
2025-02-14 15:32:40 +08:00
Xu Yang 1a44a954df feat: integrate azure deepseek r1 (#591)
* fix several task & integrate deepseek R1

* fix CI

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-02-13 22:20:17 +08:00
Tim 4d8e334ef8 fix error (#594) 2025-02-13 19:34:49 +08:00
Tim b7be0f35f8 fix: ensure expected type (#593)
* ensure expected type

* reformat
2025-02-13 19:04:26 +08:00
炼金术师华华 97c1f7a021 feat(backend): integrate LiteLLM API Backend (#564)
* File structure for supporting litellm

* more litellm support

* feat: Add CachedAPIBackend class and dynamic API backend retrieval function

* fix: update benchmark folder path and add default values for architecture and hyperparameters

* feat: add LiteLLMAPIBackend and DeprecBackend ; changed structure of the project ; with bus

* fix : deprec_backend

* feat: Add LiteLLMAPIBackend class and related features; update configuration and test cases.

* feat: Enhance LiteLLMAPIBackend with encoder support and dynamic argument handling;Enhance log Colors

* lint

* fix lint...

* fix: Lint

* fix:make auto-lint

* fix:test oai

* fix:redundant _abckend.py

* fix: Optimize LiteLLMAPIBackend on token counting functiona, and clean up unused code;add test on this function

* feat: Add LiteLLMSettings class and update model settings usage

* fix: Update LiteLLMSettings environment variable prefix and model configurations

* fix : gitignore

* test: Consolidate and relocate test files for litellm backend and oai

* fix : lint

* fix: lint

* auto lint

* lint

* LINT

* lint

* chore: remove deprecated backend configuration comments

* refactor: Remove unused functions and imports from deprec.py and llm_utils.py

* refactor: Move md5_hash function from deprec.py to llm_utils.py

* chore: Remove extra newline and add missing import in deprec.py

* lint

* refactor: Move md5_hash function to utils module

* lint

* lint

* lint

---------

Co-authored-by: Young <afe.young@gmail.com>
Co-authored-by: Yihua Chen <v-yihuachen@microsoft.com>
2025-02-13 15:16:18 +08:00
Yuante Li f362a1618d fix: fix a bug in threshold score display (#592)
* fix a bug in threshold score display

* fix
2025-02-13 14:50:56 +08:00
Yuante Li 43703d45d2 feat: add baseline score stat (#590)
* add baseline score stat

* fix ci

* fix

* fix
2025-02-12 18:57:08 +08:00
Tim f06412e628 sample group files by basename (#589) 2025-02-12 16:36:46 +08:00
Xu Yang dc2bf4b442 fix: sort file name for cache reproduction (#588) 2025-02-12 15:29:57 +08:00
you-n-g 8f1f19d4b9 fix: Handle ValueError when resolving relative path for uri (#585) 2025-02-12 13:23:08 +08:00
Xu Yang 064733d82b fix runner as costeer when using static task (#587) 2025-02-12 12:35:17 +08:00
Tim da7169675c ignore score value (#586) 2025-02-12 11:39:49 +08:00
XianBW 6de33fa13b fix: coder prompt & model test text (#583)
* test text fix

* Require LLM to use print() instead of logging
2025-02-11 21:12:25 +08:00
Xu Yang c1085921b5 add feedback to workspace and ds runner base on costeer 2025-02-11 20:50:19 +08:00
XianBW 18de5eea43 feat: summary and UI update (#581)
* summary and UI update

* fix CI

* fix

* fix CI
2025-02-11 20:48:30 +08:00
Tim 13214ba5d0 avoid length exception (#580) 2025-02-11 18:12:45 +08:00
you-n-g 56f3a668f2 fix: handle invalid regex patterns in filter_progress_bar function (#579)
* fix: handle invalid regex patterns in filter_progress_bar function

* Update rdagent/utils/__init__.py
2025-02-11 18:07:16 +08:00
Yuante Li 75f29f0dd9 refine the code in hypo&task generating (#578) 2025-02-10 22:09:42 +08:00
Yuante Li 345a702501 fix: fix the errors in the coder and evaluator of the five components (#576)
* refine the prompt in feat coder

* refine data loader prompt in coder & eval

* fix

* fix

* refine model prompt in coder & eval

* refine ensemble prompt in coder & eval

* refine workflow prompt in coder & eval

* fix
2025-02-10 20:20:30 +08:00
Yuante Li d2baa40fb1 add the none check for data loader & feature output (#577) 2025-02-10 20:18:01 +08:00
XianBW 216361c640 score chart error catch (#575) 2025-02-10 12:19:29 +08:00
you-n-g 904f4b8523 refactor: Use file dictionaries for diff generation in feedback module (#574) 2025-02-10 09:03:13 +08:00
you-n-g 59337a9050 fix: add retry mechanism for GPU device check in DockerEnv (#573)
* fix: add retry mechanism for GPU device check in DockerEnv

* lint

* my py linting

* refactor: Improve type annotations and retry logic in workflow utils

* fix syntax
2025-02-10 08:59:46 +08:00
you-n-g 0db49991cb feat: add retry mechanism with wait_retry decorator and refactor diff generation (#572) 2025-02-10 01:35:54 +08:00
Yuante Li 34bf87c410 refine the logic in feedback (#571) 2025-02-08 21:14:30 +08:00
XianBW f37ec32981 text change (#568) 2025-02-08 21:14:13 +08:00
Haoran Pan f8a4d2a7b5 update qrcode (#570) 2025-02-08 20:48:19 +08:00
you-n-g cefef61d0e feat: diff mode fix (#569)
* feat: Add last runnable experiment feedback retrieval and improve diff generation

* lint
2025-02-08 20:13:38 +08:00
you-n-g 3090718ca3 fix: include data information in cache key generation (#566) 2025-02-08 20:05:57 +08:00
XianBW 7eb7f49f52 fix: add scores.csv checking in ensemble_test (#567)
* add scores.csv checking in ensemble_test

* text modify
2025-02-08 19:03:29 +08:00
Tim c255b79da4 chore: format check result (#565)
* format check result placed next to the metric result

* reformat
2025-02-08 18:53:16 +08:00
Tim 94d0eca0ca support multiple types in feature engineering (#562) 2025-02-08 15:21:11 +08:00
XianBW bfdee6b692 add time info and stdout window (#563) 2025-02-07 22:00:45 +08:00
Yuante Li 732839e4bd feat: add the shape of the CSV to the dataset description (#561)
* add csv's shape info to data description

* fix CI
2025-02-07 18:12:18 +08:00
XianBW 98a0801a32 fix bugs (#560) 2025-02-07 11:00:18 +08:00
you-n-g e1f86d7ca0 fix: add stdout context length setting and improve text shrinking logic (#559)
* feat: Add stdout context length setting and improve text shrinking logic

* lint
2025-02-06 23:00:15 +08:00
you-n-g 5c7ceec37f fix: fix task return dict with wrong format (#558)
* refactor: Simplify exp_gen and enhance workflow with init_kwargs_update_func

* fix: Correct type hint for init_kwargs_udpate_func parameter

* lint

* lint

* lint

* lint
2025-02-06 19:24:14 +08:00
Tim 723a3f4225 fix: keep some txt files (#557)
* keep some txt files

* reformat
2025-02-06 18:01:15 +08:00
Xu Yang b2d56e39e5 fix: move mlebench check into runner (#556)
* abandon mlebench check in workflow

* move mlebench check to runner and put it into the exp
2025-02-06 15:37:41 +08:00
XianBW 0e447a3a19 feat: multi log folder, replace "epxx" in workspace path (#555)
* multi log folder, replace "epxx" in workspace path

* valid trace path

* hypothesis show change

* fix CI

* add total stat in all summary page
2025-02-06 15:14:34 +08:00
you-n-g e937f8710c feat: exclude invalid session log folder (#554)
* refactor: Add is_valid_session check in save_all_grade_info

* refactor: Use is_valid_session to check log trace validity
2025-02-06 09:56:34 +08:00
XianBW b1fce69153 fix: change summary info of log folder (#552)
* update stat data in log summary

* show logic change

* add workspace None judgement

* fix CI
2025-02-05 16:31:30 +08:00
XianBW b092c24374 fix: trace summary df showing in dsapp (#551)
* fix trace summary df show

* fix ci
2025-02-05 10:48:25 +08:00
you-n-g 1678461f5a fix: handle division by zero in percentage calculations (#550)
* fix: Handle division by zero in percentage calculations

* lint
2025-02-05 10:21:53 +08:00
you-n-g 35e3156018 fix: replace API call with build_cls_from_json_with_retry function (#548)
* refactor: Replace API call with build_cls_from_json_with_retry function

* fix lint error

* fix lint errors

* lint

* trigger
2025-01-27 20:19:11 +08:00
Xu Yang 611fb28c58 fix: refine prompt to generate the most simple task in init stage (#546)
* refine prompt to generate the most simple task in init stage

* feature test dtype check improve
2025-01-27 00:51:40 +08:00
XianBW 10abb20117 feat: add mlebench submission validitor (#545)
* add mlebench submission check

* fix CI

* fix bug
2025-01-27 00:41:35 +08:00
you-n-g 6e96cff435 fix: fix submission file search and add TODO in env.py (#544) 2025-01-26 17:08:59 +08:00
XianBW fcf17d3292 fix summary loop_num count (#543) 2025-01-26 11:58:12 +08:00
you-n-g 4235440ff4 feat: Dynamically find and use sample submission file in eval tests (#542) 2025-01-24 18:16:15 +08:00
Tim 111dddda18 chore: rename ens_and_decision (#541)
* rename ens_and_decision

* clarify workflow prompt

* rename
2025-01-24 17:24:31 +08:00
Xu Yang 4b25dd1913 fix score bug and refine restart strategy (#540) 2025-01-24 16:02:21 +08:00
you-n-g 2453a6bff7 feat: add timeout settings and cleanup step in data science runner (#539)
* feat: Add timeout settings and cleanup step in data science runner

* lint
2025-01-24 15:03:21 +08:00
you-n-g f596e59bd8 feat: add configurable volume mode for Docker volumes in env.py (#537)
* feat: Add configurable volume mode for Docker volumes in env.py

* fix: Change default extra_volume_mode to read-only in DockerConf
2025-01-24 14:08:38 +08:00
Xu Yang cb5127735f feat: add restart and fix unzip (#538)
* add restart function

* update

* fix ci

* update code

* fix restart

---------

Co-authored-by: yuanteli <1957922024@qq.com>
Co-authored-by: Xu Yang <xuyang1@microsoft.com>
2025-01-24 13:34:47 +08:00
XianBW 993f16a089 fix ui on new log trace (#536) 2025-01-24 12:40:56 +08:00
you-n-g 90ffb6cc8a fix: add DSExperiment type check and directory validation in log proc… (#535)
* fix: Add DSExperiment type check and directory validation in log processing

* style: Reformat FileNotFoundError message for readability
2025-01-24 00:03:41 +08:00
XianBW 17526da856 fix: filter empty log traces in ds UI (#533)
* filter empty log traces

* fix CI
2025-01-23 18:01:30 +08:00
XianBW eb597924b2 feat: base data science scenario UI (#525)
* base data science ui

* fix bug

* fix mle grade

* not cache when mle prepare

* fix

* fix grade sample

* fix a small bug

* fix

* cache mle score

* fix

* add gen_mle_score script

* update for mle score

* simple debug show

* small change

* summary folder

* add evo loop tag

* add loop id

* add comment

* fix CI

* add enable_cache for docker conf

* CI

* use setting data path

* fix ui bug

---------

Co-authored-by: yuanteli <1957922024@qq.com>
2025-01-23 16:12:22 +08:00
Xu Yang e5b1912bfd fix inject code bug and improve dataloader spec code (#532) 2025-01-23 13:24:44 +08:00
Xu Yang f19a91abfc fix minor bug in feature test (#531) 2025-01-23 10:15:21 +08:00
Xu Yang 7ff55f0013 update all (#530) 2025-01-22 22:22:48 +08:00
you-n-g 17a901e8da feat: Enhance eval script with file cleanup and detailed submission checks (#529) 2025-01-22 21:51:34 +08:00
Tim 1a19622add chore: clean unused scripts (#528)
* clean unused scripts

* reformat
2025-01-22 14:21:08 +08:00
Xu Yang 7cfeaff95b add former task to exp_gen (#527) 2025-01-22 12:15:20 +08:00
Tim a355b57623 chore: add runtime info (#526)
* add runtime info

* Update rdagent/scenarios/data_science/scen/__init__.py

Co-authored-by: you-n-g <you-n-g@users.noreply.github.com>

* reformatted by black

---------

Co-authored-by: you-n-g <you-n-g@users.noreply.github.com>
2025-01-21 16:15:45 +08:00
Yuante Li 14f7fc5e53 fix a small bug (#524) 2025-01-20 12:19:21 +08:00
you-n-g 7f4c2d18c6 feat: refactor for general data science (#498)
* refine ds modal for more cases: eval and es

* update model template

* prompts for model and ensemble

* fix a bug

* fix a bug

* init: ds workflow evovingstrategy

* Adding ensemble (#505)

* Initial Draft

* Updating logic for init

* Revising

* Successful Testing

* Updating to use the latest & right class

* bug: bug-fixing for testing

* data science loop changes

* data science loop base

* ds loop feedback

* fix

* remove measure_time because it's duplicated (in LoopBase)

* add the knowledge query for data_loader & feature

* edit ds workflow evaluator

* data_loader bug fix

* stop evolving when all tasks completed

* llm app change

* fix break all complete strategy

* Adding queried knowledge (#508)

Co-authored-by: XianBW <36835909+XianBW@users.noreply.github.com>

* fix loop bug

* ds workflow evaluator; test; refine prompts

* workflow spec

* fix ci

* feature task changes

* ds loop change

* fix a bug in feat

* add query knowledge for model and workflow

* llm_debug info(for show) using pickle instead of json

* remove NextLoopException

* loop change

* coder raise CoderError when all sub_tasks failed

* rename code_dict to file_dict in FBWorkspace

* add CoSTEER unittest

* now show self.version in Task.get_task_information(), simplify CoSTEER sub tasks definition

* remove some properties in ModelTask, add model_type in it.

* fix llm app bug

* llm web app bug fix

* ds loop bug fix

* fix: give component code to feature&ens eval

* loop catch error bug

* rename load_from_raw_data to load_data

* feat: Add debug data creation functionality for data science scenarios

* support local folder (#511)

* support local folder

* remove unnecessary random

* KaggleScen Subclass

* small fix

* use template for style description

* update default scen to kaggle

* update sample data script

* make sure frac < 1

* fix a bug

* feature spec changes

* fix

* changeimport order

* clear unnecessary std outputs

* fix a typo

* create sample folder after unzip kaggle data

* feature/model test script update

* Align the data types across modules.

* fix a bug in model eval

* show line number

* move sample entry point to app

* spec & model prompt changes

* Refine the competition specification to address the data type problem and the coherence issue.

* fix some bugs

* add file filter in FBworkspace.code property

* support non-binary prediction

* avoid too much warnings

* fix a bug in ensemble module

* filtered the knowledge query in all modules

* delete RAG in idea proposal

* refine the code in ensemble

* show exp workspace in llm_st

* exp_gen bug fix

* feedback bug fix

* use `feature` instead of `feat01`

* Trace & method of judging if exp is completed change

* fix a bug in package calling and execute ci

* fix code

* bug fix

* bug fix

* fix a bug

* fix some bugs

* fix a bug

* refactor: Enhance error handling and feedback in data science loop

* support different use_azure on chat and embedding models

* multi-model proposal logic

* fix a small syntax error

* loopBase and some changes

* ensemble scores change

* fbworkspace.code -> .all_codes

* use all model codes in workflow coder

* check scores.csv's keys(model_names)

* model name changes

* add a todo in  ensemble test

* sota_exp changes

* give model info in exp gen

* add runner time limit

* config using debug data or not in evals

* exp to feedback base

* add feature code when writing model task

* small problem

* copying during sampling

* update

* refactor: Simplify code handling and improve workspace management

* model part output fix

* print model's execution time

* bug fix

* ensemble test fix

* ens small change

* ens_test bug fix

* Refine partial expansion logic to display only a few subfolders when their structure is uniform, improving readability in nested directories.

* several update on prompts

* sample subfolders

* Filter the stdout after code execution to remove irrelevant information e.g. progress bars, whitespace characters, excessive line breaks.

* Add some more prompts and comments

* several update on the first init rounds

* model timeout as error

* fix pattern of getting model codes in workspace

* small bux fix on model prompts

* remove get_code_with_key since we have regex pattern

* fix: Correct tqdm progress bar update logic in LoopBase class

* feat: Add diff generation and enhance feedback mechanism in data science loop

* update some fix to model and workflow prompts

* refine the logic of progress bar filter

* add last_successful_exp in exp_gen

* fix a one line bug

* add a hint in prompt

* fix data sample for bms

* fix data sample for bms

* hypothesis small fix

* crawler readme update

* fix component gen

* fix bug

* annotation change

* load description.md if it exists

* refactor: Simplify SOTA description handling in feedback and prompts

* refactor: Use shared templates for feedback and experiment descriptions

* change webapp for model codes changes

* update proposal

* add timeout message for docker run output

* fix

* refine the code in docker time processing

* use .shape instead of len() when do shape eval

* won't change size during iteration

* support bson sample

* sample support jsonl and bson

* add former_code to coder prompts

* a little speed us in debug data creating

* filter progress bar when eval ens and main

* avoid costeer makes no change to former code

* fix several log error

* add timeout judge threshold

* fix some bugs in the evaluation of component output shapes

* File structure for supporting litellm (#517)

Co-authored-by: Young <afe.young@gmail.com>

* ignore submission and show processing

* ignore submission and show processing

* add efficiency notice

* refactor: Enhance error message with detailed feedback summary

* refactor: Simplify component handling in DSExpGen class

* refactor: Update code structure and add docstring for clarity

* reserve one sample to each label in data sampling

* add Evaluation info

* refine costeer code to avoid giving same code twice

* use raw_description as plain text

* add a prompt hint to avoid same dict key

* model task name bug in first model exp gen

* fix a typo

* add some debug info in costeer tests

* task init change

* enhance data sampling

* refine the code in data_loader

* more reasonable loop

* fix a bug in data folder description

* add error msg & traceback to execution feedback

* fix llm error msg detection

* add task information to costeer eval & add cache to docker run(use zipfile to store the whole workspace)

* fix CI first round

* fix CI second round

* use txt to store test script to avoid pytest

* remove zipfile in requirements

* add azure.identity to requirements

* ignore debug web page

* component test changes

* remove redundent task_desc in model coder

* feat: Add APE module and prompts for automated prompt engineering

* fix: Update .gitignore and improve text formatting in eval.py

* refactor: Update print output and improve code comments and imports

* style: Fix string formatting and import order in ape.py and fmt.py

* exclude ape

* add a data folder notice

* reduce unnecessary output to stdout

* refine the code of describe_data_folder

* fix ci

* style: streamlit style update (#522)

* streamlit style update

* fix import

* fix format

* fix llm_st loop progress bar

* debugapp small change

* fix model str

* refine some prompts

* fix model str

* fix CI

* refine the logic associated with the data_folder

* fix ci

* small change

* set filter_progress_bar as default in execute

* model proposal with workflow

* add submission check in workflow eval

* fix bug

* small change

* fix CI

* fix CI

* refactor: Move generate_diff to utils and update DSExpGen logic

* more reasonable prompt describing metric direction

* fix a minor jinja2 bug

* quick fix exp_gen bugs

* fix the following bug

* fix

* fix some bugs

* remove workflow from model

* add pending_tasks_list in data science to enable coding model and workflow

* refine the code for handling JSON-formatted data descriptions

* assert with information

* ensure correct csv file name

* add logging to help record the output

* log competition

* add log tag for debug llm app

* test: Test ds refactor ll (#523)

* fix bugs to former scenario

* fix a bug because coding in rdloop changed

* fix the bug when feedback gets no hypothesis

* fix trace structure

* change all trace hist when merging hypothesis to experiments

* ignore some error in ruff

* fix kaggle scenario bugs

* refine one line

* another bug

* another small bug

* fix ui bugs

* chage kaggle  train.py path

---------

Co-authored-by: Xu Yang <peteryang@vip.qq.com>

* fix CI

* Update rdagent/app/data_science/loop.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* add samplecsv into spec prompts

* fix CI

---------

Co-authored-by: TPLin22 <tplin2@163.com>
Co-authored-by: yuanteli <1957922024@qq.com>
Co-authored-by: Xisen Wang <118058822+xisen-w@users.noreply.github.com>
Co-authored-by: Bowen Xian <xianbowen@outlook.com>
Co-authored-by: Xu Yang <peteryang@vip.qq.com>
Co-authored-by: XianBW <36835909+XianBW@users.noreply.github.com>
Co-authored-by: Tim <illking@foxmail.com>
Co-authored-by: 炼金术师华华 <37462254+YeewahChan@users.noreply.github.com>
Co-authored-by: Linlang <30293408+SunsetWolf@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-01-17 22:53:05 +08:00
Haoran Pan d1fdfe10ea update new qr group code (#521) 2025-01-14 17:25:06 +08:00
Xu Yang 4546ebba98 Update factor_runner.py to ignore failed implementation (#514) 2025-01-02 23:29:52 +08:00
Yuante Li dd600c0b0c docs: update WeChat QR code on Dec 31, 2024 (#513) 2024-12-31 14:01:17 +08:00
Haoran Pan 0a89784116 fix: avoid warning for missing llama installation when not in use (#509)
* Update llm_utils to check llama use

* modify the logic of the condition
2024-12-20 17:54:13 +08:00
Haoran Pan cb66555a9c fix: a default conf in scen qlib (#503) 2024-12-10 18:07:19 +08:00
Haoran Pan 1a5aaf3fea update wechat qrcode at Dec 2nd (#502) 2024-12-03 14:07:26 +08:00
Haoran Pan cff2d79c42 fix bug in model evaluator final feedback ignoring shape feedback (#501) 2024-12-03 13:55:28 +08:00
Linlang ea85d5efc8 chore: fix PR template (#487)
* fix PR template

* subfolders of the log displayed on the web page

* fix code error

* add health check

* reformat with isort

* reformat with black

* update README

* fix bug && experience confusing

* reformat with black & update health check code

* reformat with isort

* reformat with black

* update README.md

* Removed duplicates in documentation and health_check && Upgraded code for filtering folders

* update docs

* reformat with black
2024-11-28 15:35:13 +08:00
you-n-g c3f78f8bce feat: run benchmark on gpt-4o & llama 3.1 (#497)
* Run benchmark on gpt-4o & llama 3.1

* update link
2024-11-26 12:02:09 +08:00
Xu Yang d54e14f1d9 very small fix (#496) 2024-11-25 20:08:05 +08:00
Xu Yang b7fcb13c33 feat: a unified CoSTEER to fit more scenarios (#491)
* Use ExtendedBaseSettings to replace BaseSettings

* update a more general way to pass the default setting

* update all code

* fix CI

* fix CI

* fix qlib scenario

* fix CI

* fix CI

* fix CI & add data science interfaces

* remove redundant code

* abandon costeer knowledge base v1

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>
Co-authored-by: XianBW <36835909+XianBW@users.noreply.github.com>
2024-11-25 16:27:34 +08:00
you-n-g e1032b6a31 fix: patching weird azure deployment (#494)
* patching weird azure deployment

* Auto link
2024-11-25 13:47:21 +08:00
Haoran Pan ca46d11123 update qr_code (#492) 2024-11-22 13:16:45 +08:00
you-n-g f9bd19179f feat: kaggle refactor (#489)
* init trail

* Add spec info

* auto unzip mlebench prepared data for out scenario

* successfully run example

* successfully run main

* simplify load traing

* extract load_from_raw_data

* split the fies(still buggy)
It should stop on ~20 epoch and reach the end

* some changes

* Fix bug to run example

* (success) until feature

* refine model and ensemble

* add metrics in ens.py

* update README &  spec.md

* ens change

* fix ens bug

* Delete rdagent/scenarios/kaggle/tpl_ex/aerial-cactus-identification/train.py

* add template_path in KG_conf

* fix test kaggle

* CI

* make test_import not check kaggle template codes

---------

Co-authored-by: Bowen Xian <xianbowen@outlook.com>
2024-11-20 17:01:18 +08:00
you-n-g ae8fc773cb feat: new-york-city-taxi-fare-prediction_template (#488)
* copy init version

* feat: new-york-city-taxi-fare-prediction_template

* add move to linear model

* Add more details about docker

* auto lint

* auto lint with new black
2024-11-15 16:47:44 +08:00
Xu Yang 8662211492 feat: align mlebench data and evaluation & several fix on kaggle workflow (#477)
* several improvement on kaggle loop

* small refinement on prompt

* fix bugs

* add the score of each model in every experiment

* fix ci error

* fix error in ventilator tpl

* fix CI

---------

Co-authored-by: Xu Yang <xuyang1@microsoft.com>
Co-authored-by: Bowen Xian <xianbowen@outlook.com>
Co-authored-by: WinstonLiye <1957922024@qq.com>
Co-authored-by: TPLin22 <tplin2@163.com>
2024-11-15 15:40:22 +08:00
XianBW 892283dc89 feat: template changes for some kaggle competitions (#484)
* change tpl metric codes

* change tpl
2024-11-12 11:24:01 +08:00
Linlang 76b8f073e4 update QR (#483) 2024-11-11 23:41:48 +08:00
XianBW fe7eb4cbe1 add kaggle tpl (#482) 2024-11-11 22:31:32 +08:00
XianBW 8c4c53339c feat: (Kaggle) add base template for competition: tabular-playground-series-may-2022 (#481)
* add tpl kaggle

* CI
2024-11-11 21:18:07 +08:00
Linlang ef66c56c2b docs: fix url in docs (#478)
* Fix the links in documents don't jump properly

* recover badge
2024-11-08 14:19:06 +08:00
Yuante Li e512d08439 docs: fix a bug in the document (#466)
* fix a bug

* edit guidance to run kaggle application

* update docs

* optimize docs

* read RTD badge

---------

Co-authored-by: TPLin22 <tplin2@163.com>
Co-authored-by: Linlang <Lv.Linlang@hotmail.com>
2024-11-08 13:55:24 +08:00
dependabot[bot] c6304add4a build(actions): bump actions/setup-node from 3 to 4 (#425)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-06 13:17:50 +08:00
Xu Yang 90d9cdd0e9 feat(kaggle): several update in kaggle scenarios (#476)
* udpate plot

* log and reduce token

* trace tag

* add simple_background parameter to get_scenario_all_desc

* update trace

* update first version code

* chat model map

* add annotation for stack index

* add annotation

* reformatted by black

* several update on kaggle scenarios

* update some new change

* fix CI

* fix CI

* fix a bug

* fix bugs in graph RAG

---------

Co-authored-by: Tim <illking@foxmail.com>
2024-11-06 13:14:35 +08:00
Yuante Li bf719e0993 feat: add a new competition (#474)
* add tabular-playground-series-dec-2021

* finished

* fix a mistake

* fix a bug

* fix a bug
2024-11-05 20:42:20 +08:00
Yuante Li 1726caa414 feat: end-to-end optimization (#473)
* fix

* refine the code

* aligned data with MLE Kaggle competition dataset

* fix ci error

* fix ci
2024-11-05 15:41:50 +08:00
Xu Yang 25af7e6cce fix a bug (#470) 2024-11-04 15:05:05 +08:00
Linlang cbbbb4e9a5 fix: unzip kaggle data (#464)
* unzip kaggle data

* read local_data_path from .env file

* fix build docs error

* recover azure-identity packages

* optimize code logic

* add error when downloading data from kaggle

---------

Co-authored-by: Xu Yang <peteryang@vip.qq.com>
2024-11-04 14:57:10 +08:00
WinstonLiyt 450317d8fe fix a bug in kaggle runner cache and kaggle costeer execute template (#467) 2024-11-04 11:16:16 +08:00
Haoran Pan d62407cfbb docs: correct some mistakes in Kaggle scenario guidance (#465)
* update readme correct some mistakes in guide

* update the doc

---------

Co-authored-by: WinstonLiye <1957922024@qq.com>
2024-11-01 17:33:59 +08:00
WinstonLiyt 09325aed89 feat: refine logic for qlib_factor_from_report (#463)
* fix a bug in kaggle conf

* fix a ci error

* refine logic for qlib_factor_from_report
2024-10-31 16:04:32 +08:00
Haoran Pan e0ce86b180 docs: update readme (#462)
* update readme

* update some concrete description

* update quick start
2024-10-31 12:49:38 +08:00
XianBW 2c206e9ce5 docs: some changes in kaggle doc (#461)
* add kaggle scenario description for webapp

* catch download button error

* change kaggle auto_submit to False default

* Added guidance for custom templates in kaggle doc

* CI

* CI

* add kaggle data set instruction(NOTE)

* delete repeated description for kaggle scenario

---------

Co-authored-by: TPLin22 <tplin2@163.com>
2024-10-30 17:00:56 +08:00
WinstonLiyt 80e4a2aa79 fix: fix a bug in kaggle conf (#459)
* fix a bug in kaggle conf

* fix a ci error
2024-10-29 15:13:18 +08:00
Haoran Pan 3da6af95bd add docs for scen catalog (#458) 2024-10-29 11:08:15 +08:00
Haoran Pan 62beb3a7ae fix: templates bug (#456)
* Update model_nn.py

* ci issue
2024-10-28 14:22:04 +08:00
Haoran Pan a7ec1485a7 docs: improve kaggle scenario description (#455)
* add docs

* add docs

* add docs for roadmap & guide

* edit roapmap format

* edit design image
2024-10-26 00:03:59 +08:00
dependabot[bot] 992956db8e build(requirements): bump the prod group across 1 directory with 164 updates (#443)
* build(requirements): bump the prod group across 1 directory with 164 updates

Bumps the prod group with 164 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [pydantic-settings](https://github.com/pydantic/pydantic-settings) | `2.1.0` | `2.6.0` |
| [cython](https://github.com/cython/cython) | `3.0.7` | `3.0.11` |
| [scipy](https://github.com/scipy/scipy) | `1.11.4` | `1.14.1` |
| [python-levenshtein](https://github.com/rapidfuzz/python-Levenshtein) | `0.25.1` | `0.26.0` |
| [scikit-learn](https://github.com/scikit-learn/scikit-learn) | `1.5.1` | `1.5.2` |
| [filelock](https://github.com/tox-dev/py-filelock) | `3.13.1` | `3.16.1` |
| [fire](https://github.com/google/python-fire) | `0.5.0` | `0.7.0` |
| [openai](https://github.com/openai/openai-python) | `1.6.1` | `1.52.0` |
| [ruamel-yaml]() | `0.18.5` | `0.18.6` |
| [torch](https://github.com/pytorch/pytorch) | `2.1.2` | `2.5.0` |
| [torch-geometric](https://github.com/pyg-team/pytorch_geometric) | `2.5.3` | `2.6.1` |
| [numpy](https://github.com/numpy/numpy) | `1.26.2` | `2.1.2` |
| [pandas](https://github.com/pandas-dev/pandas) | `2.1.4` | `2.2.3` |
| [matplotlib](https://github.com/matplotlib/matplotlib) | `3.9.1` | `3.9.2` |
| [langchain](https://github.com/langchain-ai/langchain) | `0.0.353` | `0.3.4` |
| [langchain-community](https://github.com/langchain-ai/langchain) | `0.0.7` | `0.3.3` |
| [tiktoken](https://github.com/openai/tiktoken) | `0.7.0` | `0.8.0` |
| [pymupdf](https://github.com/pymupdf/pymupdf) | `1.24.9` | `1.24.11` |
| [azure-identity](https://github.com/Azure/azure-sdk-for-python) | `1.17.1` | `1.19.0` |
| [pypdf](https://github.com/py-pdf/pypdf) | `3.17.4` | `5.0.1` |
| [azure-core](https://github.com/Azure/azure-sdk-for-python) | `1.29.6` | `1.31.0` |
| [azure-ai-formrecognizer](https://github.com/Azure/azure-sdk-for-python) | `3.3.2` | `3.3.3` |
| [statsmodels](https://github.com/statsmodels/statsmodels) | `0.14.2` | `0.14.4` |
| [tables](https://github.com/PyTables/PyTables) | `3.9.2` | `3.10.1` |
| [tree-sitter-python](https://github.com/tree-sitter/tree-sitter-python) | `0.21.0` | `0.23.2` |
| [tree-sitter](https://github.com/tree-sitter/py-tree-sitter) | `0.22.3` | `0.23.1` |
| [jupyter](https://jupyter.org) | `1.0.0` | `1.1.1` |
| [python-dotenv](https://github.com/theskumar/python-dotenv) | `1.0.0` | `1.0.1` |
| [setuptools-scm](https://github.com/pypa/setuptools_scm) | `8.0.4` | `8.1.0` |
| [sphinx](https://github.com/sphinx-doc/sphinx) | `7.2.6` | `8.1.3` |
| [furo](https://github.com/pradyunsg/furo) | `2023.9.10` | `2024.8.6` |
| [importlib-metadata](https://github.com/python/importlib_metadata) | `7.0.1` | `8.5.0` |
| [aiohttp](https://github.com/aio-libs/aiohttp) | `3.9.1` | `3.10.10` |
| [alabaster](https://github.com/sphinx-doc/alabaster) | `0.7.13` | `1.0.0` |
| [annotated-types](https://github.com/annotated-types/annotated-types) | `0.6.0` | `0.7.0` |
| [anyio](https://github.com/agronholm/anyio) | `4.2.0` | `4.6.2.post1` |
| [attrs](https://github.com/sponsors/hynek) | `23.2.0` | `24.2.0` |
| [autodoc-pydantic](https://github.com/mansenfranzen/autodoc_pydantic) | `2.0.1` | `2.2.0` |
| [babel](https://github.com/python-babel/babel) | `2.14.0` | `2.16.0` |
| [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) | `4.12.2` | `4.12.3` |
| [black](https://github.com/psf/black) | `23.12.1` | `24.10.0` |
| [build](https://github.com/pypa/build) | `1.0.3` | `1.2.2.post1` |
| [certifi](https://github.com/certifi/python-certifi) | `2023.11.17` | `2024.8.30` |
| [cffi](https://github.com/python-cffi/cffi) | `1.16.0` | `1.17.1` |
| [charset-normalizer](https://github.com/Ousret/charset_normalizer) | `3.3.2` | `3.4.0` |
| [contourpy](https://github.com/contourpy/contourpy) | `1.2.1` | `1.3.0` |
| [coverage](https://github.com/nedbat/coveragepy) | `7.4.0` | `7.6.4` |
| [cryptography](https://github.com/pyca/cryptography) | `41.0.7` | `43.0.3` |
| [dataclasses-json](https://github.com/lidatong/dataclasses-json) | `0.6.3` | `0.6.7` |
| [debugpy](https://github.com/microsoft/debugpy) | `1.8.2` | `1.8.7` |
| [dill](https://github.com/uqfoundation/dill) | `0.3.8` | `0.3.9` |
| [docutils](https://docutils.sourceforge.io) | `0.20.1` | `0.21.2` |
| [executing](https://github.com/alexmojaki/executing) | `2.0.1` | `2.1.0` |
| [fonttools](https://github.com/fonttools/fonttools) | `4.53.1` | `4.54.1` |
| [fsspec](https://github.com/fsspec/filesystem_spec) | `2023.12.2` | `2024.10.0` |
| [git-changelog](https://github.com/pawamoy/git-changelog) | `2.4.0` | `2.5.2` |
| [greenlet](https://github.com/python-greenlet/greenlet) | `3.0.3` | `3.1.1` |
| [httpcore](https://github.com/encode/httpcore) | `1.0.2` | `1.0.6` |
| [httpx](https://github.com/encode/httpx) | `0.26.0` | `0.27.2` |
| [idna](https://github.com/kjd/idna) | `3.6` | `3.10` |
| [ipython](https://github.com/ipython/ipython) | `8.26.0` | `8.28.0` |
| [ipywidgets](https://github.com/jupyter-widgets/ipywidgets) | `8.1.3` | `8.1.5` |
| [isodate](https://github.com/gweis/isodate) | `0.6.1` | `0.7.2` |
| [jaraco-classes](https://github.com/jaraco/jaraco.classes) | `3.3.0` | `3.4.0` |
| [jinja2](https://github.com/pallets/jinja) | `3.1.2` | `3.1.4` |
| [jsonpointer](https://github.com/stefankoegl/python-json-pointer) | `2.4` | `3.0.0` |
| [jsonschema-specifications](https://github.com/python-jsonschema/jsonschema-specifications) | `2023.12.1` | `2024.10.1` |
| [jupyter-client](https://github.com/jupyter/jupyter_client) | `8.6.2` | `8.6.3` |
| [jupyterlab](https://github.com/jupyterlab/jupyterlab) | `4.2.4` | `4.2.5` |
| [jupyterlab-widgets](https://github.com/jupyter-widgets/ipywidgets) | `3.0.11` | `3.0.13` |
| [keyring](https://github.com/jaraco/keyring) | `24.3.0` | `25.4.1` |
| [kiwisolver](https://github.com/nucleic/kiwi) | `1.4.5` | `1.4.7` |
| [langchain-core](https://github.com/langchain-ai/langchain) | `0.1.4` | `0.3.12` |
| [langsmith](https://github.com/langchain-ai/langsmith-sdk) | `0.0.75` | `0.1.136` |
| [levenshtein](https://github.com/rapidfuzz/Levenshtein) | `0.25.1` | `0.26.0` |
| [livereload](https://github.com/lepture/python-livereload) | `2.6.3` | `2.7.0` |
| [lxml](https://github.com/lxml/lxml) | `5.0.0` | `5.3.0` |
| [markupsafe](https://github.com/pallets/markupsafe) | `2.1.3` | `3.0.2` |
| [marshmallow](https://github.com/marshmallow-code/marshmallow) | `3.20.1` | `3.23.0` |
| [mdit-py-plugins](https://github.com/executablebooks/mdit-py-plugins) | `0.4.0` | `0.4.2` |
| [more-itertools](https://github.com/more-itertools/more-itertools) | `10.1.0` | `10.5.0` |
| [msal](https://github.com/AzureAD/microsoft-authentication-library-for-python) | `1.30.0` | `1.31.0` |
| [msgpack](https://github.com/msgpack/msgpack-python) | `1.0.8` | `1.1.0` |
| [multidict](https://github.com/aio-libs/multidict) | `6.0.4` | `6.1.0` |
| [mypy](https://github.com/python/mypy) | `1.10.0` | `1.12.1` |
| [myst-parser](https://github.com/executablebooks/MyST-Parser) | `2.0.0` | `4.0.0` |
| [ndindex](https://github.com/Quansight-Labs/ndindex) | `1.8` | `1.9.2` |
| [networkx](https://github.com/networkx/networkx) | `3.2.1` | `3.4.1` |
| [nh3](https://github.com/messense/nh3) | `0.2.15` | `0.2.18` |
| [notebook](https://github.com/jupyter/notebook) | `7.2.1` | `7.2.2` |
| [nvidia-cublas-cu12](https://developer.nvidia.com/cuda-zone) | `12.1.3.1` | `12.6.3.3` |
| [nvidia-cuda-cupti-cu12](https://developer.nvidia.com/cuda-zone) | `12.1.105` | `12.6.80` |
| [nvidia-cuda-nvrtc-cu12](https://developer.nvidia.com/cuda-zone) | `12.1.105` | `12.6.77` |
| [nvidia-cuda-runtime-cu12](https://developer.nvidia.com/cuda-zone) | `12.1.105` | `12.6.77` |
| [nvidia-cudnn-cu12](https://developer.nvidia.com/cuda-zone) | `8.9.2.26` | `9.5.0.50` |
| [nvidia-cufft-cu12](https://developer.nvidia.com/cuda-zone) | `11.0.2.54` | `11.3.0.4` |
| [nvidia-curand-cu12](https://developer.nvidia.com/cuda-zone) | `10.3.2.106` | `10.3.7.77` |
| [nvidia-cusolver-cu12](https://developer.nvidia.com/cuda-zone) | `11.4.5.107` | `11.7.1.2` |
| [nvidia-cusparse-cu12](https://developer.nvidia.com/cuda-zone) | `12.1.0.106` | `12.5.4.2` |
| [nvidia-nccl-cu12](https://developer.nvidia.com/cuda-zone) | `2.18.1` | `2.23.4` |
| [nvidia-nvjitlink-cu12](https://developer.nvidia.com/cuda-zone) | `12.3.101` | `12.6.77` |
| [nvidia-nvtx-cu12](https://developer.nvidia.com/cuda-zone) | `12.1.105` | `12.6.77` |
| [packaging](https://github.com/pypa/packaging) | `23.2` | `24.1` |
| [pillow](https://github.com/python-pillow/Pillow) | `10.4.0` | `11.0.0` |
| [pkginfo](https://code.launchpad.net/~tseaver/pkginfo/trunk) | `1.9.6` | `1.11.2` |
| [platformdirs](https://github.com/tox-dev/platformdirs) | `4.1.0` | `4.3.6` |
| [pluggy](https://github.com/pytest-dev/pluggy) | `1.3.0` | `1.5.0` |
| [prometheus-client](https://github.com/prometheus/client_python) | `0.20.0` | `0.21.0` |
| [prompt-toolkit](https://github.com/prompt-toolkit/python-prompt-toolkit) | `3.0.47` | `3.0.48` |
| [psutil](https://github.com/giampaolo/psutil) | `6.0.0` | `6.1.0` |
| [pycparser](https://github.com/eliben/pycparser) | `2.21` | `2.22` |
| [pydantic](https://github.com/pydantic/pydantic) | `2.5.3` | `2.9.2` |
| [pydantic-core](https://github.com/pydantic/pydantic-core) | `2.14.6` | `2.24.2` |
| [pygments](https://github.com/pygments/pygments) | `2.17.2` | `2.18.0` |
| [pyjwt](https://github.com/jpadilla/pyjwt) | `2.8.0` | `2.9.0` |
| [pymupdfb](https://github.com/pymupdf/pymupdf) | `1.24.9` | `1.24.10` |
| [pyparsing](https://github.com/pyparsing/pyparsing) | `3.1.2` | `3.2.0` |
| [pyproject-hooks](https://github.com/pypa/pyproject-hooks) | `1.0.0` | `1.2.0` |
| [pytest](https://github.com/pytest-dev/pytest) | `7.4.4` | `8.3.3` |
| [python-dateutil](https://github.com/dateutil/dateutil) | `2.8.2` | `2.9.0.post0` |
| [pytz](https://github.com/stub42/pytz) | `2023.3.post1` | `2024.2` |
| [pyyaml](https://github.com/yaml/pyyaml) | `6.0.1` | `6.0.2` |
| [pyzmq](https://github.com/zeromq/pyzmq) | `26.0.3` | `26.2.0` |
| [qtconsole](https://github.com/jupyter/qtconsole) | `5.5.2` | `5.6.0` |
| [rapidfuzz](https://github.com/rapidfuzz/RapidFuzz) | `3.9.5` | `3.10.0` |
| [readme-renderer](https://github.com/pypa/readme_renderer) | `42.0` | `44.0` |
| [regex](https://github.com/mrabarnett/mrab-regex) | `2024.7.24` | `2024.9.11` |
| [requests](https://github.com/psf/requests) | `2.31.0` | `2.32.3` |
| [requests-oauthlib](https://github.com/requests/requests-oauthlib) | `1.3.1` | `2.0.0` |
| [rich](https://github.com/Textualize/rich) | `13.7.0` | `13.9.2` |
| [rpds-py](https://github.com/crate-py/rpds) | `0.19.1` | `0.20.0` |
| ruamel-yaml-clib | `0.2.8` | `0.2.12` |
| [ruff](https://github.com/astral-sh/ruff) | `0.4.5` | `0.7.0` |
| [sniffio](https://github.com/python-trio/sniffio) | `1.3.0` | `1.3.1` |
| [soupsieve](https://github.com/facelessuser/soupsieve) | `2.5` | `2.6` |
| [sphinx-autobuild](https://github.com/sphinx-doc/sphinx-autobuild) | `2021.3.14` | `2024.10.3` |
| [sphinx-click](https://github.com/click-contrib/sphinx-click) | `5.1.0` | `6.0.0` |
| [sphinxcontrib-applehelp](https://github.com/sphinx-doc/sphinxcontrib-applehelp) | `1.0.7` | `2.0.0` |
| [sphinxcontrib-devhelp](https://github.com/sphinx-doc/sphinxcontrib-devhelp) | `1.0.5` | `2.0.0` |
| [sphinxcontrib-htmlhelp](https://github.com/sphinx-doc/sphinxcontrib-htmlhelp) | `2.0.4` | `2.1.0` |
| [sphinxcontrib-qthelp](https://github.com/sphinx-doc/sphinxcontrib-qthelp) | `1.0.6` | `2.0.0` |
| [sphinxcontrib-serializinghtml](https://github.com/sphinx-doc/sphinxcontrib-serializinghtml) | `1.1.9` | `2.0.0` |
| [sqlalchemy](https://github.com/sqlalchemy/sqlalchemy) | `2.0.24` | `2.0.36` |
| [sympy](https://github.com/sympy/sympy) | `1.12` | `1.13.3` |
| [tenacity](https://github.com/jd/tenacity) | `8.2.3` | `9.0.0` |
| [termcolor](https://github.com/termcolor/termcolor) | `2.4.0` | `2.5.0` |
| [tomlkit](https://github.com/sdispater/tomlkit) | `0.12.3` | `0.13.2` |
| [tornado](https://github.com/tornadoweb/tornado) | `6.4` | `6.4.1` |
| [tqdm](https://github.com/tqdm/tqdm) | `4.66.1` | `4.66.5` |
| [triton](https://github.com/triton-lang/triton) | `2.1.0` | `3.1.0` |
| [twine](https://github.com/pypa/twine) | `4.0.2` | `5.1.1` |
| [typer](https://github.com/fastapi/typer) | `0.9.0` | `0.12.5` |
| [types-psutil](https://github.com/python/typeshed) | `6.0.0.20240621` | `6.0.0.20241011` |
| [types-python-dateutil](https://github.com/python/typeshed) | `2.9.0.20240316` | `2.9.0.20241003` |
| [types-pyyaml](https://github.com/python/typeshed) | `6.0.12.20240724` | `6.0.12.20240917` |
| [typing-extensions](https://github.com/python/typing_extensions) | `4.9.0` | `4.12.2` |
| [tzdata](https://github.com/python/tzdata) | `2023.4` | `2024.2` |
| [urllib3](https://github.com/urllib3/urllib3) | `2.1.0` | `2.2.3` |
| [webcolors](https://github.com/ubernostrum/webcolors) | `24.6.0` | `24.8.0` |
| [widgetsnbextension](http://jupyter.org) | `4.0.11` | `4.0.13` |
| [yarl](https://github.com/aio-libs/yarl) | `1.9.4` | `1.15.5` |
| [zipp](https://github.com/jaraco/zipp) | `3.17.0` | `3.20.2` |
| [exceptiongroup](https://github.com/agronholm/exceptiongroup) | `1.2.0` | `1.2.2` |
| [tomli](https://github.com/hukkin/tomli) | `2.0.1` | `2.0.2` |



Updates `pydantic-settings` from 2.1.0 to 2.6.0
- [Release notes](https://github.com/pydantic/pydantic-settings/releases)
- [Commits](https://github.com/pydantic/pydantic-settings/compare/v2.1.0...v2.6.0)

Updates `cython` from 3.0.7 to 3.0.11
- [Release notes](https://github.com/cython/cython/releases)
- [Changelog](https://github.com/cython/cython/blob/master/CHANGES.rst)
- [Commits](https://github.com/cython/cython/compare/3.0.7...3.0.11)

Updates `scipy` from 1.11.4 to 1.14.1
- [Release notes](https://github.com/scipy/scipy/releases)
- [Commits](https://github.com/scipy/scipy/compare/v1.11.4...v1.14.1)

Updates `python-levenshtein` from 0.25.1 to 0.26.0
- [Release notes](https://github.com/rapidfuzz/python-Levenshtein/releases)
- [Changelog](https://github.com/rapidfuzz/python-Levenshtein/blob/main/HISTORY.md)
- [Commits](https://github.com/rapidfuzz/python-Levenshtein/compare/v0.25.1...v0.26.0)

Updates `scikit-learn` from 1.5.1 to 1.5.2
- [Release notes](https://github.com/scikit-learn/scikit-learn/releases)
- [Commits](https://github.com/scikit-learn/scikit-learn/compare/1.5.1...1.5.2)

Updates `filelock` from 3.13.1 to 3.16.1
- [Release notes](https://github.com/tox-dev/py-filelock/releases)
- [Changelog](https://github.com/tox-dev/filelock/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/py-filelock/compare/3.13.1...3.16.1)

Updates `fire` from 0.5.0 to 0.7.0
- [Release notes](https://github.com/google/python-fire/releases)
- [Commits](https://github.com/google/python-fire/compare/v0.5.0...v0.7.0)

Updates `openai` from 1.6.1 to 1.52.0
- [Release notes](https://github.com/openai/openai-python/releases)
- [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md)
- [Commits](https://github.com/openai/openai-python/compare/v1.6.1...v1.52.0)

Updates `ruamel-yaml` from 0.18.5 to 0.18.6

Updates `torch` from 2.1.2 to 2.5.0
- [Release notes](https://github.com/pytorch/pytorch/releases)
- [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md)
- [Commits](https://github.com/pytorch/pytorch/compare/v2.1.2...v2.5.0)

Updates `torch-geometric` from 2.5.3 to 2.6.1
- [Release notes](https://github.com/pyg-team/pytorch_geometric/releases)
- [Changelog](https://github.com/pyg-team/pytorch_geometric/blob/master/CHANGELOG.md)
- [Commits](https://github.com/pyg-team/pytorch_geometric/compare/2.5.3...2.6.1)

Updates `numpy` from 1.26.2 to 2.1.2
- [Release notes](https://github.com/numpy/numpy/releases)
- [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst)
- [Commits](https://github.com/numpy/numpy/compare/v1.26.2...v2.1.2)

Updates `pandas` from 2.1.4 to 2.2.3
- [Release notes](https://github.com/pandas-dev/pandas/releases)
- [Commits](https://github.com/pandas-dev/pandas/compare/v2.1.4...v2.2.3)

Updates `matplotlib` from 3.9.1 to 3.9.2
- [Release notes](https://github.com/matplotlib/matplotlib/releases)
- [Commits](https://github.com/matplotlib/matplotlib/compare/v3.9.1...v3.9.2)

Updates `langchain` from 0.0.353 to 0.3.4
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](https://github.com/langchain-ai/langchain/compare/v0.0.353...langchain==0.3.4)

Updates `langchain-community` from 0.0.7 to 0.3.3
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](https://github.com/langchain-ai/langchain/compare/langchain-robocorp==0.0.7...langchain-community==0.3.3)

Updates `tiktoken` from 0.7.0 to 0.8.0
- [Release notes](https://github.com/openai/tiktoken/releases)
- [Changelog](https://github.com/openai/tiktoken/blob/main/CHANGELOG.md)
- [Commits](https://github.com/openai/tiktoken/compare/0.7.0...0.8.0)

Updates `pymupdf` from 1.24.9 to 1.24.11
- [Release notes](https://github.com/pymupdf/pymupdf/releases)
- [Changelog](https://github.com/pymupdf/PyMuPDF/blob/main/changes.txt)
- [Commits](https://github.com/pymupdf/pymupdf/compare/1.24.9...1.24.11)

Updates `azure-identity` from 1.17.1 to 1.19.0
- [Release notes](https://github.com/Azure/azure-sdk-for-python/releases)
- [Changelog](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/esrp_release.md)
- [Commits](https://github.com/Azure/azure-sdk-for-python/compare/azure-identity_1.17.1...azure-identity_1.19.0)

Updates `pypdf` from 3.17.4 to 5.0.1
- [Release notes](https://github.com/py-pdf/pypdf/releases)
- [Changelog](https://github.com/py-pdf/pypdf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/py-pdf/pypdf/compare/3.17.4...5.0.1)

Updates `azure-core` from 1.29.6 to 1.31.0
- [Release notes](https://github.com/Azure/azure-sdk-for-python/releases)
- [Changelog](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/esrp_release.md)
- [Commits](https://github.com/Azure/azure-sdk-for-python/compare/azure-core_1.29.6...azure-core_1.31.0)

Updates `azure-ai-formrecognizer` from 3.3.2 to 3.3.3
- [Release notes](https://github.com/Azure/azure-sdk-for-python/releases)
- [Changelog](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/esrp_release.md)
- [Commits](https://github.com/Azure/azure-sdk-for-python/compare/azure-ai-formrecognizer_3.3.2...azure-ai-formrecognizer_3.3.3)

Updates `statsmodels` from 0.14.2 to 0.14.4
- [Release notes](https://github.com/statsmodels/statsmodels/releases)
- [Changelog](https://github.com/statsmodels/statsmodels/blob/main/CHANGES.md)
- [Commits](https://github.com/statsmodels/statsmodels/compare/v0.14.2...v0.14.4)

Updates `tables` from 3.9.2 to 3.10.1
- [Release notes](https://github.com/PyTables/PyTables/releases)
- [Changelog](https://github.com/PyTables/PyTables/blob/master/RELEASE_NOTES.rst)
- [Commits](https://github.com/PyTables/PyTables/compare/v3.9.2...v3.10.1)

Updates `tree-sitter-python` from 0.21.0 to 0.23.2
- [Commits](https://github.com/tree-sitter/tree-sitter-python/compare/v0.21.0...v0.23.2)

Updates `tree-sitter` from 0.22.3 to 0.23.1
- [Release notes](https://github.com/tree-sitter/py-tree-sitter/releases)
- [Commits](https://github.com/tree-sitter/py-tree-sitter/compare/v0.22.3...v0.23.1)

Updates `jupyter` from 1.0.0 to 1.1.1

Updates `python-dotenv` from 1.0.0 to 1.0.1
- [Release notes](https://github.com/theskumar/python-dotenv/releases)
- [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/theskumar/python-dotenv/compare/v1.0.0...v1.0.1)

Updates `setuptools-scm` from 8.0.4 to 8.1.0
- [Release notes](https://github.com/pypa/setuptools_scm/releases)
- [Changelog](https://github.com/pypa/setuptools-scm/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pypa/setuptools_scm/compare/v8.0.4...v8.1.0)

Updates `sphinx` from 7.2.6 to 8.1.3
- [Release notes](https://github.com/sphinx-doc/sphinx/releases)
- [Changelog](https://github.com/sphinx-doc/sphinx/blob/v8.1.3/CHANGES.rst)
- [Commits](https://github.com/sphinx-doc/sphinx/compare/v7.2.6...v8.1.3)

Updates `furo` from 2023.9.10 to 2024.8.6
- [Release notes](https://github.com/pradyunsg/furo/releases)
- [Changelog](https://github.com/pradyunsg/furo/blob/main/docs/changelog.md)
- [Commits](https://github.com/pradyunsg/furo/compare/2023.09.10...2024.08.06)

Updates `importlib-metadata` from 7.0.1 to 8.5.0
- [Release notes](https://github.com/python/importlib_metadata/releases)
- [Changelog](https://github.com/python/importlib_metadata/blob/main/NEWS.rst)
- [Commits](https://github.com/python/importlib_metadata/compare/v7.0.1...v8.5.0)

Updates `aiohttp` from 3.9.1 to 3.10.10
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.1...v3.10.10)

Updates `alabaster` from 0.7.13 to 1.0.0
- [Release notes](https://github.com/sphinx-doc/alabaster/releases)
- [Changelog](https://github.com/sphinx-doc/alabaster/blob/master/docs/changelog.rst)
- [Commits](https://github.com/sphinx-doc/alabaster/compare/0.7.13...1.0.0)

Updates `annotated-types` from 0.6.0 to 0.7.0
- [Release notes](https://github.com/annotated-types/annotated-types/releases)
- [Commits](https://github.com/annotated-types/annotated-types/compare/v0.6.0...v0.7.0)

Updates `anyio` from 4.2.0 to 4.6.2.post1
- [Release notes](https://github.com/agronholm/anyio/releases)
- [Changelog](https://github.com/agronholm/anyio/blob/master/docs/versionhistory.rst)
- [Commits](https://github.com/agronholm/anyio/compare/4.2.0...4.6.2.post1)

Updates `attrs` from 23.2.0 to 24.2.0
- [Commits](https://github.com/sponsors/hynek/commits)

Updates `autodoc-pydantic` from 2.0.1 to 2.2.0
- [Release notes](https://github.com/mansenfranzen/autodoc_pydantic/releases)
- [Changelog](https://github.com/mansenfranzen/autodoc_pydantic/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mansenfranzen/autodoc_pydantic/compare/v2.0.1...v2.2.0)

Updates `babel` from 2.14.0 to 2.16.0
- [Release notes](https://github.com/python-babel/babel/releases)
- [Changelog](https://github.com/python-babel/babel/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-babel/babel/compare/v2.14.0...v2.16.0)

Updates `beautifulsoup4` from 4.12.2 to 4.12.3

Updates `black` from 23.12.1 to 24.10.0
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/23.12.1...24.10.0)

Updates `build` from 1.0.3 to 1.2.2.post1
- [Release notes](https://github.com/pypa/build/releases)
- [Changelog](https://github.com/pypa/build/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pypa/build/compare/1.0.3...1.2.2.post1)

Updates `certifi` from 2023.11.17 to 2024.8.30
- [Commits](https://github.com/certifi/python-certifi/compare/2023.11.17...2024.08.30)

Updates `cffi` from 1.16.0 to 1.17.1
- [Release notes](https://github.com/python-cffi/cffi/releases)
- [Commits](https://github.com/python-cffi/cffi/compare/v1.16.0...v1.17.1)

Updates `charset-normalizer` from 3.3.2 to 3.4.0
- [Release notes](https://github.com/Ousret/charset_normalizer/releases)
- [Changelog](https://github.com/jawah/charset_normalizer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Ousret/charset_normalizer/compare/3.3.2...3.4.0)

Updates `contourpy` from 1.2.1 to 1.3.0
- [Release notes](https://github.com/contourpy/contourpy/releases)
- [Changelog](https://github.com/contourpy/contourpy/blob/main/docs/changelog.rst)
- [Commits](https://github.com/contourpy/contourpy/compare/v1.2.1...v1.3.0)

Updates `coverage` from 7.4.0 to 7.6.4
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.4.0...7.6.4)

Updates `cryptography` from 41.0.7 to 43.0.3
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/41.0.7...43.0.3)

Updates `dataclasses-json` from 0.6.3 to 0.6.7
- [Release notes](https://github.com/lidatong/dataclasses-json/releases)
- [Commits](https://github.com/lidatong/dataclasses-json/compare/v0.6.3...v0.6.7)

Updates `debugpy` from 1.8.2 to 1.8.7
- [Release notes](https://github.com/microsoft/debugpy/releases)
- [Commits](https://github.com/microsoft/debugpy/compare/v1.8.2...v1.8.7)

Updates `dill` from 0.3.8 to 0.3.9
- [Release notes](https://github.com/uqfoundation/dill/releases)
- [Commits](https://github.com/uqfoundation/dill/compare/0.3.8...0.3.9)

Updates `docutils` from 0.20.1 to 0.21.2

Updates `executing` from 2.0.1 to 2.1.0
- [Release notes](https://github.com/alexmojaki/executing/releases)
- [Commits](https://github.com/alexmojaki/executing/compare/v2.0.1...v2.1.0)

Updates `fonttools` from 4.53.1 to 4.54.1
- [Release notes](https://github.com/fonttools/fonttools/releases)
- [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst)
- [Commits](https://github.com/fonttools/fonttools/compare/4.53.1...4.54.1)

Updates `fsspec` from 2023.12.2 to 2024.10.0
- [Commits](https://github.com/fsspec/filesystem_spec/compare/2023.12.2...2024.10.0)

Updates `git-changelog` from 2.4.0 to 2.5.2
- [Release notes](https://github.com/pawamoy/git-changelog/releases)
- [Changelog](https://github.com/pawamoy/git-changelog/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pawamoy/git-changelog/compare/2.4.0...2.5.2)

Updates `greenlet` from 3.0.3 to 3.1.1
- [Changelog](https://github.com/python-greenlet/greenlet/blob/master/CHANGES.rst)
- [Commits](https://github.com/python-greenlet/greenlet/compare/3.0.3...3.1.1)

Updates `httpcore` from 1.0.2 to 1.0.6
- [Release notes](https://github.com/encode/httpcore/releases)
- [Changelog](https://github.com/encode/httpcore/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/httpcore/compare/1.0.2...1.0.6)

Updates `httpx` from 0.26.0 to 0.27.2
- [Release notes](https://github.com/encode/httpx/releases)
- [Changelog](https://github.com/encode/httpx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/httpx/compare/0.26.0...0.27.2)

Updates `idna` from 3.6 to 3.10
- [Release notes](https://github.com/kjd/idna/releases)
- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst)
- [Commits](https://github.com/kjd/idna/compare/v3.6...v3.10)

Updates `ipython` from 8.26.0 to 8.28.0
- [Release notes](https://github.com/ipython/ipython/releases)
- [Commits](https://github.com/ipython/ipython/compare/8.26.0...8.28.0)

Updates `ipywidgets` from 8.1.3 to 8.1.5
- [Release notes](https://github.com/jupyter-widgets/ipywidgets/releases)
- [Commits](https://github.com/jupyter-widgets/ipywidgets/compare/8.1.3...8.1.5)

Updates `isodate` from 0.6.1 to 0.7.2
- [Changelog](https://github.com/gweis/isodate/blob/master/CHANGES.txt)
- [Commits](https://github.com/gweis/isodate/compare/0.6.1...0.7.2)

Updates `jaraco-classes` from 3.3.0 to 3.4.0
- [Release notes](https://github.com/jaraco/jaraco.classes/releases)
- [Changelog](https://github.com/jaraco/jaraco.classes/blob/main/NEWS.rst)
- [Commits](https://github.com/jaraco/jaraco.classes/compare/v3.3.0...v3.4.0)

Updates `jinja2` from 3.1.2 to 3.1.4
- [Release notes](https://github.com/pallets/jinja/releases)
- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.4)

Updates `jsonpointer` from 2.4 to 3.0.0
- [Commits](https://github.com/stefankoegl/python-json-pointer/compare/v2.4...v3.0.0)

Updates `jsonschema-specifications` from 2023.12.1 to 2024.10.1
- [Release notes](https://github.com/python-jsonschema/jsonschema-specifications/releases)
- [Commits](https://github.com/python-jsonschema/jsonschema-specifications/compare/v2023.12.1...v2024.10.1)

Updates `jupyter-client` from 8.6.2 to 8.6.3
- [Release notes](https://github.com/jupyter/jupyter_client/releases)
- [Changelog](https://github.com/jupyter/jupyter_client/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/jupyter_client/compare/v8.6.2...v8.6.3)

Updates `jupyterlab` from 4.2.4 to 4.2.5
- [Release notes](https://github.com/jupyterlab/jupyterlab/releases)
- [Changelog](https://github.com/jupyterlab/jupyterlab/blob/@jupyterlab/lsp@4.2.5/CHANGELOG.md)
- [Commits](https://github.com/jupyterlab/jupyterlab/compare/@jupyterlab/lsp@4.2.4...@jupyterlab/lsp@4.2.5)

Updates `jupyterlab-widgets` from 3.0.11 to 3.0.13
- [Release notes](https://github.com/jupyter-widgets/ipywidgets/releases)
- [Commits](https://github.com/jupyter-widgets/ipywidgets/commits)

Updates `keyring` from 24.3.0 to 25.4.1
- [Release notes](https://github.com/jaraco/keyring/releases)
- [Changelog](https://github.com/jaraco/keyring/blob/main/NEWS.rst)
- [Commits](https://github.com/jaraco/keyring/compare/v24.3.0...v25.4.1)

Updates `kiwisolver` from 1.4.5 to 1.4.7
- [Release notes](https://github.com/nucleic/kiwi/releases)
- [Changelog](https://github.com/nucleic/kiwi/blob/main/releasenotes.rst)
- [Commits](https://github.com/nucleic/kiwi/compare/1.4.5...1.4.7)

Updates `langchain-core` from 0.1.4 to 0.3.12
- [Release notes](https://github.com/langchain-ai/langchain/releases)
- [Commits](https://github.com/langchain-ai/langchain/compare/v0.1.4...langchain-core==0.3.12)

Updates `langsmith` from 0.0.75 to 0.1.136
- [Release notes](https://github.com/langchain-ai/langsmith-sdk/releases)
- [Commits](https://github.com/langchain-ai/langsmith-sdk/compare/v0.0.75...v0.1.136)

Updates `levenshtein` from 0.25.1 to 0.26.0
- [Release notes](https://github.com/rapidfuzz/Levenshtein/releases)
- [Changelog](https://github.com/rapidfuzz/Levenshtein/blob/main/HISTORY.md)
- [Commits](https://github.com/rapidfuzz/Levenshtein/compare/v0.25.1...v0.26.0)

Updates `livereload` from 2.6.3 to 2.7.0
- [Release notes](https://github.com/lepture/python-livereload/releases)
- [Changelog](https://github.com/lepture/python-livereload/blob/master/CHANGES.rst)
- [Commits](https://github.com/lepture/python-livereload/compare/2.6.3...2.7.0)

Updates `lxml` from 5.0.0 to 5.3.0
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-5.0.0...lxml-5.3.0)

Updates `markupsafe` from 2.1.3 to 3.0.2
- [Release notes](https://github.com/pallets/markupsafe/releases)
- [Changelog](https://github.com/pallets/markupsafe/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/markupsafe/compare/2.1.3...3.0.2)

Updates `marshmallow` from 3.20.1 to 3.23.0
- [Changelog](https://github.com/marshmallow-code/marshmallow/blob/dev/CHANGELOG.rst)
- [Commits](https://github.com/marshmallow-code/marshmallow/compare/3.20.1...3.23.0)

Updates `mdit-py-plugins` from 0.4.0 to 0.4.2
- [Release notes](https://github.com/executablebooks/mdit-py-plugins/releases)
- [Changelog](https://github.com/executablebooks/mdit-py-plugins/blob/master/CHANGELOG.md)
- [Commits](https://github.com/executablebooks/mdit-py-plugins/compare/v0.4.0...v0.4.2)

Updates `more-itertools` from 10.1.0 to 10.5.0
- [Release notes](https://github.com/more-itertools/more-itertools/releases)
- [Commits](https://github.com/more-itertools/more-itertools/compare/v10.1.0...v10.5.0)

Updates `msal` from 1.30.0 to 1.31.0
- [Release notes](https://github.com/AzureAD/microsoft-authentication-library-for-python/releases)
- [Commits](https://github.com/AzureAD/microsoft-authentication-library-for-python/compare/1.30.0...1.31.0)

Updates `msgpack` from 1.0.8 to 1.1.0
- [Release notes](https://github.com/msgpack/msgpack-python/releases)
- [Changelog](https://github.com/msgpack/msgpack-python/blob/main/ChangeLog.rst)
- [Commits](https://github.com/msgpack/msgpack-python/compare/v1.0.8...v1.1.0)

Updates `multidict` from 6.0.4 to 6.1.0
- [Release notes](https://github.com/aio-libs/multidict/releases)
- [Changelog](https://github.com/aio-libs/multidict/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/multidict/compare/v6.0.4...v6.1.0)

Updates `mypy` from 1.10.0 to 1.12.1
- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python/mypy/compare/v1.10.0...v1.12.1)

Updates `myst-parser` from 2.0.0 to 4.0.0
- [Release notes](https://github.com/executablebooks/MyST-Parser/releases)
- [Changelog](https://github.com/executablebooks/MyST-Parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/executablebooks/MyST-Parser/compare/v2.0.0...v4.0.0)

Updates `ndindex` from 1.8 to 1.9.2
- [Release notes](https://github.com/Quansight-Labs/ndindex/releases)
- [Changelog](https://github.com/Quansight-Labs/ndindex/blob/main/docs/changelog.md)
- [Commits](https://github.com/Quansight-Labs/ndindex/compare/1.8...1.9.2)

Updates `networkx` from 3.2.1 to 3.4.1
- [Release notes](https://github.com/networkx/networkx/releases)
- [Commits](https://github.com/networkx/networkx/compare/networkx-3.2.1...networkx-3.4.1)

Updates `nh3` from 0.2.15 to 0.2.18
- [Release notes](https://github.com/messense/nh3/releases)
- [Commits](https://github.com/messense/nh3/compare/v0.2.15...v0.2.18)

Updates `notebook` from 7.2.1 to 7.2.2
- [Release notes](https://github.com/jupyter/notebook/releases)
- [Changelog](https://github.com/jupyter/notebook/blob/@jupyter-notebook/tree@7.2.2/CHANGELOG.md)
- [Commits](https://github.com/jupyter/notebook/compare/@jupyter-notebook/tree@7.2.1...@jupyter-notebook/tree@7.2.2)

Updates `nvidia-cublas-cu12` from 12.1.3.1 to 12.6.3.3

Updates `nvidia-cuda-cupti-cu12` from 12.1.105 to 12.6.80

Updates `nvidia-cuda-nvrtc-cu12` from 12.1.105 to 12.6.77

Updates `nvidia-cuda-runtime-cu12` from 12.1.105 to 12.6.77

Updates `nvidia-cudnn-cu12` from 8.9.2.26 to 9.5.0.50

Updates `nvidia-cufft-cu12` from 11.0.2.54 to 11.3.0.4

Updates `nvidia-curand-cu12` from 10.3.2.106 to 10.3.7.77

Updates `nvidia-cusolver-cu12` from 11.4.5.107 to 11.7.1.2

Updates `nvidia-cusparse-cu12` from 12.1.0.106 to 12.5.4.2

Updates `nvidia-nccl-cu12` from 2.18.1 to 2.23.4

Updates `nvidia-nvjitlink-cu12` from 12.3.101 to 12.6.77

Updates `nvidia-nvtx-cu12` from 12.1.105 to 12.6.77

Updates `packaging` from 23.2 to 24.1
- [Release notes](https://github.com/pypa/packaging/releases)
- [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pypa/packaging/compare/23.2...24.1)

Updates `pillow` from 10.4.0 to 11.0.0
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/10.4.0...11.0.0)

Updates `pkginfo` from 1.9.6 to 1.11.2

Updates `platformdirs` from 4.1.0 to 4.3.6
- [Release notes](https://github.com/tox-dev/platformdirs/releases)
- [Changelog](https://github.com/tox-dev/platformdirs/blob/main/CHANGES.rst)
- [Commits](https://github.com/tox-dev/platformdirs/compare/4.1.0...4.3.6)

Updates `pluggy` from 1.3.0 to 1.5.0
- [Changelog](https://github.com/pytest-dev/pluggy/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pluggy/compare/1.3.0...1.5.0)

Updates `prometheus-client` from 0.20.0 to 0.21.0
- [Release notes](https://github.com/prometheus/client_python/releases)
- [Commits](https://github.com/prometheus/client_python/compare/v0.20.0...v0.21.0)

Updates `prompt-toolkit` from 3.0.47 to 3.0.48
- [Release notes](https://github.com/prompt-toolkit/python-prompt-toolkit/releases)
- [Changelog](https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/CHANGELOG)
- [Commits](https://github.com/prompt-toolkit/python-prompt-toolkit/compare/3.0.47...3.0.48)

Updates `psutil` from 6.0.0 to 6.1.0
- [Changelog](https://github.com/giampaolo/psutil/blob/master/HISTORY.rst)
- [Commits](https://github.com/giampaolo/psutil/compare/release-6.0.0...release-6.1.0)

Updates `pycparser` from 2.21 to 2.22
- [Release notes](https://github.com/eliben/pycparser/releases)
- [Changelog](https://github.com/eliben/pycparser/blob/main/CHANGES)
- [Commits](https://github.com/eliben/pycparser/compare/release_v2.21...release_v2.22)

Updates `pydantic` from 2.5.3 to 2.9.2
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.5.3...v2.9.2)

Updates `pydantic-core` from 2.14.6 to 2.24.2
- [Release notes](https://github.com/pydantic/pydantic-core/releases)
- [Commits](https://github.com/pydantic/pydantic-core/compare/v2.14.6...v2.24.2)

Updates `pygments` from 2.17.2 to 2.18.0
- [Release notes](https://github.com/pygments/pygments/releases)
- [Changelog](https://github.com/pygments/pygments/blob/master/CHANGES)
- [Commits](https://github.com/pygments/pygments/compare/2.17.2...2.18.0)

Updates `pyjwt` from 2.8.0 to 2.9.0
- [Release notes](https://github.com/jpadilla/pyjwt/releases)
- [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/jpadilla/pyjwt/compare/2.8.0...2.9.0)

Updates `pymupdfb` from 1.24.9 to 1.24.10
- [Release notes](https://github.com/pymupdf/pymupdf/releases)
- [Changelog](https://github.com/pymupdf/PyMuPDF/blob/main/changes.txt)
- [Commits](https://github.com/pymupdf/pymupdf/compare/1.24.9...1.24.10)

Updates `pyparsing` from 3.1.2 to 3.2.0
- [Release notes](https://github.com/pyparsing/pyparsing/releases)
- [Changelog](https://github.com/pyparsing/pyparsing/blob/master/CHANGES)
- [Commits](https://github.com/pyparsing/pyparsing/compare/pyparsing_3.1.2...3.2.0)

Updates `pyproject-hooks` from 1.0.0 to 1.2.0
- [Changelog](https://github.com/pypa/pyproject-hooks/blob/main/docs/changelog.rst)
- [Commits](https://github.com/pypa/pyproject-hooks/compare/v1.0.0...v1.2.0)

Updates `pytest` from 7.4.4 to 8.3.3
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/7.4.4...8.3.3)

Updates `python-dateutil` from 2.8.2 to 2.9.0.post0
- [Release notes](https://github.com/dateutil/dateutil/releases)
- [Changelog](https://github.com/dateutil/dateutil/blob/master/NEWS)
- [Commits](https://github.com/dateutil/dateutil/compare/2.8.2...2.9.0.post0)

Updates `pytz` from 2023.3.post1 to 2024.2
- [Release notes](https://github.com/stub42/pytz/releases)
- [Commits](https://github.com/stub42/pytz/compare/release_2023.3.post1...release_2024.2)

Updates `pyyaml` from 6.0.1 to 6.0.2
- [Release notes](https://github.com/yaml/pyyaml/releases)
- [Changelog](https://github.com/yaml/pyyaml/blob/main/CHANGES)
- [Commits](https://github.com/yaml/pyyaml/compare/6.0.1...6.0.2)

Updates `pyzmq` from 26.0.3 to 26.2.0
- [Release notes](https://github.com/zeromq/pyzmq/releases)
- [Commits](https://github.com/zeromq/pyzmq/compare/v26.0.3...v26.2.0)

Updates `qtconsole` from 5.5.2 to 5.6.0
- [Changelog](https://github.com/jupyter/qtconsole/blob/main/RELEASE.md)
- [Commits](https://github.com/jupyter/qtconsole/compare/5.5.2...5.6.0)

Updates `rapidfuzz` from 3.9.5 to 3.10.0
- [Release notes](https://github.com/rapidfuzz/RapidFuzz/releases)
- [Changelog](https://github.com/rapidfuzz/RapidFuzz/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/rapidfuzz/RapidFuzz/compare/v3.9.5...v3.10.0)

Updates `readme-renderer` from 42.0 to 44.0
- [Release notes](https://github.com/pypa/readme_renderer/releases)
- [Changelog](https://github.com/pypa/readme_renderer/blob/main/CHANGES.rst)
- [Commits](https://github.com/pypa/readme_renderer/compare/42.0...44.0)

Updates `regex` from 2024.7.24 to 2024.9.11
- [Changelog](https://github.com/mrabarnett/mrab-regex/blob/hg/changelog.txt)
- [Commits](https://github.com/mrabarnett/mrab-regex/compare/2024.7.24...2024.9.11)

Updates `requests` from 2.31.0 to 2.32.3
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.31.0...v2.32.3)

Updates `requests-oauthlib` from 1.3.1 to 2.0.0
- [Release notes](https://github.com/requests/requests-oauthlib/releases)
- [Changelog](https://github.com/requests/requests-oauthlib/blob/master/HISTORY.rst)
- [Commits](https://github.com/requests/requests-oauthlib/compare/v1.3.1...v2.0.0)

Updates `rich` from 13.7.0 to 13.9.2
- [Release notes](https://github.com/Textualize/rich/releases)
- [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Textualize/rich/compare/v13.7.0...v13.9.2)

Updates `rpds-py` from 0.19.1 to 0.20.0
- [Release notes](https://github.com/crate-py/rpds/releases)
- [Commits](https://github.com/crate-py/rpds/compare/v0.19.1...v0.20.0)

Updates `ruamel-yaml-clib` from 0.2.8 to 0.2.12

Updates `ruff` from 0.4.5 to 0.7.0
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.4.5...0.7.0)

Updates `sniffio` from 1.3.0 to 1.3.1
- [Commits](https://github.com/python-trio/sniffio/compare/v1.3.0...v1.3.1)

Updates `soupsieve` from 2.5 to 2.6
- [Release notes](https://github.com/facelessuser/soupsieve/releases)
- [Commits](https://github.com/facelessuser/soupsieve/compare/2.5...2.6)

Updates `sphinx-autobuild` from 2021.3.14 to 2024.10.3
- [Release notes](https://github.com/sphinx-doc/sphinx-autobuild/releases)
- [Changelog](https://github.com/sphinx-doc/sphinx-autobuild/blob/main/NEWS.rst)
- [Commits](https://github.com/sphinx-doc/sphinx-autobuild/compare/2021.03.14...2024.10.03)

Updates `sphinx-click` from 5.1.0 to 6.0.0
- [Release notes](https://github.com/click-contrib/sphinx-click/releases)
- [Commits](https://github.com/click-contrib/sphinx-click/compare/5.1.0...6.0.0)

Updates `sphinxcontrib-applehelp` from 1.0.7 to 2.0.0
- [Release notes](https://github.com/sphinx-doc/sphinxcontrib-applehelp/releases)
- [Changelog](https://github.com/sphinx-doc/sphinxcontrib-applehelp/blob/master/CHANGES.rst)
- [Commits](https://github.com/sphinx-doc/sphinxcontrib-applehelp/compare/1.0.7...2.0.0)

Updates `sphinxcontrib-devhelp` from 1.0.5 to 2.0.0
- [Release notes](https://github.com/sphinx-doc/sphinxcontrib-devhelp/releases)
- [Changelog](https://github.com/sphinx-doc/sphinxcontrib-devhelp/blob/master/CHANGES.rst)
- [Commits](https://github.com/sphinx-doc/sphinxcontrib-devhelp/compare/1.0.5...2.0.0)

Updates `sphinxcontrib-htmlhelp` from 2.0.4 to 2.1.0
- [Release notes](https://github.com/sphinx-doc/sphinxcontrib-htmlhelp/releases)
- [Changelog](https://github.com/sphinx-doc/sphinxcontrib-htmlhelp/blob/master/CHANGES.rst)
- [Commits](https://github.com/sphinx-doc/sphinxcontrib-htmlhelp/compare/2.0.4...2.1.0)

Updates `sphinxcontrib-qthelp` from 1.0.6 to 2.0.0
- [Release notes](https://github.com/sphinx-doc/sphinxcontrib-qthelp/releases)
- [Changelog](https://github.com/sphinx-doc/sphinxcontrib-qthelp/blob/master/CHANGES.rst)
- [Commits](https://github.com/sphinx-doc/sphinxcontrib-qthelp/compare/1.0.6...2.0.0)

Updates `sphinxcontrib-serializinghtml` from 1.1.9 to 2.0.0
- [Release notes](https://github.com/sphinx-doc/sphinxcontrib-serializinghtml/releases)
- [Changelog](https://github.com/sphinx-doc/sphinxcontrib-serializinghtml/blob/master/CHANGES.rst)
- [Commits](https://github.com/sphinx-doc/sphinxcontrib-serializinghtml/compare/1.1.9...2.0.0)

Updates `sqlalchemy` from 2.0.24 to 2.0.36
- [Release notes](https://github.com/sqlalchemy/sqlalchemy/releases)
- [Changelog](https://github.com/sqlalchemy/sqlalchemy/blob/main/CHANGES.rst)
- [Commits](https://github.com/sqlalchemy/sqlalchemy/commits)

Updates `sympy` from 1.12 to 1.13.3
- [Release notes](https://github.com/sympy/sympy/releases)
- [Commits](https://github.com/sympy/sympy/compare/sympy-1.12...sympy-1.13.3)

Updates `tenacity` from 8.2.3 to 9.0.0
- [Release notes](https://github.com/jd/tenacity/releases)
- [Commits](https://github.com/jd/tenacity/compare/8.2.3...9.0.0)

Updates `termcolor` from 2.4.0 to 2.5.0
- [Release notes](https://github.com/termcolor/termcolor/releases)
- [Changelog](https://github.com/termcolor/termcolor/blob/main/CHANGES.md)
- [Commits](https://github.com/termcolor/termcolor/compare/2.4.0...2.5.0)

Updates `tomlkit` from 0.12.3 to 0.13.2
- [Release notes](https://github.com/sdispater/tomlkit/releases)
- [Changelog](https://github.com/python-poetry/tomlkit/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sdispater/tomlkit/compare/0.12.3...0.13.2)

Updates `tornado` from 6.4 to 6.4.1
- [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst)
- [Commits](https://github.com/tornadoweb/tornado/compare/v6.4.0...v6.4.1)

Updates `tqdm` from 4.66.1 to 4.66.5
- [Release notes](https://github.com/tqdm/tqdm/releases)
- [Commits](https://github.com/tqdm/tqdm/compare/v4.66.1...v4.66.5)

Updates `triton` from 2.1.0 to 3.1.0
- [Commits](https://github.com/triton-lang/triton/commits)

Updates `twine` from 4.0.2 to 5.1.1
- [Release notes](https://github.com/pypa/twine/releases)
- [Changelog](https://github.com/pypa/twine/blob/main/docs/changelog.rst)
- [Commits](https://github.com/pypa/twine/compare/4.0.2...v5.1.1)

Updates `typer` from 0.9.0 to 0.12.5
- [Release notes](https://github.com/fastapi/typer/releases)
- [Changelog](https://github.com/fastapi/typer/blob/master/docs/release-notes.md)
- [Commits](https://github.com/fastapi/typer/compare/0.9.0...0.12.5)

Updates `types-psutil` from 6.0.0.20240621 to 6.0.0.20241011
- [Commits](https://github.com/python/typeshed/commits)

Updates `types-python-dateutil` from 2.9.0.20240316 to 2.9.0.20241003
- [Commits](https://github.com/python/typeshed/commits)

Updates `types-pyyaml` from 6.0.12.20240724 to 6.0.12.20240917
- [Commits](https://github.com/python/typeshed/commits)

Updates `typing-extensions` from 4.9.0 to 4.12.2
- [Release notes](https://github.com/python/typing_extensions/releases)
- [Changelog](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md)
- [Commits](https://github.com/python/typing_extensions/compare/4.9.0...4.12.2)

Updates `tzdata` from 2023.4 to 2024.2
- [Release notes](https://github.com/python/tzdata/releases)
- [Changelog](https://github.com/python/tzdata/blob/master/NEWS.md)
- [Commits](https://github.com/python/tzdata/compare/2023.4...2024.2)

Updates `urllib3` from 2.1.0 to 2.2.3
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.1.0...2.2.3)

Updates `webcolors` from 24.6.0 to 24.8.0
- [Changelog](https://github.com/ubernostrum/webcolors/blob/trunk/docs/changelog.rst)
- [Commits](https://github.com/ubernostrum/webcolors/compare/24.6.0...24.8.0)

Updates `widgetsnbextension` from 4.0.11 to 4.0.13

Updates `yarl` from 1.9.4 to 1.15.5
- [Release notes](https://github.com/aio-libs/yarl/releases)
- [Changelog](https://github.com/aio-libs/yarl/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/yarl/compare/v1.9.4...v1.15.5)

Updates `zipp` from 3.17.0 to 3.20.2
- [Release notes](https://github.com/jaraco/zipp/releases)
- [Changelog](https://github.com/jaraco/zipp/blob/main/NEWS.rst)
- [Commits](https://github.com/jaraco/zipp/compare/v3.17.0...v3.20.2)

Updates `exceptiongroup` from 1.2.0 to 1.2.2
- [Release notes](https://github.com/agronholm/exceptiongroup/releases)
- [Changelog](https://github.com/agronholm/exceptiongroup/blob/main/CHANGES.rst)
- [Commits](https://github.com/agronholm/exceptiongroup/compare/1.2.0...1.2.2)

Updates `tomli` from 2.0.1 to 2.0.2
- [Changelog](https://github.com/hukkin/tomli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hukkin/tomli/compare/2.0.1...2.0.2)

---
updated-dependencies:
- dependency-name: pydantic-settings
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: cython
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: scipy
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: python-levenshtein
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: scikit-learn
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: filelock
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: fire
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: openai
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: ruamel-yaml
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: torch
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: torch-geometric
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: numpy
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: pandas
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: matplotlib
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: langchain
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: langchain-community
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: tiktoken
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pymupdf
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: azure-identity
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pypdf
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: azure-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: azure-ai-formrecognizer
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: statsmodels
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: tables
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: tree-sitter-python
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: tree-sitter
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: jupyter
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: python-dotenv
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: setuptools-scm
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: sphinx
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: furo
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: importlib-metadata
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: aiohttp
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: alabaster
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: annotated-types
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: anyio
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: attrs
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: autodoc-pydantic
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: babel
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: beautifulsoup4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: black
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: build
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: certifi
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: cffi
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: charset-normalizer
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: contourpy
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: coverage
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: cryptography
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: dataclasses-json
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: debugpy
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: dill
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: docutils
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: executing
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: fonttools
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: fsspec
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: git-changelog
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: greenlet
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: httpcore
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: httpx
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: idna
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: ipython
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: ipywidgets
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: isodate
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: jaraco-classes
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: jinja2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: jsonpointer
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: jsonschema-specifications
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: jupyter-client
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: jupyterlab
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: jupyterlab-widgets
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: keyring
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: kiwisolver
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: langchain-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: langsmith
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: levenshtein
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: livereload
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: lxml
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: markupsafe
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: marshmallow
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: mdit-py-plugins
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: more-itertools
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: msal
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: msgpack
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: multidict
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: mypy
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: myst-parser
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: ndindex
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: networkx
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: nh3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: notebook
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: nvidia-cublas-cu12
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: nvidia-cuda-cupti-cu12
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: nvidia-cuda-nvrtc-cu12
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: nvidia-cuda-runtime-cu12
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: nvidia-cudnn-cu12
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: nvidia-cufft-cu12
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: nvidia-curand-cu12
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: nvidia-cusolver-cu12
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: nvidia-cusparse-cu12
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: nvidia-nccl-cu12
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: nvidia-nvjitlink-cu12
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: nvidia-nvtx-cu12
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: packaging
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: pillow
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: pkginfo
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: platformdirs
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pluggy
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: prometheus-client
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: prompt-toolkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: psutil
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pycparser
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pydantic
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pydantic-core
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pygments
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pyjwt
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pymupdfb
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: pyparsing
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pyproject-hooks
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pytest
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: python-dateutil
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: pytz
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: pyyaml
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod
- dependency-name: pyzmq
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: qtconsole
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: rapidfuzz
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: readme-renderer
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: requests
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prod
- dependency-name: requests-oauthlib
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: prod
- dependency-name: rich
  depende...

Signed-off-by: dependabot[bot] <support@github.com>

* build: Update constraints for dependabot.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Linlang <30293408+SunsetWolf@users.noreply.github.com>
2024-10-25 13:02:33 +08:00
Linlang 6fe0d75b38 chore: remove package (#449)
* remove package

* reformat with black

* fix pytest error

* fix pytest error

* fix pytest error

* add packages

* change code
2024-10-24 20:38:13 +08:00
Xu Yang c379b9221a feat: independent use_azure_token_provider on chat and embedding (#452)
* independent use_azure_token_provider

* fix CI

* fix doc format
2024-10-23 18:22:58 +08:00
Tim effce1df15 always return str (#453) 2024-10-23 16:47:36 +08:00
XianBW d57477aefa fix KGFactorRunner cache system bug (#451) 2024-10-23 15:17:38 +08:00
WinstonLiyt 972d8602c2 docs: add documentation for kaggle scen (#448)
* init for bg & quickstart for kaggle docs

* Add documentation for the environment configuration in the Kaggle scenario.

* add some descriptions in documents

* remove useless docs

* ci issue

---------

Co-authored-by: TPLin22 <tplin2@163.com>
2024-10-23 13:26:57 +08:00
Linlang b3e627fb80 remove_package (#447) 2024-10-22 11:40:31 +08:00
492 changed files with 28282 additions and 6890 deletions
+39 -10
View File
@@ -7,24 +7,53 @@ For more information about configuration options, please refer to the documentat
"""
# ==========================================
# Global configs:
USE_AZURE=False
USE_AZURE_TOKEN_PROVIDER=False
MAX_RETRY=10
RETRY_WAIT_SECONDS=20
# ==========================================
# LLM API Setting:
OPENAI_API_KEY=<your_api_key>
CHAT_MODEL=gpt-4-turbo
CHAT_MAX_TOKENS=3000
CHAT_TEMPERATURE=0.7
# ==========================================
# Backend Configuration
# ==========================================
# BACKEND=rdagent.oai.backend.LiteLLMAPIBackend
# ==========================================
# ==========================================
# Backend Configuration (choose one)
# ==========================================
# 1. Set universal API key
# CHAT_MODEL="gpt-4o"
# EMBEDDING_MODEL="text-embedding-3-small"
# OPENAI_API_BASE="https://your-endpoint.com/v1"
# OPENAI_API_KEY="sk-your-api-key-here"
# 2. Set separate API KEY
# Chat configuration
OPENAI_API_KEY="sk-chat-key"
OPENAI_API_BASE="https://xxx-litellm.com/v1"
CHAT_MODEL='gpt-4o'
# Embedding configuration (using other service)
# Use siliconflow as example, pay attention to the litellm_proxy prefix
LITELLM_PROXY_API_KEY="sk-embedding-service-key"
LITELLM_PROXY_API_BASE="https://api.siliconflow.cn/v1"
EMBEDDING_MODEL="litellm_proxy/BAAI/bge-large-en-v1.5"
# ==========================================
# ==========================================
# Other Configuration
# ==========================================
# CHAT_AZURE_API_BASE=<for_Azure_user>
# CHAT_AZURE_API_VERSION=<for_Azure_user>
EMBEDDING_MODEL=text-embedding-3-small
# EMBEDDING_AZURE_API_BASE=<for_Azure_user>
# EMBEDDING_AZURE_API_VERSION=<for_Azure_user>
# Cache Setting (Optional):
# Senario Configs:
# USE_CHAT_CACHE=True
# USE_EMBEDDING_CACHE=True
# Senario Configs:
# ==========================================
+1 -3
View File
@@ -20,14 +20,12 @@
## How Has This Been Tested?
<!--- Put an `x` in all the boxes that apply: --->
- [ ] Pass the test by running: `pytest qlib/tests/test_all_pipeline.py` under upper directory of `qlib`.
- [ ] If you are adding a new feature, test on your own test scripts.
<!--- **ATTENTION**: If you are adding a new feature, please make sure your codes are **correctly tested**. If our test scripts do not cover your cases, please provide your own test scripts under the `tests` folder and test them. More information about test scripts can be found [here](https://docs.python.org/3/library/unittest.html#basic-example), or you could refer to those we provide under the `tests` folder. -->
## Screenshots of Test Results (if appropriate):
1. Pipeline test:
2. Your own tests:
1. Your own tests:
## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: '16'
+11 -3
View File
@@ -4,6 +4,7 @@
Pipfile
public
release-notes.md
typescript*
# Byte-compiled / optimized / DLL files
__pycache__/
@@ -64,7 +65,7 @@ coverage.xml
# Django stuff:
*.log
/log/
/log*/
local_settings.py
db.sqlite3
db.sqlite3-journal
@@ -110,7 +111,8 @@ celerybeat.pid
*.sage.py
# Environments
.env
.env*
*.env
.venv
^env/
venv/
@@ -169,4 +171,10 @@ mlruns/
# shell script
*.out
*.sh
/*.sh
.aider*
rdagent/app/benchmark/factor/example.json
# UI Server resources
videos/
static/
+12
View File
@@ -10,6 +10,18 @@ build:
os: ubuntu-22.04
tools:
python: "3.10"
# During the build process, you need to fetch tags, and since the default command to read the docs only pulls shallow code, it will cause an error.
# So we added the `git fetch --tags --unshallow || true` command to fetch the full tag record.
# Adding this command overrides the default command, so we copied it over to make sure the build was successful.
commands:
- python -mvirtualenv $READTHEDOCS_VIRTUALENV_PATH
- python -m pip install --upgrade --no-cache-dir pip setuptools
- python -m pip install --upgrade --no-cache-dir sphinx
- python -m pip install --exists-action=w --no-cache-dir -r requirements/docs.txt
- python -m pip install --upgrade --upgrade-strategy only-if-needed --no-cache-dir .
- git fetch --tags --unshallow || true
- mkdir -p $READTHEDOCS_OUTPUT/html/
- python -m sphinx -T -b html -d _build/doctrees -D language=en ./docs $READTHEDOCS_OUTPUT/html
# Build documentation in the docs/ directory with Sphinx
sphinx:
+252
View File
@@ -1,5 +1,257 @@
# Changelog
## [0.6.0](https://github.com/microsoft/RD-Agent/compare/v0.5.0...v0.6.0) (2025-06-26)
### Features
* async mechanism for multi-trace ([#981](https://github.com/microsoft/RD-Agent/issues/981)) ([9e60c32](https://github.com/microsoft/RD-Agent/commit/9e60c32cf348481eb55617809c059c359d7603b8))
### Bug Fixes
* add async to direct_exp_gen avoid infinite loop ([#992](https://github.com/microsoft/RD-Agent/issues/992)) ([78c203d](https://github.com/microsoft/RD-Agent/commit/78c203d8eefbba67fc120b35cb25e85b2200ac49))
* docker container cleanup to prevent accumulation and system slowdown ([#975](https://github.com/microsoft/RD-Agent/issues/975)) ([05cf094](https://github.com/microsoft/RD-Agent/commit/05cf094913e48c903c8a4476d6c609d8bfa10681))
* fix a bug and update the docs ([#978](https://github.com/microsoft/RD-Agent/issues/978)) ([d1ae9e1](https://github.com/microsoft/RD-Agent/commit/d1ae9e1dcc2ccd1ffe05cb1c6db3e905fa70425c))
* merge datascience v3 and v2 ([#974](https://github.com/microsoft/RD-Agent/issues/974)) ([1ba7548](https://github.com/microsoft/RD-Agent/commit/1ba754853ce2010ce1cb0bbd217b67689fa1ebdf))
* refine details ([#979](https://github.com/microsoft/RD-Agent/issues/979)) ([25caa3d](https://github.com/microsoft/RD-Agent/commit/25caa3d00c255286dce27915b9355987b87ed2e8))
* refine prompt ([#987](https://github.com/microsoft/RD-Agent/issues/987)) ([76df96e](https://github.com/microsoft/RD-Agent/commit/76df96ee88212a8aee7f518b9cacf80591dc2939))
## [0.5.0](https://github.com/microsoft/RD-Agent/compare/v0.4.0...v0.5.0) (2025-06-18)
### Features
* add a check for whether values in score_df are NaN ([#756](https://github.com/microsoft/RD-Agent/issues/756)) ([d9cc780](https://github.com/microsoft/RD-Agent/commit/d9cc78098beb27f3a1bf2f2d461302db177b7d41))
* add competition level filter and extract constants to utils ([#869](https://github.com/microsoft/RD-Agent/issues/869)) ([b40b605](https://github.com/microsoft/RD-Agent/commit/b40b6055368e6c72d8435352104b1c281b06da7f))
* add DocDev for auto-generating workspace documentation ([#781](https://github.com/microsoft/RD-Agent/issues/781)) ([bcba6ea](https://github.com/microsoft/RD-Agent/commit/bcba6eac32684ebb267c93b4e85dbfa9561d15d1))
* add drafting pipeline ([#832](https://github.com/microsoft/RD-Agent/issues/832)) ([efedddf](https://github.com/microsoft/RD-Agent/commit/efedddf39bc19221fdffc2e39ee0a09097fc82b0))
* add last_exp_fb to DSTrace and update feedback retrieval usage ([#910](https://github.com/microsoft/RD-Agent/issues/910)) ([10531fd](https://github.com/microsoft/RD-Agent/commit/10531fda9438c6915b26d5013bd2413e1333ceb9))
* add mlflow logger in RD loop to log ([#815](https://github.com/microsoft/RD-Agent/issues/815)) ([b91b54f](https://github.com/microsoft/RD-Agent/commit/b91b54f355c26b751087d0c14774f466e82866de))
* add naive experiment generator and update proposal configurations ([#759](https://github.com/microsoft/RD-Agent/issues/759)) ([75494f4](https://github.com/microsoft/RD-Agent/commit/75494f4fed5bc845acfd7f7bacef385f0f96c514))
* add RD-Agent-Quant scenario ([#838](https://github.com/microsoft/RD-Agent/issues/838)) ([6e42d52](https://github.com/microsoft/RD-Agent/commit/6e42d523a85df67aa13927abbf0894564c71880e))
* add reasoning_effort parameter to LiteLLMAPIBackend and LLMSett… ([#754](https://github.com/microsoft/RD-Agent/issues/754)) ([113889f](https://github.com/microsoft/RD-Agent/commit/113889fefe9b09aaea1b564704c81664b8f77ec5))
* add reviewer in feedback ([#765](https://github.com/microsoft/RD-Agent/issues/765)) ([1a95bee](https://github.com/microsoft/RD-Agent/commit/1a95bee6aa6bc6f45fdeb484f3a6f81caa273038))
* advanced checkpoint selectors ([#790](https://github.com/microsoft/RD-Agent/issues/790)) ([50ea033](https://github.com/microsoft/RD-Agent/commit/50ea0336e93d8cb39fb871e81a3f61abdf293bc7))
* archive python and csv files in workspace to maintain results ([#814](https://github.com/microsoft/RD-Agent/issues/814)) ([67d0e01](https://github.com/microsoft/RD-Agent/commit/67d0e01e7c9237da1371d93cbf9d86f5f46faac4))
* checkpoint selection ([#744](https://github.com/microsoft/RD-Agent/issues/744)) ([a15a06a](https://github.com/microsoft/RD-Agent/commit/a15a06ad643977db59d7cac9da52e637cf80395a))
* custom data ([#810](https://github.com/microsoft/RD-Agent/issues/810)) ([6322916](https://github.com/microsoft/RD-Agent/commit/632291608cf605bd8bcfcab0017824823bdecdb8))
* dump model ([#776](https://github.com/microsoft/RD-Agent/issues/776)) ([b49481e](https://github.com/microsoft/RD-Agent/commit/b49481e073e6f536d2b1b3bd2d01229ed05abdea))
* enable to set different version of idea-proposal for multi traces ([#895](https://github.com/microsoft/RD-Agent/issues/895)) ([236c28f](https://github.com/microsoft/RD-Agent/commit/236c28f29c6bc5da62129632e464bbc32056ebdb))
* enhance compatibility with more LLM models ([#905](https://github.com/microsoft/RD-Agent/issues/905)) ([8800624](https://github.com/microsoft/RD-Agent/commit/8800624ad4749d6e798785a082c9f94c306792ef))
* idea pool integrated to exp_gen & add timer to RD-Agent & pause-resume to RD-loops ([#795](https://github.com/microsoft/RD-Agent/issues/795)) ([e62aefa](https://github.com/microsoft/RD-Agent/commit/e62aefa56e34ff45a8ed033f7bf28b95c8e63656))
* joblib cache ([#749](https://github.com/microsoft/RD-Agent/issues/749)) ([83a0411](https://github.com/microsoft/RD-Agent/commit/83a041148ff908871b1906f9e6889d80ab513412))
* log api status to mlflow ([#860](https://github.com/microsoft/RD-Agent/issues/860)) ([049921b](https://github.com/microsoft/RD-Agent/commit/049921beb0b4ed0ba1ab7508d9857d2c1e729349))
* log reaching max time limit before breaking CoSTEER evolution ([#921](https://github.com/microsoft/RD-Agent/issues/921)) ([837fff2](https://github.com/microsoft/RD-Agent/commit/837fff29096fefe1369d386ef8a860395b737173))
* merge failed and successful traces together ([#766](https://github.com/microsoft/RD-Agent/issues/766)) ([3a2aa8c](https://github.com/microsoft/RD-Agent/commit/3a2aa8cf0102647950b2dfc0007c118b0c799cd4))
* merge selectively ([#888](https://github.com/microsoft/RD-Agent/issues/888)) ([06ba314](https://github.com/microsoft/RD-Agent/commit/06ba314ff0f91e7e78e8d456c719ac3194a8c774))
* multi-trace online merge ([#886](https://github.com/microsoft/RD-Agent/issues/886)) ([2112d67](https://github.com/microsoft/RD-Agent/commit/2112d676d0938de6fea163b2e5eb9c36771e7041))
* new proposal (structured outputs) prompts ([#887](https://github.com/microsoft/RD-Agent/issues/887)) ([150796a](https://github.com/microsoft/RD-Agent/commit/150796aaa72eaa5037fd7db8e785058fbc4d4967))
* parallel loop running based on asyncio ([#932](https://github.com/microsoft/RD-Agent/issues/932)) ([c63e207](https://github.com/microsoft/RD-Agent/commit/c63e2071f3179feef69f88061c0172cb5c3157f2))
* propose hypothesis across multiple parts in pipeline ([#827](https://github.com/microsoft/RD-Agent/issues/827)) ([acb0e21](https://github.com/microsoft/RD-Agent/commit/acb0e21a331410d044849e12e2887f41e5ff1c3a))
* pull image with progress ([#777](https://github.com/microsoft/RD-Agent/issues/777)) ([5cad086](https://github.com/microsoft/RD-Agent/commit/5cad0860204ede974533dc7bdc9808cfd135fa24))
* raise error when timeout in api call ([#793](https://github.com/microsoft/RD-Agent/issues/793)) ([eafd4df](https://github.com/microsoft/RD-Agent/commit/eafd4dfc6263f19a8cdaf27498a1d07b43815306))
* raise policy violation ([#894](https://github.com/microsoft/RD-Agent/issues/894)) ([5b9d007](https://github.com/microsoft/RD-Agent/commit/5b9d0072aebe15369e9a0010af83e71684baeae7))
* reanalyze competition info & pipeline coding evaluator prompt ([#837](https://github.com/microsoft/RD-Agent/issues/837)) ([f7b5258](https://github.com/microsoft/RD-Agent/commit/f7b52580080c75d311355bcc6193b49495801809))
* refine merge ([#842](https://github.com/microsoft/RD-Agent/issues/842)) ([99463b4](https://github.com/microsoft/RD-Agent/commit/99463b46819b3a0dcb2bb12a823a9cdf7ec560b4))
* refine prompt ([#760](https://github.com/microsoft/RD-Agent/issues/760)) ([a91b182](https://github.com/microsoft/RD-Agent/commit/a91b182c4c9510eb34e4aab956588e909fa5d70b))
* replace hard-coded cache paths with dynamic cache_path config ([#952](https://github.com/microsoft/RD-Agent/issues/952)) ([db56894](https://github.com/microsoft/RD-Agent/commit/db568947f1084a80d603718f5a13fdbd72b90a47))
* revert draft stage into a soft decay in hypothesis selection ([#849](https://github.com/microsoft/RD-Agent/issues/849)) ([d41db0c](https://github.com/microsoft/RD-Agent/commit/d41db0ca357b07091825ebd9d18c303b6db3cc6a))
* trace merging ([#836](https://github.com/microsoft/RD-Agent/issues/836)) ([a3d5473](https://github.com/microsoft/RD-Agent/commit/a3d547369e408a05cff570c1239b6320be40418d))
* truncate by time ([#863](https://github.com/microsoft/RD-Agent/issues/863)) ([2b9427a](https://github.com/microsoft/RD-Agent/commit/2b9427ae036ffe1e28a717502f45500fe91fe5ac))
* update prompt to improve json respond format of some LLM models ([#928](https://github.com/microsoft/RD-Agent/issues/928)) ([0b84709](https://github.com/microsoft/RD-Agent/commit/0b84709e59c7abb9754961cd17cc9673fcf508aa))
* using different chat model in different part ([#822](https://github.com/microsoft/RD-Agent/issues/822)) ([c052ea6](https://github.com/microsoft/RD-Agent/commit/c052ea6d1f8948183a4a6ebc873ec01b57373cce))
### Bug Fixes
* 'DSProposalV2ExpGen' object has no attribute 'COMPONENT_TASK_MAP… ([#950](https://github.com/microsoft/RD-Agent/issues/950)) ([e353895](https://github.com/microsoft/RD-Agent/commit/e353895251f231fee85abdcb1b22b022a577af77))
* adapting UI to mock trace ([#841](https://github.com/microsoft/RD-Agent/issues/841)) ([8a5754c](https://github.com/microsoft/RD-Agent/commit/8a5754c9b9c9410d0943aeed777a93c13422e54a))
* add missing semicolon after chmod in env shell command ([#955](https://github.com/microsoft/RD-Agent/issues/955)) ([1128eaa](https://github.com/microsoft/RD-Agent/commit/1128eaa89ec1dcab4a05ef50d64c7f7e6aae88a8))
* add time to timer when api timeout bug ([#826](https://github.com/microsoft/RD-Agent/issues/826)) ([f45d6ae](https://github.com/microsoft/RD-Agent/commit/f45d6ae6595c1c39b389485b637a0ae53ffc8782))
* add wait_retry to exp_gen v2 ([#783](https://github.com/microsoft/RD-Agent/issues/783)) ([b9fb7cf](https://github.com/microsoft/RD-Agent/commit/b9fb7cf4e3070062d91b5b67d0f10d6266b45142))
* adjust ds_trace lookup and add stderr redirect to mlebench command ([#853](https://github.com/microsoft/RD-Agent/issues/853)) ([4e53108](https://github.com/microsoft/RD-Agent/commit/4e53108e020db719b39cba3a67e0c6dae3de19cf))
* align competion_full_desc and scenario_all_desc, remove redundant info in problems proposal ([#808](https://github.com/microsoft/RD-Agent/issues/808)) ([76d8536](https://github.com/microsoft/RD-Agent/commit/76d8536d9ec53952383019306781d49cb3e9f75c))
* bug fix in timer start ([#807](https://github.com/microsoft/RD-Agent/issues/807)) ([9af7161](https://github.com/microsoft/RD-Agent/commit/9af7161eb57bdd2e24b072335e9d185951c32472))
* bug in problem identification ([#806](https://github.com/microsoft/RD-Agent/issues/806)) ([e1d5a29](https://github.com/microsoft/RD-Agent/commit/e1d5a2914046476f2f10d5884ed3c3ff956d65ff))
* conda error information ([#941](https://github.com/microsoft/RD-Agent/issues/941)) ([fd39a94](https://github.com/microsoft/RD-Agent/commit/fd39a947763fb4a9be87b907c399bebe384df505))
* default cost to NaN when calculation fails in LiteLLM backend ([#912](https://github.com/microsoft/RD-Agent/issues/912)) ([51a4048](https://github.com/microsoft/RD-Agent/commit/51a4048129cbfbc3b84bcf50fd8866fafb3e2da3))
* ds trace ([#929](https://github.com/microsoft/RD-Agent/issues/929)) ([127e441](https://github.com/microsoft/RD-Agent/commit/127e441602e21a46d6313ff39133ab8ca841937e))
* duplicate model names test in pipeline coder & runner ([#763](https://github.com/microsoft/RD-Agent/issues/763)) ([be3ee9d](https://github.com/microsoft/RD-Agent/commit/be3ee9da9882edda3c06ff7d1099d1bbda2203c3))
* filter system metadata dirs and init missing DSTrace attribute ([#946](https://github.com/microsoft/RD-Agent/issues/946)) ([10050ef](https://github.com/microsoft/RD-Agent/commit/10050ef368ae7ec07cbf20ac4e52e21c2875eaab))
* fix a bug in docker result extraction ([#824](https://github.com/microsoft/RD-Agent/issues/824)) ([e1c0f98](https://github.com/microsoft/RD-Agent/commit/e1c0f9826abcbc11dda215a600a2637c9ac6e984))
* fix competition metric direction ([#784](https://github.com/microsoft/RD-Agent/issues/784)) ([3be0057](https://github.com/microsoft/RD-Agent/commit/3be0057556f46c899065ee1c7f9bafe33e79249c))
* fix model input shape bug and costeer_model bug ([#821](https://github.com/microsoft/RD-Agent/issues/821)) ([b34bd89](https://github.com/microsoft/RD-Agent/commit/b34bd895d6d9c326aab85856a15be0cb72b2c4c8))
* fix some minor bugs ([#758](https://github.com/microsoft/RD-Agent/issues/758)) ([963f96e](https://github.com/microsoft/RD-Agent/commit/963f96e5596bee04074135c2a0e31a8adc39ad8c))
* fix some minor bugs in qlib scenario ([#817](https://github.com/microsoft/RD-Agent/issues/817)) ([79962a7](https://github.com/microsoft/RD-Agent/commit/79962a7ca40c77a3997a68da9ad1b5ab16728483))
* fix the bug in the regular expression matching for stdout ([#890](https://github.com/microsoft/RD-Agent/issues/890)) ([ee57e37](https://github.com/microsoft/RD-Agent/commit/ee57e37a22af874b262c033d1606dbe7799706db))
* fix the bug of Exceed-LLM-Context in online merge of multi-tarce ([#892](https://github.com/microsoft/RD-Agent/issues/892)) ([f760a3e](https://github.com/microsoft/RD-Agent/commit/f760a3eff7bd927a31e4958ed2f706312e83e3e3))
* fix the problems weights bug ([#898](https://github.com/microsoft/RD-Agent/issues/898)) ([013d79f](https://github.com/microsoft/RD-Agent/commit/013d79f12060e908aeb57c3eb1bb56eea86df086))
* fixed CI execution failures caused by document builds ([#857](https://github.com/microsoft/RD-Agent/issues/857)) ([5c116b2](https://github.com/microsoft/RD-Agent/commit/5c116b24ce727f6ed9ef39d5aa5b60442038c344))
* get_metric_direction for aerial-cactus-identification ([#970](https://github.com/microsoft/RD-Agent/issues/970)) ([70dc62d](https://github.com/microsoft/RD-Agent/commit/70dc62de5fbd4272ecda1b6fcbcf898b3624a991))
* import path of T ([#787](https://github.com/microsoft/RD-Agent/issues/787)) ([ac008a6](https://github.com/microsoft/RD-Agent/commit/ac008a61d03b4737ab3d994024e922839d8f3fe1))
* improve eval alignment check (e.g. small-scale finetuning) ([#802](https://github.com/microsoft/RD-Agent/issues/802)) ([d391578](https://github.com/microsoft/RD-Agent/commit/d3915788082de640a4ce1eea6d2e607319b89c3e))
* improve file tree and _walk symlink handling ([#877](https://github.com/microsoft/RD-Agent/issues/877)) ([516cb69](https://github.com/microsoft/RD-Agent/commit/516cb69357483ddd99f84b221a056d8491c34f9b))
* log info ([#965](https://github.com/microsoft/RD-Agent/issues/965)) ([f1dbc21](https://github.com/microsoft/RD-Agent/commit/f1dbc2100498e22c8e5edbb2e4563c99c3d54775))
* main bug ([#938](https://github.com/microsoft/RD-Agent/issues/938)) ([c6d34d6](https://github.com/microsoft/RD-Agent/commit/c6d34d67b8aedf5496bf6a875915ce657fc58448))
* non-exist variable test_eval.py ([#847](https://github.com/microsoft/RD-Agent/issues/847)) ([4948c38](https://github.com/microsoft/RD-Agent/commit/4948c38560f4cf021d9354b201b22dfa5ccb9441))
* refine feedback prompt ([#901](https://github.com/microsoft/RD-Agent/issues/901)) ([12bb2c4](https://github.com/microsoft/RD-Agent/commit/12bb2c4a1494b9aa29962905abb5e433a60eb716))
* refine the time/memory constraints prompt in hypothesis proposal ([#856](https://github.com/microsoft/RD-Agent/issues/856)) ([51ce8ef](https://github.com/microsoft/RD-Agent/commit/51ce8ef84b4fe6590ce20599a56eee596f2f04e6))
* Set PYTHONPATH in env.run_ret_code call in FBWorkspace class ([#755](https://github.com/microsoft/RD-Agent/issues/755)) ([68b5018](https://github.com/microsoft/RD-Agent/commit/68b501889caca754f27b57d9ab6f72184e93b15c))
* task_gen for better understanding ([#752](https://github.com/microsoft/RD-Agent/issues/752)) ([6bfc1e5](https://github.com/microsoft/RD-Agent/commit/6bfc1e570449ee69ac110a4ced9a7cecbc0e6a73))
* trace list but ([#852](https://github.com/microsoft/RD-Agent/issues/852)) ([32cdc57](https://github.com/microsoft/RD-Agent/commit/32cdc575bde103d71a358d4d99bd413076328ebd))
* typo in workflow ([#861](https://github.com/microsoft/RD-Agent/issues/861)) ([0e54c9f](https://github.com/microsoft/RD-Agent/commit/0e54c9fe41d25a4cc45ab9e61bb2c2c01b854751))
* update DS env setup with competition volume and timeout ([#878](https://github.com/microsoft/RD-Agent/issues/878)) ([816ada0](https://github.com/microsoft/RD-Agent/commit/816ada096afabe90578672b0e61b656802a30b62))
* update feedback.py ([#772](https://github.com/microsoft/RD-Agent/issues/772)) ([133778c](https://github.com/microsoft/RD-Agent/commit/133778c67ee3349f1c2fe029bcf6a9ee14568efe))
* update metric direction to return bool ([#791](https://github.com/microsoft/RD-Agent/issues/791)) ([0bf365e](https://github.com/microsoft/RD-Agent/commit/0bf365e7830aa86d2350b9d1c47410af46b3a7e8))
* update runner max loop to 1 in DS scenario ([#820](https://github.com/microsoft/RD-Agent/issues/820)) ([3da378e](https://github.com/microsoft/RD-Agent/commit/3da378e986e8b776a17dbc694d29ef211192ed3e))
* use fallback messages for missing submission and scores files ([#882](https://github.com/microsoft/RD-Agent/issues/882)) ([898fdea](https://github.com/microsoft/RD-Agent/commit/898fdeae80801d537ebc5c4a3b7df9de74c3403a))
* use simple stdout and stderr ([#966](https://github.com/microsoft/RD-Agent/issues/966)) ([0b1c445](https://github.com/microsoft/RD-Agent/commit/0b1c445f1f0c212887ffff9f8fac44236df3607c))
* use trace count as index ([#909](https://github.com/microsoft/RD-Agent/issues/909)) ([b87de56](https://github.com/microsoft/RD-Agent/commit/b87de56e54b206b3aada53850804474eff80b96d))
* wrong variable test_eval.py ([#846](https://github.com/microsoft/RD-Agent/issues/846)) ([808ea6c](https://github.com/microsoft/RD-Agent/commit/808ea6cba541e60c35dd283cee9098ce46f2a59e))
## [0.4.0](https://github.com/microsoft/RD-Agent/compare/v0.3.0...v0.4.0) (2025-04-04)
### Features
* (Kaggle) add base template for competition: tabular-playground-series-may-2022 ([#481](https://github.com/microsoft/RD-Agent/issues/481)) ([f3405ca](https://github.com/microsoft/RD-Agent/commit/f3405ca732eb0ddca8e18ea72f69cbd86055c4ab))
* a unified CoSTEER to fit more scenarios ([#491](https://github.com/microsoft/RD-Agent/issues/491)) ([cddbd02](https://github.com/microsoft/RD-Agent/commit/cddbd02e3ad3ccf6ad01443777319dc5c7eb08a7))
* add a new competition ([#474](https://github.com/microsoft/RD-Agent/issues/474)) ([2fc0d77](https://github.com/microsoft/RD-Agent/commit/2fc0d77c485a31f647e21f4578e2e326f7032964))
* add a tool to enable saving workspace files into a specific folder ([#728](https://github.com/microsoft/RD-Agent/issues/728)) ([bca864b](https://github.com/microsoft/RD-Agent/commit/bca864b7edeafe3f88405efb695ca8acad6252f8))
* add baseline score stat ([#590](https://github.com/microsoft/RD-Agent/issues/590)) ([2948026](https://github.com/microsoft/RD-Agent/commit/2948026c390d067b643f8c8247c1447f1dc023e4))
* add configurable volume mode for Docker volumes in env.py ([#537](https://github.com/microsoft/RD-Agent/issues/537)) ([642a022](https://github.com/microsoft/RD-Agent/commit/642a02239431411b91959f23e69b454997ca75d5))
* add constraint labels for semantic search ([#680](https://github.com/microsoft/RD-Agent/issues/680)) ([0584cfc](https://github.com/microsoft/RD-Agent/commit/0584cfcd13ca1a62c85390ea2ee7574370748d31))
* add cross validation to workflow ([#700](https://github.com/microsoft/RD-Agent/issues/700)) ([82e9b00](https://github.com/microsoft/RD-Agent/commit/82e9b00be62b01673353a7aaa3ab0e2e3ecaf3ca))
* add describe_data_folder_v2 ([#738](https://github.com/microsoft/RD-Agent/issues/738)) ([bc8e846](https://github.com/microsoft/RD-Agent/commit/bc8e8460e0246321792ff3347b1b8905416ad075))
* add do_truncate control for the load function ([#656](https://github.com/microsoft/RD-Agent/issues/656)) ([2b960a5](https://github.com/microsoft/RD-Agent/commit/2b960a58dfdeba69522a0f72ecf0975bb6ae87ee))
* add do_truncate control for the load function ([#656](https://github.com/microsoft/RD-Agent/issues/656)) ([2b960a5](https://github.com/microsoft/RD-Agent/commit/2b960a58dfdeba69522a0f72ecf0975bb6ae87ee))
* add eda to data science scenario ([#639](https://github.com/microsoft/RD-Agent/issues/639)) ([35aa479](https://github.com/microsoft/RD-Agent/commit/35aa479f00edf118d43ec228e0a84c155332957a))
* add hypothesis guidelines and rule-based ranking ([#746](https://github.com/microsoft/RD-Agent/issues/746)) ([c077b82](https://github.com/microsoft/RD-Agent/commit/c077b8239cc72904c4bc450845ed2a11aa5445f0))
* Add line length limit to shrink_text function and settings ([#715](https://github.com/microsoft/RD-Agent/issues/715)) ([75ed5e1](https://github.com/microsoft/RD-Agent/commit/75ed5e1c2ce1bf20bb55190c10a4134e04694d2b))
* add loop_n parameter to the main loop ([#611](https://github.com/microsoft/RD-Agent/issues/611)) ([778c166](https://github.com/microsoft/RD-Agent/commit/778c166962250e3b9e7ad85de37f62297d370b45))
* add max time config to costeer in data science ([#645](https://github.com/microsoft/RD-Agent/issues/645)) ([534686c](https://github.com/microsoft/RD-Agent/commit/534686c2ba7d9fa979c0762ad3177c36f6d7f4cb))
* add mlebench submission validitor ([#545](https://github.com/microsoft/RD-Agent/issues/545)) ([712d94a](https://github.com/microsoft/RD-Agent/commit/712d94a7d6f22187fc3d18bd434e71ec6997aa9f))
* add model removal and adjust some framework logic ([#681](https://github.com/microsoft/RD-Agent/issues/681)) ([1edf881](https://github.com/microsoft/RD-Agent/commit/1edf881c63512d351c0dd074d7a1c0965ff3119b))
* add output_path to load function of LoopBase ([#628](https://github.com/microsoft/RD-Agent/issues/628)) ([dd33726](https://github.com/microsoft/RD-Agent/commit/dd33726ac5de75dc2030d193d457d59490b3361e))
* add pipeline coder ([#742](https://github.com/microsoft/RD-Agent/issues/742)) ([759f295](https://github.com/microsoft/RD-Agent/commit/759f295dbf1224e177006e72d694e42dd6f372b6))
* add rank into report (mle_summary) ([#665](https://github.com/microsoft/RD-Agent/issues/665)) ([13f7922](https://github.com/microsoft/RD-Agent/commit/13f7922aaae9e4143aac4ad08ec1c556c2faf04e))
* add restart and fix unzip ([#538](https://github.com/microsoft/RD-Agent/issues/538)) ([ed2c7d1](https://github.com/microsoft/RD-Agent/commit/ed2c7d175f1f44ca06ad7a63b08da12f6c4df9ab))
* add retry mechanism with wait_retry decorator and refactor diff generation ([#572](https://github.com/microsoft/RD-Agent/issues/572)) ([de1cd72](https://github.com/microsoft/RD-Agent/commit/de1cd72f068ebd1e1bd5bc2ad2b12ae484d54831))
* add the shape of the CSV to the dataset description ([#561](https://github.com/microsoft/RD-Agent/issues/561)) ([a10c881](https://github.com/microsoft/RD-Agent/commit/a10c881bd86796e6167257ad26dd165f7e46d813))
* add timeout settings and cleanup step in data science runner ([#539](https://github.com/microsoft/RD-Agent/issues/539)) ([295abd5](https://github.com/microsoft/RD-Agent/commit/295abd56f7b58055bd27b247dfed47eb85e9b0cd))
* add type checker to api backend & align litellm and old backend ([#647](https://github.com/microsoft/RD-Agent/issues/647)) ([d38eae9](https://github.com/microsoft/RD-Agent/commit/d38eae986a0ba69d71288fa09fcc21e227551a02))
* align mlebench data and evaluation & several fix on kaggle workflow ([#477](https://github.com/microsoft/RD-Agent/issues/477)) ([f6c522b](https://github.com/microsoft/RD-Agent/commit/f6c522b651db3c1f6af6815347589917f46e433a))
* **backend:** integrate LiteLLM API Backend ([#564](https://github.com/microsoft/RD-Agent/issues/564)) ([f477687](https://github.com/microsoft/RD-Agent/commit/f4776879c76a213d53875b307c94be1ea5cfd9ba))
* base data science scenario UI ([#525](https://github.com/microsoft/RD-Agent/issues/525)) ([39917b3](https://github.com/microsoft/RD-Agent/commit/39917b354b22a8488a17396fe2245cb41e3def03))
* condaenv & full docker env ([#668](https://github.com/microsoft/RD-Agent/issues/668)) ([084dd6d](https://github.com/microsoft/RD-Agent/commit/084dd6d748a89492ea0888acb316b9bb9efeb62f))
* diff mode fix ([#569](https://github.com/microsoft/RD-Agent/issues/569)) ([0c509f5](https://github.com/microsoft/RD-Agent/commit/0c509f599ce19303b44d8192ec3eb634c24992d6))
* display LLM prompt ([#676](https://github.com/microsoft/RD-Agent/issues/676)) ([8c93bba](https://github.com/microsoft/RD-Agent/commit/8c93bba82e185edcf4204cc574df5f41bcdfa9d2))
* Dynamically find and use sample submission file in eval tests ([#542](https://github.com/microsoft/RD-Agent/issues/542)) ([5f12b44](https://github.com/microsoft/RD-Agent/commit/5f12b44c89dd26b250e914192f9beb2da38fb3ab))
* end-to-end optimization ([#473](https://github.com/microsoft/RD-Agent/issues/473)) ([d41343a](https://github.com/microsoft/RD-Agent/commit/d41343a63d87bf3479f5ec30745ea788580495bf))
* Enhance eval script with file cleanup and detailed submission checks ([#529](https://github.com/microsoft/RD-Agent/issues/529)) ([cf2ff92](https://github.com/microsoft/RD-Agent/commit/cf2ff9213d3a8b0fad64df7cae0c35f996d72e27))
* exclude invalid session log folder ([#554](https://github.com/microsoft/RD-Agent/issues/554)) ([fa86e4d](https://github.com/microsoft/RD-Agent/commit/fa86e4d1805000e0e5779c662ccbb5273fda623c))
* improve the framework's ability to adaptively adjust the model ([#629](https://github.com/microsoft/RD-Agent/issues/629)) ([93806f3](https://github.com/microsoft/RD-Agent/commit/93806f33a1e0f29a125e29303d4b984a9817c3c0))
* independent use_azure_token_provider on chat and embedding ([#452](https://github.com/microsoft/RD-Agent/issues/452)) ([d223004](https://github.com/microsoft/RD-Agent/commit/d223004917692e231b251330cbc8676081d5a10d))
* integrate azure deepseek r1 ([#591](https://github.com/microsoft/RD-Agent/issues/591)) ([e79ce5c](https://github.com/microsoft/RD-Agent/commit/e79ce5c38539138abe04eb9809fbde437e97bbb7))
* kaggle refactor ([#489](https://github.com/microsoft/RD-Agent/issues/489)) ([1b057d0](https://github.com/microsoft/RD-Agent/commit/1b057d0d63a861fba4b3cb59c6c5fc1a0e3da383))
* **kaggle:** several update in kaggle scenarios ([#476](https://github.com/microsoft/RD-Agent/issues/476)) ([245d211](https://github.com/microsoft/RD-Agent/commit/245d211dcbfb18ebcc554247a0e3a8dbecf6f3bd))
* loader prompt & simplify YAML loading and update data loader specifications ([#736](https://github.com/microsoft/RD-Agent/issues/736)) ([86f8bbf](https://github.com/microsoft/RD-Agent/commit/86f8bbf15895e7c198f9bc395d055ca5f02a5bb6))
* make spec optional ([#719](https://github.com/microsoft/RD-Agent/issues/719)) ([a16b70f](https://github.com/microsoft/RD-Agent/commit/a16b70ff34c66d7e1c4c7ff5236eca8e7d8abea9))
* Make system prompt role customizable in LLM settings ([#632](https://github.com/microsoft/RD-Agent/issues/632)) ([e4acd92](https://github.com/microsoft/RD-Agent/commit/e4acd92cc5eec6db5c29cb2d4788020fb89099b7))
* multi log folder, replace "epxx" in workspace path ([#555](https://github.com/microsoft/RD-Agent/issues/555)) ([8a69c9c](https://github.com/microsoft/RD-Agent/commit/8a69c9c9630860c9b644356e1f71654aea222328))
* new exp gen v2 implementation ([#725](https://github.com/microsoft/RD-Agent/issues/725)) ([5dcc2d5](https://github.com/microsoft/RD-Agent/commit/5dcc2d5fa63bbe9ae8c4817d9b40b77600440edb))
* new-york-city-taxi-fare-prediction_template ([#488](https://github.com/microsoft/RD-Agent/issues/488)) ([a9caab7](https://github.com/microsoft/RD-Agent/commit/a9caab7bc5dc86f395a008e523355922137aef17))
* out spec change for o1-preview ([#666](https://github.com/microsoft/RD-Agent/issues/666)) ([22894bd](https://github.com/microsoft/RD-Agent/commit/22894bdbee26b9cad73646d2975857787e515f75))
* refactor for general data science ([#498](https://github.com/microsoft/RD-Agent/issues/498)) ([7002dc4](https://github.com/microsoft/RD-Agent/commit/7002dc4981a4f72096b438d2fe4fd9ff268c54f3))
* refine logic for qlib_factor_from_report ([#463](https://github.com/microsoft/RD-Agent/issues/463)) ([21348d8](https://github.com/microsoft/RD-Agent/commit/21348d89e0e0eec1b4fab4e7a497f1eb34b8fe72))
* run benchmark on gpt-4o & llama 3.1 ([#497](https://github.com/microsoft/RD-Agent/issues/497)) ([64af0b5](https://github.com/microsoft/RD-Agent/commit/64af0b5529b687cce8b5b7a1893946e15edca626))
* summary and UI update ([#581](https://github.com/microsoft/RD-Agent/issues/581)) ([efa51f9](https://github.com/microsoft/RD-Agent/commit/efa51f9c259a06fe219f3137f0a1005e50d2bfdd))
* template changes for some kaggle competitions ([#484](https://github.com/microsoft/RD-Agent/issues/484)) ([2e38000](https://github.com/microsoft/RD-Agent/commit/2e38000091030811fc081d72016c7bbadf7efd50))
* track and log accumulated completion cost in LiteLLMAPIBackend ([#727](https://github.com/microsoft/RD-Agent/issues/727)) ([b294a95](https://github.com/microsoft/RD-Agent/commit/b294a95e0b7b2ef96af355cebac92d9c87f3acab))
* update prompts and descriptions for data science components ([#731](https://github.com/microsoft/RD-Agent/issues/731)) ([c20e226](https://github.com/microsoft/RD-Agent/commit/c20e226c3e7771c9fcd1c879a8937e4694dc03eb))
* variable printing tool of data_science coder testing ([#658](https://github.com/microsoft/RD-Agent/issues/658)) ([116c061](https://github.com/microsoft/RD-Agent/commit/116c06190b01f0b621c021726a1be23458ab1154))
### Bug Fixes
* a default conf in scen qlib ([#503](https://github.com/microsoft/RD-Agent/issues/503)) ([d64a228](https://github.com/microsoft/RD-Agent/commit/d64a228525cbedd7687c1e06132eacd0d0647697))
* a small bug in exp_gen ([#606](https://github.com/microsoft/RD-Agent/issues/606)) ([f734dde](https://github.com/microsoft/RD-Agent/commit/f734dde0b0101e13f38151468c8ddf9e23af26ac))
* add check when retrying gen model codes ([#699](https://github.com/microsoft/RD-Agent/issues/699)) ([3b82f15](https://github.com/microsoft/RD-Agent/commit/3b82f159474087902d3c6007d370e3282b549015))
* add DSExperiment type check and directory validation in log proc… ([#535](https://github.com/microsoft/RD-Agent/issues/535)) ([f59b12c](https://github.com/microsoft/RD-Agent/commit/f59b12c9cc9afde82b74bc133797ff1396678627))
* add ensemble test, change to "use cross-validation if possible" in workflow spec ([#634](https://github.com/microsoft/RD-Agent/issues/634)) ([acc97a8](https://github.com/microsoft/RD-Agent/commit/acc97a8217253497afedcfa829902b4432e1031e))
* add force parameter for cache_with_pickle & using cache when get kaggle leaderboard ([#687](https://github.com/microsoft/RD-Agent/issues/687)) ([c8841e5](https://github.com/microsoft/RD-Agent/commit/c8841e590a925200859acba9fda4a17d4c3aa1c7))
* add metric name check for valid scores ([#724](https://github.com/microsoft/RD-Agent/issues/724)) ([acc2ffb](https://github.com/microsoft/RD-Agent/commit/acc2ffbde4df3b53654559d14cd035ee6be6b35e))
* add retry mechanism for GPU device check in DockerEnv ([#573](https://github.com/microsoft/RD-Agent/issues/573)) ([a780cfb](https://github.com/microsoft/RD-Agent/commit/a780cfb621dc487cc17072bfd4aedd7d581249ab))
* add scores.csv checking in ensemble_test ([#567](https://github.com/microsoft/RD-Agent/issues/567)) ([01808b4](https://github.com/microsoft/RD-Agent/commit/01808b47c314d1daffacc0a65e0ab934a1c41d65))
* add stdout context length setting and improve text shrinking logic ([#559](https://github.com/microsoft/RD-Agent/issues/559)) ([4ac26a6](https://github.com/microsoft/RD-Agent/commit/4ac26a65c1f18f7513480dd562566c8a96298aa7))
* align components' name ([#701](https://github.com/microsoft/RD-Agent/issues/701)) ([295a114](https://github.com/microsoft/RD-Agent/commit/295a1148c53d00b716b2d540573a7f43e7e2d762))
* auto continue small bug ([#598](https://github.com/microsoft/RD-Agent/issues/598)) ([75eaecf](https://github.com/microsoft/RD-Agent/commit/75eaecf36b9f70dfc2d7fedd35836acdb05f89d6))
* avoid try-except in ensemble eval prompts ([#637](https://github.com/microsoft/RD-Agent/issues/637)) ([5c58d6e](https://github.com/microsoft/RD-Agent/commit/5c58d6e524ef848024578033ab6d47bc9b220822))
* avoid warning for missing llama installation when not in use ([#509](https://github.com/microsoft/RD-Agent/issues/509)) ([5ec3422](https://github.com/microsoft/RD-Agent/commit/5ec342224c2c8c4cf591f1eae673e25b14218726))
* change devault to default ([#688](https://github.com/microsoft/RD-Agent/issues/688)) ([7f401cd](https://github.com/microsoft/RD-Agent/commit/7f401cd1c3b333285acf6d6e57654f4b9f0cb6c5))
* change ensemble test ([#622](https://github.com/microsoft/RD-Agent/issues/622)) ([5de3595](https://github.com/microsoft/RD-Agent/commit/5de35953ed0d3e2e1f4dff0e0522f2d6475079ec))
* change summary info of log folder ([#552](https://github.com/microsoft/RD-Agent/issues/552)) ([0eb258d](https://github.com/microsoft/RD-Agent/commit/0eb258d734e9a1280a238b9a6f63eb33047ee0a7))
* clarify an ambiguous explanation ([#705](https://github.com/microsoft/RD-Agent/issues/705)) ([5dbfc68](https://github.com/microsoft/RD-Agent/commit/5dbfc6859cbf6cc31932dae30cf05506108fc871))
* clarify cross_validation ([#644](https://github.com/microsoft/RD-Agent/issues/644)) ([906993e](https://github.com/microsoft/RD-Agent/commit/906993ef6482f88131d1af46f5bc66a77034b549))
* coder prompt & model test text ([#583](https://github.com/microsoft/RD-Agent/issues/583)) ([0a41227](https://github.com/microsoft/RD-Agent/commit/0a41227f267050feaeeb47ddd4d749643eb9f198))
* correct the configuration inheritance relationship ([#671](https://github.com/microsoft/RD-Agent/issues/671)) ([30b1ff8](https://github.com/microsoft/RD-Agent/commit/30b1ff8e1ce59b741e0b81481962063014641c0b))
* default emb model ([#702](https://github.com/microsoft/RD-Agent/issues/702)) ([4329a72](https://github.com/microsoft/RD-Agent/commit/4329a722832a201b3fa6f9d8f9d8d46f78110410))
* direct_exp_gen to json_target_type in DSExpGen class ([#661](https://github.com/microsoft/RD-Agent/issues/661)) ([428b74a](https://github.com/microsoft/RD-Agent/commit/428b74a988157ea864ebb40e828bd9f67589c863))
* docker error will trigger retry and data science runner loop set to 3 ([#602](https://github.com/microsoft/RD-Agent/issues/602)) ([ad785e0](https://github.com/microsoft/RD-Agent/commit/ad785e03d5db05d9191d5e772e184532835a787b))
* ensure expected type ([#593](https://github.com/microsoft/RD-Agent/issues/593)) ([098a9a6](https://github.com/microsoft/RD-Agent/commit/098a9a6618f70fa8dd276b9014b9e7ba9621553b))
* filter empty log traces in ds UI ([#533](https://github.com/microsoft/RD-Agent/issues/533)) ([1a2057c](https://github.com/microsoft/RD-Agent/commit/1a2057c9fc11edc4637f0baaa6dd226eb049c36e))
* fix a bug in cross validation ([#618](https://github.com/microsoft/RD-Agent/issues/618)) ([05a4f10](https://github.com/microsoft/RD-Agent/commit/05a4f101e0b64b860ad03294619b2350004657e8))
* fix a bug in ensemble test script ([#713](https://github.com/microsoft/RD-Agent/issues/713)) ([ad32100](https://github.com/microsoft/RD-Agent/commit/ad321000acbd9291d22fe03a9c60e57c70511c73))
* fix a bug in initial tasks ([#635](https://github.com/microsoft/RD-Agent/issues/635)) ([edb552e](https://github.com/microsoft/RD-Agent/commit/edb552ed283119444f357fbd0b6170b2ad97712a))
* fix a bug in kaggle conf ([#459](https://github.com/microsoft/RD-Agent/issues/459)) ([b4ed32b](https://github.com/microsoft/RD-Agent/commit/b4ed32b17ef07d8557450063765585a48d5fcd32))
* fix a bug in progress_bar filter ([#712](https://github.com/microsoft/RD-Agent/issues/712)) ([ba5a84d](https://github.com/microsoft/RD-Agent/commit/ba5a84dee59c39cc2a8c0d428a82da1f899ce537))
* fix a bug in proposal (add last loop's exception to last task desc) ([#596](https://github.com/microsoft/RD-Agent/issues/596)) ([419186f](https://github.com/microsoft/RD-Agent/commit/419186ffb985fe5a0aa0f7fe59c7a223e355492e))
* fix a bug in regular expression exception processing ([#734](https://github.com/microsoft/RD-Agent/issues/734)) ([67d3702](https://github.com/microsoft/RD-Agent/commit/67d37027bbcd7294a5890a350fe16fe78e0dfa77))
* fix a bug in threshold score display ([#592](https://github.com/microsoft/RD-Agent/issues/592)) ([0b0a2dc](https://github.com/microsoft/RD-Agent/commit/0b0a2dc512a5560a66464ad49de25d362d0dc17e))
* fix a bug related to model_name in ensemble ([#692](https://github.com/microsoft/RD-Agent/issues/692)) ([c6ce473](https://github.com/microsoft/RD-Agent/commit/c6ce4733f32578298abe0b60f9d82611b793cc09))
* fix a minor bug ([#694](https://github.com/microsoft/RD-Agent/issues/694)) ([1405d8d](https://github.com/microsoft/RD-Agent/commit/1405d8dafd99ecde6f3ba9dd76133d8830d03b47))
* fix an error in model_coder prompt ([#690](https://github.com/microsoft/RD-Agent/issues/690)) ([4528826](https://github.com/microsoft/RD-Agent/commit/452882674e915dbd9e3399c26c70ce5bb86d012c))
* fix combined_factors_df.pkl not loading in docker ([#697](https://github.com/microsoft/RD-Agent/issues/697)) ([3984b99](https://github.com/microsoft/RD-Agent/commit/3984b995aa74318b40de7712e100d4de5cc95b11))
* fix docs build error ([#711](https://github.com/microsoft/RD-Agent/issues/711)) ([c9e1d32](https://github.com/microsoft/RD-Agent/commit/c9e1d32d6b63560350cc7cb799c3a908e2c04e42))
* fix ExtendedSettingsConfigDict does not work ([#660](https://github.com/microsoft/RD-Agent/issues/660)) ([3a877f3](https://github.com/microsoft/RD-Agent/commit/3a877f383b908da8d027560714030b201946bb76))
* fix kaggle templates path error ([#747](https://github.com/microsoft/RD-Agent/issues/747)) ([3b3f504](https://github.com/microsoft/RD-Agent/commit/3b3f5041514baf741fe2d4613fa651fb5d9c002d))
* fix KeyError direct_exp_gen ([#735](https://github.com/microsoft/RD-Agent/issues/735)) ([7200682](https://github.com/microsoft/RD-Agent/commit/7200682ac4e60d3910c29a4f7c4a37b3d24e4224))
* fix some bugs (ensemble output, HPO, model tuning) ([#648](https://github.com/microsoft/RD-Agent/issues/648)) ([818ee29](https://github.com/microsoft/RD-Agent/commit/818ee29f8e5d4765b9801463b85b42ee9516ec33))
* fix some bugs in the ensemble component ([#595](https://github.com/microsoft/RD-Agent/issues/595)) ([c0990ab](https://github.com/microsoft/RD-Agent/commit/c0990abb06c73ae062d9a50f50cdfd6d04aded22))
* fix some bugs in workflow unit test ([#624](https://github.com/microsoft/RD-Agent/issues/624)) ([f845dcc](https://github.com/microsoft/RD-Agent/commit/f845dcc0ee1b059b8b32485ad46bb90c7ae0fa78))
* fix some description errors in direct_exp_gen ([#698](https://github.com/microsoft/RD-Agent/issues/698)) ([dfaacb6](https://github.com/microsoft/RD-Agent/commit/dfaacb6d06e5d5f55e950d7177570d1efebf958f))
* fix some minor bugs and add AutoML & cross-validation ([#604](https://github.com/microsoft/RD-Agent/issues/604)) ([18c5ef2](https://github.com/microsoft/RD-Agent/commit/18c5ef268d40efe7bb9ee18aa0d250732bdda6fa))
* fix submission file search and add TODO in env.py ([#544](https://github.com/microsoft/RD-Agent/issues/544)) ([54d930e](https://github.com/microsoft/RD-Agent/commit/54d930e91e629f0fc2f8bdd0d0d62fcad1e99a9c))
* fix task return dict with wrong format ([#558](https://github.com/microsoft/RD-Agent/issues/558)) ([2008244](https://github.com/microsoft/RD-Agent/commit/20082440a249dd0e5a7026c2d98c9de0288dd400))
* fix the errors in the coder and evaluator of the five components ([#576](https://github.com/microsoft/RD-Agent/issues/576)) ([c487f83](https://github.com/microsoft/RD-Agent/commit/c487f835b651cdc40b95bbbe4efcb9a617be9e40))
* handle division by zero in percentage calculations ([#550](https://github.com/microsoft/RD-Agent/issues/550)) ([de16c91](https://github.com/microsoft/RD-Agent/commit/de16c915e1716ef8cee43ce41069ea1a09cf1f24))
* handle invalid regex patterns in filter_progress_bar function ([#579](https://github.com/microsoft/RD-Agent/issues/579)) ([b0daee0](https://github.com/microsoft/RD-Agent/commit/b0daee0d90e193ca1d028e01c31ebf368af89601))
* Handle ValueError when resolving relative path for uri ([#585](https://github.com/microsoft/RD-Agent/issues/585)) ([4c7765a](https://github.com/microsoft/RD-Agent/commit/4c7765a12bda5dcfd9af72b292853d9bc28c5baf))
* include data information in cache key generation ([#566](https://github.com/microsoft/RD-Agent/issues/566)) ([26dda46](https://github.com/microsoft/RD-Agent/commit/26dda4682b7b643c164589057cb568a4d9e55e17))
* keep some txt files ([#557](https://github.com/microsoft/RD-Agent/issues/557)) ([54aba85](https://github.com/microsoft/RD-Agent/commit/54aba851c9fa194e318d37700307df59e06c6c84))
* mle_score save problem ([#674](https://github.com/microsoft/RD-Agent/issues/674)) ([ca2e478](https://github.com/microsoft/RD-Agent/commit/ca2e478cf25c2c8511d5f027e32f8a98fc8e3a07))
* move docker timeout message to __run() ([#620](https://github.com/microsoft/RD-Agent/issues/620)) ([585f4f9](https://github.com/microsoft/RD-Agent/commit/585f4f96e09f70d00eb397c10bf49c09973111df))
* move mlebench check into runner ([#556](https://github.com/microsoft/RD-Agent/issues/556)) ([b0f7965](https://github.com/microsoft/RD-Agent/commit/b0f7965f650638273710302efee2e5da037368a2))
* move next_component_required logic to DSTrace class and accurate implement ([#612](https://github.com/microsoft/RD-Agent/issues/612)) ([c20d311](https://github.com/microsoft/RD-Agent/commit/c20d311792f33b2ccccb466c6ec3155ff8be3213))
* patching weird azure deployment ([#494](https://github.com/microsoft/RD-Agent/issues/494)) ([89c50ae](https://github.com/microsoft/RD-Agent/commit/89c50aee2ec8bfd1cb23767ddf7dcdd023daac8b))
* qlib and other scenario bugs ([#636](https://github.com/microsoft/RD-Agent/issues/636)) ([98de31d](https://github.com/microsoft/RD-Agent/commit/98de31d4e577c8c450c9694f73a755c19af571f7))
* refine prompt to generate the most simple task in init stage ([#546](https://github.com/microsoft/RD-Agent/issues/546)) ([9d6feed](https://github.com/microsoft/RD-Agent/commit/9d6feed28ce034db48482d8d9741ef8c72f4bddc))
* replace API call with build_cls_from_json_with_retry function ([#548](https://github.com/microsoft/RD-Agent/issues/548)) ([eb72a47](https://github.com/microsoft/RD-Agent/commit/eb72a47fbf9c88dacea9691b8d7e92610492d190))
* replace func "len()" in ensemble test code to support various data type ([#739](https://github.com/microsoft/RD-Agent/issues/739)) ([ab9c7b9](https://github.com/microsoft/RD-Agent/commit/ab9c7b955f78c5de7ec08a6c1a012a76badbdd0e))
* return 1D embedding if create_embedding receive a string input ([#670](https://github.com/microsoft/RD-Agent/issues/670)) ([4a9c318](https://github.com/microsoft/RD-Agent/commit/4a9c3180ae4a4b043b1b4a89f51ee69cb6843142))
* rich.print error when some control char in output ([#684](https://github.com/microsoft/RD-Agent/issues/684)) ([ec0cb2a](https://github.com/microsoft/RD-Agent/commit/ec0cb2a032824023dcd04a3acc93202471d1f90a))
* Runnable on first complete & Rename method to next_incomplete_component for clarity ([#615](https://github.com/microsoft/RD-Agent/issues/615)) ([93d9f63](https://github.com/microsoft/RD-Agent/commit/93d9f63369a78f78e1a67ab548923bb994d1d3b4))
* runner COSTEER evaluator ([#693](https://github.com/microsoft/RD-Agent/issues/693)) ([6a379ec](https://github.com/microsoft/RD-Agent/commit/6a379ec9b84d4e4944f1e412347aae4f5a93d476))
* save only one mle_score pkl for a running exp ([#675](https://github.com/microsoft/RD-Agent/issues/675)) ([f87ab67](https://github.com/microsoft/RD-Agent/commit/f87ab676b73cce82bd9f997ac779e31c571b53c4))
* Set default value for 'entry' parameter in Env.run method ([#643](https://github.com/microsoft/RD-Agent/issues/643)) ([e50d242](https://github.com/microsoft/RD-Agent/commit/e50d2424b849e4181d6ca02e9cace90236665924))
* sort file name for cache reproduction ([#588](https://github.com/microsoft/RD-Agent/issues/588)) ([7158410](https://github.com/microsoft/RD-Agent/commit/7158410fbfdd84052f9a69cf1e04e09ac07ca598))
* sota comparison logic ([#608](https://github.com/microsoft/RD-Agent/issues/608)) ([3575372](https://github.com/microsoft/RD-Agent/commit/35753722c0800d62855faeab996d513e62cfe7de))
* target json type & round ([#662](https://github.com/microsoft/RD-Agent/issues/662)) ([58cb58f](https://github.com/microsoft/RD-Agent/commit/58cb58f966a1db26f5ea9662a54ba12bc921ee24))
* templates bug ([#456](https://github.com/microsoft/RD-Agent/issues/456)) ([434a868](https://github.com/microsoft/RD-Agent/commit/434a8687eeda77e27b4938fb19694c15858ee446))
* trace summary df showing in dsapp ([#551](https://github.com/microsoft/RD-Agent/issues/551)) ([177096d](https://github.com/microsoft/RD-Agent/commit/177096d55fecb8c7dab9650ef8f5a31024cd4c1c))
* unzip kaggle data ([#464](https://github.com/microsoft/RD-Agent/issues/464)) ([3a9fc8e](https://github.com/microsoft/RD-Agent/commit/3a9fc8e73337d3757267b6f4482499499a1b6792))
## [0.3.0](https://github.com/microsoft/RD-Agent/compare/v0.2.1...v0.3.0) (2024-10-21)
+50
View File
@@ -0,0 +1,50 @@
# Contributing to RD-Agent
We welcome contributions and suggestions to improve RD-Agent. Whether it's solving an issue, addressing a bug, enhancing documentation, or even correcting a typo, every contribution is valuable and helps improve the project.
## Getting Started
To get started, you can explore the issues list or search for `TODO:` comments in the codebase by running the command:
```sh
grep -r "TODO:"
```
## How to Contribute
1. **Fork the Repository**: Create a fork of the repository on GitHub.
2. **Clone the Repository**: Clone your forked repository to your local machine.
```sh
git clone https://github.com/your-username/RD-Agent.git
```
3. **Create a Branch**: Create a new branch for your changes.
```sh
git checkout -b feature/your-feature-name
```
4. **Make Changes**: Make your changes to the codebase.
5. **Commit Changes**: Commit your changes with a descriptive commit message.
```sh
git commit -m "Description of your changes"
```
6. **Push Changes**: Push your changes to your forked repository.
```sh
git push origin feature/your-feature-name
```
7. **Ensure CI Passes**: Make sure your code passes the automatic CI checks on GitHub.
8. **Create a Pull Request**: Create a pull request from your forked repository to the main repository.
## Code of Conduct
Please adhere to the [Code of Conduct](CODE_OF_CONDUCT.md) in all your interactions with the project.
## Reporting Issues
If you encounter any issues or have suggestions for improvements, please open an issue on GitHub.
## Guidelines
- Ensure your code follows the project's coding standards.
- Write clear and concise commit messages.
- Update documentation as needed.
- Test your changes thoroughly before submitting a pull request.
Thank you for contributing to RD-Agent!
+2 -1
View File
@@ -68,6 +68,7 @@ init-qlib-env:
dev:
$(PIPRUN) pip install -e .[docs,lint,package,test] -c $(CONSTRAINTS_FILE)
$(PIPRUN) pip install -U kaggle
if [ "$(CI)" != "true" ] && command -v pre-commit > /dev/null 2>&1; then pre-commit install --hook-type pre-push; fi
# Generate constraints for current Python version.
@@ -91,7 +92,7 @@ isort:
# First deal with the core folder, and then gradually increase the scope of detection,
# and eventually realize the detection of the complete project.
mypy:
$(PIPRUN) python -m mypy rdagent/core # --exclude rdagent/scripts,git_ignore_folder
$(PIPRUN) python -m mypy rdagent/core
# Check lint with ruff.
# First deal with the core folder, and then gradually increase the scope of detection,
+197 -37
View File
@@ -1,7 +1,11 @@
<h4 align="center">
<img src="docs/_static/logo.png" alt="RA-Agent logo" style="width:70%; ">
<a href="https://rdagent.azurewebsites.net" target="_blank">🖥️ Live Demo</a> | <a href="https://rdagent.azurewebsites.net/factor_loop" target="_blank">🎥 Demo Video</a> <a href="https://www.youtube.com/watch?v=JJ4JYO3HscM&list=PLALmKB0_N3_i52fhUmPQiL4jsO354uopR" target="_blank">▶️YouTube</a> | <a href="https://rdagent.readthedocs.io/en/latest/index.html" target="_blank">📖 Documentation</a> | <a href="#-paperwork-list"> 📃 Papers </a>
<a href="https://rdagent.azurewebsites.net" target="_blank">🖥️ Live Demo</a> |
<a href="https://rdagent.azurewebsites.net/factor_loop" target="_blank">🎥 Demo Video</a> <a href="https://www.youtube.com/watch?v=JJ4JYO3HscM&list=PLALmKB0_N3_i52fhUmPQiL4jsO354uopR" target="_blank">▶️YouTube</a> |
<a href="https://rdagent.readthedocs.io/en/latest/index.html" target="_blank">📖 Documentation</a> |
<a href="https://aka.ms/RD-Agent-Tech-Report" target="_blank">📄 Tech Report</a> |
<a href="#-paperwork-list"> 📃 Papers </a>
</h3>
@@ -19,31 +23,82 @@
[![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Chat](https://img.shields.io/badge/chat-discord-blue)](https://discord.gg/ybQ97B6Jjy)
[![Documentation Status](https://readthedocs.org/projects/rdagent/badge/?version=latest)](https://rdagent.readthedocs.io/en/latest/?badge=latest)
[![Readthedocs Preview](https://github.com/microsoft/RD-Agent/actions/workflows/readthedocs-preview.yml/badge.svg)](https://github.com/microsoft/RD-Agent/actions/workflows/readthedocs-preview.yml) <!-- this badge is too long, please place it in the last one to make it pretty -->
[![arXiv](https://img.shields.io/badge/arXiv-2505.14738-00ff00.svg)](https://arxiv.org/abs/2505.14738)
# 🏆 The Best Machine Learning Engineering Agent!
[MLE-bench](https://github.com/openai/mle-bench) is a comprehensive benchmark evaluating the performance of AI agents on machine learning engineering tasks. Utilizing datasets from 75 Kaggle competitions, MLE-bench provides robust assessments of AI systems' capabilities in real-world ML engineering scenarios.
R&D-Agent currently leads as the top-performing machine learning engineering agent on MLE-bench:
| Agent | Low == Lite (%) | Medium (%) | High (%) | All (%) |
|---------|--------|-----------|---------|----------|
| R&D-Agent o1-preview | 48.18 ± 2.49 | 8.95 ± 2.36 | 18.67 ± 2.98 | 22.4 ± 1.1 |
| R&D-Agent o3(R)+GPT-4.1(D) | 51.52 ± 6.21 | 7.89 ± 3.33 | 16.67 ± 3.65 | 22.45 ± 2.45 |
| AIDE o1-preview | 34.3 ± 2.4 | 8.8 ± 1.1 | 10.0 ± 1.9 | 16.9 ± 1.1 |
**Notes:**
- **O3(R)+GPT-4.1(D)**: This version is designed to both reduce average time per loop and leverage a cost-effective combination of backend LLMs by seamlessly integrating Research Agent (o3) with Development Agent (GPT-4.1).
- **AIDE o1-preview**: Represents the previously best public result on MLE-bench as reported in the original MLE-bench paper.
- Average and standard deviation results for R&D-Agent o1-preview is based on a independent of 5 seeds and for R&D-Agent o3(R)+GPT-4.1(D) is based on 6 seeds.
- According to MLE-Bench, the 75 competitions are categorized into three levels of complexity: **Low==Lite** if we estimate that an experienced ML engineer can produce a sensible solution in under 2 hours, excluding the time taken to train any models; **Medium** if it takes between 2 and 10 hours; and **High** if it takes more than 10 hours.
You can inspect the detailed runs of the above results online.
- [R&D-Agent o1-preview detailed runs](https://aka.ms/RD-Agent_MLE-Bench_O1-preview)
- [R&D-Agent o3(R)+GPT-4.1(D) detailed runs](https://aka.ms/RD-Agent_MLE-Bench_O3_GPT41)
For running R&D-Agent on MLE-bench, refer to **[MLE-bench Guide: Running ML Engineering via MLE-bench](https://rdagent.readthedocs.io/en/latest/scens/data_science.html)**
# 🥇 The First Data-Centric Quant Multi-Agent Framework!
R&D-Agent for Quantitative Finance, in short **RD-Agent(Q)**, is the first data-centric, multi-agent framework designed to automate the full-stack research and development of quantitative strategies via coordinated factor-model co-optimization.
![image](https://github.com/user-attachments/assets/3198bc10-47ba-4ee0-8a8e-46d5ce44f45d)
Extensive experiments in real stock markets show that, at a cost under $10, RD-Agent(Q) achieves approximately 2× higher ARR than benchmark factor libraries while using over 70% fewer factors. It also surpasses state-of-the-art deep time-series models under smaller resource budgets. Its alternating factormodel optimization further delivers excellent trade-off between predictive accuracy and strategy robustness.
You can learn more details about **RD-Agent(Q)** through the [paper](https://arxiv.org/abs/2505.15155) and reproduce it through the [documentation](https://rdagent.readthedocs.io/en/latest/scens/quant_agent_fin.html).
# 📰 News
| 🗞️ News | 📝 Description |
| -- | ------ |
| Official WeChat group release | We created a WeChat group, welcome to join! (🗪[QR Code](docs/WeChat_QR_code.jpg)) |
| -- | ------ |
| [Technical Report Release](#overall-technical-report) | Overall framework description and results on MLE-bench |
| [R&D-Agent-Quant Release](#deep-application-in-diverse-scenarios) | Apply R&D-Agent to quant trading |
| MLE-Bench Results Released | R&D-Agent currently leads as the [top-performing machine learning engineering agent](#-the-best-machine-learning-engineering-agent) on MLE-bench |
| Support LiteLLM Backend | We now fully support **[LiteLLM](https://github.com/BerriAI/litellm)** as a backend for integration with multiple LLM providers. |
| General Data Science Agent | [Data Science Agent](https://rdagent.readthedocs.io/en/latest/scens/data_science.html) |
| Kaggle Scenario release | We release **[Kaggle Agent](https://rdagent.readthedocs.io/en/latest/scens/data_science.html)**, try the new features! |
| Official WeChat group release | We created a WeChat group, welcome to join! (🗪[QR Code](https://github.com/microsoft/RD-Agent/issues/880)) |
| Official Discord release | We launch our first chatting channel in Discord (🗪[![Chat](https://img.shields.io/badge/chat-discord-blue)](https://discord.gg/ybQ97B6Jjy)) |
| First release | **RDAgent** is released on GitHub |
| First release | **R&D-Agent** is released on GitHub |
# Data Science Agent Preview
Check out our demo video showcasing the current progress of our Data Science Agent under development:
https://github.com/user-attachments/assets/3eccbecb-34a4-4c81-bce4-d3f8862f7305
# 🌟 Introduction
<div align="center">
<img src="docs/_static/scen.png" alt="Our focused scenario" style="width:80%; ">
</div>
RDAgent aims to automate the most critical and valuable aspects of the industrial R&D process, and we begin with focusing on the data-driven scenarios to streamline the development of models and data.
R&D-Agent aims to automate the most critical and valuable aspects of the industrial R&D process, and we begin with focusing on the data-driven scenarios to streamline the development of models and data.
Methodologically, we have identified a framework with two key components: 'R' for proposing new ideas and 'D' for implementing them.
We believe that the automatic evolution of R&D will lead to solutions of significant industrial value.
<!-- Tag Cloud -->
R&D is a very general scenario. The advent of RDAgent can be your
R&D is a very general scenario. The advent of R&D-Agent can be your
- 💰 **Automatic Quant Factory** ([🎥Demo Video](https://rdagent.azurewebsites.net/factor_loop)|[▶️YouTube](https://www.youtube.com/watch?v=X4DK2QZKaKY&t=6s))
- 🤖 **Data Mining Agent:** Iteratively proposing data & models ([🎥Demo Video 1](https://rdagent.azurewebsites.net/model_loop)|[▶️YouTube](https://www.youtube.com/watch?v=dm0dWL49Bc0&t=104s)) ([🎥Demo Video 2](https://rdagent.azurewebsites.net/dmm)|[▶️YouTube](https://www.youtube.com/watch?v=VIaSTZuoZg4)) and implementing them by gaining knowledge from data.
- 🦾 **Research Copilot:** Auto read research papers ([🎥Demo Video](https://rdagent.azurewebsites.net/report_model)|[▶️YouTube](https://www.youtube.com/watch?v=BiA2SfdKQ7o)) / financial reports ([🎥Demo Video](https://rdagent.azurewebsites.net/report_factor)|[▶️YouTube](https://www.youtube.com/watch?v=ECLTXVcSx-c)) and implement model structures or building datasets.
- 🤖 **Kaggle Agent:** Auto Model Tuning and Feature Engineering([🎥Demo Video Coming Soon...]()) and implementing them to achieve more in competitions.
- ...
You can click the links above to view the demo. We're continuously adding more methods and scenarios to the project to enhance your R&D processes and boost productivity.
@@ -63,6 +118,7 @@ You can try above demos by running the following command:
### 🐳 Docker installation.
Users must ensure Docker is installed before attempting most scenarios. Please refer to the [official 🐳Docker page](https://docs.docker.com/engine/install/) for installation instructions.
Ensure the current user can run Docker commands **without using sudo**. You can verify this by executing `docker run hello-world`.
### 🐍 Create a Conda Environment
- Create a new conda environment with Python (3.10 and 3.11 are well-tested in our CI):
@@ -74,26 +130,77 @@ Users must ensure Docker is installed before attempting most scenarios. Please r
conda activate rdagent
```
### 🛠️ Install the RDAgent
- You can directly install the RDAgent package from PyPI:
### 🛠️ Install the R&D-Agent
- You can directly install the R&D-Agent package from PyPI:
```sh
pip install rdagent
```
### 💊 Health check
- rdagent provides a health check that currently checks two things.
- whether the docker installation was successful.
- whether the default port used by the [rdagent ui](https://github.com/microsoft/RD-Agent?tab=readme-ov-file#%EF%B8%8F-monitor-the-application-results) is occupied.
```sh
rdagent health_check
```
### ⚙️ Configuration
- You have to config your GPT model in the `.env`
- The demos requires following ability:
- ChatCompletion
- json_mode
- embedding query
You can set your Chat Model and Embedding Model in the following ways:
- **Using LiteLLM (Default)**: We now support LiteLLM as a backend for integration with multiple LLM providers. You can configure in two ways:
**Option 1: Unified API base for both models**
```bash
cat << EOF > .env
OPENAI_API_KEY=<your_api_key>
# EMBEDDING_MODEL=text-embedding-3-small
CHAT_MODEL=gpt-4-turbo
EOF
# Set to any model supported by LiteLLM.
CHAT_MODEL=gpt-4o
EMBEDDING_MODEL=text-embedding-3-small
# Configure unified API base
OPENAI_API_BASE=<your_unified_api_base>
OPENAI_API_KEY=<replace_with_your_openai_api_key>
```
**Option 2: Separate API bases for Chat and Embedding models**
```bash
cat << EOF > .env
# Set to any model supported by LiteLLM.
# Configure separate API bases for chat and embedding
# CHAT MODEL:
CHAT_MODEL=gpt-4o
OPENAI_API_BASE=<your_chat_api_base>
OPENAI_API_KEY=<replace_with_your_openai_api_key>
# EMBEDDING MODEL:
# TAKE siliconflow as an example, you can use other providers.
# Note: embedding requires litellm_proxy prefix
EMBEDDING_MODEL=litellm_proxy/BAAI/bge-large-en-v1.5
LITELLM_PROXY_API_KEY=<replace_with_your_siliconflow_api_key>
LITELLM_PROXY_API_BASE=https://api.siliconflow.cn/v1
```
Notice: If you are using reasoning models that include thought processes in their responses (such as \<think> tags), you need to set the following environment variable:
```bash
REASONING_THINK_RM=True
```
- You can also use a deprecated backend if you only use `OpenAI API` or `Azure OpenAI` directly. For this deprecated setting and more configuration information, please refer to the [documentation](https://rdagent.readthedocs.io/en/latest/installation_and_configuration.html).
### 🚀 Run the Application
The **[🖥️ Live Demo](https://rdagent.azurewebsites.net/)** is implemented by the following commands(each item represents one demo, you can select the one you prefer):
- Run the **Automated Quantitative Trading & Iterative Factors Model Joint Evolution**: [Qlib](http://github.com/microsoft/qlib) self-loop factor & model proposal and implementation application
```sh
rdagent fin_quant
```
- Run the **Automated Quantitative Trading & Iterative Factors Evolution**: [Qlib](http://github.com/microsoft/qlib) self-loop factor proposal and implementation application
```sh
rdagent fin_factor
@@ -104,19 +211,6 @@ The **[🖥️ Live Demo](https://rdagent.azurewebsites.net/)** is implemented b
rdagent fin_model
```
- Run the **Automated Medical Prediction Model Evolution**: Medical self-loop model proposal and implementation application
>(1) Apply for an account at [PhysioNet](https://physionet.org/). <br /> (2) Request access to FIDDLE preprocessed data: [FIDDLE Dataset](https://physionet.org/content/mimic-eicu-fiddle-feature/1.0.0/). <br />
(3) Place your username and password in `.env`.
```bash
cat << EOF >> .env
DM_USERNAME=<your_username>
DM_PASSWORD=<your_password>
EOF
```
```sh
rdagent med_model
```
- Run the **Automated Quantitative Trading & Factors Extraction from Financial Reports**: Run the [Qlib](http://github.com/microsoft/qlib) factor extraction and implementation application based on financial reports
```sh
# 1. Generally, you can run this scenario using the following command:
@@ -137,15 +231,49 @@ The **[🖥️ Live Demo](https://rdagent.azurewebsites.net/)** is implemented b
rdagent general_model "https://arxiv.org/pdf/2210.09789"
```
- Run the **Automated Kaggle Model Tuning & Feature Engineering**: self-loop model proposal and feature engineering implementation application <br />
> Using **sf-crime** *(San Francisco Crime Classification)* as an example. <br />
> 1. Register and login on the [Kaggle](https://www.kaggle.com/) website. <br />
> 2. Configuring the Kaggle API. <br />
> (1) Click on the avatar (usually in the top right corner of the page) -> `Settings` -> `Create New Token`, A file called `kaggle.json` will be downloaded. <br />
> (2) Move `kaggle.json` to `~/.config/kaggle/` <br />
> (3) Modify the permissions of the kaggle.json file. Reference command: `chmod 600 ~/.config/kaggle/kaggle.json` <br />
> 3. Join the competition: Click `Join the competition` -> `I Understand and Accept` at the bottom of the [competition details page](https://www.kaggle.com/competitions/sf-crime/data).
```bash
# Generally, you can run the Kaggle competition program with the following command:
rdagent data_science --competition <your competition name>
# Specifically, you need to create a folder for storing competition files (e.g., competition description file, competition datasets, etc.), and configure the path to the folder in your environment. In addition, you need to use chromedriver when you download the competition descriptors, which you can follow for this specific example:
# 1. Install chromedriver.
# 2. Add the competition description file path to the `.env` file.
mkdir -p ./git_ignore_folder/kaggle_data
dotenv set DS_LOCAL_DATA_PATH "$(pwd)/git_ignore_folder/kaggle_data"
dotenv set DS_IF_USING_MLE_DATA True
# 3. run the application
rdagent data_science --competition sf-crime
```
### 🖥️ Monitor the Application Results
- You can serve our demo app to monitor the RD loop by running the following command:
- You can run the following command for our demo program to see the run logs.
```sh
rdagent ui --port 80 --log_dir <your log folder like "log/">
rdagent ui --port 19899 --log_dir <your log folder like "log/">
```
**Note:** Although port 19899 is not commonly used, but before you run this demo, you need to check if port 19899 is occupied. If it is, please change it to another port that is not occupied.
You can check if a port is occupied by running the following command.
```sh
rdagent health_check
```
# 🏭 Scenarios
We have applied RD-Agent to multiple valuable data-driven industrial scenarios.
We have applied R&D-Agent to multiple valuable data-driven industrial scenarios.
## 🎯 Goal: Agent for Data-driven R&D
@@ -170,15 +298,13 @@ The supported scenarios are listed below:
| -- | -- | -- |
| **💹 Finance** | 🤖 [Iteratively Proposing Ideas & Evolving](https://rdagent.azurewebsites.net/model_loop)[▶️YouTube](https://www.youtube.com/watch?v=dm0dWL49Bc0&t=104s) | 🤖 [Iteratively Proposing Ideas & Evolving](https://rdagent.azurewebsites.net/factor_loop) [▶️YouTube](https://www.youtube.com/watch?v=X4DK2QZKaKY&t=6s) <br/> 🦾 [Auto reports reading & implementation](https://rdagent.azurewebsites.net/report_factor)[▶️YouTube](https://www.youtube.com/watch?v=ECLTXVcSx-c) |
| **🩺 Medical** | 🤖 [Iteratively Proposing Ideas & Evolving](https://rdagent.azurewebsites.net/dmm)[▶️YouTube](https://www.youtube.com/watch?v=VIaSTZuoZg4) | - |
| **🏭 General** | 🦾 [Auto paper reading & implementation](https://rdagent.azurewebsites.net/report_model)[▶️YouTube](https://www.youtube.com/watch?v=BiA2SfdKQ7o) | - |
| **🏭 General** | 🦾 [Auto paper reading & implementation](https://rdagent.azurewebsites.net/report_model)[▶️YouTube](https://www.youtube.com/watch?v=BiA2SfdKQ7o) <br/> 🤖 Auto Kaggle Model Tuning | 🤖Auto Kaggle feature Engineering |
- **[RoadMap](https://rdagent.readthedocs.io/en/latest/scens/data_science.html#roadmap)**: Currently, we are working hard to add new features to the Kaggle scenario.
Different scenarios vary in entrance and configuration. Please check the detailed setup tutorial in the scenarios documents.
Here is a gallery of [successful explorations](https://github.com/SunsetWolf/rdagent_resource/releases/download/demo_traces/demo_traces.zip) (5 traces showed in **[🖥️ Live Demo](https://rdagent.azurewebsites.net/)**). You can download and view the execution trace using the command below:
```bash
rdagent ui --port 80 --log_dir ./demo_traces
```
Here is a gallery of [successful explorations](https://github.com/SunsetWolf/rdagent_resource/releases/download/demo_traces/demo_traces.zip) (5 traces showed in **[🖥️ Live Demo](https://rdagent.azurewebsites.net/)**). You can download and view the execution trace using [this command](https://github.com/microsoft/RD-Agent?tab=readme-ov-file#%EF%B8%8F-monitor-the-application-results) from the documentation.
Please refer to **[📖readthedocs_scen](https://rdagent.readthedocs.io/en/latest/scens/catalog.html)** for more details of the scenarios.
@@ -204,6 +330,21 @@ More documents can be found in the **[📖 readthedocs](https://rdagent.readthed
# 📃 Paper/Work list
## Overall Technical Report
- [R&D-Agent: Automating Data-Driven AI Solution Building Through LLM-Powered Automated Research, Development, and Evolution](https://arxiv.org/abs/2505.14738)
```BibTeX
@misc{yang2024rdagent,
title={R\&D-Agent: Automating Data-Driven AI Solution Building Through LLM-Powered Automated Research, Development, and Evolution},
author={Xu Yang and Xiao Yang and Shikai Fang and Bowen Xian and Yuante Li and Jian Wang and Minrui Xu and Haoran Pan and Xinpeng Hong and Weiqing Liu and Yelong Shen and Weizhu Chen and Jiang Bian},
year={2025},
eprint={2505.14738},
archivePrefix={arXiv},
primaryClass={cs.AI},
url={https://arxiv.org/abs/2505.14738}
}
```
![image](https://github.com/user-attachments/assets/28b0488d-a546-4fef-8dc5-563ed64a9b4d)
## 📊 Benchmark
- [Towards Data-Centric Automatic R&D](https://arxiv.org/abs/2404.11276)
```BibTeX
@@ -241,12 +382,31 @@ For more detail, please refer to our **[🖥️ Live Demo page](https://rdagent.
```
![image](https://github.com/user-attachments/assets/75d9769b-0edd-4caf-9d45-57d1e577054b)
## Deep Application in Diverse Scenarios
- [R&D-Agent-Quant: A Multi-Agent Framework for Data-Centric Factors and Model Joint Optimization](https://arxiv.org/abs/2505.15155)
```BibTeX
@misc{li2025rdagentquant,
title={R\&D-Agent-Quant: A Multi-Agent Framework for Data-Centric Factors and Model Joint Optimization},
author={Yuante Li and Xu Yang and Xiao Yang and Minrui Xu and Xisen Wang and Weiqing Liu and Jiang Bian},
year={2025},
eprint={2505.15155},
archivePrefix={arXiv},
primaryClass={cs.AI}
}
```
![image](https://github.com/user-attachments/assets/3186f67a-c2f8-4b6b-8bb9-a9b959c13866)
# 🤝 Contributing
We welcome contributions and suggestions to improve R&D-Agent. Please refer to the [Contributing Guide](CONTRIBUTING.md) for more details on how to contribute.
Before submitting a pull request, ensure that your code passes the automatic CI checks.
## 📝 Guidelines
This project welcomes contributions and suggestions.
Contributing to this project is straightforward and rewarding. Whether it's solving an issue, addressing a bug, enhancing documentation, or even correcting a typo, every contribution is valuable and helps improve RDAgent.
Contributing to this project is straightforward and rewarding. Whether it's solving an issue, addressing a bug, enhancing documentation, or even correcting a typo, every contribution is valuable and helps improve R&D-Agent.
To get started, you can explore the issues list, or search for `TODO:` comments in the codebase by running the command `grep -r "TODO:"`.
@@ -256,7 +416,7 @@ To get started, you can explore the issues list, or search for `TODO:` comments
<img src="https://contrib.rocks/image?repo=microsoft/RD-Agent&max=100&columns=15" />
</a>
Before we released RD-Agent as an open-source project on GitHub, it was an internal project within our group. Unfortunately, the internal commit history was not preserved when we removed some confidential code. As a result, some contributions from our group members, including Haotian Chen, Wenjun Feng, Haoxue Wang, Zeqi Ye, Xinjie Shen, and Jinhui Li, were not included in the public commits.
Before we released R&D-Agent as an open-source project on GitHub, it was an internal project within our group. Unfortunately, the internal commit history was not preserved when we removed some confidential code. As a result, some contributions from our group members, including Haotian Chen, Wenjun Feng, Haoxue Wang, Zeqi Ye, Xinjie Shen, and Jinhui Li, were not included in the public commits.
# ⚖️ Legal disclaimer
<p style="line-height: 1; font-style: italic;">The RD-agent is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. The RD-agent is aimed to facilitate research and development process in the financial industry and not ready-to-use for any financial investment or advice. Users shall independently assess and test the risks of the RD-agent in a specific use scenario, ensure the responsible use of AI technology, including but not limited to developing and integrating risk mitigation measures, and comply with all applicable laws and regulations in all applicable jurisdictions. The RD-agent does not provide financial opinions or reflect the opinions of Microsoft, nor is it designed to replace the role of qualified financial professionals in formulating, assessing, and approving finance products. The inputs and outputs of the RD-agent belong to the users and users shall assume all liability under any theory of liability, whether in contract, torts, regulatory, negligence, products liability, or otherwise, associated with use of the RD-agent and any inputs and outputs thereof.</p>
+7 -242
View File
@@ -1,243 +1,8 @@
aiohttp==3.9.1
aiosignal==1.3.1
alabaster==0.7.13
annotated-types==0.6.0
anyio==4.2.0
appdirs==1.4.4
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
asttokens==2.4.1
async-lru==2.0.4
async-timeout==4.0.3
attrs==23.2.0
autodoc-pydantic==2.0.1
azure-ai-formrecognizer==3.3.2
azure-common==1.1.28
azure-core==1.29.6
azure-identity==1.17.1
Babel==2.14.0
beautifulsoup4==4.12.2
black==23.12.1
bleach==6.1.0
blosc2==2.7.1
build==1.0.3
certifi==2023.11.17
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
colorama==0.4.6
comm==0.2.2
contourpy==1.2.1
coverage==7.4.0
cryptography==41.0.7
cycler==0.12.1
Cython==3.0.7
dataclasses-json==0.6.3
debugpy==1.8.2
decorator==5.1.1
defusedxml==0.7.1
dill==0.3.8
distro==1.9.0
docker==7.1.0
docutils==0.20.1
exceptiongroup==1.2.0
executing==2.0.1
fastjsonschema==2.20.0
feedparser==6.0.11
filelock==3.13.1
fire==0.5.0
fonttools==4.53.1
fqdn==1.5.1
frozenlist==1.4.1
fsspec==2023.12.2
furo==2023.9.10
fuzzywuzzy==0.18.0
git-changelog==2.4.0
greenlet==3.0.3
h11==0.14.0
httpcore==1.0.2
httpx==0.26.0
idna==3.6
imagesize==1.4.1
importlib-metadata==7.0.1
iniconfig==2.0.0
ipykernel==6.29.5
ipython==8.26.0
ipywidgets==8.1.3
isodate==0.6.1
isoduration==20.11.0
isort==5.13.2
jaraco.classes==3.3.0
jedi==0.19.1
jeepney==0.8.0
joblib==1.4.2
json5==0.9.25
jsonpatch==1.33
jsonpointer==2.4
jsonschema==4.23.0
jsonschema-specifications==2023.12.1
jupyter==1.0.0
jupyter-console==6.6.3
jupyter-events==0.10.0
jupyter-lsp==2.2.5
jupyter_client==8.6.2
jupyter_core==5.7.2
jupyter_server==2.14.2
jupyter_server_terminals==0.5.3
jupyterlab==4.2.4
jupyterlab_pygments==0.3.0
jupyterlab_server==2.27.3
jupyterlab_widgets==3.0.11
keyring==24.3.0
kiwisolver==1.4.5
langchain==0.0.353
langchain-community==0.0.7
langchain-core==0.1.4
langsmith==0.0.75
Levenshtein==0.25.1
livereload==2.6.3
loguru==0.7.2
loguru-mypy==0.0.4
lxml==5.0.0
markdown-it-py==3.0.0
marshmallow==3.20.1
matplotlib==3.9.1
matplotlib-inline==0.1.7
mdit-py-plugins==0.4.0
mdurl==0.1.2
mistune==3.0.2
more-itertools==10.1.0
msal==1.30.0
msal-extensions==1.2.0
msgpack==1.0.8
msrest==0.7.1
multidict==6.0.4
mypy==1.10.0
mypy-extensions==1.0.0
myst-parser==2.0.0
nbclient==0.10.0
nbconvert==7.16.4
nbformat==5.10.4
ndindex==1.8
nest-asyncio==1.6.0
nh3==0.2.15
notebook==7.2.1
notebook_shim==0.2.4
numexpr==2.10.1
numpy==1.26.2
oauthlib==3.2.2
openai==1.6.1
overrides==7.7.0
packaging==23.2
pandarallel==1.6.5
pandas==2.1.4
pandocfilters==1.5.1
parso==0.8.4
pathspec==0.12.1
patsy==0.5.6
pexpect==4.9.0
pkginfo==1.9.6
platformdirs==4.1.0
pluggy==1.3.0
portalocker==2.10.1
prometheus_client==0.20.0
prompt_toolkit==3.0.47
psutil==6.0.0
ptyprocess==0.7.0
pure_eval==0.2.3
py-cpuinfo==9.0.0
pycparser==2.21
pydantic==2.5.3
pydantic-settings==2.1.0
pydantic_core==2.14.6
Pygments==2.17.2
PyJWT==2.8.0
PyMuPDF==1.24.9
PyMuPDFb==1.24.9
pyparsing==3.1.2
pypdf==3.17.4
pyproject_hooks==1.0.0
pytest==7.4.4
python-dateutil==2.8.2
python-dotenv==1.0.0
python-json-logger==2.0.7
python-Levenshtein==0.25.1
pytz==2023.3.post1
PyYAML==6.0.1
pyzmq==26.0.3
qtconsole==5.5.2
QtPy==2.4.1
rapidfuzz==3.9.5
readme-renderer==42.0
referencing==0.35.1
regex==2024.7.24
requests==2.31.0
requests-oauthlib==1.3.1
requests-toolbelt==1.0.0
rfc3339-validator==0.1.4
rfc3986==2.0.0
rfc3986-validator==0.1.1
rich==13.7.0
rpds-py==0.19.1
ruamel.yaml==0.18.5
ruamel.yaml.clib==0.2.8
ruff==0.4.5
scikit-learn==1.5.1
SecretStorage==3.3.3
semver==3.0.2
Send2Trash==1.8.3
setuptools-scm==8.0.4
sgmllib3k==1.0.0
shellingham==1.5.4
six==1.16.0
sniffio==1.3.0
snowballstemmer==2.2.0
soupsieve==2.5
Sphinx==7.2.6
sphinx-autobuild==2021.3.14
sphinx-basic-ng==1.0.0b2
sphinx-click==5.1.0
sphinx-togglebutton==0.3.2
sphinxcontrib-applehelp==1.0.7
sphinxcontrib-devhelp==1.0.5
sphinxcontrib-htmlhelp==2.0.4
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.6
sphinxcontrib-serializinghtml==1.1.9
SQLAlchemy==2.0.24
stack-data==0.6.3
statsmodels==0.14.2
tables==3.9.2
tabulate==0.9.0
tenacity==8.2.3
termcolor==2.4.0
terminado==0.18.1
threadpoolctl==3.5.0
tiktoken==0.7.0
tinycss2==1.3.0
toml-sort==0.23.1
tomli==2.0.1
tomlkit==0.12.3
tornado==6.4
tqdm==4.66.1
traitlets==5.14.3
tree-sitter==0.22.3
tree-sitter-python==0.21.0
twine==4.0.2
typer==0.9.0
types-psutil==6.0.0.20240621
types-python-dateutil==2.9.0.20240316
types-PyYAML==6.0.12.20240724
types-tqdm==4.66.0.20240417
typing-inspect==0.9.0
tzdata==2023.4
uri-template==1.3.0
urllib3==2.1.0
wcwidth==0.2.13
webcolors==24.6.0
webencodings==0.5.1
websocket-client==1.8.0
widgetsnbextension==4.0.11
yarl==1.9.4
zipp==3.17.0
dill==0.3.9
pillow==10.4.0
psutil==6.1.0
rich==13.9.2
scipy==1.14.1
tqdm==4.66.5
litellm==1.72.4
+7 -239
View File
@@ -1,240 +1,8 @@
aiohttp==3.9.1
aiosignal==1.3.1
alabaster==0.7.13
annotated-types==0.6.0
anyio==4.2.0
appdirs==1.4.4
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
asttokens==2.4.1
async-lru==2.0.4
attrs==23.2.0
autodoc-pydantic==2.0.1
azure-ai-formrecognizer==3.3.2
azure-common==1.1.28
azure-core==1.29.6
azure-identity==1.17.1
Babel==2.14.0
beautifulsoup4==4.12.2
black==23.12.1
bleach==6.1.0
blosc2==2.7.1
build==1.0.3
certifi==2023.11.17
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
colorama==0.4.6
comm==0.2.2
contourpy==1.2.1
coverage==7.4.0
cryptography==41.0.7
cycler==0.12.1
Cython==3.0.7
dataclasses-json==0.6.3
debugpy==1.8.2
decorator==5.1.1
defusedxml==0.7.1
dill==0.3.8
distro==1.9.0
docker==7.1.0
docutils==0.20.1
executing==2.0.1
fastjsonschema==2.20.0
feedparser==6.0.11
filelock==3.13.1
fire==0.5.0
fonttools==4.53.1
fqdn==1.5.1
frozenlist==1.4.1
fsspec==2023.12.2
furo==2023.9.10
fuzzywuzzy==0.18.0
git-changelog==2.4.0
greenlet==3.0.3
h11==0.14.0
httpcore==1.0.2
httpx==0.26.0
idna==3.6
imagesize==1.4.1
importlib-metadata==7.0.1
iniconfig==2.0.0
ipykernel==6.29.5
ipython==8.26.0
ipywidgets==8.1.3
isodate==0.6.1
isoduration==20.11.0
isort==5.13.2
jaraco.classes==3.3.0
jedi==0.19.1
jeepney==0.8.0
joblib==1.4.2
json5==0.9.25
jsonpatch==1.33
jsonpointer==2.4
jsonschema==4.23.0
jsonschema-specifications==2023.12.1
jupyter==1.0.0
jupyter-console==6.6.3
jupyter-events==0.10.0
jupyter-lsp==2.2.5
jupyter_client==8.6.2
jupyter_core==5.7.2
jupyter_server==2.14.2
jupyter_server_terminals==0.5.3
jupyterlab==4.2.4
jupyterlab_pygments==0.3.0
jupyterlab_server==2.27.3
jupyterlab_widgets==3.0.11
keyring==24.3.0
kiwisolver==1.4.5
langchain==0.0.353
langchain-community==0.0.7
langchain-core==0.1.4
langsmith==0.0.75
Levenshtein==0.25.1
livereload==2.6.3
loguru==0.7.2
loguru-mypy==0.0.4
lxml==5.0.0
markdown-it-py==3.0.0
marshmallow==3.20.1
matplotlib==3.9.1
matplotlib-inline==0.1.7
mdit-py-plugins==0.4.0
mdurl==0.1.2
mistune==3.0.2
more-itertools==10.1.0
msal==1.30.0
msal-extensions==1.2.0
msgpack==1.0.8
msrest==0.7.1
multidict==6.0.4
mypy==1.10.0
mypy-extensions==1.0.0
myst-parser==2.0.0
nbclient==0.10.0
nbconvert==7.16.4
nbformat==5.10.4
ndindex==1.8
nest-asyncio==1.6.0
nh3==0.2.15
notebook==7.2.1
notebook_shim==0.2.4
numexpr==2.10.1
numpy==1.26.2
oauthlib==3.2.2
openai==1.6.1
overrides==7.7.0
packaging==23.2
pandarallel==1.6.5
pandas==2.1.4
pandocfilters==1.5.1
parso==0.8.4
pathspec==0.12.1
patsy==0.5.6
pexpect==4.9.0
pkginfo==1.9.6
platformdirs==4.1.0
pluggy==1.3.0
portalocker==2.10.1
prometheus_client==0.20.0
prompt_toolkit==3.0.47
psutil==6.0.0
ptyprocess==0.7.0
pure_eval==0.2.3
py-cpuinfo==9.0.0
pycparser==2.21
pydantic==2.5.3
pydantic-settings==2.1.0
pydantic_core==2.14.6
Pygments==2.17.2
PyJWT==2.9.0
PyMuPDF==1.24.9
PyMuPDFb==1.24.9
pyparsing==3.1.2
pypdf==3.17.4
pyproject_hooks==1.0.0
pytest==7.4.4
python-dateutil==2.8.2
python-dotenv==1.0.0
python-json-logger==2.0.7
python-Levenshtein==0.25.1
pytz==2023.3.post1
PyYAML==6.0.1
pyzmq==26.0.3
qtconsole==5.5.2
QtPy==2.4.1
rapidfuzz==3.9.5
readme-renderer==42.0
referencing==0.35.1
regex==2024.7.24
requests==2.31.0
requests-oauthlib==1.3.1
requests-toolbelt==1.0.0
rfc3339-validator==0.1.4
rfc3986==2.0.0
rfc3986-validator==0.1.1
rich==13.7.0
rpds-py==0.19.1
ruamel.yaml==0.18.5
ruamel.yaml.clib==0.2.8
ruff==0.4.5
scikit-learn==1.5.1
SecretStorage==3.3.3
semver==3.0.2
Send2Trash==1.8.3
setuptools-scm==8.0.4
sgmllib3k==1.0.0
shellingham==1.5.4
six==1.16.0
sniffio==1.3.0
snowballstemmer==2.2.0
soupsieve==2.5
Sphinx==7.2.6
sphinx-autobuild==2021.3.14
sphinx-basic-ng==1.0.0b2
sphinx-click==5.1.0
sphinx-togglebutton==0.3.2
sphinxcontrib-applehelp==1.0.7
sphinxcontrib-devhelp==1.0.5
sphinxcontrib-htmlhelp==2.0.4
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.6
sphinxcontrib-serializinghtml==1.1.9
SQLAlchemy==2.0.24
stack-data==0.6.3
statsmodels==0.14.2
tables==3.9.2
tabulate==0.9.0
tenacity==8.2.3
termcolor==2.4.0
terminado==0.18.1
threadpoolctl==3.5.0
tiktoken==0.7.0
tinycss2==1.3.0
toml-sort==0.23.1
tomlkit==0.12.3
tornado==6.4
tqdm==4.66.1
traitlets==5.14.3
tree-sitter==0.22.3
tree-sitter-python==0.21.0
twine==4.0.2
typer==0.9.0
types-psutil==6.0.0.20240621
types-python-dateutil==2.9.0.20240316
types-PyYAML==6.0.12.20240724
types-tqdm==4.66.0.20240417
typing-inspect==0.9.0
tzdata==2023.4
uri-template==1.3.0
urllib3==2.1.0
wcwidth==0.2.13
webcolors==24.6.0
webencodings==0.5.1
websocket-client==1.8.0
widgetsnbextension==4.0.11
yarl==1.9.4
zipp==3.17.0
dill==0.3.9
pillow==10.4.0
psutil==6.1.0
rich==13.9.2
scipy==1.14.1
tqdm==4.66.5
litellm==1.72.4
Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

+332
View File
@@ -0,0 +1,332 @@
{
"alpha053_15": {
"description": "Reversal class factor, negative delta of a ratio involving close, low, and high prices over 15 days.",
"formulation": "-1 times Deltaleft(frac{(text{close} - text{low}) - (text{high} - text{close})}{text{close} - text{low}}, 15right)",
"variables": {
"Delta(x, d)": "Change in 'x' over 'd' days.",
"text{close}": "Closing price of the stock.",
"text{low}": "Lowest price of the stock for the day.",
"text{high}": "Highest price of the stock for the day."
},
"Category": "Volume&Price",
"Difficulty": "Easy",
"gt_code": "import pandas as pd\ndata_pv = pd.read_hdf('daily_pv.h5')\nnew_df= data_pv.reset_index()\n# Calculate Alpha053\nnew_df['ratio'] = (new_df['$close'] - new_df['$low'] - (new_df['$high'] - new_df['$close'])) / (new_df['$close'] - new_df['$low'])\n# the change of ratio in new_df over the 15 days\nnew_df['result']=-new_df['ratio'].diff(15)\n# transfer the result to series\nresult=pd.DataFrame(new_df['result']).set_index(data_pv.index)\nresult=result['result']\nresult.to_hdf('result.h5', key='data')"
},
"liquidity_imbalance": {
"description": "liquidity_imbalance=std(minute trading liquidity_imbalance)/mean(minute trading liquidity_imbalance).",
"formulation": "liquidity_imbalance = frac{text{std}(text{minute trading liquidity_imbalance})}{text{mean}(text{minute liquidity_imbalance})}",
"variables": {
"std(minute liquidity_imbalance)": "Standard deviation of trading liquidity_imbalance for each minute of the trading day.",
"mean(minute liquidity_imbalance)": "Mean of trading liquidity_imbalance for each minute of the trading day.",
"liquidity_imbalance": "(bid_size-ask_size)/(bid_size+ask_size), we use something like bidV for the size"
},
"Category": "High-Frequency",
"Difficulty": "Medium",
"gt_code": "import pandas as pd\ndata_hf = pd.read_hdf('high_freq.h5')\nsample_df= data_hf.reset_index()\n# Convert 'datetime' column to datetime and extract date for grouping\nsample_df['date'] = sample_df['datetime'].dt.date\nsample_df['liquidity_imbalance']=(sample_df['bidV']-sample_df['askV'])/(sample_df['bidV']+sample_df['askV'])\n# Group by instrument and date\ngrouped = sample_df.groupby(['date','instrument'])['liquidity_imbalance']\n# Calculate mean and standard deviation of the volume for each group\nstats = grouped.agg(['mean', 'std'])\n# Calculate Z value for each instrument per day\nstats['liquidity_imbalance'] = stats['std'] / stats['mean']\n# Display the calculated Z values\nresult=stats['liquidity_imbalance']\nresult.index.names = ['datetime','instrument']\n# result = result.swaplevel().sort_index()\nresult.to_hdf('result.h5', key='data')"
},
"liquidity_imbalance_2": {
"description": "liquidity_imbalance=std(minute trading liquidity_imbalance)/mean(minute trading liquidity_imbalance).",
"formulation": "liquidity_imbalance = frac{text{std}(text{minute trading liquidity_imbalance})}{text{mean}(text{minute liquidity_imbalance})}",
"variables": {
"std(minute liquidity_imbalance)": "Standard deviation of trading liquidity_imbalance for each minute of the trading day.",
"mean(minute liquidity_imbalance)": "Mean of trading liquidity_imbalance for each minute of the trading day.",
"liquidity_imbalance": "(bid_size-ask_size)/2*(bid_size+ask_size), we use something like bidV for the size"
},
"Category": "High-Frequency",
"Difficulty": "Medium",
"gt_code": "import pandas as pd\ndata_hf = pd.read_hdf('high_freq.h5')\nsample_df= data_hf.reset_index()\n# Convert 'datetime' column to datetime and extract date for grouping\nsample_df['date'] = sample_df['datetime'].dt.date\nsample_df['liquidity_imbalance']=(sample_df['bidV']-sample_df['askV'])/((sample_df['bidV']+sample_df['askV'])*2)\n# Group by instrument and date\ngrouped = sample_df.groupby(['date','instrument'])['liquidity_imbalance']\n# Calculate mean and standard deviation of the volume for each group\nstats = grouped.agg(['mean', 'std'])\n# Calculate Z value for each instrument per day\nstats['liquidity_imbalance'] = stats['std'] / stats['mean']\n# Display the calculated Z values\nresult=stats['liquidity_imbalance']\nresult.index.names = ['datetime','instrument']\n# result = result.swaplevel().sort_index()\nresult.to_hdf('result.h5', key='data')"
},
"liquidity_imbalance_3": {
"description": "liquidity_imbalance=std(minute trading liquidity_imbalance)/mean(minute trading liquidity_imbalance).",
"formulation": "liquidity_imbalance = frac{text{std}(text{minute trading liquidity_imbalance})}{text{mean}(text{minute liquidity_imbalance})}",
"variables": {
"std(minute liquidity_imbalance)": "Standard deviation of trading liquidity_imbalance for each minute of the trading day.",
"mean(minute liquidity_imbalance)": "Mean of trading liquidity_imbalance for each minute of the trading day.",
"liquidity_imbalance": "(bid_size-ask_size)/3*(bid_size+ask_size), we use something like bidV for the size"
},
"Category": "High-Frequency",
"Difficulty": "Medium",
"gt_code": "import pandas as pd\ndata_hf = pd.read_hdf('high_freq.h5')\nsample_df= data_hf.reset_index()\n# Convert 'datetime' column to datetime and extract date for grouping\nsample_df['date'] = sample_df['datetime'].dt.date\nsample_df['liquidity_imbalance']=(sample_df['bidV']-sample_df['askV'])/((sample_df['bidV']+sample_df['askV'])*3)\n# Group by instrument and date\ngrouped = sample_df.groupby(['date','instrument'])['liquidity_imbalance']\n# Calculate mean and standard deviation of the volume for each group\nstats = grouped.agg(['mean', 'std'])\n# Calculate Z value for each instrument per day\nstats['liquidity_imbalance'] = stats['std'] / stats['mean']\n# Display the calculated Z values\nresult=stats['liquidity_imbalance']\nresult.index.names = ['datetime','instrument']\n# result = result.swaplevel().sort_index()\nresult.to_hdf('result.h5', key='data')"
},
"micro_price": {
"description": "micro_price=std(minute trading micro_price)/mean(minute trading micro_price).",
"formulation": "micro_price = frac{text{std}(text{minute trading micro_price})}{text{mean}(text{minute micro_price})}",
"variables": {
"std(minute micro_price)": "Standard deviation of trading micro_price for each minute of the trading day.",
"mean(minute micro_price)": "Mean of trading micro_price for each minute of the trading day.",
"micro_price": "((df['bid_price'] * df['ask_size']) + (df['ask_price'] * df['bid_size'])) / (df['bid_size'] + df['ask_size'])"
},
"Category": "High-Frequency",
"Difficulty": "Hard",
"gt_code": "import pandas as pd\ndata_hf = pd.read_hdf('high_freq.h5')\nsample_df= data_hf.reset_index()\n# Convert 'datetime' column to datetime and extract date for grouping\nsample_df['date'] = sample_df['datetime'].dt.date\nsample_df['micro_price']=(sample_df['bid']*sample_df['askV']+sample_df['ask']*sample_df['bidV'])/(sample_df['bidV']+sample_df['askV'])\n# Group by instrument and date\ngrouped = sample_df.groupby(['date','instrument'])['micro_price']\n# Calculate mean and standard deviation of the volume for each group\nstats = grouped.agg(['mean', 'std'])\n# Calculate Z value for each instrument per day\nstats['micro_price'] = stats['std'] / stats['mean']\n# Display the calculated Z values\nresult=stats['micro_price']\nresult.index.names = ['datetime','instrument']\n# result = result.swaplevel().sort_index()\nresult.to_hdf('result.h5', key='data')"
},
"micro_price_2": {
"description": "micro_price_2=std(minute trading micro_price)/mean(minute trading micro_price).",
"formulation": "micro_price_2 = frac{text{std}(text{minute trading micro_price})}{text{mean}(text{minute micro_price})}",
"variables": {
"std(minute micro_price)": "Standard deviation of trading micro_price for each minute of the trading day.",
"mean(minute micro_price)": "Mean of trading micro_price for each minute of the trading day.",
"micro_price": "((df['bid_price'] * df['ask_size']) + (df['ask_price'] * df['bid_size'])) / 2*(df['bid_size'] + df['ask_size']), we use something like bidV for the size"
},
"Category": "High-Frequency",
"Difficulty": "Hard",
"gt_code": "import pandas as pd\ndata_hf = pd.read_hdf('high_freq.h5')\nsample_df= data_hf.reset_index()\n# Convert 'datetime' column to datetime and extract date for grouping\nsample_df['date'] = sample_df['datetime'].dt.date\nsample_df['micro_price']=(sample_df['bid']*sample_df['askV']+sample_df['ask']*sample_df['bidV'])/((sample_df['bidV']+sample_df['askV'])*2)\n# Group by instrument and date\ngrouped = sample_df.groupby(['date','instrument'])['micro_price']\n# Calculate mean and standard deviation of the volume for each group\nstats = grouped.agg(['mean', 'std'])\n# Calculate Z value for each instrument per day\nstats['micro_price'] = stats['std'] / stats['mean']\n# Display the calculated Z values\nresult=stats['micro_price']\nresult.index.names = ['datetime','instrument']\n# result = result.swaplevel().sort_index()\nresult.to_hdf('result.h5', key='data')"
},
"micro_price_3": {
"description": "micro_price_3=std(minute trading micro_price)/mean(minute trading micro_price).",
"formulation": "micro_price_3 = frac{text{std}(text{minute trading micro_price})}{text{mean}(text{minute micro_price})}",
"variables": {
"std(minute micro_price)": "Standard deviation of trading micro_price for each minute of the trading day.",
"mean(minute micro_price)": "Mean of trading micro_price for each minute of the trading day.",
"micro_price": "((df['bid_price'] * df['ask_size']) + (df['ask_price'] * df['bid_size'])) / 3*(df['bid_size'] + df['ask_size']), we use something like bidV for the size"
},
"Category": "High-Frequency",
"Difficulty": "Hard",
"gt_code": "import pandas as pd\ndata_hf = pd.read_hdf('high_freq.h5')\nsample_df= data_hf.reset_index()\n# Convert 'datetime' column to datetime and extract date for grouping\nsample_df['date'] = sample_df['datetime'].dt.date\nsample_df['micro_price']=(sample_df['bid']*sample_df['askV']+sample_df['ask']*sample_df['bidV'])/((sample_df['bidV']+sample_df['askV'])*3)\n# Group by instrument and date\ngrouped = sample_df.groupby(['date','instrument'])['micro_price']\n# Calculate mean and standard deviation of the volume for each group\nstats = grouped.agg(['mean', 'std'])\n# Calculate Z value for each instrument per day\nstats['micro_price'] = stats['std'] / stats['mean']\n# Display the calculated Z values\nresult=stats['micro_price']\nresult.index.names = ['datetime','instrument']\n# result = result.swaplevel().sort_index()\nresult.to_hdf('result.h5', key='data')"
},
"mid_price": {
"description": "mid_price=std(minute trading mid_price)/mean(minute trading mid_price).",
"formulation": "mid_price = frac{text{std}(text{minute trading mid price})}{text{mean}(text{minute mid price})}",
"variables": {
"std(minute mid_price)": "Standard deviation of trading mid_price for each minute of the trading day.",
"mean(minute mid_price)": "Mean of trading mid_price for each minute of the trading day.",
"mid_price": "The average of the bid and ask prices."
},
"Category": "High-Frequency",
"Difficulty": "Easy",
"gt_code": "import pandas as pd\ndata_hf = pd.read_hdf('high_freq.h5')\nsample_df= data_hf.reset_index()\n# Convert 'datetime' column to datetime and extract date for grouping\nsample_df['date'] = sample_df['datetime'].dt.date\nsample_df['mid_price']=(sample_df['bid']+sample_df['ask'])/2\n# Group by instrument and date\ngrouped = sample_df.groupby(['date','instrument'])['mid_price']\n# Calculate mean and standard deviation of the volume for each group\nstats = grouped.agg(['mean', 'std'])\nstats['mid_price'] = stats['std'] / stats['mean']\nresult=stats['mid_price']\nresult.index.names = ['datetime','instrument']\n# result = result.swaplevel().sort_index()\nresult.to_hdf('result.h5', key='data')"
},
"mid_price_2": {
"description": "mid_price=std(minute trading mid_price)/mean(minute trading mid_price).",
"formulation": "mid_price = frac{text{std}(text{minute trading mid price})}{text{mean}(text{minute mid price})}",
"variables": {
"std(minute mid_price)": "Standard deviation of trading mid_price for each minute of the trading day.",
"mean(minute mid_price)": "Mean of trading mid_price for each minute of the trading day.",
"mid_price_2": "the average of the bid and ask prices plus the the average of the bid and ask size (bidV and askV)."
},
"Category": "High-Frequency",
"Difficulty": "Easy",
"gt_code": "import pandas as pd\ndata_hf = pd.read_hdf('high_freq.h5')\nsample_df= data_hf.reset_index()\n# Convert 'datetime' column to datetime and extract date for grouping\nsample_df['date'] = sample_df['datetime'].dt.date\nsample_df['mid_price']=(sample_df['bid']+sample_df['ask'])/2+(sample_df['bidV']+sample_df['askV'])/2\n# Group by instrument and date\ngrouped = sample_df.groupby(['date','instrument'])['mid_price']\n# Calculate mean and standard deviation of the volume for each group\nstats = grouped.agg(['mean', 'std'])\nstats['mid_price'] = stats['std'] / stats['mean']\nresult=stats['mid_price']\nresult.index.names = ['datetime','instrument']\n# result = result.swaplevel().sort_index()\nresult.to_hdf('result.h5', key='data')"
},
"mid_price_3": {
"description": "mid_price=std(minute trading mid_price)/mean(minute trading mid_price).",
"formulation": "mid_price = frac{text{std}(text{minute trading mid price})}{text{mean}(text{minute mid price})}",
"variables": {
"std(minute mid_price)": "Standard deviation of trading mid_price for each minute of the trading day.",
"mean(minute mid_price)": "Mean of trading mid_price for each minute of the trading day.",
"mid_price_3": "The coefficient of variation (CV) of the mid-price for each minute of the trading day, calculated as the standard deviation of the mid-price divided by the mean mid-price."
},
"Category": "High-Frequency",
"Difficulty": "Easy",
"gt_code": "import pandas as pd\ndata_hf = pd.read_hdf('high_freq.h5')\nsample_df= data_hf.reset_index()\n# Convert 'datetime' column to datetime and extract date for grouping\nsample_df['date'] = sample_df['datetime'].dt.date\nsample_df['mid_price']=(sample_df['bid']+sample_df['ask'])/3\n# Group by instrument and date\ngrouped = sample_df.groupby(['date','instrument'])['mid_price']\n# Calculate mean and standard deviation of the volume for each group\nstats = grouped.agg(['mean', 'std'])\nstats['mid_price'] = stats['std'] / stats['mean']\nresult=stats['mid_price']\nresult.index.names = ['datetime','instrument']\n# result = result.swaplevel().sort_index()\nresult.to_hdf('result.h5', key='data')"
},
"PB_ROE": {
"description": "Constructed using the ranking difference between PB and ROE, with regression versions of PB and ROE replacing original PB and ROE to obtain reconstructed factor values.",
"formulation": "text{rank}(PB_t) - rank(ROE_t)",
"variables": {
"text{rank}(PB_t)": "Ranking of regression version PB on cross-section at time t.",
"text{rank}(ROE_t)": "Ranking of regression version single-quarter ROE on cross-section at time t."
},
"Category": "Fundamentals",
"Difficulty": "Easy",
"gt_code": "import pandas as pd\ndata_f = pd.read_hdf('daily_f.h5')\ndata = data_f.reset_index()\n# Calculate the rank of PB and ROE\ndata['PB_rank'] = data.groupby('datetime')['B/P'].rank()\ndata['ROE_rank'] = data.groupby('datetime')['ROE'].rank()\n# Calculate the difference between the ranks\ndata['PB_ROE'] = data['PB_rank'] - data['ROE_rank']\n# set the datetime and instrument as index and drop the original index\nresult=pd.DataFrame(data['PB_ROE']).set_index(data_f.index)\n# transfer the result to series\nresult=result['PB_ROE']\nresult.to_hdf('result.h5', key='data')"
},
"PB_ROE_2": {
"description": "Constructed using the ranking difference between PB/2 and ROE, with regression versions of PB and ROE replacing original PB and ROE to obtain reconstructed factor values.",
"formulation": "text{rank}(PB_t)/2 - rank(ROE_t)",
"variables": {
"text{rank}(PB_t)": "Ranking of regression version PB on cross-section at time t.",
"text{rank}(ROE_t)": "Ranking of regression version single-quarter ROE on cross-section at time t."
},
"Category": "Fundamentals",
"Difficulty": "Easy",
"gt_code": "import pandas as pd\ndata_f = pd.read_hdf('daily_f.h5')\ndata = data_f.reset_index()\n# Calculate the rank of PB and ROE\ndata['PB_rank'] = data.groupby('datetime')['B/P'].rank()\ndata['ROE_rank'] = data.groupby('datetime')['ROE'].rank()\n# Calculate the difference between the ranks\ndata['PB_ROE'] = data['PB_rank']/2 - data['ROE_rank']\n# set the datetime and instrument as index and drop the original index\nresult=pd.DataFrame(data['PB_ROE']).set_index(data_f.index)\n# transfer the result to series\nresult=result['PB_ROE']\nresult.to_hdf('result.h5', key='data')"
},
"PB_ROE_3": {
"description": "Constructed using the ranking difference between PB/3 and ROE, with regression versions of PB and ROE replacing original PB and ROE to obtain reconstructed factor values.",
"formulation": "text{rank}(PB_t)/3 - rank(ROE_t)",
"variables": {
"text{rank}(PB_t)": "Ranking of regression version PB on cross-section at time t.",
"text{rank}(ROE_t)": "Ranking of regression version single-quarter ROE on cross-section at time t."
},
"Category": "Fundamentals",
"Difficulty": "Easy",
"gt_code": "import pandas as pd\ndata_f = pd.read_hdf('daily_f.h5')\ndata = data_f.reset_index()\n# Calculate the rank of PB and ROE\ndata['PB_rank'] = data.groupby('datetime')['B/P'].rank()\ndata['ROE_rank'] = data.groupby('datetime')['ROE'].rank()\n# Calculate the difference between the ranks\ndata['PB_ROE'] = data['PB_rank']/3 - data['ROE_rank']\n# set the datetime and instrument as index and drop the original index\nresult=pd.DataFrame(data['PB_ROE']).set_index(data_f.index)\n# transfer the result to series\nresult=result['PB_ROE']\nresult.to_hdf('result.h5', key='data')"
},
"PB_ROE_movement": {
"description": "PB_ROE_movement=five day PB_ROE movement indicator(-1 and 1 or 0).",
"formulation": "PB_ROE_movement = 5_day_movement(PB_ROE), PB_ROE = text{rank}(PB_t) - rank(ROE_t)",
"variables": {
"PB_ROE": "the ranking difference between PB and ROE.",
"5_day_PB_ROE_movement": "1 if PB_ROE is higher than the PB_ROE 5 days ago, -1 if PB_ROE is lower than the PB_ROE 5 days ago, 0 if PB_ROE is the same as the PB_ROE 5 days ago.",
"text{rank}(PB_t)": "Ranking of regression version PB on cross-section at time t.",
"text{rank}(ROE_t)": "Ranking of regression version single-quarter ROE on cross-section at time t."
},
"Category": "Fundamentals",
"Difficulty": "Hard",
"gt_code": "import pandas as pd\ndata_f = pd.read_hdf('daily_f.h5')\nsample_df = data_f.reset_index()\n# Calculate the rank of PB and ROE\nsample_df['PB_rank'] = sample_df.groupby('datetime')['B/P'].rank()\nsample_df['ROE_rank'] = sample_df.groupby('datetime')['ROE'].rank()\nsample_df['PB_ROE'] = sample_df['PB_rank'] - sample_df['ROE_rank']\n# Group by instrument and date\nsample_df['PB_ROE_movement'] = sample_df['PB_ROE'].diff(periods=5).apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0))\n#calculate the mid_price_movement ratio for each day\n# set the datetime and instrument as index and drop the original index\nresult=pd.DataFrame(sample_df['PB_ROE_movement']).set_index(data_f.index)\n# transfer the result to series\nresult=result['PB_ROE_movement']\nresult.to_hdf('result.h5', key='data')"
},
"PB_ROE_movement_10": {
"description": "PB_ROE_movement=10 days PB_ROE movement indicator(-1 and 1 or 0).",
"formulation": "PB_ROE_movement = 10_day_movement(PB_ROE), PB_ROE = text{rank}(PB_t) - rank(ROE_t)",
"variables": {
"PB_ROE": "the ranking difference between PB and ROE.",
"10_day_PB_ROE_movement": "1 if PB_ROE is higher than the PB_ROE 10 days ago, -1 if PB_ROE is lower than the PB_ROE 10 days ago, 0 if PB_ROE is the same as the PB_ROE 10 days ago.",
"text{rank}(PB_t)": "Ranking of regression version PB on cross-section at time t.",
"text{rank}(ROE_t)": "Ranking of regression version single-quarter ROE on cross-section at time t."
},
"Category": "Fundamentals",
"Difficulty": "Hard",
"gt_code": "import pandas as pd\ndata_f = pd.read_hdf('daily_f.h5')\nsample_df = data_f.reset_index()\n# Calculate the rank of PB and ROE\nsample_df['PB_rank'] = sample_df.groupby('datetime')['B/P'].rank()\nsample_df['ROE_rank'] = sample_df.groupby('datetime')['ROE'].rank()\nsample_df['PB_ROE'] = sample_df['PB_rank'] - sample_df['ROE_rank']\n# Group by instrument and date\nsample_df['PB_ROE_movement'] = sample_df['PB_ROE'].diff(periods=10).apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0))\n#calculate the mid_price_movement ratio for each day\n# set the datetime and instrument as index and drop the original index\nresult=pd.DataFrame(sample_df['PB_ROE_movement']).set_index(data_f.index)\n# transfer the result to series\nresult=result['PB_ROE_movement']\nresult.to_hdf('result.h5', key='data')"
},
"PB_ROE_movement_20": {
"description": "PB_ROE_movement=20 days PB_ROE movement indicator(-1 and 1 or 0).",
"formulation": "PB_ROE_movement = 20_day_movement(PB_ROE), PB_ROE = text{rank}(PB_t) - rank(ROE_t)",
"variables": {
"PB_ROE": "the ranking difference between PB and ROE.",
"20_day_PB_ROE_movement": "1 if PB_ROE is higher than the PB_ROE 20 days ago, -1 if PB_ROE is lower than the PB_ROE 20 days ago, 0 if PB_ROE is the same as the PB_ROE 20 days ago.",
"text{rank}(PB_t)": "Ranking of regression version PB on cross-section at time t.",
"text{rank}(ROE_t)": "Ranking of regression version single-quarter ROE on cross-section at time t."
},
"Category": "Fundamentals",
"Difficulty": "Hard",
"gt_code": "import pandas as pd\ndata_f = pd.read_hdf('daily_f.h5')\nsample_df = data_f.reset_index()\n# Calculate the rank of PB and ROE\nsample_df['PB_rank'] = sample_df.groupby('datetime')['B/P'].rank()\nsample_df['ROE_rank'] = sample_df.groupby('datetime')['ROE'].rank()\nsample_df['PB_ROE'] = sample_df['PB_rank'] - sample_df['ROE_rank']\n# Group by instrument and date\nsample_df['PB_ROE_movement'] = sample_df['PB_ROE'].diff(periods=20).apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0))\n#calculate the mid_price_movement ratio for each day\n# set the datetime and instrument as index and drop the original index\nresult=pd.DataFrame(sample_df['PB_ROE_movement']).set_index(data_f.index)\n# transfer the result to series\nresult=result['PB_ROE_movement']\nresult.to_hdf('result.h5', key='data')"
},
"ROE_movement": {
"description": "ROE_movement=five day ROE movement indicator(-1 and 1 or 0).",
"formulation": "ROE_movement = 5_day_movement(ROE)",
"variables": {
"ROE": "ROE in fundamental statistics.",
"5_day_ROE_movement": "1 if ROE is higher than the ROE 5 days ago, -1 if ROE is lower than the ROE 5 days ago, 0 if ROE is the same as the ROE 5 days ago."
},
"Category": "Fundamentals",
"Difficulty": "Medium",
"gt_code": "import pandas as pd\ndata_f = pd.read_hdf('daily_f.h5')\nsample_df = data_f.reset_index()\n# Group by instrument and date\nsample_df['ROE_movement'] = sample_df['ROE'].diff(periods=5).apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0))\n#calculate the mid_price_movement ratio for each day\n# set the datetime and instrument as index and drop the original index\nresult=pd.DataFrame(sample_df['ROE_movement']).set_index(data_f.index)\n# transfer the result to series\nresult=result['ROE_movement']\nresult.to_hdf('result.h5', key='data')"
},
"ROE_movement_10": {
"description": "ROE_movement_10=ten day ROE movement indicator(-1 and 1 or 0).",
"formulation": "ROE_movement = 10_day_movement(ROE)",
"variables": {
"ROE": "ROE in fundamental statistics.",
"10_day_ROE_movement": "1 if ROE is higher than the ROE 10 days ago, -1 if ROE is lower than the ROE 10 days ago, 0 if ROE is the same as the ROE 10 days ago."
},
"Category": "Fundamentals",
"Difficulty": "Medium",
"gt_code": "import pandas as pd\ndata_f = pd.read_hdf('daily_f.h5')\nsample_df = data_f.reset_index()\n# Group by instrument and date\nsample_df['ROE_movement'] = sample_df['ROE'].diff(periods=10).apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0))\n#calculate the mid_price_movement ratio for each day\n# set the datetime and instrument as index and drop the original index\nresult=pd.DataFrame(sample_df['ROE_movement']).set_index(data_f.index)\n# transfer the result to series\nresult=result['ROE_movement']\nresult.to_hdf('result.h5', key='data')"
},
"ROE_movement_20": {
"description": "ROE_movement_20=20 day ROE movement indicator(-1 and 1 or 0).",
"formulation": "ROE_movement_20 = 20_day_movement(ROE)",
"variables": {
"ROE": "ROE in fundamental statistics.",
"20_day_ROE_movement": "1 if ROE is higher than the ROE 20 days ago, -1 if ROE is lower than the ROE 20 days ago, 0 if ROE is the same as the ROE 20 days ago."
},
"Category": "Fundamentals",
"Difficulty": "Medium",
"gt_code": "import pandas as pd\ndata_f = pd.read_hdf('daily_f.h5')\nsample_df = data_f.reset_index()\n# Group by instrument and date\nsample_df['ROE_movement'] = sample_df['ROE'].diff(periods=20).apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0))\n#calculate the mid_price_movement ratio for each day\n# set the datetime and instrument as index and drop the original index\nresult=pd.DataFrame(sample_df['ROE_movement']).set_index(data_f.index)\n# transfer the result to series\nresult=result['ROE_movement']\nresult.to_hdf('result.h5', key='data')"
},
"alpha_pv_diff": {
"description": "alpha_pv_diff is defined as the ratio of the difference between close prices 10 days change and open prices 10 days change to the sum of the highest minus lowest prices plus a small constant.",
"formulation": "frac{(text{close_diff10} - text{open_diff10})}{(text{high} - text{low} + 0.001)}",
"variables": {
"close": "Closing price of the stock",
"open": "Opening price of the stock",
"high": "Highest price of the stock during the day",
"low": "Lowest price of the stock during the day"
},
"Category": "Volume&Price",
"Difficulty": "Medium",
"gt_code": "import pandas as pd\ndata_pv = pd.read_hdf('daily_pv.h5')\nnew_df= data_pv.reset_index()\n# Calculate Alpha101\nnew_df['result'] = (new_df['$close'].diff(10) - new_df['$open'].diff(10)) / (new_df['$high'] - new_df['$low'] + 0.001)\n# keep the index of the original dataframe\nresult=pd.DataFrame(new_df['result']).set_index(data_pv.index)\n# transfer the result to series\nresult=result['result']\nresult.to_hdf('result.h5', key='data')"
},
"alpha_pv_diff_15": {
"description": "alpha_pv_diff is defined as the ratio of the difference between close prices 15 days change and open prices 15 days change to the sum of the highest minus lowest prices plus a small constant.",
"formulation": "frac{(text{close_diff15} - text{open_diff15})}{(text{high} - text{low} + 0.001)}",
"variables": {
"close": "Closing price of the stock",
"open": "Opening price of the stock",
"high": "Highest price of the stock during the day",
"low": "Lowest price of the stock during the day"
},
"Category": "Volume&Price",
"Difficulty": "Medium",
"gt_code": "import pandas as pd\ndata_pv = pd.read_hdf('daily_pv.h5')\nnew_df= data_pv.reset_index()\n# Calculate Alpha101\nnew_df['result'] = (new_df['$close'].diff(15) - new_df['$open'].diff(15)) / (new_df['$high'] - new_df['$low'] + 0.001)\n# keep the index of the original dataframe\nresult=pd.DataFrame(new_df['result']).set_index(data_pv.index)\n# transfer the result to series\nresult=result['result']\nresult.to_hdf('result.h5', key='data')"
},
"alpha_pv_diff_20": {
"description": "alpha_pv_diff is defined as the ratio of the difference between close prices 20 days change and open prices 20 days change to the sum of the highest minus lowest prices plus a small constant.",
"formulation": "frac{(text{close_diff20} - text{open_diff20})}{(text{high} - text{low} + 0.001)}",
"variables": {
"close": "Closing price of the stock",
"open": "Opening price of the stock",
"high": "Highest price of the stock during the day",
"low": "Lowest price of the stock during the day"
},
"Category": "Volume&Price",
"Difficulty": "Medium",
"gt_code": "import pandas as pd\ndata_pv = pd.read_hdf('daily_pv.h5')\nnew_df= data_pv.reset_index()\n# Calculate Alpha101\nnew_df['result'] = (new_df['$close'].diff(20) - new_df['$open'].diff(20)) / (new_df['$high'] - new_df['$low'] + 0.001)\n# keep the index of the original dataframe\nresult=pd.DataFrame(new_df['result']).set_index(data_pv.index)\n# transfer the result to series\nresult=result['result']\nresult.to_hdf('result.h5', key='data')"
},
"alpha_pv_diff_pct": {
"description": "alpha_pv is defined as the ratio of the difference between close prices 10 days change and open prices 10 days change to the sum of the highest prices 10 days change ratio minus lowest prices 10 days change ratio plus a small constant.",
"formulation": "frac{(text{close_diff10} - text{open_diff10})}{(text{high_pct10} - text{low_pct10} + 0.001)}",
"variables": {
"close": "Closing price of the stock",
"open": "Opening price of the stock",
"high": "Highest price of the stock during the day",
"low": "Lowest price of the stock during the day"
},
"Category": "Volume&Price",
"Difficulty": "Hard",
"gt_code": "import pandas as pd\ndata_pv = pd.read_hdf('daily_pv.h5')\nnew_df= data_pv.reset_index()\n# Calculate Alpha101\nnew_df['result'] = (new_df['$close'].diff(10) - new_df['$open'].diff(10)) / (new_df['$high'].pct_change(10) - new_df['$low'].pct_change(10) + 0.001)\n# keep the index of the original dataframe\nresult=pd.DataFrame(new_df['result']).set_index(data_pv.index)\n# transfer the result to series\nresult=result['result']\nresult.to_hdf('result.h5', key='data')"
},
"alpha_pv_diff_pct_15": {
"description": "alpha_pv is defined as the ratio of the difference between close prices 15 days change and open prices 15 days change to the sum of the highest prices 10 days change ratio minus lowest prices 10 days change ratio plus a small constant.",
"formulation": "frac{(text{close_diff15} - text{open_diff15})}{(text{high_pct10} - text{low_pct10} + 0.001)}",
"variables": {
"close": "Closing price of the stock",
"open": "Opening price of the stock",
"high": "Highest price of the stock during the day",
"low": "Lowest price of the stock during the day"
},
"Category": "Volume&Price",
"Difficulty": "Hard",
"gt_code": "import pandas as pd\ndata_pv = pd.read_hdf('daily_pv.h5')\nnew_df= data_pv.reset_index()\n# Calculate Alpha101\nnew_df['result'] = (new_df['$close'].diff(15) - new_df['$open'].diff(15)) / (new_df['$high'].pct_change(10) - new_df['$low'].pct_change(10) + 0.001)\n# keep the index of the original dataframe\nresult=pd.DataFrame(new_df['result']).set_index(data_pv.index)\n# transfer the result to series\nresult=result['result']\nresult.to_hdf('result.h5', key='data')"
},
"alpha_pv_diff_pct_20": {
"description": "alpha_pv is defined as the ratio of the difference between close prices 20 days change and open prices 20 days change to the sum of the highest prices 10 days change ratio minus lowest prices 10 days change ratio plus a small constant.",
"formulation": "frac{(text{close_diff20} - text{open_diff20})}{(text{high_pct10} - text{low_pct10} + 0.001)}",
"variables": {
"close": "Closing price of the stock",
"open": "Opening price of the stock",
"high": "Highest price of the stock during the day",
"low": "Lowest price of the stock during the day"
},
"Category": "Volume&Price",
"Difficulty": "Hard",
"gt_code": "import pandas as pd\ndata_pv = pd.read_hdf('daily_pv.h5')\nnew_df= data_pv.reset_index()\n# Calculate Alpha101\nnew_df['result'] = (new_df['$close'].diff(20) - new_df['$open'].diff(20)) / (new_df['$high'].pct_change(10) - new_df['$low'].pct_change(10) + 0.001)\n# keep the index of the original dataframe\nresult=pd.DataFrame(new_df['result']).set_index(data_pv.index)\n# transfer the result to series\nresult=result['result']\nresult.to_hdf('result.h5', key='data')"
},
"alpha053": {
"description": "Reversal class factor, negative delta of a ratio involving close, low, and high prices over 9 days.",
"formulation": "-1 times Deltaleft(frac{(text{close} - text{low}) - (text{high} - text{close})}{text{close} - text{low}}, 9right)",
"variables": {
"Delta(x, d)": "Change in 'x' over 'd' days.",
"text{close}": "Closing price of the stock.",
"text{low}": "Lowest price of the stock for the day.",
"text{high}": "Highest price of the stock for the day."
},
"Category": "Volume&Price",
"Difficulty": "Easy",
"gt_code": "import pandas as pd\ndata_pv = pd.read_hdf('daily_pv.h5')\nnew_df= data_pv.reset_index()\n# Calculate Alpha053\nnew_df['ratio'] = (new_df['$close'] - new_df['$low'] - (new_df['$high'] - new_df['$close'])) / (new_df['$close'] - new_df['$low'])\n# the change of ratio in new_df over the 9 days\nnew_df['result']=-new_df['ratio'].diff(9)\n# transfer the result to series\nresult=pd.DataFrame(new_df['result']).set_index(data_pv.index)\nresult=result['result']\nresult.to_hdf('result.h5', key='data')"
},
"alpha053_5": {
"description": "Reversal class factor, negative delta of a ratio involving close, low, and high prices over 5 days.",
"formulation": "-1 times Deltaleft(frac{(text{close} - text{low}) - (text{high} - text{close})}{text{close} - text{low}}, 5right)",
"variables": {
"Delta(x, d)": "Change in 'x' over 'd' days.",
"text{close}": "Closing price of the stock.",
"text{low}": "Lowest price of the stock for the day.",
"text{high}": "Highest price of the stock for the day."
},
"Category": "Volume&Price",
"Difficulty": "Easy",
"gt_code": "import pandas as pd\ndata_pv = pd.read_hdf('daily_pv.h5')\nnew_df= data_pv.reset_index()\n# Calculate Alpha053\nnew_df['ratio'] = (new_df['$close'] - new_df['$low'] - (new_df['$high'] - new_df['$close'])) / (new_df['$close'] - new_df['$low'])\n# the change of ratio in new_df over the 5 days\nnew_df['result']=-new_df['ratio'].diff(5)\n# transfer the result to series\nresult=pd.DataFrame(new_df['result']).set_index(data_pv.index)\nresult=result['result']\nresult.to_hdf('result.h5', key='data')"
}
}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 88 KiB

+115 -36
View File
@@ -11,13 +11,89 @@ Installation
- for dev users: `See development <development.html>`_
**Install Docker**: RDAgent is designed for research and development, acting like a human researcher and developer. It can write and run code in various environments, primarily using Docker for code execution. This keeps the remaining dependencies simple. Users must ensure Docker is installed before attempting most scenarios. Please refer to the `official 🐳Docker page <https://docs.docker.com/engine/install/>`_ for installation instructions.
Ensure the current user can run Docker commands **without using sudo**. You can verify this by executing `docker run hello-world`.
Configuration
=============
LiteLLM Backend Configuration (Default)
=======================================
Option 1: Unified API base for both models
------------------------------------------
.. code-block:: Properties
# Set to any model supported by LiteLLM.
CHAT_MODEL=gpt-4o
EMBEDDING_MODEL=text-embedding-3-small
# Configure unified API base
# The backend api_key fully follows the convention of litellm.
OPENAI_API_BASE=<your_unified_api_base>
OPENAI_API_KEY=<replace_with_your_openai_api_key>
Option 2: Separate API bases for Chat and Embedding models
----------------------------------------------------------
.. code-block:: Properties
# Set to any model supported by LiteLLM.
# CHAT MODEL:
CHAT_MODEL=gpt-4o
OPENAI_API_BASE=<your_chat_api_base>
OPENAI_API_KEY=<replace_with_your_openai_api_key>
# EMBEDDING MODEL:
# TAKE siliconflow as an example, you can use other providers.
# Note: embedding requires litellm_proxy prefix
EMBEDDING_MODEL=litellm_proxy/BAAI/bge-large-en-v1.5
LITELLM_PROXY_API_KEY=<replace_with_your_siliconflow_api_key>
LITELLM_PROXY_API_BASE=https://api.siliconflow.cn/v1
Necessary parameters include:
- `CHAT_MODEL`: The model name of the chat model.
- `EMBEDDING_MODEL`: The model name of the embedding model.
- `OPENAI_API_BASE`: The base URL of the API. If `EMBEDDING_MODEL` does not start with `litellm_proxy/`, this is used for both chat and embedding models; otherwise, it is used for `CHAT_MODEL` only.
Optional parameters (required if your embedding model is provided by a different provider than `CHAT_MODEL`):
- `LITELLM_PROXY_API_KEY`: The API key for the embedding model, required if `EMBEDDING_MODEL` starts with `litellm_proxy/`.
- `LITELLM_PROXY_API_BASE`: The base URL for the embedding model, required if `EMBEDDING_MODEL` starts with `litellm_proxy/`.
**Note:** If you are using an embedding model from a provider different from the chat model, remember to add the `litellm_proxy/` prefix to the `EMBEDDING_MODEL` name.
The `CHAT_MODEL` and `EMBEDDING_MODEL` parameters will be passed into LiteLLM's completion function.
Therefore, when utilizing models provided by different providers, first review the interface configuration of LiteLLM. The model names must match those allowed by LiteLLM.
Additionally, you need to set up the the additional parameters for the respective model provider, and the parameter names must align with those required by LiteLLM.
For example, if you are using a DeepSeek model, you need to set as follows:
.. code-block:: Properties
# For some models LiteLLM requires a prefix to the model name.
CHAT_MODEL=deepseek/deepseek-chat
DEEPSEEK_API_KEY=<replace_with_your_deepseek_api_key>
Besides, when you are using reasoning models, the response might include the thought process. For this case, you need to set the following environment variable:
.. code-block:: Properties
REASONING_THINK_RM=True
For more details on LiteLLM requirements, refer to the `official LiteLLM documentation <https://docs.litellm.ai/docs>`_.
Configuration(deprecated)
=========================
To run the application, please create a `.env` file in the root directory of the project and add environment variables according to your requirements.
The standard configuration options for the user using the OpenAI API are provided in the `.env.example` file.
If you are using this deprecated version, you should set `BACKEND` to `rdagent.oai.backend.DeprecBackend`.
Here are some other configuration options that you can use:
@@ -38,22 +114,23 @@ Azure OpenAI
The following environment variables are standard configuration options for the user using the OpenAI API.
.. code-block:: Properties
USE_AZURE=True
OPENAI_API_KEY=<replace_with_your_openai_api_key>
EMBEDDING_OPENAI_API_KEY=<replace_with_your_azure_openai_api_key>
EMBEDDING_AZURE_API_BASE= # The endpoint for the Azure OpenAI API.
EMBEDDING_AZURE_API_VERSION= # The version of the Azure OpenAI API.
EMBEDDING_MODEL=text-embedding-3-small
EMBEDDING_AZURE_API_BASE= # The base URL for the Azure OpenAI API.
EMBEDDING_AZURE_API_VERSION = # The version of the Azure OpenAI API.
CHAT_MODEL=gpt-4-turbo
CHAT_AZURE_API_VERSION = # The version of the Azure OpenAI API.
CHAT_OPENAI_API_KEY=<replace_with_your_azure_openai_api_key>
CHAT_AZURE_API_BASE= # The endpoint for the Azure OpenAI API.
CHAT_AZURE_API_VERSION= # The version of the Azure OpenAI API.
CHAT_MODEL= # The model name of the Azure OpenAI API.
Use Azure Token Provider
------------------------
If you are using the Azure token provider, you need to set the `USE_AZURE_TOKEN_PROVIDER` environment variable to `True`. then
If you are using the Azure token provider, you need to set the `CHAT_USE_AZURE_TOKEN_PROVIDER` and `EMBEDDING_USE_AZURE_TOKEN_PROVIDER` environment variable to `True`. then
use the environment variables provided in the `Azure Configuration section <installation_and_configuration.html#azure-openai>`_.
@@ -80,31 +157,33 @@ Configuration List
- OpenAI API Setting
+-----------------------------+--------------------------------------------------+-------------------------+
| Configuration Option | Meaning | Default Value |
+=============================+==================================================+=========================+
| OPENAI_API_KEY | API key for both chat and embedding models | None |
+-----------------------------+--------------------------------------------------+-------------------------+
| EMBEDDING_OPENAI_API_KEY | Use a different API key for embedding model | None |
+-----------------------------+--------------------------------------------------+-------------------------+
| CHAT_OPENAI_API_KEY | Set to use a different API key for chat model | None |
+-----------------------------+--------------------------------------------------+-------------------------+
| EMBEDDING_MODEL | Name of the embedding model | text-embedding-3-small |
+-----------------------------+--------------------------------------------------+-------------------------+
| CHAT_MODEL | Name of the chat model | gpt-4-turbo |
+-----------------------------+--------------------------------------------------+-------------------------+
| EMBEDDING_AZURE_API_BASE | Base URL for the Azure OpenAI API | None |
+-----------------------------+--------------------------------------------------+-------------------------+
| EMBEDDING_AZURE_API_VERSION | Version of the Azure OpenAI API | None |
+-----------------------------+--------------------------------------------------+-------------------------+
| CHAT_AZURE_API_BASE | Base URL for the Azure OpenAI API | None |
+-----------------------------+--------------------------------------------------+-------------------------+
| CHAT_AZURE_API_VERSION | Version of the Azure OpenAI API | None |
+-----------------------------+--------------------------------------------------+-------------------------+
| USE_AZURE | True if you are using Azure OpenAI | False |
+-----------------------------+--------------------------------------------------+-------------------------+
| USE_AZURE_TOKEN_PROVIDER | True if you are using a Azure Token Provider | False |
+-----------------------------+--------------------------------------------------+-------------------------+
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| Configuration Option | Meaning | Default Value |
+===================================+=================================================================+=========================+
| OPENAI_API_KEY | API key for both chat and embedding models | None |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| EMBEDDING_OPENAI_API_KEY | Use a different API key for embedding model | None |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| CHAT_OPENAI_API_KEY | Set to use a different API key for chat model | None |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| EMBEDDING_MODEL | Name of the embedding model | text-embedding-3-small |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| CHAT_MODEL | Name of the chat model | gpt-4-turbo |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| EMBEDDING_AZURE_API_BASE | Base URL for the Azure OpenAI API | None |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| EMBEDDING_AZURE_API_VERSION | Version of the Azure OpenAI API | None |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| CHAT_AZURE_API_BASE | Base URL for the Azure OpenAI API | None |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| CHAT_AZURE_API_VERSION | Version of the Azure OpenAI API | None |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| USE_AZURE | True if you are using Azure OpenAI | False |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| CHAT_USE_AZURE_TOKEN_PROVIDER | True if you are using an Azure Token Provider in chat model | False |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
| EMBEDDING_USE_AZURE_TOKEN_PROVIDER| True if you are using an Azure Token Provider in embedding model| False |
+-----------------------------------+-----------------------------------------------------------------+-------------------------+
- Globol Setting
+21 -30
View File
@@ -5,21 +5,12 @@ Benchmark
Introduction
=============
Benchmarking the capabilities of the R&D is a very important research problem of the research area.
Currently we are continuously exploring how to benchmark them.
The current benchmarks are listed in this page
Benchmarking the capabilities of R&D is a crucial research problem in this area. We are continuously exploring methods to benchmark these capabilities. The current benchmarks are listed on this page.
Development Capability Benchmarking
===================================
Benchmark is used to evaluate the effectiveness of factors with fixed data.
It mainly includes the following steps:
Benchmarking is used to evaluate the effectiveness of factors with fixed data. It mainly includes the following steps:
1. :ref:`read and prepare the eval_data <data>`
@@ -27,34 +18,31 @@ It mainly includes the following steps:
3. :ref:`declare the eval method and pass the arguments <config>`
4. :ref:`run the eval <run>`
4. :ref:`run the eval <run>`
5. :ref:`save and show the result <show>`
5. :ref:`save and show the result <show>`
Configuration
Configuration
-------------
.. _config:
.. autopydantic_settings:: rdagent.components.benchmark.conf.BenchmarkSettings
Example
++++++++
+++++++
.. _example:
The default value for ``bench_test_round`` is 10, and it will take about 2 hours to run 10 rounds.
To modify it from ``10`` to ``2`` you can adjust this by adding environment variables in the .env file as shown below.
The default value for ``bench_test_round`` is 10, which takes about 2 hours to run. To modify it from ``10`` to ``2``, adjust the environment variables in the .env file as shown below.
.. code-block:: Properties
BENCHMARK_BENCH_TEST_ROUND=1
BENCHMARK_BENCH_TEST_ROUND=2
Data Format
-------------
.. _data:
The sample data in ``bench_data_path`` is a dictionary where each key represents a factor name.
The value associated with each key is factor data containing the following information:
The sample data in ``bench_data_path`` is a dictionary where each key represents a factor name. The value associated with each key is factor data containing the following information:
- **description**: A textual description of the factor.
- **formulation**: A LaTeX formula representing the model's formulation.
@@ -63,22 +51,24 @@ The value associated with each key is factor data containing the following infor
- **Difficulty**: The difficulty level of implementing or understanding the factor.
- **gt_code**: A piece of code associated with the factor.
Here is the example of this data format:
Here is an example of this data format:
.. literalinclude:: ../../rdagent/components/benchmark/example.json
:language: json
Ensure the data is placed in the ``FACTOR_COSTEER_SETTINGS.data_folder_debug``. The data files should be in ``.h5`` or ``.md`` format and must not be stored in any subfolders. LLM-Agents will review the file content and implement the tasks.
.. TODO: Add a script to automatically generate the data in the `rdagent/app/quant_factor_benchmark/data` folder.
Run Benchmark
-------------
.. _run:
Start benchmark after finishing the :doc:`../installation_and_configuration`.
Start the benchmark after completing the :doc:`../installation_and_configuration`.
.. code-block:: Properties
python rdagent/app/quant_factor_benchmark/eval.py
dotenv run -- python rdagent/app/benchmark/factor/eval.py
Once completed, a pkl file will be generated, and its path will be printed on the last line of the console.
@@ -86,18 +76,16 @@ Show Result
-------------
.. _show:
The ``analysis.py`` script is used to read data from pkl and convert it to an image.
Modify the python code in ``rdagent/app/quant_factor_benchmark/analysis.py`` to specify the path to the pkl file and the output path for the png file.
The ``analysis.py`` script reads data from the pkl file and converts it to an image. Modify the Python code in ``rdagent/app/quant_factor_benchmark/analysis.py`` to specify the path to the pkl file and the output path for the png file.
.. code-block:: Properties
python rdagent/app/quant_factor_benchmark/analysis.py
dotenv run -- python rdagent/app/benchmark/factor/analysis.py <log/path to.pkl>
A png file will be saved to the designated path as shown below.
.. image:: ../_static/benchmark.png
Related Paper
-------------
@@ -116,3 +104,6 @@ Related Paper
}
.. image:: https://github.com/user-attachments/assets/494f55d3-de9e-4e73-ba3d-a787e8f9e841
To replicate the benchmark detailed in the paper, please consult the factors listed in the following file: `RD2bench.json <../_static/RD2bench.json>`_.
Please note use ``only_correct_format=False`` when evaluating the results.
+18 -19
View File
@@ -13,34 +13,33 @@ In the two key areas of data-driven scenarios, model implementation and data bui
The supported scenarios are listed below:
.. list-table::
.. list-table::
:header-rows: 1
* - Scenario/Target
- Model Implementation
- Data Building
* - 💹 Finance
- :ref:`🤖Iteratively Proposing Ideas & Evolving <model_agent_fin>`
- :ref:`🦾Auto reports reading & implementation <data_copilot_fin>`
- :ref:`🥇The First Data-Centric Quant Multi-Agent Framework <quant_agent_fin>`
- :ref:`🤖Iteratively Proposing Ideas & Evolving <model_agent_fin>`
:ref:`🦾Auto reports reading & implementation <data_copilot_fin>`
:ref:`🤖Iteratively Proposing Ideas & Evolving <data_agent_fin>`
* - 🩺 Medical
- :ref:`🤖Iteratively Proposing Ideas & Evolving <model_agent_med>`
-
* - 🏭 General
- :ref:`🦾Auto paper reading & implementation <model_copilot_general>`
-
- :ref:`🦾Auto paper reading & implementation <model_copilot_general>`
- :ref:`🤖 Data Science <data_science_agent>`
.. toctree::
:maxdepth: 1
:caption: Doctree:
:hidden:
data_agent_fin
data_copilot_fin
model_agent_fin
model_agent_med
model_copilot_general
:maxdepth: 1
:caption: Doctree:
:hidden:
quant_agent_fin
data_agent_fin
data_copilot_fin
model_agent_fin
model_copilot_general
data_science
+2 -2
View File
@@ -131,8 +131,8 @@ The following environment variables can be set in the `.env` file to customize t
:settings-show-field-summary: False
:exclude-members: Config
.. autopydantic_settings:: rdagent.components.coder.factor_coder.config.FactorImplementSettings
.. autopydantic_settings:: rdagent.components.coder.factor_coder.config.FactorCoSTEERSettings
:settings-show-field-summary: False
:members: coder_use_cache, data_folder, data_folder_debug, file_based_execution_timeout, select_method, select_threshold, max_loop, knowledge_base_path, new_knowledge_base_path
:members: coder_use_cache, data_folder, data_folder_debug, file_based_execution_timeout, select_method, max_loop, knowledge_base_path, new_knowledge_base_path
:exclude-members: Config, fail_task_trial_limit, v1_query_former_trace_limit, v1_query_similar_success_limit, v2_query_component_limit, v2_query_error_limit, v2_query_former_trace_limit, v2_error_summary, v2_knowledge_sampler
:no-index:
+2 -2
View File
@@ -157,8 +157,8 @@ The following environment variables can be set in the `.env` file to customize t
:show-inheritance:
:exclude-members: Config
.. autopydantic_settings:: rdagent.components.coder.factor_coder.config.FactorImplementSettings
.. autopydantic_settings:: rdagent.components.coder.factor_coder.config.FactorCoSTEERSettings
:settings-show-field-summary: False
:members: coder_use_cache, data_folder, data_folder_debug, file_based_execution_timeout, select_method, select_threshold, max_loop, knowledge_base_path, new_knowledge_base_path
:members: coder_use_cache, data_folder, data_folder_debug, file_based_execution_timeout, select_method, max_loop, knowledge_base_path, new_knowledge_base_path
:exclude-members: Config, python_bin, fail_task_trial_limit, v1_query_former_trace_limit, v1_query_similar_success_limit, v2_query_component_limit, v2_query_error_limit, v2_query_former_trace_limit, v2_error_summary, v2_knowledge_sampler
:no-index:
+184
View File
@@ -0,0 +1,184 @@
.. _data_science_agent:
=======================
Data Science Agent
=======================
**🤖 Automated Feature Engineering & Model Tuning Evolution**
------------------------------------------------------------------------------------------
The Data Science Agent is an agent that can automatically perform feature engineering and model tuning. It can be used to solve various data science problems, such as image classification, time series forecasting, and text classification.
🧭 Example Guide
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 🔧 **Set up RD-Agent Environment**
- Before you start, please make sure you have installed RD-Agent and configured the environment for RD-Agent correctly. If you want to know how to install and configure the RD-Agent, please refer to the `documentation <../installation_and_configuration.html>`_.
- 🔩 **Setting the Environment variables at .env file**
- Determine the path where the data will be stored and add it to the ``.env`` file.
.. code-block:: sh
dotenv set DS_LOCAL_DATA_PATH <your local directory>/ds_data
dotenv set DS_SCEN rdagent.scenarios.data_science.scen.DataScienceScen
- 📥 **Prepare Competition Data**
- Data Science competition data typically consists of three components: a competition description file (in Markdown format), the competition dataset, and evaluation scripts. For reference, an example of a custom user-defined dataset is provided in ``rdagent/scenarios/data_science/example``.
- **Correct directory structure (Here is an example of competition data with id custom_data)**
.. code-block:: text
ds_data
└── eval
| └── custom_data
| └── grade.py
| └── valid.py
| └── test.csv
└── custom_data
└── train.csv
└── test.csv
└── sample_submission.csv
└── description.md
└── sample.py
- ``ds_data/custom_data/train.csv:`` Necessary training data in csv or parquet format, or training images.
- ``ds_data/custom_data/description.md:`` (Optional) Competition description file.
- ``ds_data/custom_data/sample_submission.csv:`` (Optional) Competition sample submission file.
- ``ds_data/custom_data/sample.py:`` (Optional) Sample code for generating debug data from the competition dataset. If not provided, R&D-Agent will use its default sampling logic. For details, see the ``create_debug_data`` function in ``rdagent/scenarios/data_science/debug/data.py``.
- ``ds_data/eval/custom_data/grade.py:`` (Optional) Competition grade script, in order to calculate the score for the submission.
- ``ds_data/eval/custom_data/valid.py:`` (Optional) Competition validation script, in order to check if the submission format is correct.
- ``ds_data/eval/custom_data/submission_test.csv:`` (Optional) Competition test label file.
- 🔧 **Set up Environment for Custom User-defined Dataset**
.. code-block:: sh
dotenv set DS_SCEN rdagent.scenarios.data_science.scen.DataScienceScen
dotenv set DS_LOCAL_DATA_PATH rdagent/scenarios/data_science/example
dotenv set DS_IF_USING_MLE_DATA False
dotenv set DS_CODER_ON_WHOLE_PIPELINE True
dotenv set DS_CODER_COSTEER_ENV_TYPE docker
- 🚀 **Run the Application**
- You can directly run the application by using the following command:
.. code-block:: sh
rdagent data_science --competition <Competition ID>
- Then, you can run the test set score corresponding to each round of the loop.
.. code-block:: sh
dotenv run -- python rdagent/log/mle_summary.py grade <url_to_log>
Here, <url_to_log> refers to the parent directory of the log folder generated during the run.
- 📥 **Visualize the R&D Process**
- We provide a web UI to visualize the log. You just need to run:
.. code-block:: sh
streamlit run rdagent/log/ui/dsapp.py
- Then you can input the log path and visualize the R&D process.
🔍 MLE-bench Guide: Running ML Engineering via MLE-bench
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 📝 **MLE-bench Overview**
- MLE-bench is a comprehensive benchmark designed to evaluate the ML engineering capabilities of AI systems using real-world scenarios. The dataset comprises 75 Kaggle competitions. Since Kaggle does not provide held-out test sets for these competitions, the benchmark includes preparation scripts that split the publicly available training data into new training and test sets, and grading scripts are provided for each competition to accurately evaluate submission scores.
- 🔧 **Set up Environment for MLE-bench**
- Running R&D-Agent on MLE-bench is designed for full automation. There is no need for manual downloads and data preparation. Simply set the environment variable ``DS_IF_USING_MLE_DATA`` to True.
- At runtime, R&D-Agent will automatically build the Docker image specified at ``rdagent/scenarios/kaggle/docker/mle_bench_docker/Dockerfile``. This image is responsible for downloading the required datasets and grading files for MLE-bench.
- Note: The first run may take longer than subsequent runs as the Docker image and data are being downloaded and set up for the first time.
.. code-block:: sh
dotenv set DS_LOCAL_DATA_PATH <your local directory>/ds_data
dotenv set DS_IF_USING_MLE_DATA True
- 🔨 **Configuring the Kaggle API**
- Downloading Kaggle competition data requires the Kaggle API. You can set up the Kaggle API by following these steps:
- Register and login on the `Kaggle <https://www.kaggle.com/>`_ website.
- Click on the avatar (usually in the top right corner of the page) -> ``Settings`` -> ``Create New Token``, A file called ``kaggle.json`` will be downloaded.
- Move ``kaggle.json`` to ``~/.config/kaggle/``
- Modify the permissions of the ``kaggle.json`` file.
.. code-block:: sh
chmod 600 ~/.config/kaggle/kaggle.json
- For more information about Kaggle API Settings, refer to the `Kaggle API <https://github.com/Kaggle/kaggle-api>`_.
- 🔩 **Setting the Environment Variables for MLE-bench**
- In addition to auto-downloading the benchmark data, you must also configure the runtime environment for executing the competition code.
- Use the environment variable ``DS_CODER_COSTEER_ENV_TYPE`` to select the execution mode:
• When set to docker (the default), RD-Agent utilizes the official Kaggle Docker image (``gcr.io/kaggle-gpu-images/python:latest``) to ensure that all required packages are available.
• If you prefer to use a custom Docker setup, you can modify the configuration using ``DS_DOCKER_IMAGE`` or ``DS_DOCKERFILE_FOLDER_PATH``.
• Alternatively, if your competition work only demands basic libraries, you may set ``DS_CODER_COSTEER_ENV_TYPE`` to conda. In this mode, you must create a local conda environment named “kaggle” and pre-install the necessary packages. RD-Agent will execute the competition code within this “kaggle” conda environment.
.. code-block:: sh
# Configure the runtime environment: choice between 'docker' (default) or 'conda'
dotenv set DS_CODER_COSTEER_ENV_TYPE docker
- 🚀 **Run the Application**
- You can directly run the application by using the following command:
.. code-block:: sh
rdagent data_science --competition <Competition ID>
- 📥 **Visualize the R&D Process**
- We provide a web UI to visualize the log. You just need to run:
.. code-block:: sh
streamlit run rdagent/log/ui/dsapp.py
- Then you can input the log path and visualize the R&D process.
- **Additional Guidance**
- **Combine different LLM Models at R&D Stage**
- You can combine different LLM models at the R&D stage.
- By default, when you set environment variable ``CHAT_MODEL``, it covers both R&D stages. When customizing the model for the development stage, you can set:
.. code-block:: sh
# This example sets the model to "o3-mini". For some models, the reasoning effort shoule be set to "None".
dotenv set LITELLM_CHAT_MODEL_MAP '{"coding":{"model":"o3-mini","reasoning_effort":"high"},"running":{"model":"o3-mini","reasoning_effort":"high"}}'
Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

-128
View File
@@ -1,128 +0,0 @@
.. _model_agent_med:
=======================
Medical Model Agent
=======================
**🤖 Automated Medical Predtion Model Evolution**
------------------------------------------------------------------------------------------
📖 Background
~~~~~~~~~~~~~~
In this scenario, we consider the problem of risk prediction from patients' ICU monitoring data. We use the a public EHR dataset - MIMIC-III and extract a binary classification task for evaluating the framework.
In this task, we aim at predicting the whether the patients will suffer from Acute Respiratory Failure (ARF) based their first 12 hours ICU monitoring data.
🎥 `Demo <https://rdagent.azurewebsites.net/dmm>`_
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. raw:: html
<div style="display: flex; justify-content: center; align-items: center;">
<video width="600" controls>
<source src="https://rdagent.azurewebsites.net/media/1653542fc1b9fa14a306c35c1b1fc48288f980793f38abe82b023af9.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
🌟 Introduction
~~~~~~~~~~~~~~~~
In this scenario, our automated system proposes hypothesis, constructs model, implements code, receives back-testing, and uses feedbacks.
Hypothesis is iterated in this continuous process.
The system aims to automatically optimise performance metrics of medical prediction thereby finding the optimised code through autonomous research and development.
Here's an enhanced outline of the steps:
**Step 1 : Hypothesis Generation 🔍**
- Generate and propose initial hypotheses based on previous experiment analysis and domain expertise, with thorough reasoning and justification.
**Step 2 : Model Creation ✨**
- Transform the hypothesis into a model.
- Develop, define, and implement a machine learning model, including its name, description, and formulation.
**Step 3 : Model Implementation 👨‍💻**
- Implement the model code based on the detailed description.
- Evolve the model iteratively as a developer would, ensuring accuracy and efficiency.
**Step 4 : Backtesting with MIMIC-III 📉**
- Conduct backtesting using the newly developed model on the extracted task from MIMIC-III.
- Evaluate the model's effectiveness and performance in terms of AUROC score.
**Step 5 : Feedback Analysis 🔍**
- Analyze backtest results to assess performance.
- Incorporate feedback to refine hypotheses and improve the model.
**Step 6 :Hypothesis Refinement ♻️**
- Refine hypotheses based on feedback from backtesting.
- Repeat the process to continuously improve the model.
⚡ Quick Start
~~~~~~~~~~~~~~~~~
Please refer to the installation part in :doc:`../installation_and_configuration` to prepare your system dependency.
You can try our demo by running the following command:
- 🐍 Create a Conda Environment
- Create a new conda environment with Python (3.10 and 3.11 are well tested in our CI):
.. code-block:: sh
conda create -n rdagent python=3.10
- Activate the environment:
.. code-block:: sh
conda activate rdagent
- 📦 Install the RDAgent
- You can install the RDAgent package from PyPI:
.. code-block:: sh
pip install rdagent
- 📦 Request PhysioNet Account
- Apply for an account at `PhysioNet <https://physionet.org/>`_.
- Request access to FIDDLE preprocessed data: `FIDDLE Dataset <https://physionet.org/content/mimic-eicu-fiddle-feature/1.0.0/>`_.
- Place your username and password in `.env`.
.. code-block:: bash
cat << EOF >> .env
DM_USERNAME=<your_username>
DM_PASSWORD=<your_password>
EOF
- 🚀 Run the Application
- You can directly run the application by using the following command:
.. code-block:: sh
rdagent med_model
🛠️ Usage of modules
~~~~~~~~~~~~~~~~~~~~~
.. _Env Config:
- **Env Config**
The following environment variables can be set in the `.env` file to customize the application's behavior:
.. autopydantic_settings:: rdagent.app.data_mining.conf.MedBasePropSetting
:settings-show-field-summary: False
:exclude-members: Config
+113
View File
@@ -0,0 +1,113 @@
.. _quant_agent_fin:
=====================
Finance Quant Agent
=====================
**🥇The First Data-Centric Quant Multi-Agent Framework RD-Agent(Q)**
---------------------------------------------------------------------
R&D-Agent for Quantitative Finance, in short **RD-Agent(Q)**, is the first data-centric, multi-agent framework designed to automate the full-stack research and development of quantitative strategies via coordinated factor-model co-optimization.
You can learn more details about **RD-Agent(Q)** through the `paper <https://arxiv.org/abs/2505.15155>`_.
⚡ Quick Start
~~~~~~~~~~~~~~~~~
Before you start, please make sure you have installed RD-Agent and configured the environment for RD-Agent correctly. If you want to know how to install and configure the RD-Agent, please refer to the `documentation <../installation_and_configuration.html>`_.
Then, you can run the framework by running the following command:
- 🐍 Create a Conda Environment
- Create a new conda environment with Python (3.10 and 3.11 are well tested in our CI):
.. code-block:: sh
conda create -n rdagent python=3.10
- Activate the environment:
.. code-block:: sh
conda activate rdagent
- 📦 Install the RDAgent
- You can install the RDAgent package from PyPI:
.. code-block:: sh
pip install rdagent
- 🚀 Run the Application
- You can directly run the application by using the following command:
.. code-block:: sh
rdagent fin_quant
🛠️ Usage of modules
~~~~~~~~~~~~~~~~~~~~~
.. _Env Config:
- **Env Config**
The following environment variables can be set in the `.env` file to customize the application's behavior:
.. autopydantic_settings:: rdagent.app.qlib_rd_loop.conf.QuantBasePropSetting
:settings-show-field-summary: False
:exclude-members: Config
.. autopydantic_settings:: rdagent.components.coder.factor_coder.config.FactorCoSTEERSettings
:settings-show-field-summary: False
:members: coder_use_cache, data_folder, data_folder_debug, file_based_execution_timeout, select_method, max_loop, knowledge_base_path, new_knowledge_base_path
:exclude-members: Config, fail_task_trial_limit, v1_query_former_trace_limit, v1_query_similar_success_limit, v2_query_component_limit, v2_query_error_limit, v2_query_former_trace_limit, v2_error_summary, v2_knowledge_sampler
:no-index:
- **Qlib Configuration**
- The `.yaml` files in both the `model_template` and `factor_template` directories contain some configurations for running the corresponding models or factors within the Qlib framework. Below is an overview of their contents and roles:
- **General Settings**:
- **provider_uri**: Specifies the local Qlib data path, set to `~/.qlib/qlib_data/cn_data`.
- **market**: Configured to `csi300`, representing the CSI 300 index constituents.
- **benchmark**: Set to `SH000300`, used for backtesting evaluation.
- **Data Handling**:
- **start_time** and **end_time**: Define the full data range, from `2008-01-01` to `2022-08-01`.
- **fit_start_time**: The start date for fitting the model, set to `2008-01-01`.
- **fit_end_time**: The end date for fitting the model, set to `2014-12-31`.
- **features and labels**: Generated via a nested data loader combining `Alpha158DL` (for engineered features such as `RESI5`, `WVMA5`, `RSQR5`, `KLEN`, etc.) and a `StaticDataLoader` that loads precomputed factor files (`combined_factors_df.parquet`).
- **normalization**: The pipeline includes `RobustZScoreNorm` (with clipping) and `Fillna` for inference, and `DropnaLabel` with `CSZScoreNorm` for training.
- **Training Configuration**:
- **Model**: Uses `GeneralPTNN`, a PyTorch-based neural network model.
- **Dataset Splits**:
- **train**: `2008-01-01` to `2014-12-31`
- **valid**: `2015-01-01` to `2016-12-31`
- **test**: `2017-01-01` to `2020-08-01`
- **Default Hyperparameters** (can be overridden by command-line arguments):
- **n_epochs**: `100`
- **lr**: `2e-4`
- **early_stop**: `10`
- **batch_size**: `256`
- **weight_decay**: `0.0`
- **metric**: `loss`
- **loss**: `mse`
- **n_jobs**: `20`
- **GPU**: `0` (uses GPU 0 if available)
- **Backtesting and Evaluation**:
- **strategy**: `TopkDropoutStrategy`, which selects the top 50 stocks and randomly drops 5 to introduce exploration.
- **backtest period**: `2017-01-01` to `2020-08-01`
- **initial capital**: `100,000,000`
- **cost configuration**: Includes open/close costs, minimum transaction costs, and slippage control.
- **Recording and Analysis**:
- **SignalRecord**: Logs predicted signals.
- **SigAnaRecord**: Performs signal analysis without long-short separation.
- **PortAnaRecord**: Conducts portfolio analysis using the configured strategy and backtest settings.
+1
View File
@@ -38,6 +38,7 @@ Use Web App
- Qlib Factor
- Data Mining
- Model from Paper
- Kaggle
3. Click the `Config⚙️` button and input the log path (if you set the log_dir parameter, you can select a log_path in the dropdown list).
+6 -2
View File
@@ -61,6 +61,10 @@ explicit_package_bases = true
warn_return_any = true
warn_unused_ignores = true
[[tool.mypy.overrides]]
ignore_missing_imports = true
module = "llama"
[tool.pytest.ini_options]
addopts = "-l -s --durations=0"
log_cli = true
@@ -77,10 +81,10 @@ src = ["rdagent"]
[tool.ruff.lint]
ignore = [
# https://docs.astral.sh/ruff/rules/#pydocstyle-d
"ANN101",
"ANN401",
"D",
"ERA001",
"EXE002",
"FIX",
"INP001",
"PGH",
@@ -88,7 +92,7 @@ ignore = [
"S101",
"S301",
"T20",
"TCH003",
"TC003",
"TD",
]
select = ["ALL"]
+39 -24
View File
@@ -13,9 +13,10 @@ from rdagent.components.benchmark.eval_method import FactorImplementEval
class BenchmarkAnalyzer:
def __init__(self, settings):
def __init__(self, settings, only_correct_format=False):
self.settings = settings
self.index_map = self.load_index_map()
self.only_correct_format = only_correct_format
def load_index_map(self):
index_map = {}
@@ -82,12 +83,12 @@ class BenchmarkAnalyzer:
for i in x:
order_v.append(
{
"avg. Run successful rate": 0,
"avg. Format successful rate": 1,
"avg. Correlation (value only)": 2,
"max. Correlation": 3,
"max. accuracy": 4,
"avg. accuracy": 5,
"Avg Run SR": 0,
"Avg Format SR": 1,
"Avg Correlation": 2,
"Max Correlation": 3,
"Max Accuracy": 4,
"Avg Accuracy": 5,
}.get(i, i),
)
return order_v
@@ -119,11 +120,13 @@ class BenchmarkAnalyzer:
format_succ_rate_f = self.reformat_index(format_succ_rate)
corr = sum_df_clean["FactorCorrelationEvaluator"].fillna(0.0)
corr = corr.unstack().T.mean(axis=0).to_frame("corr(only success)")
corr_res = self.reformat_index(corr)
corr_max = sum_df_clean["FactorCorrelationEvaluator"]
if self.only_correct_format:
corr = corr.loc[format_issue == 1.0]
corr_max = corr_max.unstack().T.max(axis=0).to_frame("corr(only success)")
corr_res = corr.unstack().T.mean(axis=0).to_frame("corr(only success)")
corr_res = self.reformat_index(corr_res)
corr_max = corr.unstack().T.max(axis=0).to_frame("corr(only success)")
corr_max_res = self.reformat_index(corr_max)
value_max = sum_df_clean["FactorEqualValueRatioEvaluator"]
@@ -140,19 +143,25 @@ class BenchmarkAnalyzer:
result_all = pd.concat(
{
"avg. Correlation (value only)": corr_res.iloc[:, 0],
"avg. Format successful rate": format_succ_rate_f.iloc[:, 0],
"avg. Run successful rate": succ_rate_f.iloc[:, 0],
"max. Correlation": corr_max_res.iloc[:, 0],
"max. accuracy": value_max_res.iloc[:, 0],
"avg. accuracy": value_avg_res.iloc[:, 0],
"Avg Correlation": corr_res.iloc[:, 0],
"Avg Format SR": format_succ_rate_f.iloc[:, 0],
"Avg Run SR": succ_rate_f.iloc[:, 0],
"Max Correlation": corr_max_res.iloc[:, 0],
"Max Accuracy": value_max_res.iloc[:, 0],
"Avg Accuracy": value_avg_res.iloc[:, 0],
},
axis=1,
)
df = result_all.sort_index(axis=1, key=self.result_all_key_order)
df = result_all.sort_index(axis=1, key=self.result_all_key_order).sort_index(axis=0)
print(df)
print()
print(df.groupby("Category").mean())
print()
print(df.mean())
# Calculate the mean of each column
mean_values = df.fillna(0.0).mean()
mean_df = pd.DataFrame(mean_values).T
@@ -179,11 +188,16 @@ class Plotter:
@staticmethod
def plot_data(data, file_name, title):
plt.figure(figsize=(10, 6))
sns.barplot(x="index", y="b", hue="a", data=data)
plt.xlabel("Method")
plt.figure(figsize=(10, 10))
plt.ylabel("Value")
plt.title(title)
colors = ["#3274A1", "#E1812C", "#3A923A", "#C03D3E"]
plt.bar(data["a"], data["b"], color=colors, capsize=5)
for idx, row in data.iterrows():
plt.text(idx, row["b"] + 0.01, f"{row['b']:.2f}", ha="center", va="bottom")
plt.suptitle(title, y=0.98)
plt.xticks(rotation=45)
plt.ylim(0, 1)
plt.tight_layout()
plt.savefig(file_name)
@@ -191,9 +205,10 @@ def main(
path="git_ignore_folder/eval_results/res_promptV220240724-060037.pkl",
round=1,
title="Comparison of Different Methods",
only_correct_format=False,
):
settings = BenchmarkSettings()
benchmark = BenchmarkAnalyzer(settings)
benchmark = BenchmarkAnalyzer(settings, only_correct_format=only_correct_format)
results = {
f"{round} round experiment": path,
}
@@ -201,7 +216,7 @@ def main(
final_results_df = pd.DataFrame(final_results)
Plotter.change_fs(20)
plot_data = final_results_df.drop(["max. accuracy", "avg. accuracy"], axis=0).T
plot_data = final_results_df.drop(["Max Accuracy", "Avg Accuracy"], axis=0).T
plot_data = plot_data.reset_index().melt("index", var_name="a", value_name="b")
Plotter.plot_data(plot_data, "./comparison_plot.png", title)
+2 -9
View File
@@ -1,16 +1,9 @@
import os
import pickle
import time
from pathlib import Path
from pprint import pprint
from rdagent.app.qlib_rd_loop.conf import FACTOR_PROP_SETTING
from rdagent.components.benchmark.conf import BenchmarkSettings
from rdagent.components.benchmark.eval_method import FactorImplementEval
from rdagent.core.scenario import Scenario
from rdagent.core.utils import import_class
from rdagent.log import rdagent_logger as logger
from rdagent.scenarios.qlib.experiment.factor_experiment import QlibFactorScenario
from rdagent.scenarios.qlib.factor_experiment_loader.json_loader import (
FactorTestCaseLoaderFromJsonFile,
)
@@ -25,7 +18,7 @@ if __name__ == "__main__":
# 3.declare the method to be tested and pass the arguments.
scen: Scenario = import_class(FACTOR_PROP_SETTING.scen)()
generate_method = import_class(bs.bench_method_cls)(scen=scen)
generate_method = import_class(bs.bench_method_cls)(scen=scen, **bs.bench_method_extra_kwargs)
# 4.declare the eval method and pass the arguments.
eval_method = FactorImplementEval(
method=generate_method,
@@ -36,7 +29,7 @@ if __name__ == "__main__":
)
# 5.run the eval
res = eval_method.eval()
res = eval_method.eval(eval_method.develop())
# 6.save the result
logger.log_object(res)
+2 -2
View File
@@ -1,6 +1,6 @@
from pathlib import Path
from rdagent.components.coder.model_coder.CoSTEER import ModelCoSTEER
from rdagent.components.coder.model_coder import ModelCoSTEER
from rdagent.components.loader.task_loader import ModelTaskLoaderJson, ModelWsLoader
from rdagent.scenarios.qlib.experiment.model_experiment import (
QlibModelExperiment,
@@ -13,7 +13,7 @@ if __name__ == "__main__":
from rdagent.components.coder.model_coder.benchmark.eval import ModelImpValEval
from rdagent.components.coder.model_coder.one_shot import ModelCodeWriter
bench_folder = DIRNAME.parent.parent / "components" / "coder" / "model_coder" / "benchmark"
bench_folder = DIRNAME.parent.parent.parent / "components" / "coder" / "model_coder" / "benchmark"
mtl = ModelTaskLoaderJson(str(bench_folder / "model_dict.json"))
task_l = mtl.load()
+17 -6
View File
@@ -1,10 +1,11 @@
"""
CLI entrance for all rdagent application.
This will
This will
- make rdagent a nice entry and
- autoamtically load dotenv
"""
from dotenv import load_dotenv
load_dotenv(".env")
@@ -16,18 +17,19 @@ from importlib.resources import path as rpath
import fire
from rdagent.app.data_mining.model import main as med_model
from rdagent.app.data_science.loop import main as data_science
from rdagent.app.general_model.general_model import (
extract_models_and_implement as general_model,
)
from rdagent.app.kaggle.loop import main as kaggle_main
from rdagent.app.qlib_rd_loop.factor import main as fin_factor
from rdagent.app.qlib_rd_loop.factor_from_report import main as fin_factor_report
from rdagent.app.qlib_rd_loop.model import main as fin_model
from rdagent.app.qlib_rd_loop.quant import main as fin_quant
from rdagent.app.utils.health_check import health_check
from rdagent.app.utils.info import collect_info
def ui(port=80, log_dir="", debug=False):
def ui(port=19899, log_dir="", debug=False):
"""
start web app to show the log traces.
"""
@@ -42,16 +44,25 @@ def ui(port=80, log_dir="", debug=False):
subprocess.run(cmds)
def server_ui(port=19899):
"""
start web app to show the log traces in real time
"""
subprocess.run(["python", "rdagent/log/server/app.py", f"--port={port}"])
def app():
fire.Fire(
{
"fin_factor": fin_factor,
"fin_factor_report": fin_factor_report,
"fin_model": fin_model,
"med_model": med_model,
"fin_quant": fin_quant,
"general_model": general_model,
"ui": ui,
"health_check": health_check,
"collect_info": collect_info,
"kaggle": kaggle_main,
"data_science": data_science,
"server_ui": server_ui,
}
)
-49
View File
@@ -1,49 +0,0 @@
from pathlib import Path
from pydantic_settings import BaseSettings
from rdagent.components.workflow.conf import BasePropSetting
class MedBasePropSetting(BasePropSetting):
class Config:
env_prefix = "DM_"
"""Use `DM_` as prefix for environment variables"""
protected_namespaces = ()
"""Add 'model_' to the protected namespaces"""
# 1) overriding the default
scen: str = "rdagent.scenarios.data_mining.experiment.model_experiment.DMModelScenario"
"""Scenario class for data mining model"""
hypothesis_gen: str = "rdagent.scenarios.data_mining.proposal.model_proposal.DMModelHypothesisGen"
"""Hypothesis generation class"""
hypothesis2experiment: str = "rdagent.scenarios.data_mining.proposal.model_proposal.DMModelHypothesis2Experiment"
"""Hypothesis to experiment class"""
coder: str = "rdagent.scenarios.data_mining.developer.model_coder.DMModelCoSTEER"
"""Coder class"""
runner: str = "rdagent.scenarios.data_mining.developer.model_runner.DMModelRunner"
"""Runner class"""
summarizer: str = "rdagent.scenarios.data_mining.developer.feedback.DMModelHypothesisExperiment2Feedback"
"""Summarizer class"""
evolving_n: int = 10
"""Number of evolutions"""
evolving_n: int = 10
# 2) Extra config for the scenario
# physionet account
# NOTE: You should apply the account in https://physionet.org/
username: str = ""
"""Physionet account username"""
password: str = ""
"""Physionet account password"""
MED_PROP_SETTING = MedBasePropSetting()
-31
View File
@@ -1,31 +0,0 @@
import fire
from rdagent.app.data_mining.conf import MED_PROP_SETTING
from rdagent.components.workflow.rd_loop import RDLoop
from rdagent.core.exception import ModelEmptyError
class ModelRDLoop(RDLoop):
skip_loop_error = (ModelEmptyError,)
def main(path=None, step_n=None):
"""
Auto R&D Evolving loop for models in a medical scenario.
You can continue running session by
.. code-block:: python
dotenv run -- python rdagent/app/data_mining/model.py $LOG_PATH/__session__/1/0_propose --step_n 1 # `step_n` is a optional paramter
"""
if path is None:
model_loop = ModelRDLoop(MED_PROP_SETTING)
else:
model_loop = ModelRDLoop.load(path)
model_loop.run(step_n=step_n)
if __name__ == "__main__":
fire.Fire(main)
+115
View File
@@ -0,0 +1,115 @@
from typing import Literal
from pydantic_settings import SettingsConfigDict
from rdagent.app.kaggle.conf import KaggleBasePropSetting
class DataScienceBasePropSetting(KaggleBasePropSetting):
# TODO: Kaggle Setting should be the subclass of DataScience
model_config = SettingsConfigDict(env_prefix="DS_", protected_namespaces=())
# Main components
## Scen
scen: str = "rdagent.scenarios.data_science.scen.KaggleScen"
"""
Scenario class for data science tasks.
- For Kaggle competitions, use: "rdagent.scenarios.data_science.scen.KaggleScen"
- For custom data science scenarios, use: "rdagent.scenarios.data_science.scen.DataScienceScen"
"""
hypothesis_gen: str = "rdagent.scenarios.data_science.proposal.exp_gen.proposal.DSProposalV2ExpGen"
"""Hypothesis generation class"""
## Workflow Related
consecutive_errors: int = 5
## Coding Related
coding_fail_reanalyze_threshold: int = 3
debug_timeout: int = 600
"""The timeout limit for running on debugging data"""
full_timeout: int = 3600
"""The timeout limit for running on full data"""
### specific feature
#### enable specification
spec_enabled: bool = True
#### proposal related
proposal_version: str = "v1"
coder_on_whole_pipeline: bool = False
max_trace_hist: int = 3
coder_max_loop: int = 10
runner_max_loop: int = 1
rule_base_eval: bool = False
sample_data: bool = True
use_raw_description: bool = False
show_nan_columns: bool = False
#### model dump
enable_model_dump: bool = False
enable_doc_dev: bool = False
model_dump_check_level: Literal["medium", "high"] = "medium"
### knowledge base
enable_knowledge_base: bool = False
knowledge_base_version: str = "v1"
knowledge_base_path: str | None = None
idea_pool_json_path: str | None = None
### archive log folder after each loop
enable_log_archive: bool = True
log_archive_path: str | None = None
log_archive_temp_path: str | None = (
None # This is to store the mid tar file since writing the tar file is preferred in local storage then copy to target storage
)
#### Evaluation on Test related
eval_sub_dir: str = "eval" # TODO: fixme, this is not a good name
"""We'll use f"{DS_RD_SETTING.local_data_path}/{DS_RD_SETTING.eval_sub_dir}/{competition}"
to find the scriipt to evaluate the submission on test"""
"""---below are the settings for multi-trace---"""
### multi-trace related
max_trace_num: int = 3
"""The maximum number of traces to grow before merging"""
#### multi-trace:checkpoint selector
selector_name: str = "rdagent.scenarios.data_science.proposal.exp_gen.ckp_select.LatestCKPSelector"
"""The name of the selector to use"""
sota_count_window: int = 5
"""The number of trials to consider for SOTA count"""
sota_count_threshold: int = 1
"""The threshold for SOTA count"""
#### multi-trace: SOTA experiment selector
sota_exp_selector_name: str = "rdagent.scenarios.data_science.proposal.exp_gen.sota_exp_select.GlobalSOTASelector"
"""The name of the SOTA experiment selector to use"""
### multi-trace:inject optimals for multi-trace
# inject diverse when start a new sub-trace
enable_inject_diverse: bool = False
# inject knowledge at the root of the trace
enable_inject_knowledge_at_root: bool = False
# enable different version of DSExpGen for multi-trace
enable_multi_version_exp_gen: bool = False
exp_gen_version_list: str = "v3,v2"
#### multi-trace: time for final multi-trace merge
merge_hours: int = 2
"""The time for merge"""
#### multi-trace: max SOTA-retrieved number, used in AutoSOTAexpSelector
# constrains the number of SOTA experiments to retrieve, otherwise too many SOTA experiments to retrieve will cause the exceed of the context window of LLM
max_sota_retrieved_num: int = 10
"""The maximum number of SOTA experiments to retrieve in a LLM call"""
DS_RD_SETTING = DataScienceBasePropSetting()
+6
View File
@@ -0,0 +1,6 @@
import fire
from rdagent.scenarios.data_science.debug.data import create_debug_data
if __name__ == "__main__":
fire.Fire(create_debug_data)
+74
View File
@@ -0,0 +1,74 @@
import asyncio
from pathlib import Path
import fire
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.core.utils import import_class
from rdagent.log import rdagent_logger as logger
from rdagent.scenarios.data_science.loop import DataScienceRDLoop
def main(
path: str | None = None,
checkout: bool | str | Path = True,
step_n: int | None = None,
loop_n: int | None = None,
competition="bms-molecular-translation",
timeout=None,
replace_timer=True,
exp_gen_cls: str | None = None,
):
"""
Parameters
----------
path :
A path like `$LOG_PATH/__session__/1/0_propose`. This indicates that we restore the state after finishing step 0 in loop 1.
checkout :
Used only when a path is provided.
Can be True, False, or a path.
Default is True.
- If True, the new loop will use the existing folder and clear logs for sessions after the one corresponding to the given path.
- If False, the new loop will use the existing folder but keep the logs for sessions after the one corresponding to the given path.
- If a path (or a str like Path) is provided, the new loop will be saved to that path, leaving the original path unchanged.
step_n :
Number of steps to run; if None, the process will run indefinitely until an error or KeyboardInterrupt occurs.
loop_n :
Number of loops to run; if None, the process will run indefinitely until an error or KeyboardInterrupt occurs.
- If the current loop is incomplete, it will be counted as the first loop for completion.
- If both step_n and loop_n are provided, the process will stop as soon as either condition is met.
competition :
Competition name.
replace_timer :
If a session is loaded, determines whether to replace the timer with session.timer.
exp_gen_cls :
When there are different stages, the exp_gen can be replaced with the new proposal.
Auto R&D Evolving loop for models in a Kaggle scenario.
You can continue running a session by using the command:
.. code-block:: bash
dotenv run -- python rdagent/app/data_science/loop.py [--competition titanic] $LOG_PATH/__session__/1/0_propose --step_n 1 # `step_n` is an optional parameter
rdagent kaggle --competition playground-series-s4e8 # This command is recommended.
"""
if competition is not None:
DS_RD_SETTING.competition = competition
if not DS_RD_SETTING.competition:
logger.error("Please specify competition name.")
if path is None:
kaggle_loop = DataScienceRDLoop(DS_RD_SETTING)
else:
kaggle_loop: DataScienceRDLoop = DataScienceRDLoop.load(path, checkout=checkout, replace_timer=replace_timer)
# replace exp_gen if we have new class
if exp_gen_cls is not None:
kaggle_loop.exp_gen = import_class(exp_gen_cls)(kaggle_loop.exp_gen.scen)
asyncio.run(kaggle_loop.run(step_n=step_n, loop_n=loop_n, all_duration=timeout))
if __name__ == "__main__":
fire.Fire(main)
+9 -13
View File
@@ -30,19 +30,15 @@ def extract_models_and_implement(report_file_path: str) -> None:
Returns:
None
"""
with logger.tag("init"):
scenario = GeneralModelScenario()
logger.log_object(scenario, tag="scenario")
with logger.tag("r"):
# Save Relevant Images
img = extract_first_page_screenshot_from_pdf(report_file_path)
logger.log_object(img, tag="pdf_image")
exp = ModelExperimentLoaderFromPDFfiles().load(report_file_path)
logger.log_object(exp, tag="load_experiment")
with logger.tag("d"):
exp = QlibModelCoSTEER(scenario).develop(exp)
logger.log_object(exp, tag="developed_experiment")
return exp
scenario = GeneralModelScenario()
logger.log_object(scenario, tag="scenario")
# Save Relevant Images
img = extract_first_page_screenshot_from_pdf(report_file_path)
logger.log_object(img, tag="pdf_image")
exp = ModelExperimentLoaderFromPDFfiles().load(report_file_path)
logger.log_object(exp, tag="load_experiment")
exp = QlibModelCoSTEER(scenario).develop(exp)
logger.log_object(exp, tag="developed_experiment")
if __name__ == "__main__":
+31 -24
View File
@@ -1,28 +1,15 @@
from pathlib import Path
from pydantic_settings import SettingsConfigDict
from pydantic_settings import BaseSettings
from rdagent.components.workflow.conf import BasePropSetting
from rdagent.core.conf import ExtendedBaseSettings
class KaggleBasePropSetting(BasePropSetting):
class Config:
env_prefix = "KG_"
"""Use `KG_` as prefix for environment variables"""
protected_namespaces = ()
"""Do not allow overriding of these namespaces"""
class KaggleBasePropSetting(ExtendedBaseSettings):
model_config = SettingsConfigDict(env_prefix="KG_", protected_namespaces=())
# 1) overriding the default
scen: str = "rdagent.scenarios.kaggle.experiment.scenario.KGScenario"
"""Scenario class for data mining model"""
knowledge_base: str = "" # TODO enable this line to use the knowledge base
# knowledge_base: str = "rdagent.scenarios.kaggle.knowledge_management.graph.KGKnowledgeGraph"
"""Knowledge base class"""
knowledge_base_path: str = "kg_graph.pkl"
"""Knowledge base path"""
hypothesis_gen: str = "rdagent.scenarios.kaggle.proposal.proposal.KGHypothesisGen"
"""Hypothesis generation class"""
@@ -44,29 +31,49 @@ class KaggleBasePropSetting(BasePropSetting):
model_runner: str = "rdagent.scenarios.kaggle.developer.runner.KGModelRunner"
"""Model Runner class"""
summarizer: str = "rdagent.scenarios.kaggle.developer.feedback.KGHypothesisExperiment2Feedback"
summarizer: str = "rdagent.scenarios.kaggle.developer.feedback.KGExperiment2Feedback"
"""Summarizer class"""
evolving_n: int = 10
"""Number of evolutions"""
competition: str = ""
"""Kaggle competition name, e.g., 'sf-crime'"""
local_data_path: str = "/data/userdata/share/kaggle"
template_path: str = "rdagent/scenarios/kaggle/experiment/templates"
"""Kaggle competition base templates path"""
local_data_path: str = ""
"""Folder storing Kaggle competition data"""
# Evaluation on Test related
if_using_mle_data: bool = False
auto_submit: bool = False
"""Automatically upload and submit each experiment result to Kaggle platform"""
# Conditionally set the knowledge_base based on the use of graph RAG
knowledge_base: str = ""
"""Knowledge base class, uses 'KGKnowledgeGraph' when advanced graph-based RAG is enabled, otherwise empty."""
if_action_choosing_based_on_UCB: bool = False
"""Enable decision mechanism based on UCB algorithm"""
domain_knowledge_path: str = "/data/userdata/share/kaggle/domain_knowledge"
"""Folder storing domain knowledge files in .case format"""
rag_path: str = "git_ignore_folder/rag"
knowledge_base_path: str = "kg_graph.pkl"
"""Advanced version of graph-based RAG"""
if_action_choosing_based_on_UCB: bool = False
if_using_graph_rag: bool = False
rag_path: str = "git_ignore_folder/kaggle_vector_base.pkl"
"""Base version of vector-based RAG"""
if_using_vector_rag: bool = False
"""Enable basic vector-based RAG"""
auto_submit: bool = True
if_using_graph_rag: bool = False
"""Enable advanced graph-based RAG"""
mini_case: bool = False
"""Enable mini-case study for experiments"""
KAGGLE_IMPLEMENT_SETTING = KaggleBasePropSetting()
+80 -83
View File
@@ -1,5 +1,4 @@
import subprocess
from collections import defaultdict
from typing import Any
import fire
@@ -8,17 +7,15 @@ from rdagent.app.kaggle.conf import KAGGLE_IMPLEMENT_SETTING
from rdagent.components.workflow.conf import BasePropSetting
from rdagent.components.workflow.rd_loop import RDLoop
from rdagent.core.developer import Developer
from rdagent.core.exception import FactorEmptyError, ModelEmptyError
from rdagent.core.exception import CoderError, FactorEmptyError, ModelEmptyError
from rdagent.core.proposal import (
Experiment2Feedback,
Hypothesis2Experiment,
HypothesisExperiment2Feedback,
HypothesisGen,
Trace,
)
from rdagent.core.scenario import Scenario
from rdagent.core.utils import import_class
from rdagent.log import rdagent_logger as logger
from rdagent.log.time import measure_time
from rdagent.scenarios.kaggle.experiment.scenario import (
KG_ACTION_FEATURE_ENGINEERING,
KG_ACTION_FEATURE_PROCESSING,
@@ -30,92 +27,88 @@ from rdagent.scenarios.kaggle.proposal.proposal import KGTrace
class KaggleRDLoop(RDLoop):
@measure_time
def __init__(self, PROP_SETTING: BasePropSetting):
with logger.tag("init"):
scen: Scenario = import_class(PROP_SETTING.scen)(PROP_SETTING.competition)
logger.log_object(scen, tag="scenario")
knowledge_base = (
import_class(PROP_SETTING.knowledge_base)(PROP_SETTING.knowledge_base_path, scen)
if PROP_SETTING.knowledge_base != ""
else None
)
logger.log_object(knowledge_base, tag="knowledge_base")
self.hypothesis_gen: HypothesisGen = import_class(PROP_SETTING.hypothesis_gen)(scen)
logger.log_object(self.hypothesis_gen, tag="hypothesis generator")
self.hypothesis2experiment: Hypothesis2Experiment = import_class(PROP_SETTING.hypothesis2experiment)()
logger.log_object(self.hypothesis2experiment, tag="hypothesis2experiment")
self.feature_coder: Developer = import_class(PROP_SETTING.feature_coder)(scen)
logger.log_object(self.feature_coder, tag="feature coder")
self.model_feature_selection_coder: Developer = import_class(PROP_SETTING.model_feature_selection_coder)(
scen
)
logger.log_object(self.model_feature_selection_coder, tag="model feature selection coder")
self.model_coder: Developer = import_class(PROP_SETTING.model_coder)(scen)
logger.log_object(self.model_coder, tag="model coder")
self.feature_runner: Developer = import_class(PROP_SETTING.feature_runner)(scen)
logger.log_object(self.feature_runner, tag="feature runner")
self.model_runner: Developer = import_class(PROP_SETTING.model_runner)(scen)
logger.log_object(self.model_runner, tag="model runner")
self.summarizer: HypothesisExperiment2Feedback = import_class(PROP_SETTING.summarizer)(scen)
logger.log_object(self.summarizer, tag="summarizer")
self.trace = KGTrace(scen=scen, knowledge_base=knowledge_base)
super(RDLoop, self).__init__()
scen: Scenario = import_class(PROP_SETTING.scen)(PROP_SETTING.competition)
logger.log_object(scen, tag="scenario")
knowledge_base = (
import_class(PROP_SETTING.knowledge_base)(PROP_SETTING.knowledge_base_path, scen)
if PROP_SETTING.knowledge_base != ""
else None
)
logger.log_object(knowledge_base, tag="knowledge_base")
self.hypothesis_gen: HypothesisGen = import_class(PROP_SETTING.hypothesis_gen)(scen)
logger.log_object(self.hypothesis_gen, tag="hypothesis generator")
self.hypothesis2experiment: Hypothesis2Experiment = import_class(PROP_SETTING.hypothesis2experiment)()
logger.log_object(self.hypothesis2experiment, tag="hypothesis2experiment")
self.feature_coder: Developer = import_class(PROP_SETTING.feature_coder)(scen)
logger.log_object(self.feature_coder, tag="feature coder")
self.model_feature_selection_coder: Developer = import_class(PROP_SETTING.model_feature_selection_coder)(scen)
logger.log_object(self.model_feature_selection_coder, tag="model feature selection coder")
self.model_coder: Developer = import_class(PROP_SETTING.model_coder)(scen)
logger.log_object(self.model_coder, tag="model coder")
self.feature_runner: Developer = import_class(PROP_SETTING.feature_runner)(scen)
logger.log_object(self.feature_runner, tag="feature runner")
self.model_runner: Developer = import_class(PROP_SETTING.model_runner)(scen)
logger.log_object(self.model_runner, tag="model runner")
self.summarizer: Experiment2Feedback = import_class(PROP_SETTING.summarizer)(scen)
logger.log_object(self.summarizer, tag="summarizer")
self.trace = KGTrace(scen=scen, knowledge_base=knowledge_base)
super(RDLoop, self).__init__()
@measure_time
def coding(self, prev_out: dict[str, Any]):
with logger.tag("d"): # develop
if prev_out["propose"].action in [KG_ACTION_FEATURE_ENGINEERING, KG_ACTION_FEATURE_PROCESSING]:
exp = self.feature_coder.develop(prev_out["exp_gen"])
elif prev_out["propose"].action == KG_ACTION_MODEL_FEATURE_SELECTION:
exp = self.model_feature_selection_coder.develop(prev_out["exp_gen"])
else:
exp = self.model_coder.develop(prev_out["exp_gen"])
logger.log_object(exp.sub_workspace_list, tag="coder result")
if prev_out["direct_exp_gen"]["propose"].action in [
KG_ACTION_FEATURE_ENGINEERING,
KG_ACTION_FEATURE_PROCESSING,
]:
exp = self.feature_coder.develop(prev_out["direct_exp_gen"]["exp_gen"])
elif prev_out["direct_exp_gen"]["propose"].action == KG_ACTION_MODEL_FEATURE_SELECTION:
exp = self.model_feature_selection_coder.develop(prev_out["direct_exp_gen"]["exp_gen"])
else:
exp = self.model_coder.develop(prev_out["direct_exp_gen"]["exp_gen"])
logger.log_object(exp.sub_workspace_list, tag="coder result")
return exp
@measure_time
def running(self, prev_out: dict[str, Any]):
with logger.tag("ef"): # evaluate and feedback
if prev_out["propose"].action in [KG_ACTION_FEATURE_ENGINEERING, KG_ACTION_FEATURE_PROCESSING]:
exp = self.feature_runner.develop(prev_out["coding"])
else:
exp = self.model_runner.develop(prev_out["coding"])
logger.log_object(exp, tag="runner result")
if KAGGLE_IMPLEMENT_SETTING.competition in [
"optiver-realized-volatility-prediction",
"covid19-global-forecasting-week-1",
]:
try:
python_files_to_notebook(
KAGGLE_IMPLEMENT_SETTING.competition, exp.experiment_workspace.workspace_path
)
except Exception as e:
logger.error(f"Merge python files to one file failed: {e}")
if KAGGLE_IMPLEMENT_SETTING.auto_submit:
csv_path = exp.experiment_workspace.workspace_path / "submission.csv"
try:
subprocess.run(
[
"kaggle",
"competitions",
"submit",
"-f",
str(csv_path.absolute()),
"-m",
str(csv_path.parent.absolute()),
KAGGLE_IMPLEMENT_SETTING.competition,
],
check=True,
)
except subprocess.CalledProcessError as e:
logger.error(f"Auto submission failed: \n{e}")
except Exception as e:
logger.error(f"Other exception when use kaggle api:\n{e}")
if prev_out["direct_exp_gen"]["propose"].action in [
KG_ACTION_FEATURE_ENGINEERING,
KG_ACTION_FEATURE_PROCESSING,
]:
exp = self.feature_runner.develop(prev_out["coding"])
else:
exp = self.model_runner.develop(prev_out["coding"])
logger.log_object(exp, tag="runner result")
if KAGGLE_IMPLEMENT_SETTING.competition in [
"optiver-realized-volatility-prediction",
"covid19-global-forecasting-week-1",
]:
try:
python_files_to_notebook(KAGGLE_IMPLEMENT_SETTING.competition, exp.experiment_workspace.workspace_path)
except Exception as e:
logger.error(f"Merge python files to one file failed: {e}")
if KAGGLE_IMPLEMENT_SETTING.auto_submit:
csv_path = exp.experiment_workspace.workspace_path / "submission.csv"
try:
subprocess.run(
[
"kaggle",
"competitions",
"submit",
"-f",
str(csv_path.absolute()),
"-m",
str(csv_path.parent.absolute()),
KAGGLE_IMPLEMENT_SETTING.competition,
],
check=True,
)
except subprocess.CalledProcessError as e:
logger.error(f"Auto submission failed: \n{e}")
except Exception as e:
logger.error(f"Other exception when use kaggle api:\n{e}")
return exp
skip_loop_error = (ModelEmptyError, FactorEmptyError)
skip_loop_error = (ModelEmptyError, FactorEmptyError, CoderError)
def main(path=None, step_n=None, competition=None):
@@ -128,7 +121,11 @@ def main(path=None, step_n=None, competition=None):
"""
if competition:
KAGGLE_IMPLEMENT_SETTING.competition = competition
download_data(competition=competition, local_path=KAGGLE_IMPLEMENT_SETTING.local_data_path)
download_data(competition=competition, settings=KAGGLE_IMPLEMENT_SETTING)
if KAGGLE_IMPLEMENT_SETTING.if_using_graph_rag:
KAGGLE_IMPLEMENT_SETTING.knowledge_base = (
"rdagent.scenarios.kaggle.knowledge_management.graph.KGKnowledgeGraph"
)
else:
logger.error("Please specify competition name.")
if path is None:
+52 -13
View File
@@ -1,14 +1,10 @@
from pydantic_settings import BaseSettings
from pydantic_settings import SettingsConfigDict
from rdagent.components.workflow.conf import BasePropSetting
class ModelBasePropSetting(BasePropSetting):
class Config:
env_prefix = "QLIB_MODEL_"
"""Use `QLIB_MODEL_` as prefix for environment variables"""
protected_namespaces = ()
"""Add 'model_' to the protected namespaces"""
model_config = SettingsConfigDict(env_prefix="QLIB_MODEL_", protected_namespaces=())
# 1) override base settings
scen: str = "rdagent.scenarios.qlib.experiment.model_experiment.QlibModelScenario"
@@ -26,7 +22,7 @@ class ModelBasePropSetting(BasePropSetting):
runner: str = "rdagent.scenarios.qlib.developer.model_runner.QlibModelRunner"
"""Runner class"""
summarizer: str = "rdagent.scenarios.qlib.developer.feedback.QlibModelHypothesisExperiment2Feedback"
summarizer: str = "rdagent.scenarios.qlib.developer.feedback.QlibModelExperiment2Feedback"
"""Summarizer class"""
evolving_n: int = 10
@@ -34,11 +30,7 @@ class ModelBasePropSetting(BasePropSetting):
class FactorBasePropSetting(BasePropSetting):
class Config:
env_prefix = "QLIB_FACTOR_"
"""Use `QLIB_FACTOR_` as prefix for environment variables"""
protected_namespaces = ()
"""Add 'factor_' to the protected namespaces"""
model_config = SettingsConfigDict(env_prefix="QLIB_FACTOR_", protected_namespaces=())
# 1) override base settings
scen: str = "rdagent.scenarios.qlib.experiment.factor_experiment.QlibFactorScenario"
@@ -56,7 +48,7 @@ class FactorBasePropSetting(BasePropSetting):
runner: str = "rdagent.scenarios.qlib.developer.factor_runner.QlibFactorRunner"
"""Runner class"""
summarizer: str = "rdagent.scenarios.qlib.developer.feedback.QlibFactorHypothesisExperiment2Feedback"
summarizer: str = "rdagent.scenarios.qlib.developer.feedback.QlibFactorExperiment2Feedback"
"""Summarizer class"""
evolving_n: int = 10
@@ -75,7 +67,54 @@ class FactorFromReportPropSetting(FactorBasePropSetting):
max_factors_per_exp: int = 10000
"""Maximum number of factors implemented per experiment"""
report_limit: int = 10000
"""Maximum number of reports to process"""
class QuantBasePropSetting(BasePropSetting):
model_config = SettingsConfigDict(env_prefix="QLIB_QUANT_", protected_namespaces=())
# 1) override base settings
scen: str = "rdagent.scenarios.qlib.experiment.quant_experiment.QlibQuantScenario"
"""Scenario class for Qlib Model"""
quant_hypothesis_gen: str = "rdagent.scenarios.qlib.proposal.quant_proposal.QlibQuantHypothesisGen"
"""Hypothesis generation class"""
model_hypothesis2experiment: str = "rdagent.scenarios.qlib.proposal.model_proposal.QlibModelHypothesis2Experiment"
"""Hypothesis to experiment class"""
model_coder: str = "rdagent.scenarios.qlib.developer.model_coder.QlibModelCoSTEER"
"""Coder class"""
model_runner: str = "rdagent.scenarios.qlib.developer.model_runner.QlibModelRunner"
"""Runner class"""
model_summarizer: str = "rdagent.scenarios.qlib.developer.feedback.QlibModelExperiment2Feedback"
"""Summarizer class"""
factor_hypothesis2experiment: str = (
"rdagent.scenarios.qlib.proposal.factor_proposal.QlibFactorHypothesis2Experiment"
)
"""Hypothesis to experiment class"""
factor_coder: str = "rdagent.scenarios.qlib.developer.factor_coder.QlibFactorCoSTEER"
"""Coder class"""
factor_runner: str = "rdagent.scenarios.qlib.developer.factor_runner.QlibFactorRunner"
"""Runner class"""
factor_summarizer: str = "rdagent.scenarios.qlib.developer.feedback.QlibFactorExperiment2Feedback"
"""Summarizer class"""
evolving_n: int = 10
"""Number of evolutions"""
action_selection: str = "bandit"
"""Action selection strategy: 'bandit' for bandit-based selection, 'llm' for LLM-based selection, 'random' for random selection"""
FACTOR_PROP_SETTING = FactorBasePropSetting()
FACTOR_FROM_REPORT_PROP_SETTING = FactorFromReportPropSetting()
MODEL_PROP_SETTING = ModelBasePropSetting()
QUANT_PROP_SETTING = QuantBasePropSetting()
+9 -11
View File
@@ -2,6 +2,7 @@
Factor workflow with session control
"""
import asyncio
from typing import Any
import fire
@@ -10,24 +11,21 @@ from rdagent.app.qlib_rd_loop.conf import FACTOR_PROP_SETTING
from rdagent.components.workflow.rd_loop import RDLoop
from rdagent.core.exception import FactorEmptyError
from rdagent.log import rdagent_logger as logger
from rdagent.log.time import measure_time
class FactorRDLoop(RDLoop):
skip_loop_error = (FactorEmptyError,)
@measure_time
def running(self, prev_out: dict[str, Any]):
with logger.tag("ef"): # evaluate and feedback
exp = self.runner.develop(prev_out["coding"])
if exp is None:
logger.error(f"Factor extraction failed.")
raise FactorEmptyError("Factor extraction failed.")
logger.log_object(exp, tag="runner result")
exp = self.runner.develop(prev_out["coding"])
if exp is None:
logger.error(f"Factor extraction failed.")
raise FactorEmptyError("Factor extraction failed.")
logger.log_object(exp, tag="runner result")
return exp
def main(path=None, step_n=None):
def main(path=None, step_n=None, loop_n=None, all_duration=None, checkout=True):
"""
Auto R&D Evolving loop for fintech factors.
@@ -41,8 +39,8 @@ def main(path=None, step_n=None):
if path is None:
model_loop = FactorRDLoop(FACTOR_PROP_SETTING)
else:
model_loop = FactorRDLoop.load(path)
model_loop.run(step_n=step_n)
model_loop = FactorRDLoop.load(path, checkout=checkout)
asyncio.run(model_loop.run(step_n=step_n, loop_n=loop_n, all_duration=all_duration))
if __name__ == "__main__":
+38 -57
View File
@@ -1,9 +1,9 @@
import asyncio
import json
from pathlib import Path
from typing import Any, Tuple
from typing import Any, Dict, Tuple
import fire
from jinja2 import Environment, StrictUndefined
from rdagent.app.qlib_rd_loop.conf import FACTOR_FROM_REPORT_PROP_SETTING
from rdagent.app.qlib_rd_loop.factor import FactorRDLoop
@@ -11,20 +11,17 @@ from rdagent.components.document_reader.document_reader import (
extract_first_page_screenshot_from_pdf,
load_and_process_pdfs_by_langchain,
)
from rdagent.core.prompts import Prompts
from rdagent.core.conf import RD_AGENT_SETTINGS
from rdagent.core.proposal import Hypothesis
from rdagent.log import rdagent_logger as logger
from rdagent.log.time import measure_time
from rdagent.oai.llm_utils import APIBackend
from rdagent.scenarios.qlib.experiment.factor_experiment import QlibFactorExperiment
from rdagent.scenarios.qlib.factor_experiment_loader.pdf_loader import (
FactorExperimentLoaderFromPDFfiles,
)
from rdagent.utils.agent.tpl import T
from rdagent.utils.workflow import LoopMeta
prompts_path = Path(__file__).parent / "prompts.yaml"
prompts = Prompts(file_path=prompts_path)
def generate_hypothesis(factor_result: dict, report_content: str) -> str:
"""
@@ -37,19 +34,16 @@ def generate_hypothesis(factor_result: dict, report_content: str) -> str:
Returns:
str: The generated hypothesis.
"""
system_prompt = (
Environment(undefined=StrictUndefined).from_string(prompts["hypothesis_generation"]["system"]).render()
)
user_prompt = (
Environment(undefined=StrictUndefined)
.from_string(prompts["hypothesis_generation"]["user"])
.render(factor_descriptions=json.dumps(factor_result), report_content=report_content)
system_prompt = T(".prompts:hypothesis_generation.system").r()
user_prompt = T(".prompts:hypothesis_generation.user").r(
factor_descriptions=json.dumps(factor_result), report_content=report_content
)
response = APIBackend().build_messages_and_create_chat_completion(
user_prompt=user_prompt,
system_prompt=system_prompt,
json_mode=True,
json_target_type=Dict[str, str],
)
response_json = json.loads(response)
@@ -64,7 +58,7 @@ def generate_hypothesis(factor_result: dict, report_content: str) -> str:
)
def extract_hypothesis_and_exp_from_reports(report_file_path: str) -> Tuple[QlibFactorExperiment, Hypothesis]:
def extract_hypothesis_and_exp_from_reports(report_file_path: str) -> QlibFactorExperiment | None:
"""
Extract hypothesis and experiment details from report files.
@@ -72,17 +66,15 @@ def extract_hypothesis_and_exp_from_reports(report_file_path: str) -> Tuple[Qlib
report_file_path (str): Path to the report file.
Returns:
Tuple[QlibFactorExperiment, Hypothesis]: The extracted experiment and generated hypothesis.
QlibFactorExperiment: An instance of QlibFactorExperiment containing the extracted details.
None: If no valid experiment is found in the report.
"""
with logger.tag("extract_factors_and_implement"):
with logger.tag("load_factor_tasks"):
exp = FactorExperimentLoaderFromPDFfiles().load(report_file_path)
if exp is None or exp.sub_tasks == []:
return None, None
exp = FactorExperimentLoaderFromPDFfiles().load(report_file_path)
if exp is None or exp.sub_tasks == []:
return None
with logger.tag("load_pdf_screenshot"):
pdf_screenshot = extract_first_page_screenshot_from_pdf(report_file_path)
logger.log_object(pdf_screenshot)
pdf_screenshot = extract_first_page_screenshot_from_pdf(report_file_path)
logger.log_object(pdf_screenshot, tag="load_pdf_screenshot")
docs_dict = load_and_process_pdfs_by_langchain(report_file_path)
@@ -98,11 +90,11 @@ def extract_hypothesis_and_exp_from_reports(report_file_path: str) -> Tuple[Qlib
report_content = "\n".join(docs_dict.values())
hypothesis = generate_hypothesis(factor_result, report_content)
return exp, hypothesis
exp.hypothesis = hypothesis
return exp
class FactorReportLoop(FactorRDLoop, metaclass=LoopMeta):
@measure_time
def __init__(self, report_folder: str = None):
super().__init__(PROP_SETTING=FACTOR_FROM_REPORT_PROP_SETTING)
if report_folder is None:
@@ -112,44 +104,33 @@ class FactorReportLoop(FactorRDLoop, metaclass=LoopMeta):
else:
self.judge_pdf_data_items = [i for i in Path(report_folder).rglob("*.pdf")]
self.pdf_file_index = 0
self.valid_pdf_file_count = 0
self.current_loop_hypothesis = None
self.current_loop_exp = None
self.steps = ["propose_hypo_exp", "propose", "exp_gen", "coding", "running", "feedback"]
self.loop_n = min(len(self.judge_pdf_data_items), FACTOR_FROM_REPORT_PROP_SETTING.report_limit)
@measure_time
def propose_hypo_exp(self, prev_out: dict[str, Any]):
with logger.tag("r"):
while True:
if self.valid_pdf_file_count > 15:
break
report_file_path = self.judge_pdf_data_items[self.pdf_file_index]
logger.info(f"Processing number {self.pdf_file_index} report: {report_file_path}")
self.pdf_file_index += 1
exp, hypothesis = extract_hypothesis_and_exp_from_reports(str(report_file_path))
async def direct_exp_gen(self, prev_out: dict[str, Any]):
while True:
if self.get_unfinished_loop_cnt(self.loop_idx) < RD_AGENT_SETTINGS.get_max_parallel():
report_file_path = self.judge_pdf_data_items[self.loop_idx]
logger.info(f"Processing number {self.loop_idx} report: {report_file_path}")
exp = extract_hypothesis_and_exp_from_reports(str(report_file_path))
if exp is None:
continue
self.valid_pdf_file_count += 1
exp.based_experiments = [QlibFactorExperiment(sub_tasks=[])] + [t[1] for t in self.trace.hist if t[2]]
exp.based_experiments = [QlibFactorExperiment(sub_tasks=[], hypothesis=exp.hypothesis)] + [
t[0] for t in self.trace.hist if t[1]
]
exp.sub_workspace_list = exp.sub_workspace_list[: FACTOR_FROM_REPORT_PROP_SETTING.max_factors_per_exp]
exp.sub_tasks = exp.sub_tasks[: FACTOR_FROM_REPORT_PROP_SETTING.max_factors_per_exp]
logger.log_object(hypothesis, tag="hypothesis generation")
logger.log_object(exp.hypothesis, tag="hypothesis generation")
logger.log_object(exp.sub_tasks, tag="experiment generation")
self.current_loop_hypothesis = hypothesis
self.current_loop_exp = exp
return None
return exp
await asyncio.sleep(1)
@measure_time
def propose(self, prev_out: dict[str, Any]):
return self.current_loop_hypothesis
@measure_time
def exp_gen(self, prev_out: dict[str, Any]):
return self.current_loop_exp
def coding(self, prev_out: dict[str, Any]):
exp = self.coder.develop(prev_out["direct_exp_gen"])
logger.log_object(exp.sub_workspace_list, tag="coder result")
return exp
def main(report_folder=None, path=None, step_n=None):
def main(report_folder=None, path=None, all_duration=None, checkout=True):
"""
Auto R&D Evolving loop for fintech factors (the factors are extracted from finance reports).
@@ -161,11 +142,11 @@ def main(report_folder=None, path=None, step_n=None):
if path is None and report_folder is None:
model_loop = FactorReportLoop()
elif path is not None:
model_loop = FactorReportLoop.load(path)
model_loop = FactorReportLoop.load(path, checkout=checkout)
else:
model_loop = FactorReportLoop(report_folder=report_folder)
model_loop.run(step_n=step_n)
asyncio.run(model_loop.run(all_duration=all_duration))
if __name__ == "__main__":
+5 -3
View File
@@ -2,6 +2,8 @@
Model workflow with session control
"""
import asyncio
import fire
from rdagent.app.qlib_rd_loop.conf import MODEL_PROP_SETTING
@@ -13,7 +15,7 @@ class ModelRDLoop(RDLoop):
skip_loop_error = (ModelEmptyError,)
def main(path=None, step_n=None):
def main(path=None, step_n=None, loop_n=None, all_duration=None, checkout=True):
"""
Auto R&D Evolving loop for fintech models
@@ -27,8 +29,8 @@ def main(path=None, step_n=None):
if path is None:
model_loop = ModelRDLoop(MODEL_PROP_SETTING)
else:
model_loop = ModelRDLoop.load(path)
model_loop.run(step_n=step_n)
model_loop = ModelRDLoop.load(path, checkout=checkout)
asyncio.run(model_loop.run(step_n=step_n, loop_n=loop_n, all_duration=all_duration))
if __name__ == "__main__":
-4
View File
@@ -5,10 +5,6 @@ hypothesis_generation:
{
"hypothesis": "A clear and concise hypothesis based on the provided information.",
"reason": "A detailed explanation supporting the generated hypothesis.",
"concise_reason": "One line summary that focuses on the justification for the change that leads to the hypothesis (like a part of a knowledge that we are building)",
"concise_observation": "One line summary. It focuses on the observation of the given scenario, data characteristics, or previous experiences (failures & succeses).",
"concise_justification": "One line summary. It focuses on the justification for the change in new hypothesis and the route of exploration supporting the growth of the hypothesis, based on the observation. ",
"concise_knowledge": "One line summary. It focuses on a transferable knowledege that comes with the new hypothesis. Use conditional grammar. eg. "If...., ..; When..., .; and etc"
}
user: |-
+137
View File
@@ -0,0 +1,137 @@
"""
Quant (Factor & Model) workflow with session control
"""
import asyncio
from typing import Any
import fire
from rdagent.app.qlib_rd_loop.conf import QUANT_PROP_SETTING
from rdagent.components.workflow.conf import BasePropSetting
from rdagent.components.workflow.rd_loop import RDLoop
from rdagent.core.conf import RD_AGENT_SETTINGS
from rdagent.core.developer import Developer
from rdagent.core.exception import FactorEmptyError, ModelEmptyError
from rdagent.core.proposal import (
Experiment2Feedback,
Hypothesis2Experiment,
HypothesisFeedback,
HypothesisGen,
)
from rdagent.core.scenario import Scenario
from rdagent.core.utils import import_class
from rdagent.log import rdagent_logger as logger
from rdagent.scenarios.qlib.proposal.quant_proposal import QuantTrace
class QuantRDLoop(RDLoop):
skip_loop_error = (
FactorEmptyError,
ModelEmptyError,
)
def __init__(self, PROP_SETTING: BasePropSetting):
scen: Scenario = import_class(PROP_SETTING.scen)()
logger.log_object(scen, tag="scenario")
self.hypothesis_gen: HypothesisGen = import_class(PROP_SETTING.quant_hypothesis_gen)(scen)
logger.log_object(self.hypothesis_gen, tag="quant hypothesis generator")
self.factor_hypothesis2experiment: Hypothesis2Experiment = import_class(
PROP_SETTING.factor_hypothesis2experiment
)()
logger.log_object(self.factor_hypothesis2experiment, tag="factor hypothesis2experiment")
self.model_hypothesis2experiment: Hypothesis2Experiment = import_class(
PROP_SETTING.model_hypothesis2experiment
)()
logger.log_object(self.model_hypothesis2experiment, tag="model hypothesis2experiment")
self.factor_coder: Developer = import_class(PROP_SETTING.factor_coder)(scen)
logger.log_object(self.factor_coder, tag="factor coder")
self.model_coder: Developer = import_class(PROP_SETTING.model_coder)(scen)
logger.log_object(self.model_coder, tag="model coder")
self.factor_runner: Developer = import_class(PROP_SETTING.factor_runner)(scen)
logger.log_object(self.factor_runner, tag="factor runner")
self.model_runner: Developer = import_class(PROP_SETTING.model_runner)(scen)
logger.log_object(self.model_runner, tag="model runner")
self.factor_summarizer: Experiment2Feedback = import_class(PROP_SETTING.factor_summarizer)(scen)
logger.log_object(self.factor_summarizer, tag="factor summarizer")
self.model_summarizer: Experiment2Feedback = import_class(PROP_SETTING.model_summarizer)(scen)
logger.log_object(self.model_summarizer, tag="model summarizer")
self.trace = QuantTrace(scen=scen)
super(RDLoop, self).__init__()
async def direct_exp_gen(self, prev_out: dict[str, Any]):
while True:
if self.get_unfinished_loop_cnt(self.loop_idx) < RD_AGENT_SETTINGS.get_max_parallel():
hypo = self._propose()
assert hypo.action in ["factor", "model"]
if hypo.action == "factor":
exp = self.factor_hypothesis2experiment.convert(hypo, self.trace)
else:
exp = self.model_hypothesis2experiment.convert(hypo, self.trace)
logger.log_object(exp.sub_tasks, tag="experiment generation")
return {"propose": hypo, "exp_gen": exp}
await asyncio.sleep(1)
def coding(self, prev_out: dict[str, Any]):
if prev_out["direct_exp_gen"]["propose"].action == "factor":
exp = self.factor_coder.develop(prev_out["direct_exp_gen"]["exp_gen"])
elif prev_out["direct_exp_gen"]["propose"].action == "model":
exp = self.model_coder.develop(prev_out["direct_exp_gen"]["exp_gen"])
logger.log_object(exp, tag="coder result")
return exp
def running(self, prev_out: dict[str, Any]):
if prev_out["direct_exp_gen"]["propose"].action == "factor":
exp = self.factor_runner.develop(prev_out["coding"])
if exp is None:
logger.error(f"Factor extraction failed.")
raise FactorEmptyError("Factor extraction failed.")
elif prev_out["direct_exp_gen"]["propose"].action == "model":
exp = self.model_runner.develop(prev_out["coding"])
logger.log_object(exp, tag="runner result")
return exp
def feedback(self, prev_out: dict[str, Any]):
e = prev_out.get(self.EXCEPTION_KEY, None)
if e is not None:
feedback = HypothesisFeedback(
observations=str(e),
hypothesis_evaluation="",
new_hypothesis="",
reason="",
decision=False,
)
logger.log_object(feedback, tag="feedback")
self.trace.hist.append((prev_out["direct_exp_gen"]["exp_gen"], feedback))
else:
if prev_out["direct_exp_gen"]["propose"].action == "factor":
feedback = self.factor_summarizer.generate_feedback(prev_out["running"], self.trace)
elif prev_out["direct_exp_gen"]["propose"].action == "model":
feedback = self.model_summarizer.generate_feedback(prev_out["running"], self.trace)
logger.log_object(feedback, tag="feedback")
self.trace.hist.append((prev_out["running"], feedback))
def main(path=None, step_n=None, loop_n=None, all_duration=None, checkout=True):
"""
Auto R&D Evolving loop for fintech factors.
You can continue running session by
.. code-block:: python
dotenv run -- python rdagent/app/qlib_rd_loop/quant.py $LOG_PATH/__session__/1/0_propose --step_n 1 # `step_n` is a optional paramter
"""
if path is None:
quant_loop = QuantRDLoop(QUANT_PROP_SETTING)
else:
quant_loop = QuantRDLoop.load(path, checkout=checkout)
asyncio.run(quant_loop.run(step_n=step_n, loop_n=loop_n, all_duration=all_duration))
if __name__ == "__main__":
fire.Fire(main)
+49
View File
@@ -0,0 +1,49 @@
"""
This is the preliminary version of the APE (Automated Prompt Engineering)
"""
import pickle
from pathlib import Path
from rdagent.log.conf import LOG_SETTINGS
def get_llm_qa(file_path):
data_flt = []
with open(file_path, "rb") as f:
data = pickle.load(f)
print(len(data))
for item in data:
if "debug_llm" in item["tag"]:
data_flt.append(item)
return data_flt
# Example usage
# use
file_path = Path(LOG_SETTINGS.trace_path) / "debug_llm.pkl"
llm_qa = get_llm_qa(file_path)
print(len(llm_qa))
print(llm_qa[0])
# Initialize APE backend
from rdagent.oai.llm_utils import APIBackend
from rdagent.utils.agent.tpl import T
api = APIBackend()
# Analyze test data and generate improved prompts
for qa in llm_qa:
# Generate system prompt for APE
system_prompt = T(".prompts:ape.system").r()
# Generate user prompt with context from LLM QA
user_prompt = T(".prompts:ape.user").r(
system=qa["obj"].get("system", ""), user=qa["obj"]["user"], answer=qa["obj"]["resp"]
)
analysis_result = api.build_messages_and_create_chat_completion(
system_prompt=system_prompt, user_prompt=user_prompt
)
print(f"" * 60)
yes = input("Do you want to continue? (y/n)")
+52
View File
@@ -0,0 +1,52 @@
import socket
import docker
from rdagent.log import rdagent_logger as logger
from rdagent.utils.env import cleanup_container
def check_docker() -> None:
container = None
try:
client = docker.from_env()
client.images.pull("hello-world")
container = client.containers.run("hello-world", detach=True)
logs = container.logs().decode("utf-8")
print(logs)
logger.info(f"The docker status is normal")
except docker.errors.DockerException as e:
logger.error(f"An error occurred: {e}")
logger.warning(
f"Docker status is exception, please check the docker configuration or reinstall it. Refs: https://docs.docker.com/engine/install/ubuntu/."
)
finally:
cleanup_container(container, "health check")
def is_port_in_use(port):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex(("127.0.0.1", port)) == 0
def check_and_list_free_ports(start_port=19899, max_ports=10) -> None:
is_occupied = is_port_in_use(port=start_port)
if is_occupied:
free_ports = []
for port in range(start_port, start_port + max_ports):
if not is_port_in_use(port):
free_ports.append(port)
logger.warning(
f"Port 19899 is occupied, please replace it with an available port when running the `rdagent ui` command. Available ports: {free_ports}"
)
else:
logger.info(f"Port 19899 is not occupied, you can run the `rdagent ui` command")
def health_check():
"""
Check that docker is installed correctly,
and that the ports used in the sample README are not occupied.
"""
check_docker()
check_and_list_free_ports()
+119
View File
@@ -0,0 +1,119 @@
ape:
system: |-
We'll provide you with a pair of Chat QA about data science.
We are creating solutions for a Kaggle Competition based on the answers.
Good questions are crucial for getting good answers.
Please suggest how to improve the question.
You can analyze based on these aspects:
- Is the question complete (is all the information needed to answer the question provided?)
The conversation will be provided in the following format:
<question>
<part1>
...text to describe the question...
</part1>
<part2>
...text to describe the question...
</part2>
</question>
<answer>
...text to describe the answer.
</answer>
You response should be very concorete and concise(less than 20 words) and focuse on the mentioned aspects, like
```
Info Missing: the question ask for changing code, but it does not provide the description of current code.
```
Please be very conversatiive when you propose improvements. Only propose improvements when it becomes impossible to give the answer.
Don't propose conerete modifications
user: |-
<question>
<part1>
{{system}}
</part1>
<part2>
{{user}}
</part2>
</question>
<answer>
{{answer}}
</answer>
optional: |-
If you want to suggest modification on the question. Please follow the *SEARCH/REPLACE block* Rules!!!! It is optional.
Please make it concise and less than 20 lines!!!
# *SEARCH/REPLACE block* Rules:
Every *SEARCH/REPLACE block* must use this format:
1. The *FULL* file path alone on a line, verbatim. No bold asterisks, no quotes around it, no escaping of characters, etc.
2. The opening fence and code language, eg: ```python
3. The start of search block: <<<<<<< SEARCH
4. A contiguous chunk of lines to search for in the existing source code
5. The dividing line: =======
6. The lines to replace into the source code
7. The end of the replace block: >>>>>>> REPLACE
8. The closing fence: ```
Use the *FULL* file path, as shown to you by the user.
Every *SEARCH* section must *EXACTLY MATCH* the existing file content, character for character, including all comments, docstrings, etc.
If the file contains code or other data wrapped/escaped in json/xml/quotes or other containers, you need to propose edits to the literal contents of the file, including the container markup.
*SEARCH/REPLACE* blocks will *only* replace the first match occurrence.
Including multiple unique *SEARCH/REPLACE* blocks if needed.
Include enough lines in each SEARCH section to uniquely match each set of lines that need to change.
Keep *SEARCH/REPLACE* blocks concise.
Break large *SEARCH/REPLACE* blocks into a series of smaller blocks that each change a small portion of the file.
Include just the changing lines, and a few surrounding lines if needed for uniqueness.
Do not include long runs of unchanging lines in *SEARCH/REPLACE* blocks.
Only create *SEARCH/REPLACE* blocks for files that the user has added to the chat!
To move code within a file, use 2 *SEARCH/REPLACE* blocks: 1 to delete it from its current location, 1 to insert it in the new location.
Pay attention to which filenames the user wants you to edit, especially if they are asking you to create a new file.
If you want to put code in a new file, use a *SEARCH/REPLACE block* with:
- A new file path, including dir name if needed
- An empty `SEARCH` section
- The new file's contents in the `REPLACE` section
To rename files which have been added to the chat, use shell commands at the end of your response.
If the user just says something like "ok" or "go ahead" or "do that" they probably want you to make SEARCH/REPLACE blocks for the code changes you just proposed.
The user will say when they've applied your edits. If they haven't explicitly confirmed the edits have been applied, they probably want proper SEARCH/REPLACE blocks.
You are diligent and tireless!
You NEVER leave comments describing code without implementing it!
You always COMPLETELY IMPLEMENT the needed code!
ONLY EVER RETURN CODE IN A *SEARCH/REPLACE BLOCK*!
Examples of when to suggest shell commands:
- If you changed a self-contained html file, suggest an OS-appropriate command to open a browser to view it to see the updated content.
- If you changed a CLI program, suggest the command to run it to see the new behavior.
- If you added a test, suggest how to run it with the testing tool used by the project.
- Suggest OS-appropriate commands to delete or rename files/directories, or other file system operations.
- If your code changes add new dependencies, suggest the command to install them.
- Etc.
Here is a example of SEARCH/REPLACE BLOCK to change a function implementation to import.
<<<<<<< SEARCH
def hello():
"print a greeting"
print("hello")
=======
from hello import hello
>>>>>>> REPLACE
# - Is there any ambiguity in the question?
+3 -6
View File
@@ -2,19 +2,16 @@ from dataclasses import field
from pathlib import Path
from typing import Optional
from pydantic_settings import BaseSettings
from rdagent.core.conf import ExtendedBaseSettings
DIRNAME = Path("./")
class BenchmarkSettings(BaseSettings):
class BenchmarkSettings(ExtendedBaseSettings):
class Config:
env_prefix = "BENCHMARK_"
"""Use `BENCHMARK_` as prefix for environment variables"""
ground_truth_dir: Path = DIRNAME / "ground_truth"
"""ground truth dir"""
bench_data_path: Path = DIRNAME / "example.json"
"""data for benchmark"""
@@ -24,7 +21,7 @@ class BenchmarkSettings(BaseSettings):
bench_test_case_n: Optional[int] = None
"""how many test cases to run; If not given, all test cases will be run"""
bench_method_cls: str = "rdagent.components.coder.factor_coder.CoSTEER.FactorCoSTEER"
bench_method_cls: str = "rdagent.components.coder.factor_coder.FactorCoSTEER"
"""method to be used for test cases"""
bench_method_extra_kwargs: dict = field(
+2 -2
View File
@@ -5,8 +5,8 @@ from typing import Dict, List, Tuple, Union
import pandas as pd
from tqdm import tqdm
from rdagent.components.coder.factor_coder.config import FACTOR_IMPLEMENT_SETTINGS
from rdagent.components.coder.factor_coder.CoSTEER.evaluators import (
from rdagent.components.coder.factor_coder.config import FACTOR_COSTEER_SETTINGS
from rdagent.components.coder.factor_coder.eva_utils import (
FactorCorrelationEvaluator,
FactorEqualValueRatioEvaluator,
FactorEvaluator,
@@ -0,0 +1,144 @@
import pickle
from datetime import datetime
from pathlib import Path
from rdagent.components.coder.CoSTEER.config import CoSTEERSettings
from rdagent.components.coder.CoSTEER.evaluators import CoSTEERMultiFeedback
from rdagent.components.coder.CoSTEER.evolvable_subjects import EvolvingItem
from rdagent.components.coder.CoSTEER.knowledge_management import (
CoSTEERKnowledgeBaseV1,
CoSTEERKnowledgeBaseV2,
CoSTEERRAGStrategyV1,
CoSTEERRAGStrategyV2,
)
from rdagent.core.developer import Developer
from rdagent.core.evaluation import Evaluator, Feedback
from rdagent.core.evolving_agent import EvolvingStrategy, RAGEvoAgent
from rdagent.core.exception import CoderError
from rdagent.core.experiment import Experiment
from rdagent.log import rdagent_logger as logger
class CoSTEER(Developer[Experiment]):
def __init__(
self,
settings: CoSTEERSettings,
eva: Evaluator,
es: EvolvingStrategy,
evolving_version: int,
*args,
with_knowledge: bool = True,
with_feedback: bool = True,
knowledge_self_gen: bool = True,
filter_final_evo: bool = True,
max_loop: int | None = None,
**kwargs,
) -> None:
super().__init__(*args, **kwargs)
self.max_loop = settings.max_loop if max_loop is None else max_loop
self.max_seconds = settings.max_seconds
self.knowledge_base_path = (
Path(settings.knowledge_base_path) if settings.knowledge_base_path is not None else None
)
self.new_knowledge_base_path = (
Path(settings.new_knowledge_base_path) if settings.new_knowledge_base_path is not None else None
)
self.with_knowledge = with_knowledge
self.with_feedback = with_feedback
self.knowledge_self_gen = knowledge_self_gen
self.filter_final_evo = filter_final_evo
self.evolving_strategy = es
self.evaluator = eva
self.evolving_version = evolving_version
# init knowledge base
self.knowledge_base = self.load_or_init_knowledge_base(
former_knowledge_base_path=self.knowledge_base_path,
component_init_list=[],
)
# init rag method
self.rag = (
CoSTEERRAGStrategyV2(self.knowledge_base, settings=settings)
if self.evolving_version == 2
else CoSTEERRAGStrategyV1(self.knowledge_base, settings=settings)
)
def load_or_init_knowledge_base(self, former_knowledge_base_path: Path = None, component_init_list: list = []):
if former_knowledge_base_path is not None and former_knowledge_base_path.exists():
knowledge_base = pickle.load(open(former_knowledge_base_path, "rb"))
if self.evolving_version == 1 and not isinstance(knowledge_base, CoSTEERKnowledgeBaseV1):
raise ValueError("The former knowledge base is not compatible with the current version")
elif self.evolving_version == 2 and not isinstance(
knowledge_base,
CoSTEERKnowledgeBaseV2,
):
raise ValueError("The former knowledge base is not compatible with the current version")
else:
knowledge_base = (
CoSTEERKnowledgeBaseV2(
init_component_list=component_init_list,
)
if self.evolving_version == 2
else CoSTEERKnowledgeBaseV1()
)
return knowledge_base
def develop(self, exp: Experiment) -> Experiment:
# init intermediate items
evo_exp = EvolvingItem.from_experiment(exp)
self.evolve_agent = RAGEvoAgent(
max_loop=self.max_loop,
evolving_strategy=self.evolving_strategy,
rag=self.rag,
with_knowledge=self.with_knowledge,
with_feedback=self.with_feedback,
knowledge_self_gen=self.knowledge_self_gen,
)
start_datetime = datetime.now()
for evo_exp in self.evolve_agent.multistep_evolve(evo_exp, self.evaluator):
assert isinstance(evo_exp, Experiment) # multiple inheritance
logger.log_object(evo_exp.sub_workspace_list, tag="evolving code")
for sw in evo_exp.sub_workspace_list:
logger.info(f"evolving workspace: {sw}")
if (datetime.now() - start_datetime).seconds > self.max_seconds:
logger.info(f"Reached max time limit {self.max_seconds} seconds, stop evolving")
break
if self.with_feedback and self.filter_final_evo:
evo_exp = self._exp_postprocess_by_feedback(evo_exp, self.evolve_agent.evolving_trace[-1].feedback)
# save new knowledge base
if self.new_knowledge_base_path is not None:
with self.new_knowledge_base_path.open("wb") as f:
pickle.dump(self.knowledge_base, f)
logger.info(f"New knowledge base saved to {self.new_knowledge_base_path}")
exp.sub_workspace_list = evo_exp.sub_workspace_list
exp.experiment_workspace = evo_exp.experiment_workspace
return exp
def _exp_postprocess_by_feedback(self, evo: Experiment, feedback: CoSTEERMultiFeedback) -> Experiment:
"""
Responsibility:
- Raise Error if it failed to handle the develop task
-
"""
assert isinstance(evo, Experiment)
assert isinstance(feedback, CoSTEERMultiFeedback)
assert len(evo.sub_workspace_list) == len(feedback)
# FIXME: when whould the feedback be None?
failed_feedbacks = [
f"- feedback{index + 1:02d}:\n - execution: {f.execution}\n - return_checking: {f.return_checking}\n - code: {f.code}"
for index, f in enumerate(feedback)
if f is not None and not f.final_decision
]
if len(failed_feedbacks) == len(feedback):
feedback_summary = "\n".join(failed_feedbacks)
raise CoderError(f"All tasks are failed:\n{feedback_summary}")
return evo
@@ -0,0 +1,39 @@
from typing import Union
from rdagent.core.conf import ExtendedBaseSettings
class CoSTEERSettings(ExtendedBaseSettings):
"""CoSTEER settings, this setting is supposed not to be used directly!!!"""
class Config:
env_prefix = "CoSTEER_"
coder_use_cache: bool = False
"""Indicates whether to use cache for the coder"""
max_loop: int = 10
"""Maximum number of task implementation loops"""
fail_task_trial_limit: int = 20
v1_query_former_trace_limit: int = 5
v1_query_similar_success_limit: int = 5
v2_query_component_limit: int = 1
v2_query_error_limit: int = 1
v2_query_former_trace_limit: int = 1
v2_add_fail_attempt_to_latest_successful_execution: bool = False
v2_error_summary: bool = False
v2_knowledge_sampler: float = 1.0
knowledge_base_path: Union[str, None] = None
"""Path to the knowledge base"""
new_knowledge_base_path: Union[str, None] = None
"""Path to the new knowledge base"""
max_seconds: int = 10**6
CoSTEER_SETTINGS = CoSTEERSettings()
@@ -0,0 +1,277 @@
from abc import abstractmethod
from copy import deepcopy
from dataclasses import dataclass
from typing import TYPE_CHECKING, List
from rdagent.components.coder.CoSTEER.evolvable_subjects import EvolvingItem
from rdagent.core.conf import RD_AGENT_SETTINGS
from rdagent.core.evaluation import Evaluator, Feedback
from rdagent.core.evolving_framework import QueriedKnowledge
from rdagent.core.experiment import Task, Workspace
from rdagent.core.utils import multiprocessing_wrapper
from rdagent.log import rdagent_logger as logger
if TYPE_CHECKING:
from rdagent.core.scenario import Scenario
# TODO:
# 1. It seems logically sound, but we currently lack a scenario to apply it.
# 2. If it proves to be useful, relocate it to a more general location.
#
# class FBWorkspaceExeFeedback(Feedback):
# """
# It pairs with FBWorkspace in the abstract level.
# """
# # ws: FBWorkspace # potential
# stdout: str
@dataclass
class CoSTEERSingleFeedback(Feedback):
# TODO: (xiao)
# it should be more general class for FBWorkspaceExeFeedback
# A better name of it may be NormalFeedback
# TODO: It should be a general feeddback for CoSTEERR
"""
The feedback for the data loader evaluation.
It is design align the phases of the implemented code
- Execution -> Return Value -> Code -> Final Decision
"""
execution: str
# execution_feedback
return_checking: str | None # including every check in the testing (constraints about the generated value)
# value_feedback, shape_feedback, value_generated_flag
code: str
final_decision: bool
@staticmethod
def val_and_update_init_dict(data: dict) -> dict:
# TODO: (bowen) use a more general method to validate and update the data dictionary before init, like pydantic
"""
Validates and converts the 'final_decision' field in the given data dictionary.
Args:
data (dict): The data dictionary containing the 'final_decision' field.
Returns:
dict: The updated data dictionary with 'final_decision' as a boolean.
Raises:
ValueError: If 'final_decision' is not present or not a boolean.
"""
if "final_decision" not in data:
raise ValueError("'final_decision' is required")
if isinstance(data["final_decision"], str):
if data["final_decision"] == "false" or data["final_decision"] == "False":
data["final_decision"] = False
elif data["final_decision"] == "true" or data["final_decision"] == "True":
data["final_decision"] = True
if not isinstance(data["final_decision"], bool):
raise ValueError(f"'final_decision' must be a boolean, not {type(data['final_decision'])}")
return data
def __str__(self) -> str:
return f"""------------------Execution------------------
{self.execution}
------------------Return Checking------------------
{self.return_checking if self.return_checking is not None else 'No return checking'}
------------------Code------------------
{self.code}
------------------Final Decision------------------
This implementation is {'SUCCESS' if self.final_decision else 'FAIL'}.
"""
def __bool__(self):
return self.final_decision
class CoSTEERSingleFeedbackDeprecated(CoSTEERSingleFeedback):
"""This class is a base class for all code generator feedback to single implementation"""
def __init__(
self,
execution_feedback: str = None,
shape_feedback: str = None,
code_feedback: str = None,
value_feedback: str = None,
final_decision: bool = None,
final_feedback: str = None,
value_generated_flag: bool = None,
final_decision_based_on_gt: bool = None,
) -> None:
self.execution_feedback = execution_feedback
self.code_feedback = code_feedback
self.value_feedback = value_feedback
self.final_decision = final_decision
self.final_feedback = final_feedback
self.value_generated_flag = value_generated_flag
self.final_decision_based_on_gt = final_decision_based_on_gt
# TODO:
# Not general enough. So we should not put them in the general costeer feedback
# Instead, we should create subclass for it.
self.shape_feedback = shape_feedback # Not general enough. So
@property
def execution(self):
return self.execution_feedback
@execution.setter
def execution(self, value):
self.execution_feedback = value
@property
def return_checking(self):
if self.value_generated_flag:
return f"value feedback: {self.value_feedback}\n\nshape feedback: {self.shape_feedback}"
return None
@return_checking.setter
def return_checking(self, value):
# Since return_checking is derived from value_feedback and shape_feedback,
# we don't need to do anything here
self.value_feedback = value
self.shape_feedback = value
@property
def code(self):
return self.code_feedback
@code.setter
def code(self, value):
self.code_feedback = value
def __str__(self) -> str:
return f"""------------------Execution Feedback------------------
{self.execution_feedback if self.execution_feedback is not None else 'No execution feedback'}
------------------Shape Feedback------------------
{self.shape_feedback if self.shape_feedback is not None else 'No shape feedback'}
------------------Code Feedback------------------
{self.code_feedback if self.code_feedback is not None else 'No code feedback'}
------------------Value Feedback------------------
{self.value_feedback if self.value_feedback is not None else 'No value feedback'}
------------------Final Feedback------------------
{self.final_feedback if self.final_feedback is not None else 'No final feedback'}
------------------Final Decision------------------
This implementation is {'SUCCESS' if self.final_decision else 'FAIL'}.
"""
class CoSTEERMultiFeedback(Feedback):
"""Feedback contains a list, each element is the corresponding feedback for each factor implementation."""
def __init__(self, feedback_list: List[CoSTEERSingleFeedback]) -> None:
self.feedback_list = feedback_list
def __getitem__(self, index: int) -> CoSTEERSingleFeedback:
return self.feedback_list[index]
def __len__(self) -> int:
return len(self.feedback_list)
def append(self, feedback: CoSTEERSingleFeedback) -> None:
self.feedback_list.append(feedback)
def __iter__(self):
return iter(self.feedback_list)
def finished(self) -> bool:
"""
In some implementations, tasks may fail multiple times, leading agents to skip the implementation.
This results in None feedback. However, we want to accept the correct parts and ignore None feedback.
"""
return all(feedback.final_decision for feedback in self.feedback_list if feedback is not None)
def __bool__(self) -> bool:
return all(feedback.final_decision for feedback in self.feedback_list)
class CoSTEEREvaluator(Evaluator):
def __init__(
self,
scen: "Scenario",
) -> None:
self.scen = scen
# TODO:
# I think we should have unified interface for all evaluates, for examples.
# So we should adjust the interface of other factors
@abstractmethod
def evaluate(
self,
target_task: Task,
implementation: Workspace,
gt_implementation: Workspace,
**kwargs,
) -> CoSTEERSingleFeedback:
raise NotImplementedError("Please implement the `evaluator` method")
class CoSTEERMultiEvaluator(CoSTEEREvaluator):
"""This is for evaluation of experiment. Due to we have multiple tasks, so we will return a list of evaluation feebacks"""
def __init__(self, single_evaluator: CoSTEEREvaluator | list[CoSTEEREvaluator], *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.single_evaluator = single_evaluator
def evaluate(
self,
evo: EvolvingItem,
queried_knowledge: QueriedKnowledge = None,
**kwargs,
) -> CoSTEERMultiFeedback:
eval_l = self.single_evaluator if isinstance(self.single_evaluator, list) else [self.single_evaluator]
task_li_feedback_li = []
for ev in eval_l:
multi_implementation_feedback = multiprocessing_wrapper(
[
(
ev.evaluate,
(
evo.sub_tasks[index],
evo.sub_workspace_list[index],
evo.sub_gt_implementations[index] if evo.sub_gt_implementations is not None else None,
queried_knowledge,
),
)
for index in range(len(evo.sub_tasks))
],
n=RD_AGENT_SETTINGS.multi_proc_n,
)
task_li_feedback_li.append(multi_implementation_feedback)
# merge the feedbacks
merged_task_feedback = []
for task_id, fb in enumerate(task_li_feedback_li[0]):
fb = deepcopy(fb) # deep copy to make it more robust
fb.final_decision = all(
task_li_feedback[task_id].final_decision for task_li_feedback in task_li_feedback_li
)
for attr in "execution", "return_checking", "code":
setattr(
fb,
attr,
"\n\n".join(
[
getattr(task_li_feedback[task_id], attr)
for task_li_feedback in task_li_feedback_li
if getattr(task_li_feedback[task_id], attr) is not None
]
),
)
merged_task_feedback.append(fb)
final_decision = [
None if single_feedback is None else single_feedback.final_decision
for single_feedback in merged_task_feedback
]
logger.info(f"Final decisions: {final_decision} True count: {final_decision.count(True)}")
# TODO: this is to be compatible with factor_implementation;
for index in range(len(evo.sub_tasks)):
if final_decision[index]:
evo.sub_tasks[index].factor_implementation = True
return CoSTEERMultiFeedback(merged_task_feedback)
@@ -1,24 +1,19 @@
from rdagent.components.coder.factor_coder.factor import (
FactorExperiment,
FactorFBWorkspace,
FactorTask,
)
from rdagent.core.evolving_framework import EvolvableSubjects
from rdagent.core.experiment import Experiment, FBWorkspace, Task
from rdagent.log import rdagent_logger as logger
class FactorEvolvingItem(FactorExperiment, EvolvableSubjects):
class EvolvingItem(Experiment, EvolvableSubjects):
"""
Intermediate item of factor implementation.
"""
def __init__(
self,
sub_tasks: list[FactorTask],
sub_gt_implementations: list[FactorFBWorkspace] = None,
sub_tasks: list[Task],
sub_gt_implementations: list[FBWorkspace] = None,
):
FactorExperiment.__init__(self, sub_tasks=sub_tasks)
self.corresponding_selection: list = None
Experiment.__init__(self, sub_tasks=sub_tasks)
if sub_gt_implementations is not None and len(
sub_gt_implementations,
) != len(self.sub_tasks):
@@ -30,7 +25,7 @@ class FactorEvolvingItem(FactorExperiment, EvolvableSubjects):
self.sub_gt_implementations = sub_gt_implementations
@classmethod
def from_experiment(cls, exp: FactorExperiment) -> "FactorExperiment":
def from_experiment(cls, exp: Experiment) -> Experiment:
ei = cls(sub_tasks=exp.sub_tasks)
ei.based_experiments = exp.based_experiments
ei.experiment_workspace = exp.experiment_workspace
@@ -0,0 +1,120 @@
from __future__ import annotations
from abc import abstractmethod
from rdagent.components.coder.CoSTEER.config import CoSTEERSettings
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEERMultiFeedback,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.CoSTEER.evolvable_subjects import EvolvingItem
from rdagent.components.coder.CoSTEER.knowledge_management import (
CoSTEERQueriedKnowledge,
)
from rdagent.core.conf import RD_AGENT_SETTINGS
from rdagent.core.evolving_framework import EvolvingStrategy, EvoStep, QueriedKnowledge
from rdagent.core.experiment import FBWorkspace, Task
from rdagent.core.scenario import Scenario
from rdagent.core.utils import multiprocessing_wrapper
class MultiProcessEvolvingStrategy(EvolvingStrategy):
def __init__(self, scen: Scenario, settings: CoSTEERSettings):
super().__init__(scen)
self.settings = settings
@abstractmethod
def implement_one_task(
self,
target_task: Task,
queried_knowledge: QueriedKnowledge | None = None,
workspace: FBWorkspace | None = None,
prev_task_feedback: CoSTEERSingleFeedback | None = None,
) -> dict[str, str]: # FIXME: fix interface of previous implement
"""
This method will input the task & current workspace,
and output the modification to applied to the workspace.
(i.e. replace the content <filename> with <content>)
Parameters
----------
target_task : Task
queried_knowledge : QueriedKnowledge | None
workspace : FBWorkspace | None
prev_task_feedback : CoSTEERSingleFeedback | None
task feedback for previous evolving step
None indicate it is the first loop.
Return
------
The new files {<filename>: <content>} to update the workspace.
"""
raise NotImplementedError
@abstractmethod
def assign_code_list_to_evo(self, code_list: list[dict], evo: EvolvingItem) -> None:
"""
Assign the code list to the evolving item.
Due to the implement_one_task take `workspace` as input and output the `modification`.
We should apply implementation to evo
The code list is aligned with the evolving item's sub-tasks.
If a task is not implemented, put a None in the list.
"""
raise NotImplementedError
def evolve(
self,
*,
evo: EvolvingItem,
queried_knowledge: CoSTEERQueriedKnowledge | None = None,
evolving_trace: list[EvoStep] = [],
**kwargs,
) -> EvolvingItem:
# 1.找出需要evolve的task
to_be_finished_task_index: list[int] = []
for index, target_task in enumerate(evo.sub_tasks):
target_task_desc = target_task.get_task_information()
if target_task_desc in queried_knowledge.success_task_to_knowledge_dict:
# NOTE: very weird logic:
# it depends on the knowledge to set the already finished task
evo.sub_workspace_list[index] = queried_knowledge.success_task_to_knowledge_dict[
target_task_desc
].implementation
elif (
target_task_desc not in queried_knowledge.success_task_to_knowledge_dict
and target_task_desc not in queried_knowledge.failed_task_info_set
):
to_be_finished_task_index.append(index)
last_feedback = None
if len(evolving_trace) > 0:
last_feedback = evolving_trace[-1].feedback
assert isinstance(last_feedback, CoSTEERMultiFeedback)
result = multiprocessing_wrapper(
[
(
self.implement_one_task,
(
evo.sub_tasks[target_index],
queried_knowledge,
evo.experiment_workspace,
None if last_feedback is None else last_feedback[target_index],
),
)
for target_index in to_be_finished_task_index
],
n=RD_AGENT_SETTINGS.multi_proc_n,
)
code_list = [None for _ in range(len(evo.sub_tasks))]
for index, target_index in enumerate(to_be_finished_task_index):
code_list[target_index] = result[index]
evo = self.assign_code_list_to_evo(code_list, evo)
return evo
@@ -6,19 +6,15 @@ import random
import re
from itertools import combinations
from pathlib import Path
from typing import Union
from typing import List, Union
from jinja2 import Environment, StrictUndefined
from rdagent.components.coder.factor_coder.config import FACTOR_IMPLEMENT_SETTINGS
from rdagent.components.coder.factor_coder.CoSTEER.evaluators import (
FactorSingleFeedback,
)
from rdagent.components.coder.factor_coder.factor import FactorTask
from rdagent.components.coder.CoSTEER.config import CoSTEERSettings
from rdagent.components.coder.CoSTEER.evaluators import CoSTEERSingleFeedback
from rdagent.components.knowledge_management.graph import (
UndirectedGraph,
UndirectedNode,
)
from rdagent.core.evolving_agent import Feedback
from rdagent.core.evolving_framework import (
EvolvableSubjects,
EvolvingKnowledgeBase,
@@ -27,75 +23,73 @@ from rdagent.core.evolving_framework import (
QueriedKnowledge,
RAGStrategy,
)
from rdagent.core.experiment import Workspace
from rdagent.core.prompts import Prompts
from rdagent.core.experiment import FBWorkspace, Task
from rdagent.log import rdagent_logger as logger
from rdagent.oai.llm_utils import (
APIBackend,
calculate_embedding_distance_between_str_list,
)
from rdagent.utils.agent.tpl import T
class FactorKnowledge(Knowledge):
class CoSTEERKnowledge(Knowledge):
def __init__(
self,
target_task: FactorTask,
implementation: Workspace,
feedback: FactorSingleFeedback,
target_task: Task,
implementation: FBWorkspace,
feedback: Feedback,
) -> None:
"""
Initialize a FactorKnowledge object. The FactorKnowledge object is used to store a factor implementation without the ground truth code and value.
Args:
factor (Factor): The factor object associated with the KnowledgeManagement.
Returns:
None
"""
self.target_task = target_task
self.implementation = implementation.copy()
self.feedback = feedback
def get_implementation_and_feedback_str(self) -> str:
return f"""------------------Factor implementation code:------------------
{self.implementation.code}
------------------Factor implementation feedback:------------------
return f"""------------------implementation code:------------------
{self.implementation.all_codes}
------------------implementation feedback:------------------
{self.feedback!s}
"""
class FactorQueriedKnowledge(QueriedKnowledge):
class CoSTEERQueriedKnowledge(QueriedKnowledge):
def __init__(self, success_task_to_knowledge_dict: dict = {}, failed_task_info_set: set = set()) -> None:
self.success_task_to_knowledge_dict = success_task_to_knowledge_dict
self.failed_task_info_set = failed_task_info_set
class FactorKnowledgeBaseV1(EvolvingKnowledgeBase):
class CoSTEERKnowledgeBaseV1(EvolvingKnowledgeBase):
def __init__(self, path: str | Path = None) -> None:
self.implementation_trace: dict[str, FactorKnowledge] = dict()
self.implementation_trace: dict[str, CoSTEERKnowledge] = dict()
self.success_task_info_set: set[str] = set()
self.task_to_embedding = dict()
super().__init__(path)
def query(self) -> QueriedKnowledge | None:
def query(self) -> CoSTEERQueriedKnowledge | None:
"""
Query the knowledge base to get the queried knowledge. So far is handled in RAG strategy.
"""
raise NotImplementedError
class FactorQueriedKnowledgeV1(FactorQueriedKnowledge):
def __init__(self) -> None:
self.working_task_to_former_failed_knowledge_dict = dict()
self.working_task_to_similar_successful_knowledge_dict = dict()
super().__init__()
class CoSTEERQueriedKnowledgeV1(CoSTEERQueriedKnowledge):
def __init__(
self,
*args,
task_to_former_failed_traces: dict = {},
task_to_similar_task_successful_knowledge: dict = {},
**kwargs,
) -> None:
self.task_to_former_failed_traces = task_to_former_failed_traces
self.task_to_similar_task_successful_knowledge = task_to_similar_task_successful_knowledge
super().__init__(*args, **kwargs)
class FactorRAGStrategyV1(RAGStrategy):
def __init__(self, knowledgebase: FactorKnowledgeBaseV1) -> None:
class CoSTEERRAGStrategyV1(RAGStrategy):
def __init__(self, knowledgebase: CoSTEERKnowledgeBaseV1, settings: CoSTEERSettings) -> None:
super().__init__(knowledgebase)
self.current_generated_trace_count = 0
self.settings = settings
def generate_knowledge(
self,
@@ -103,6 +97,9 @@ class FactorRAGStrategyV1(RAGStrategy):
*,
return_knowledge: bool = False,
) -> Knowledge | None:
raise NotImplementedError(
"This method should be considered as an un-implemented method because we encourage everyone to use v2."
)
if len(evolving_trace) == self.current_generated_trace_count:
return
else:
@@ -120,7 +117,7 @@ class FactorRAGStrategyV1(RAGStrategy):
single_feedback = feedback[task_index]
if single_feedback is None:
continue
single_knowledge = FactorKnowledge(
single_knowledge = CoSTEERKnowledge(
target_task=target_task,
implementation=implementation,
feedback=single_feedback,
@@ -141,43 +138,44 @@ class FactorRAGStrategyV1(RAGStrategy):
self,
evo: EvolvableSubjects,
evolving_trace: list[EvoStep],
) -> QueriedKnowledge | None:
v1_query_former_trace_limit = FACTOR_IMPLEMENT_SETTINGS.v1_query_former_trace_limit
v1_query_similar_success_limit = FACTOR_IMPLEMENT_SETTINGS.v1_query_similar_success_limit
fail_task_trial_limit = FACTOR_IMPLEMENT_SETTINGS.fail_task_trial_limit
) -> CoSTEERQueriedKnowledge | None:
raise NotImplementedError(
"This method should be considered as an un-implemented method because we encourage everyone to use v2."
)
v1_query_former_trace_limit = self.settings.v1_query_former_trace_limit
v1_query_similar_success_limit = self.settings.v1_query_similar_success_limit
fail_task_trial_limit = self.settings.fail_task_trial_limit
queried_knowledge = FactorQueriedKnowledgeV1()
for target_factor_task in evo.sub_tasks:
target_factor_task_information = target_factor_task.get_task_information()
if target_factor_task_information in self.knowledgebase.success_task_info_set:
queried_knowledge.success_task_to_knowledge_dict[
target_factor_task_information
] = self.knowledgebase.implementation_trace[target_factor_task_information][-1]
queried_knowledge = CoSTEERQueriedKnowledgeV1()
for target_task in evo.sub_tasks:
target_task_information = target_task.get_task_information()
if target_task_information in self.knowledgebase.success_task_info_set:
queried_knowledge.success_task_to_knowledge_dict[target_task_information] = (
self.knowledgebase.implementation_trace[target_task_information][-1]
)
elif (
len(
self.knowledgebase.implementation_trace.setdefault(
target_factor_task_information,
target_task_information,
[],
),
)
>= fail_task_trial_limit
):
queried_knowledge.failed_task_info_set.add(target_factor_task_information)
queried_knowledge.failed_task_info_set.add(target_task_information)
else:
queried_knowledge.working_task_to_former_failed_knowledge_dict[
target_factor_task_information
] = self.knowledgebase.implementation_trace.setdefault(
target_factor_task_information,
[],
)[
-v1_query_former_trace_limit:
]
queried_knowledge.task_to_former_failed_traces[target_task_information] = (
self.knowledgebase.implementation_trace.setdefault(
target_task_information,
[],
)[-v1_query_former_trace_limit:]
)
knowledge_base_success_task_list = list(
self.knowledgebase.success_task_info_set,
)
similarity = calculate_embedding_distance_between_str_list(
[target_factor_task_information],
[target_task_information],
knowledge_base_success_task_list,
)[0]
similar_indexes = sorted(
@@ -192,33 +190,34 @@ class FactorRAGStrategyV1(RAGStrategy):
)[-1]
for index in similar_indexes
]
queried_knowledge.working_task_to_similar_successful_knowledge_dict[
target_factor_task_information
] = similar_successful_knowledge
queried_knowledge.task_to_similar_task_successful_knowledge[target_task_information] = (
similar_successful_knowledge
)
return queried_knowledge
class FactorQueriedGraphKnowledge(FactorQueriedKnowledge):
class CoSTEERQueriedKnowledgeV2(CoSTEERQueriedKnowledgeV1):
# Aggregation of knowledge
def __init__(
self,
former_traces: dict = {},
component_with_success_task: dict = {},
error_with_success_task: dict = {},
task_to_former_failed_traces: dict = {},
task_to_similar_task_successful_knowledge: dict = {},
task_to_similar_error_successful_knowledge: dict = {},
**kwargs,
) -> None:
self.former_traces = former_traces
self.component_with_success_task = component_with_success_task
self.error_with_success_task = error_with_success_task
super().__init__(**kwargs)
self.task_to_similar_error_successful_knowledge = task_to_similar_error_successful_knowledge
super().__init__(
task_to_former_failed_traces=task_to_former_failed_traces,
task_to_similar_task_successful_knowledge=task_to_similar_task_successful_knowledge,
**kwargs,
)
class FactorGraphRAGStrategy(RAGStrategy):
prompt = Prompts(file_path=Path(__file__).parent.parent / "prompts.yaml")
def __init__(self, knowledgebase: FactorGraphKnowledgeBase) -> None:
class CoSTEERRAGStrategyV2(RAGStrategy):
def __init__(self, knowledgebase: CoSTEERKnowledgeBaseV2, settings: CoSTEERSettings) -> None:
super().__init__(knowledgebase)
self.current_generated_trace_count = 0
self.settings = settings
def generate_knowledge(
self,
@@ -235,14 +234,13 @@ class FactorGraphRAGStrategy(RAGStrategy):
implementations = evo_step.evolvable_subjects
feedback = evo_step.feedback
for task_index in range(len(implementations.sub_tasks)):
single_feedback = feedback[task_index]
target_task = implementations.sub_tasks[task_index]
target_task_information = target_task.get_task_information()
implementation = implementations.sub_workspace_list[task_index]
single_feedback = feedback[task_index]
if single_feedback is None:
single_feedback: CoSTEERSingleFeedback = feedback[task_index]
if implementation is None or single_feedback is None:
continue
single_knowledge = FactorKnowledge(
single_knowledge = CoSTEERKnowledge(
target_task=target_task,
implementation=implementation,
feedback=single_feedback,
@@ -266,15 +264,15 @@ class FactorGraphRAGStrategy(RAGStrategy):
else:
# generate error node and store into knowledge base
error_analysis_result = []
if not single_feedback.value_generated_flag:
if single_feedback.return_checking:
error_analysis_result = self.analyze_error(
single_feedback.execution_feedback,
feedback_type="execution",
single_feedback.return_checking,
feedback_type="value",
)
else:
error_analysis_result = self.analyze_error(
single_feedback.factor_value_feedback,
feedback_type="value",
single_feedback.execution,
feedback_type="execution",
)
self.knowledgebase.working_trace_error_analysis.setdefault(
target_task_information,
@@ -286,35 +284,35 @@ class FactorGraphRAGStrategy(RAGStrategy):
self.current_generated_trace_count = len(evolving_trace)
return None
def query(self, evo: EvolvableSubjects, evolving_trace: list[EvoStep]) -> QueriedKnowledge | None:
conf_knowledge_sampler = FACTOR_IMPLEMENT_SETTINGS.v2_knowledge_sampler
factor_implementation_queried_graph_knowledge = FactorQueriedGraphKnowledge(
def query(self, evo: EvolvableSubjects, evolving_trace: list[EvoStep]) -> CoSTEERQueriedKnowledge | None:
conf_knowledge_sampler = self.settings.v2_knowledge_sampler
queried_knowledge_v2 = CoSTEERQueriedKnowledgeV2(
success_task_to_knowledge_dict=self.knowledgebase.success_task_to_knowledge_dict,
)
factor_implementation_queried_graph_knowledge = self.former_trace_query(
queried_knowledge_v2 = self.former_trace_query(
evo,
factor_implementation_queried_graph_knowledge,
FACTOR_IMPLEMENT_SETTINGS.v2_query_former_trace_limit,
FACTOR_IMPLEMENT_SETTINGS.v2_add_fail_attempt_to_latest_successful_execution,
queried_knowledge_v2,
self.settings.v2_query_former_trace_limit,
self.settings.v2_add_fail_attempt_to_latest_successful_execution,
)
factor_implementation_queried_graph_knowledge = self.component_query(
queried_knowledge_v2 = self.component_query(
evo,
factor_implementation_queried_graph_knowledge,
FACTOR_IMPLEMENT_SETTINGS.v2_query_component_limit,
queried_knowledge_v2,
self.settings.v2_query_component_limit,
knowledge_sampler=conf_knowledge_sampler,
)
factor_implementation_queried_graph_knowledge = self.error_query(
queried_knowledge_v2 = self.error_query(
evo,
factor_implementation_queried_graph_knowledge,
FACTOR_IMPLEMENT_SETTINGS.v2_query_error_limit,
queried_knowledge_v2,
self.settings.v2_query_error_limit,
knowledge_sampler=conf_knowledge_sampler,
)
return factor_implementation_queried_graph_knowledge
return queried_knowledge_v2
def analyze_component(
self,
target_factor_task_information,
target_task_information,
) -> list[UndirectedNode]: # Hardcode: certain component nodes
all_component_nodes = self.knowledgebase.graph.get_all_nodes_by_label_list(["component"])
if not len(all_component_nodes):
@@ -322,21 +320,18 @@ class FactorGraphRAGStrategy(RAGStrategy):
all_component_content = ""
for _, component_node in enumerate(all_component_nodes):
all_component_content += f"{component_node.content}, \n"
analyze_component_system_prompt = (
Environment(undefined=StrictUndefined)
.from_string(self.prompt["analyze_component_prompt_v1_system"])
.render(
all_component_content=all_component_content,
)
analyze_component_system_prompt = T(".prompts:analyze_component_prompt_v1_system").r(
all_component_content=all_component_content,
)
analyze_component_user_prompt = target_factor_task_information
analyze_component_user_prompt = target_task_information
try:
component_no_list = json.loads(
APIBackend().build_messages_and_create_chat_completion(
system_prompt=analyze_component_system_prompt,
user_prompt=analyze_component_user_prompt,
json_mode=True,
json_target_type=List[int],
),
)["component_no_list"]
return [all_component_nodes[index - 1] for index in sorted(list(set(component_no_list)))]
@@ -391,41 +386,39 @@ class FactorGraphRAGStrategy(RAGStrategy):
def former_trace_query(
self,
evo: EvolvableSubjects,
factor_implementation_queried_graph_knowledge: FactorQueriedGraphKnowledge,
queried_knowledge_v2: CoSTEERQueriedKnowledgeV2,
v2_query_former_trace_limit: int = 5,
v2_add_fail_attempt_to_latest_successful_execution: bool = False,
) -> Union[QueriedKnowledge, set]:
) -> Union[CoSTEERQueriedKnowledge, set]:
"""
Query the former trace knowledge of the working trace, and find all the failed task information which tried more than fail_task_trial_limit times
"""
fail_task_trial_limit = FACTOR_IMPLEMENT_SETTINGS.fail_task_trial_limit
fail_task_trial_limit = self.settings.fail_task_trial_limit
for target_factor_task in evo.sub_tasks:
target_factor_task_information = target_factor_task.get_task_information()
for target_task in evo.sub_tasks:
target_task_information = target_task.get_task_information()
if (
target_factor_task_information not in self.knowledgebase.success_task_to_knowledge_dict
and target_factor_task_information in self.knowledgebase.working_trace_knowledge
and len(self.knowledgebase.working_trace_knowledge[target_factor_task_information])
>= fail_task_trial_limit
target_task_information not in self.knowledgebase.success_task_to_knowledge_dict
and target_task_information in self.knowledgebase.working_trace_knowledge
and len(self.knowledgebase.working_trace_knowledge[target_task_information]) >= fail_task_trial_limit
):
factor_implementation_queried_graph_knowledge.failed_task_info_set.add(target_factor_task_information)
queried_knowledge_v2.failed_task_info_set.add(target_task_information)
if (
target_factor_task_information not in self.knowledgebase.success_task_to_knowledge_dict
and target_factor_task_information
not in factor_implementation_queried_graph_knowledge.failed_task_info_set
and target_factor_task_information in self.knowledgebase.working_trace_knowledge
target_task_information not in self.knowledgebase.success_task_to_knowledge_dict
and target_task_information not in queried_knowledge_v2.failed_task_info_set
and target_task_information in self.knowledgebase.working_trace_knowledge
):
former_trace_knowledge = copy.copy(
self.knowledgebase.working_trace_knowledge[target_factor_task_information],
self.knowledgebase.working_trace_knowledge[target_task_information],
)
# in former trace query we will delete the right trace in the following order:[..., value_generated_flag is True, value_generated_flag is False, ...]
# because we think this order means a deterioration of the trial (like a wrong gradient descent)
current_index = 1
while current_index < len(former_trace_knowledge):
if (
not former_trace_knowledge[current_index].feedback.value_generated_flag
and former_trace_knowledge[current_index - 1].feedback.value_generated_flag
not former_trace_knowledge[current_index].feedback.return_checking
and former_trace_knowledge[current_index - 1].feedback.return_checking
):
former_trace_knowledge.pop(current_index)
else:
@@ -436,47 +429,44 @@ class FactorGraphRAGStrategy(RAGStrategy):
# When the last successful execution is not the last one in the working trace, it means we have tried to correct it. We should tell the agent this fail trial to avoid endless loop in the future.
if (
len(former_trace_knowledge) > 0
and len(self.knowledgebase.working_trace_knowledge[target_factor_task_information]) > 1
and self.knowledgebase.working_trace_knowledge[target_factor_task_information].index(
and len(self.knowledgebase.working_trace_knowledge[target_task_information]) > 1
and self.knowledgebase.working_trace_knowledge[target_task_information].index(
former_trace_knowledge[-1]
)
< len(self.knowledgebase.working_trace_knowledge[target_factor_task_information]) - 1
< len(self.knowledgebase.working_trace_knowledge[target_task_information]) - 1
):
latest_attempt = self.knowledgebase.working_trace_knowledge[target_factor_task_information][-1]
latest_attempt = self.knowledgebase.working_trace_knowledge[target_task_information][-1]
factor_implementation_queried_graph_knowledge.former_traces[target_factor_task_information] = (
queried_knowledge_v2.task_to_former_failed_traces[target_task_information] = (
former_trace_knowledge[-v2_query_former_trace_limit:],
latest_attempt,
)
else:
factor_implementation_queried_graph_knowledge.former_traces[target_factor_task_information] = ([], None)
queried_knowledge_v2.task_to_former_failed_traces[target_task_information] = ([], None)
return factor_implementation_queried_graph_knowledge
return queried_knowledge_v2
def component_query(
self,
evo: EvolvableSubjects,
factor_implementation_queried_graph_knowledge: FactorQueriedGraphKnowledge,
queried_knowledge_v2: CoSTEERQueriedKnowledgeV2,
v2_query_component_limit: int = 5,
knowledge_sampler: float = 1.0,
) -> QueriedKnowledge | None:
# queried_component_knowledge = FactorQueriedGraphComponentKnowledge()
for target_factor_task in evo.sub_tasks:
target_factor_task_information = target_factor_task.get_task_information()
) -> CoSTEERQueriedKnowledge | None:
for target_task in evo.sub_tasks:
target_task_information = target_task.get_task_information()
if (
target_factor_task_information in self.knowledgebase.success_task_to_knowledge_dict
or target_factor_task_information in factor_implementation_queried_graph_knowledge.failed_task_info_set
target_task_information in self.knowledgebase.success_task_to_knowledge_dict
or target_task_information in queried_knowledge_v2.failed_task_info_set
):
factor_implementation_queried_graph_knowledge.component_with_success_task[
target_factor_task_information
] = []
queried_knowledge_v2.task_to_similar_task_successful_knowledge[target_task_information] = []
else:
if target_factor_task_information not in self.knowledgebase.task_to_component_nodes:
self.knowledgebase.task_to_component_nodes[target_factor_task_information] = self.analyze_component(
target_factor_task_information,
if target_task_information not in self.knowledgebase.task_to_component_nodes:
self.knowledgebase.task_to_component_nodes[target_task_information] = self.analyze_component(
target_task_information,
)
component_analysis_result = self.knowledgebase.task_to_component_nodes[target_factor_task_information]
component_analysis_result = self.knowledgebase.task_to_component_nodes[target_task_information]
if len(component_analysis_result) > 1:
task_des_node_list = self.knowledgebase.graph_query_by_intersection(
@@ -487,9 +477,7 @@ class FactorGraphRAGStrategy(RAGStrategy):
else:
task_des_node_list = []
single_component_constraint = v2_query_component_limit
factor_implementation_queried_graph_knowledge.component_with_success_task[
target_factor_task_information
] = []
queried_knowledge_v2.task_to_similar_task_successful_knowledge[target_task_information] = []
for component_node in component_analysis_result:
# Reverse iterate, a trade-off with intersection search
count = 0
@@ -520,19 +508,19 @@ class FactorGraphRAGStrategy(RAGStrategy):
]
if (
target_knowledge
not in factor_implementation_queried_graph_knowledge.component_with_success_task[
target_factor_task_information
not in queried_knowledge_v2.task_to_similar_task_successful_knowledge[
target_task_information
]
):
factor_implementation_queried_graph_knowledge.component_with_success_task[
target_factor_task_information
queried_knowledge_v2.task_to_similar_task_successful_knowledge[
target_task_information
].append(target_knowledge)
# finally add embedding related knowledge
knowledge_base_success_task_list = list(self.knowledgebase.success_task_to_knowledge_dict)
similarity = calculate_embedding_distance_between_str_list(
[target_factor_task_information],
[target_task_information],
knowledge_base_success_task_list,
)[0]
similar_indexes = sorted(
@@ -547,28 +535,24 @@ class FactorGraphRAGStrategy(RAGStrategy):
for knowledge in embedding_similar_successful_knowledge:
if (
knowledge
not in factor_implementation_queried_graph_knowledge.component_with_success_task[
target_factor_task_information
]
not in queried_knowledge_v2.task_to_similar_task_successful_knowledge[target_task_information]
):
factor_implementation_queried_graph_knowledge.component_with_success_task[
target_factor_task_information
].append(knowledge)
queried_knowledge_v2.task_to_similar_task_successful_knowledge[target_task_information].append(
knowledge
)
if knowledge_sampler > 0:
factor_implementation_queried_graph_knowledge.component_with_success_task[
target_factor_task_information
] = [
queried_knowledge_v2.task_to_similar_task_successful_knowledge[target_task_information] = [
knowledge
for knowledge in factor_implementation_queried_graph_knowledge.component_with_success_task[
target_factor_task_information
for knowledge in queried_knowledge_v2.task_to_similar_task_successful_knowledge[
target_task_information
]
if random.uniform(0, 1) <= knowledge_sampler
]
# Make sure no less than half of the knowledge are from GT
queried_knowledge_list = factor_implementation_queried_graph_knowledge.component_with_success_task[
target_factor_task_information
queried_knowledge_list = queried_knowledge_v2.task_to_similar_task_successful_knowledge[
target_task_information
]
queried_from_gt_knowledge_list = [
knowledge
@@ -584,51 +568,43 @@ class FactorGraphRAGStrategy(RAGStrategy):
min((v2_query_component_limit // 2 + 1), len(queried_from_gt_knowledge_list)),
v2_query_component_limit - len(queried_without_gt_knowledge_list),
)
factor_implementation_queried_graph_knowledge.component_with_success_task[
target_factor_task_information
] = (
queried_knowledge_v2.task_to_similar_task_successful_knowledge[target_task_information] = (
queried_from_gt_knowledge_list[:queried_from_gt_knowledge_count]
+ queried_without_gt_knowledge_list[: v2_query_component_limit - queried_from_gt_knowledge_count]
)
return factor_implementation_queried_graph_knowledge
return queried_knowledge_v2
def error_query(
self,
evo: EvolvableSubjects,
factor_implementation_queried_graph_knowledge: FactorQueriedGraphKnowledge,
queried_knowledge_v2: CoSTEERQueriedKnowledgeV2,
v2_query_error_limit: int = 5,
knowledge_sampler: float = 1.0,
) -> QueriedKnowledge | None:
# queried_error_knowledge = FactorQueriedGraphErrorKnowledge()
for task_index, target_factor_task in enumerate(evo.sub_tasks):
target_factor_task_information = target_factor_task.get_task_information()
factor_implementation_queried_graph_knowledge.error_with_success_task[target_factor_task_information] = {}
) -> CoSTEERQueriedKnowledge | None:
for task_index, target_task in enumerate(evo.sub_tasks):
target_task_information = target_task.get_task_information()
queried_knowledge_v2.task_to_similar_error_successful_knowledge[target_task_information] = []
if (
target_factor_task_information in self.knowledgebase.success_task_to_knowledge_dict
or target_factor_task_information in factor_implementation_queried_graph_knowledge.failed_task_info_set
target_task_information in self.knowledgebase.success_task_to_knowledge_dict
or target_task_information in queried_knowledge_v2.failed_task_info_set
):
factor_implementation_queried_graph_knowledge.error_with_success_task[
target_factor_task_information
] = []
queried_knowledge_v2.task_to_similar_error_successful_knowledge[target_task_information] = []
else:
factor_implementation_queried_graph_knowledge.error_with_success_task[
target_factor_task_information
] = []
queried_knowledge_v2.task_to_similar_error_successful_knowledge[target_task_information] = []
if (
target_factor_task_information in self.knowledgebase.working_trace_error_analysis
and len(self.knowledgebase.working_trace_error_analysis[target_factor_task_information]) > 0
and len(factor_implementation_queried_graph_knowledge.former_traces[target_factor_task_information])
> 0
target_task_information in self.knowledgebase.working_trace_error_analysis
and len(self.knowledgebase.working_trace_error_analysis[target_task_information]) > 0
and len(queried_knowledge_v2.task_to_former_failed_traces[target_task_information]) > 0
):
queried_last_trace = factor_implementation_queried_graph_knowledge.former_traces[
target_factor_task_information
][0][-1]
target_index = self.knowledgebase.working_trace_knowledge[target_factor_task_information].index(
queried_last_trace = queried_knowledge_v2.task_to_former_failed_traces[target_task_information][0][
-1
]
target_index = self.knowledgebase.working_trace_knowledge[target_task_information].index(
queried_last_trace,
)
last_knowledge_error_analysis_result = self.knowledgebase.working_trace_error_analysis[
target_factor_task_information
target_task_information
][target_index]
else:
last_knowledge_error_analysis_result = []
@@ -721,20 +697,20 @@ class FactorGraphRAGStrategy(RAGStrategy):
]
same_error_success_knowledge_pair_list = same_error_success_knowledge_pair_list[:v2_query_error_limit]
factor_implementation_queried_graph_knowledge.error_with_success_task[
target_factor_task_information
] = same_error_success_knowledge_pair_list
queried_knowledge_v2.task_to_similar_error_successful_knowledge[target_task_information] = (
same_error_success_knowledge_pair_list
)
return factor_implementation_queried_graph_knowledge
return queried_knowledge_v2
class FactorGraphKnowledgeBase(EvolvingKnowledgeBase):
class CoSTEERKnowledgeBaseV2(EvolvingKnowledgeBase):
def __init__(self, init_component_list=None, path: str | Path = None) -> None:
"""
Load knowledge, offer brief information of knowledge and common handle interfaces
"""
self.graph: UndirectedGraph = UndirectedGraph(Path.cwd() / "graph.pkl")
logger.info(f"Knowledge Graph loaded, size={self.graph.size()}")
logger.info(f"CoSTEER Knowledge Graph loaded, size={self.graph.size()}")
if init_component_list:
for component in init_component_list:
@@ -751,7 +727,7 @@ class FactorGraphKnowledgeBase(EvolvingKnowledgeBase):
# Add already success task
self.success_task_to_knowledge_dict = {}
# key:node_id(for task trace and success implement), value:knowledge instance(aka 'FactorKnowledge')
# key:node_id(for task trace and success implement), value:knowledge instance(aka 'CoSTEERKnowledge')
self.node_to_implementation_knowledge_dict = {}
# store the task description to component nodes
@@ -0,0 +1,10 @@
analyze_component_prompt_v1_system: |-
User is getting a new task that might consist of the components below (given in component_index: component_description):
{{all_component_content}}
You should find out what components does the new task have, and put their indices in a list.
Please response the critic in the json format. Here is an example structure for the JSON output, please strictly follow the format:
{
"component_no_list": the list containing indices of components.
}
+9
View File
@@ -0,0 +1,9 @@
from rdagent.core.experiment import Task
class CoSTEERTask(Task):
def __init__(self, base_code: str = None, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
# TODO: we may upgrade the base_code into a workspace-like thing to know previous.
# NOTE: (xiao) think we don't need the base_code anymore. The information should be retrieved from the workspace.
self.base_code = base_code
@@ -0,0 +1,71 @@
from typing import Literal
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER.config import CoSTEERSettings
from rdagent.utils.env import (
CondaConf,
DockerEnv,
DSDockerConf,
Env,
LocalEnv,
MLEBDockerConf,
MLECondaConf,
)
class DSCoderCoSTEERSettings(CoSTEERSettings):
"""Data Science CoSTEER settings"""
class Config:
env_prefix = "DS_Coder_CoSTEER_"
max_seconds: int = 2400
env_type: str = "docker"
# TODO: extract a function for env and conf.
def get_ds_env(
conf_type: Literal["kaggle", "mlebench"] = "kaggle",
extra_volumes: dict = {},
running_timeout_period: int = (
DS_RD_SETTING.debug_timeout if DS_RD_SETTING.sample_data else DS_RD_SETTING.full_timeout
),
) -> Env:
"""
Retrieve the appropriate environment configuration based on the env_type setting.
Returns:
Env: An instance of the environment configured either as DockerEnv or LocalEnv.
Raises:
ValueError: If the env_type is not recognized.
"""
conf = DSCoderCoSTEERSettings()
assert conf_type in ["kaggle", "mlebench"], f"Unknown conf_type: {conf_type}"
if conf.env_type == "docker":
env_conf = DSDockerConf() if conf_type == "kaggle" else MLEBDockerConf()
env = DockerEnv(conf=env_conf)
elif conf.env_type == "conda":
env = LocalEnv(
conf=(
CondaConf(conda_env_name=conf_type) if conf_type == "kaggle" else MLECondaConf(conda_env_name=conf_type)
)
)
else:
raise ValueError(f"Unknown env type: {conf.env_type}")
env.conf.extra_volumes = extra_volumes
env.conf.running_timeout_period = running_timeout_period
return env
def get_clear_ws_cmd(stage: Literal["before_training", "before_inference"] = "before_training") -> str:
"""
Clean the files in workspace to a specific stage
"""
assert stage in ["before_training", "before_inference"], f"Unknown stage: {stage}"
if DS_RD_SETTING.enable_model_dump and stage == "before_training":
cmd = "rm -r submission.csv scores.csv models"
else:
cmd = "rm submission.csv scores.csv"
return cmd
@@ -0,0 +1,164 @@
"""
File structure
- ___init__.py: the entrance/agent of coder
- evaluator.py
- conf.py
- exp.py: everything under the experiment, e.g.
- Task
- Experiment
- Workspace
- test.py
- Each coder could be tested.
"""
from pathlib import Path
from jinja2 import Environment, StrictUndefined
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER import CoSTEER
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEERMultiEvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.CoSTEER.evolving_strategy import (
MultiProcessEvolvingStrategy,
)
from rdagent.components.coder.CoSTEER.knowledge_management import (
CoSTEERQueriedKnowledge,
)
from rdagent.components.coder.data_science.conf import DSCoderCoSTEERSettings
from rdagent.components.coder.data_science.ensemble.eval import EnsembleCoSTEEREvaluator
from rdagent.components.coder.data_science.ensemble.exp import EnsembleTask
from rdagent.core.exception import CoderError
from rdagent.core.experiment import FBWorkspace
from rdagent.core.scenario import Scenario
from rdagent.oai.llm_utils import APIBackend
from rdagent.utils.agent.ret import PythonAgentOut
from rdagent.utils.agent.tpl import T
DIRNAME = Path(__file__).absolute().resolve().parent
class EnsembleMultiProcessEvolvingStrategy(MultiProcessEvolvingStrategy):
def implement_one_task(
self,
target_task: EnsembleTask,
queried_knowledge: CoSTEERQueriedKnowledge | None = None,
workspace: FBWorkspace | None = None,
prev_task_feedback: CoSTEERSingleFeedback | None = None,
) -> dict[str, str]:
# Get task information for knowledge querying
ensemble_information_str = target_task.get_task_information()
# Query knowledge
queried_similar_successful_knowledge = (
queried_knowledge.task_to_similar_task_successful_knowledge[ensemble_information_str]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
queried_knowledge.task_to_former_failed_traces[ensemble_information_str]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
[
knowledge
for knowledge in queried_former_failed_knowledge[0]
if knowledge.implementation.file_dict.get("ensemble.py") != workspace.file_dict.get("ensemble.py")
],
queried_former_failed_knowledge[1],
)
# Generate code with knowledge integration
competition_info = self.scen.get_scenario_all_desc(eda_output=workspace.file_dict.get("EDA.md", None))
system_prompt = T(".prompts:ensemble_coder.system").r(
task_desc=ensemble_information_str,
competition_info=competition_info,
queried_similar_successful_knowledge=queried_similar_successful_knowledge,
queried_former_failed_knowledge=(
queried_former_failed_knowledge[0] if queried_former_failed_knowledge else None
),
all_code=workspace.all_codes,
out_spec=PythonAgentOut.get_spec(),
)
if DS_RD_SETTING.spec_enabled:
code_spec = workspace.file_dict["spec/ensemble.md"]
else:
test_code = (
Environment(undefined=StrictUndefined)
.from_string((DIRNAME / "eval_tests" / "ensemble_test.txt").read_text())
.render(
model_names=[
fn[:-3] for fn in workspace.file_dict.keys() if fn.startswith("model_") and "test" not in fn
],
metric_name=self.scen.metric_name,
)
)
code_spec = T("scenarios.data_science.share:component_spec.general").r(
spec=T("scenarios.data_science.share:component_spec.Ensemble").r(), test_code=test_code
)
user_prompt = T(".prompts:ensemble_coder.user").r(
code_spec=code_spec,
latest_code=workspace.file_dict.get("ensemble.py"),
latest_code_feedback=prev_task_feedback,
)
for _ in range(5):
ensemble_code = PythonAgentOut.extract_output(
APIBackend().build_messages_and_create_chat_completion(
user_prompt=user_prompt,
system_prompt=system_prompt,
)
)
if ensemble_code != workspace.file_dict.get("ensemble.py"):
break
else:
user_prompt = user_prompt + "\nPlease avoid generating same code to former code!"
else:
raise CoderError("Failed to generate a new ensemble code.")
return {
"ensemble.py": ensemble_code,
}
def assign_code_list_to_evo(self, code_list: list[dict[str, str]], evo):
"""
Assign the code list to the evolving item.
The code list is aligned with the evolving item's sub-tasks.
If a task is not implemented, put a None in the list.
"""
for index in range(len(evo.sub_tasks)):
if code_list[index] is None:
continue
if evo.sub_workspace_list[index] is None:
# evo.sub_workspace_list[index] = FBWorkspace(target_task=evo.sub_tasks[index])
evo.sub_workspace_list[index] = evo.experiment_workspace
evo.sub_workspace_list[index].inject_files(**code_list[index])
return evo
class EnsembleCoSTEER(CoSTEER):
def __init__(
self,
scen: Scenario,
*args,
**kwargs,
) -> None:
settings = DSCoderCoSTEERSettings()
eva = CoSTEERMultiEvaluator(EnsembleCoSTEEREvaluator(scen=scen), scen=scen)
es = EnsembleMultiProcessEvolvingStrategy(scen=scen, settings=settings)
super().__init__(
*args,
settings=settings,
eva=eva,
es=es,
evolving_version=2,
scen=scen,
max_loop=DS_RD_SETTING.coder_max_loop,
**kwargs,
)
@@ -0,0 +1,2 @@
# Configuration file for ensemble component
# Currently empty as no specific configuration is needed
@@ -0,0 +1,95 @@
import json
import re
from pathlib import Path
from jinja2 import Environment, StrictUndefined
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEEREvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.data_science.conf import get_ds_env
from rdagent.components.coder.data_science.utils import remove_eda_part
from rdagent.core.evolving_framework import QueriedKnowledge
from rdagent.core.experiment import FBWorkspace, Task
from rdagent.utils.agent.tpl import T
from rdagent.utils.agent.workflow import build_cls_from_json_with_retry
DIRNAME = Path(__file__).absolute().resolve().parent
EnsembleEvalFeedback = CoSTEERSingleFeedback
class EnsembleCoSTEEREvaluator(CoSTEEREvaluator):
def evaluate(
self,
target_task: Task,
implementation: FBWorkspace,
gt_implementation: FBWorkspace,
queried_knowledge: QueriedKnowledge = None,
**kwargs,
) -> EnsembleEvalFeedback:
target_task_information = target_task.get_task_information()
metric_name = self.scen.metric_name
if (
queried_knowledge is not None
and target_task_information in queried_knowledge.success_task_to_knowledge_dict
):
return queried_knowledge.success_task_to_knowledge_dict[target_task_information].feedback
elif queried_knowledge is not None and target_task_information in queried_knowledge.failed_task_info_set:
return EnsembleEvalFeedback(
execution="This task has failed too many times, skip implementation.",
code="This task has failed too many times, skip implementation.",
return_checking="This task has failed too many times, skip implementation.",
final_decision=False,
)
env = get_ds_env(extra_volumes={self.scen.debug_path: T("scenarios.data_science.share:scen.input_path").r()})
fname = "test/ensemble_test.txt"
test_code = (DIRNAME / "eval_tests" / "ensemble_test.txt").read_text()
test_code = (
Environment(undefined=StrictUndefined)
.from_string(test_code)
.render(
model_names=[
fn[:-3] for fn in implementation.file_dict.keys() if fn.startswith("model_") and "test" not in fn
],
metric_name=metric_name,
)
)
implementation.inject_files(**{fname: test_code})
stdout, ret_code = implementation.execute_ret_code(env=env, entry=f"python {fname}")
stdout += f"\nNOTE: the above scripts run with return code {ret_code}"
if "main.py" in implementation.file_dict and ret_code == 0:
workflow_stdout = implementation.execute(env=env, entry="python main.py")
workflow_stdout = remove_eda_part(workflow_stdout)
else:
workflow_stdout = None
system_prompt = T(".prompts:ensemble_eval.system").r(
task_desc=target_task_information,
test_code=test_code,
metric_name=metric_name,
code=implementation.file_dict["ensemble.py"],
workflow_stdout=workflow_stdout,
workflow_code=implementation.all_codes,
)
user_prompt = T(".prompts:ensemble_eval.user").r(
stdout=stdout,
workflow_stdout=workflow_stdout,
)
efb = build_cls_from_json_with_retry(
EnsembleEvalFeedback,
system_prompt=system_prompt,
user_prompt=user_prompt,
init_kwargs_update_func=EnsembleEvalFeedback.val_and_update_init_dict,
)
efb.final_decision = efb.final_decision and ret_code == 0
return efb
@@ -0,0 +1,137 @@
"""
Tests for `ensemble_workflow` in ensemble.py
A qualified ensemble_workflow implementation should:
- Return predictions
- Have correct shapes for inputs and outputs
- Use validation data appropriately
- Generate a scores.csv file
"""
import numpy as np
import pandas as pd
from pathlib import Path
from sklearn.model_selection import train_test_split
import torch
import tensorflow as tf
from load_data import load_data
from feature import feat_eng
from ensemble import ensemble_workflow
def print_preds_info(model_name, data_type, preds):
if preds is None:
print(f"Model {model_name} {data_type} predictions: None")
else:
print(f"Model {model_name} {data_type} predictions shape: {preds.shape}")
print("Showing a preview of the predictions (first few entries only):")
if isinstance(preds, (pd.DataFrame, pd.Series)):
print(preds.head())
elif isinstance(preds, (np.ndarray, torch.Tensor, tf.Tensor)):
print(preds[:2])
elif isinstance(preds, list):
print(pd.DataFrame(preds[:5]))
else:
print(f"Unknown prediction type: {type(preds)}")
def get_length(data):
return data.shape[0] if hasattr(data, 'shape') else len(data)
X, y, test_X, test_ids = load_data()
X, y, test_X = feat_eng(X, y, test_X)
train_X, val_X, train_y, val_y = train_test_split(X, y, test_size=0.2, random_state=42)
# Print the types of train_y and val_y
print(f"train_y type: {type(train_y)}, val_y type: {type(val_y)}")
test_preds_dict = {}
val_preds_dict = {}
{% for mn in model_names %}
from {{mn}} import model_workflow as {{mn}}_workflow
val_preds_dict["{{mn}}"], test_preds_dict["{{mn}}"], _ = {{mn}}_workflow(
X=train_X,
y=train_y,
val_X=val_X,
val_y=val_y,
test_X=test_X
)
print_preds_info("{{mn}}", "test", test_preds_dict["{{mn}}"])
{% endfor %}
for key in val_preds_dict.keys():
if val_preds_dict[key] is None:
print(f"Model {key} validation predictions (val_preds_dict[key]) is None.")
elif isinstance(val_preds_dict[key], list):
print(f"Model {key} validation predictions (val_preds_dict[key]) (list type) length: {len(val_preds_dict[key])}")
else:
print(f"Model {key} validation predictions (val_preds_dict[key]) shape: {val_preds_dict[key].shape}")
if test_preds_dict[key] is None:
print(f"Model {key} test predictions (test_preds_dict[key]) is None.")
elif isinstance(test_preds_dict[key], list):
print(f"Model {key} test predictions (test_preds_dict[key]) (list type) length: {len(test_preds_dict[key])}")
else:
print(f"Model {key} test predictions (test_preds_dict[key]) shape: {test_preds_dict[key].shape}")
print(f"val_y.shape: {val_y.shape}" if not isinstance(val_y, list) else f"val_y(list)'s length: {len(val_y)}")
import sys
import reprlib
def debug_info_print(func):
aRepr = reprlib.Repr()
aRepr.maxother=300
def wrapper(*args, **kwargs):
def local_trace(frame, event, arg):
if event == "return" and frame.f_code == func.__code__:
print("\n" + "="*20 + "Running ensemble code, local variable values:" + "="*20)
for k, v in frame.f_locals.items():
printed = aRepr.repr(v)
print(f"{k}:\n {printed}")
print("="*20 + "Local variable values end" + "="*20)
return local_trace
sys.settrace(local_trace)
try:
return func(*args, **kwargs)
finally:
sys.settrace(None)
return wrapper
# Run ensemble
final_pred = debug_info_print(ensemble_workflow)(test_preds_dict, val_preds_dict, val_y)
print_preds_info("ensemble", "test", final_pred)
# Check type
pred_type = type(next(iter(test_preds_dict.values())))
assert isinstance(final_pred, pred_type), (
f"Type mismatch: 'final_pred' is of type {type(final_pred)}, but expected {pred_type} "
)
# Check shape
if isinstance(final_pred, (list, np.ndarray, pd.DataFrame, torch.Tensor, tf.Tensor)):
assert get_length(final_pred) == get_length(test_X), (
f"Wrong output sample size: get_length(final_pred)={get_length(final_pred)} "
f"vs. get_length(test_X)={get_length(test_X)}"
)
# check scores.csv
assert Path("scores.csv").exists(), "scores.csv is not generated"
score_df = pd.read_csv("scores.csv", index_col=0)
model_set_in_scores = set(score_df.index)
assert model_set_in_scores == set({{model_names}}).union({"ensemble"}), (
f"The scores dataframe does not contain the correct model names as index.\ncorrect model names are: {{model_names}} + ['ensemble']\nscore_df is:\n{score_df}"
)
assert score_df.index.is_unique, "The scores dataframe has duplicate model names."
assert score_df.columns.tolist() == ["{{metric_name}}"], f"The column names of the scores dataframe should be ['{{metric_name}}'], but is '{score_df.columns.tolist()}'"
# Check for NaN values in score_df
assert not score_df.isnull().values.any(), (
f"The scores dataframe contains NaN values at the following locations:\n{score_df[score_df.isnull().any(axis=1)]}"
)
print("Ensemble test end.")
@@ -0,0 +1,13 @@
import pickle
import site
import traceback
from pathlib import Path
from typing import Dict, Optional
from rdagent.components.coder.CoSTEER.task import CoSTEERTask
from rdagent.core.utils import cache_with_pickle
# Because we use isinstance to distinguish between different types of tasks, we need to use sub classes to represent different types of tasks
class EnsembleTask(CoSTEERTask):
pass
@@ -0,0 +1,124 @@
ensemble_coder:
system: |-
You are a world-class data scientist and machine learning engineer with deep expertise in statistics, mathematics, and computer science.
Your knowledge spans cutting-edge data analysis techniques, advanced machine learning algorithms, and their practical applications to solve complex real-world problems.
## Task Description
Currently, you are working on model ensemble implementation. Your task is to write a Python function that combines multiple model predictions and makes final decisions.
Your specific task as follows:
{{ task_desc }}
## Competition Information for This Task
{{ competition_info }}
{% if queried_similar_successful_knowledge|length != 0 or queried_former_failed_knowledge|length != 0 %}
## Relevant Information for This Task
{% endif %}
{% if queried_similar_successful_knowledge|length != 0 %}
--------- Successful Implementations for Similar Models ---------
====={% for similar_successful_knowledge in queried_similar_successful_knowledge %} Model {{ loop.index }}:=====
{{ similar_successful_knowledge.target_task.get_task_information() }}
=====Code:=====
{{ similar_successful_knowledge.implementation.file_dict["ensemble.py"] }}
{% endfor %}
{% endif %}
{% if queried_former_failed_knowledge|length != 0 %}
--------- Previous Failed Attempts ---------
{% for former_failed_knowledge in queried_former_failed_knowledge %} Attempt {{ loop.index }}:
=====Code:=====
{{ former_failed_knowledge.implementation.file_dict["ensemble.py"] }}
=====Feedback:=====
{{ former_failed_knowledge.feedback }}
{% endfor %}
{% endif %}
## Guidelines
1. The function's code is associated with several other functions including a data loader, feature engineering, and model training. all codes are as follows:
{{ all_code }}
2. You should avoid using logging module to output information in your generated code, and instead use the print() function.
{% include "scenarios.data_science.share:guidelines.coding" %}
## Output Format
{% if out_spec %}
{{ out_spec }}
{% else %}
Please response the code in the following json format. Here is an example structure for the JSON output:
{
"code": "The Python code as a string."
}
{% endif %}
user: |-
--------- Code Specification ---------
{{ code_spec }}
{% if latest_code %}
--------- Former code ---------
{{ latest_code }}
{% if latest_code_feedback is not none %}
--------- Feedback to former code ---------
{{ latest_code_feedback }}
{% endif %}
The former code contains errors. You should correct the code based on the provided information, ensuring you do not repeat the same mistakes.
{% endif %}
ensemble_eval:
system: |-
You are a data scientist responsible for evaluating ensemble implementation code generation.
## Task Description
{{ task_desc }}
## Ensemble Code
```python
{{ code }}
```
## Testing Process
The ensemble code is tested using the following script:
```python
{{ test_code }}
```
You will analyze the execution results based on the test output provided.
{% if workflow_stdout is not none %}
### Whole Workflow Consideration
The ensemble code is part of the whole workflow. The user has executed the entire pipeline and provided additional stdout.
**Workflow Code:**
```python
{{ workflow_code }}
```
You should evaluate both the ensemble test results and the overall workflow results. **Approve the code only if both tests pass.**
{% endif %}
The metric used for scoring the predictions:
**{{ metric_name }}**
## Evaluation Criteria
- You will be given the standard output (`stdout`) from the ensemble test and, if applicable, the workflow test.
- Code should have no try-except blocks because they can hide errors.
- Check whether the code implement the scoring process using the given metric.
- The stdout includes the local variable values from the ensemble code execution. Check whether the validation score is calculated correctly.
Please respond with your feedback in the following JSON format and order
```json
{
"execution": "Describe how well the ensemble executed, including any errors or issues encountered. Append all error messages and full traceback details without summarizing or omitting any information.",
"return_checking": "Detail the checks performed on the ensemble results, including shape and value validation.",
"code": "Assess code quality, readability, and adherence to specifications.",
"final_decision": <true/false>
}
```
user: |-
--------- Ensemble test stdout ---------
{{ stdout }}
{% if workflow_stdout is not none %}
--------- Whole workflow test stdout ---------
{{ workflow_stdout }}
{% endif %}
@@ -0,0 +1,58 @@
"""
Helper functions for testing the ensemble coder(CoSTEER-based) component.
"""
import sys
from pathlib import Path
from rdagent.components.coder.data_science.ensemble import EnsembleCoSTEER
from rdagent.components.coder.data_science.ensemble.exp import EnsembleTask
from rdagent.scenarios.data_science.experiment.experiment import DSExperiment
from rdagent.scenarios.data_science.scen import KaggleScen
# Add the competition folder to path
COMPETITION_PATH = (
Path(__file__).parent.parent.parent.parent.parent
/ "scenarios"
/ "kaggle"
/ "tpl_ex"
/ "aerial-cactus-identification"
)
sys.path.append(str(COMPETITION_PATH))
EnsembleExperiment = DSExperiment
def load_ensemble_spec():
spec_path = COMPETITION_PATH / "spec" / "ensemble.md"
with open(spec_path, "r") as f:
return f.read()
def develop_one_competition(competition: str):
# Initialize scenario and coder
scen = KaggleScen(competition=competition)
ensemble_coder = EnsembleCoSTEER(scen)
# Load ensemble specification
ensemble_spec = load_ensemble_spec()
# Create the ensemble task with actual data context and specification
task = EnsembleTask(
name="EnsembleTask",
description="""
Implement ensemble and decision making for model predictions.
""",
)
exp = EnsembleExperiment(pending_tasks_list=[task])
# Injecting the corresponding specification
exp.experiment_workspace.inject_files(**{"spec/ensemble.md": ensemble_spec})
# Develop the experiment
exp = ensemble_coder.develop(exp)
return exp
if __name__ == "__main__":
develop_one_competition("aerial-cactus-identification")
@@ -0,0 +1,142 @@
import json
from pathlib import Path
from typing import Dict
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER import CoSTEER
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEERMultiEvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.CoSTEER.evolving_strategy import (
MultiProcessEvolvingStrategy,
)
from rdagent.components.coder.CoSTEER.knowledge_management import (
CoSTEERQueriedKnowledge,
)
from rdagent.components.coder.data_science.conf import DSCoderCoSTEERSettings
from rdagent.components.coder.data_science.feature.eval import FeatureCoSTEEREvaluator
from rdagent.components.coder.data_science.feature.exp import FeatureTask
from rdagent.core.exception import CoderError
from rdagent.core.experiment import FBWorkspace
from rdagent.core.scenario import Scenario
from rdagent.oai.llm_utils import APIBackend
from rdagent.utils.agent.ret import PythonAgentOut
from rdagent.utils.agent.tpl import T
DIRNAME = Path(__file__).absolute().resolve().parent
class FeatureMultiProcessEvolvingStrategy(MultiProcessEvolvingStrategy):
def implement_one_task(
self,
target_task: FeatureTask,
queried_knowledge: CoSTEERQueriedKnowledge | None = None,
workspace: FBWorkspace | None = None,
prev_task_feedback: CoSTEERSingleFeedback | None = None,
) -> dict[str, str]:
# return a workspace with "load_data.py", "spec/load_data.md" inside
# assign the implemented code to the new workspace.
feature_information_str = target_task.get_task_information()
# 1. query
queried_similar_successful_knowledge = (
queried_knowledge.task_to_similar_task_successful_knowledge[feature_information_str]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
queried_knowledge.task_to_former_failed_traces[feature_information_str]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
[
knowledge
for knowledge in queried_former_failed_knowledge[0]
if knowledge.implementation.file_dict.get("feature.py") != workspace.file_dict.get("feature.py")
],
queried_former_failed_knowledge[1],
)
# 2. code
system_prompt = T(".prompts:feature_coder.system").r(
competition_info=self.scen.get_scenario_all_desc(eda_output=workspace.file_dict.get("EDA.md", None)),
task_desc=feature_information_str,
data_loader_code=workspace.file_dict.get("load_data.py"),
queried_similar_successful_knowledge=queried_similar_successful_knowledge,
queried_former_failed_knowledge=queried_former_failed_knowledge[0],
out_spec=PythonAgentOut.get_spec(),
)
code_spec = (
workspace.file_dict["spec/feature.md"]
if DS_RD_SETTING.spec_enabled
else T("scenarios.data_science.share:component_spec.general").r(
spec=T("scenarios.data_science.share:component_spec.FeatureEng").r(),
test_code=(DIRNAME / "eval_tests" / "feature_test.txt").read_text(),
)
)
user_prompt = T(".prompts:feature_coder.user").r(
code_spec=code_spec,
latest_code=workspace.file_dict.get("feature.py"),
latest_code_feedback=prev_task_feedback,
)
for _ in range(5):
feature_code = PythonAgentOut.extract_output(
APIBackend().build_messages_and_create_chat_completion(
user_prompt=user_prompt,
system_prompt=system_prompt,
)
)
if feature_code != workspace.file_dict.get("feature.py"):
break
else:
user_prompt = user_prompt + "\nPlease avoid generating same code to former code!"
else:
raise CoderError("Failed to generate a new feature code.")
return {
"feature.py": feature_code,
}
def assign_code_list_to_evo(self, code_list: list[dict[str, str]], evo):
"""
Assign the code list to the evolving item.
The code list is aligned with the evolving item's sub-tasks.
If a task is not implemented, put a None in the list.
"""
for index in range(len(evo.sub_tasks)):
if code_list[index] is None:
continue
if evo.sub_workspace_list[index] is None:
# evo.sub_workspace_list[index] = FBWorkspace(target_task=evo.sub_tasks[index])
evo.sub_workspace_list[index] = evo.experiment_workspace
evo.sub_workspace_list[index].inject_files(**code_list[index])
return evo
class FeatureCoSTEER(CoSTEER):
def __init__(
self,
scen: Scenario,
*args,
**kwargs,
) -> None:
settings = DSCoderCoSTEERSettings()
eva = CoSTEERMultiEvaluator(
FeatureCoSTEEREvaluator(scen=scen), scen=scen
) # Please specify whether you agree running your eva in parallel or not
es = FeatureMultiProcessEvolvingStrategy(scen=scen, settings=settings)
super().__init__(
*args,
settings=settings,
eva=eva,
es=es,
evolving_version=2,
scen=scen,
max_loop=DS_RD_SETTING.coder_max_loop,
**kwargs,
)
@@ -0,0 +1,81 @@
import json
import re
from pathlib import Path
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEEREvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.data_science.conf import get_ds_env
from rdagent.components.coder.data_science.utils import remove_eda_part
from rdagent.core.evolving_framework import QueriedKnowledge
from rdagent.core.experiment import FBWorkspace, Task
from rdagent.utils.agent.tpl import T
from rdagent.utils.agent.workflow import build_cls_from_json_with_retry
from rdagent.utils.fmt import shrink_text
DIRNAME = Path(__file__).absolute().resolve().parent
FeatureEvalFeedback = CoSTEERSingleFeedback
class FeatureCoSTEEREvaluator(CoSTEEREvaluator):
def evaluate(
self,
target_task: Task,
implementation: FBWorkspace,
gt_implementation: FBWorkspace,
queried_knowledge: QueriedKnowledge = None,
**kwargs,
) -> FeatureEvalFeedback:
target_task_information = target_task.get_task_information()
if (
queried_knowledge is not None
and target_task_information in queried_knowledge.success_task_to_knowledge_dict
):
return queried_knowledge.success_task_to_knowledge_dict[target_task_information].feedback
elif queried_knowledge is not None and target_task_information in queried_knowledge.failed_task_info_set:
return FeatureEvalFeedback(
execution="This task has failed too many times, skip implementation.",
return_checking="This task has failed too many times, skip implementation.",
code="This task has failed too many times, skip implementation.",
final_decision=False,
)
env = get_ds_env(extra_volumes={self.scen.debug_path: T("scenarios.data_science.share:scen.input_path").r()})
# TODO: do we need to clean the generated temporary content?
fname = "test/feature_test.py"
test_code = (DIRNAME / "eval_tests" / "feature_test.txt").read_text()
implementation.inject_files(**{fname: test_code})
stdout, ret_code = implementation.execute_ret_code(env=env, entry=f"python {fname}")
if "main.py" in implementation.file_dict and ret_code == 0:
workflow_stdout = implementation.execute(env=env, entry="python main.py")
workflow_stdout = remove_eda_part(workflow_stdout)
else:
workflow_stdout = None
system_prompt = T(".prompts:feature_eval.system").r(
task_desc=target_task.get_task_information(),
test_code=test_code,
code=implementation.file_dict["feature.py"],
workflow_stdout=workflow_stdout,
workflow_code=implementation.all_codes,
)
user_prompt = T(".prompts:feature_eval.user").r(
stdout=shrink_text(stdout),
workflow_stdout=workflow_stdout,
)
fb = build_cls_from_json_with_retry(
FeatureEvalFeedback,
system_prompt=system_prompt,
user_prompt=user_prompt,
init_kwargs_update_func=FeatureEvalFeedback.val_and_update_init_dict,
)
fb.final_decision = fb.final_decision and ret_code == 0
return fb
@@ -0,0 +1,114 @@
"""
Tests for `feat_eng` in feature.py
"""
from copy import deepcopy
import sys
import numpy as np
import pandas as pd
from feature import feat_eng
from load_data import load_data
import reprlib
aRepr = reprlib.Repr()
aRepr.maxother=300
X, y, X_test, test_ids = load_data()
print("X:", aRepr.repr(X))
print("y:", aRepr.repr(y))
print("X_test:", aRepr.repr(X_test))
print("test_ids", aRepr.repr(test_ids))
print(f"X.shape: {X.shape}" if hasattr(X, 'shape') else f"X length: {len(X)}")
print(f"y.shape: {y.shape}" if hasattr(y, 'shape') else f"y length: {len(y)}")
print(f"X_test.shape: {X_test.shape}" if hasattr(X_test, 'shape') else f"X_test length: {len(X_test)}")
print(f"test_ids length: {len(test_ids)}")
X_loaded = deepcopy(X)
y_loaded = deepcopy(y)
X_test_loaded = deepcopy(X_test)
import sys
import reprlib
from joblib.memory import MemorizedFunc
def get_original_code(func):
if isinstance(func, MemorizedFunc):
return func.func.__code__
return func.__code__
def debug_info_print(func):
def wrapper(*args, **kwargs):
original_code = get_original_code(func)
def local_trace(frame, event, arg):
if event == "return" and frame.f_code == original_code:
print("\n" + "="*20 + "Running feat_eng code, local variable values:" + "="*20)
for k, v in frame.f_locals.items():
printed = aRepr.repr(v)
print(f"{k}:\n {printed}")
print("="*20 + "Local variable values end" + "="*20)
return local_trace
sys.settrace(local_trace)
try:
return func(*args, **kwargs)
finally:
sys.settrace(None)
return wrapper
X, y, X_test = debug_info_print(feat_eng)(X, y, X_test)
def get_length(data):
return data.shape[0] if hasattr(data, 'shape') else len(data)
def get_width(data):
return 1 if isinstance(data, list) else data.shape[1:]
def get_column_list(data):
return data.columns.tolist() if isinstance(data, pd.DataFrame) else None
assert X is not None, "The feature engineering function returned None for X."
assert y is not None, "The feature engineering function returned None for y."
assert X_test is not None, "The feature engineering function returned None for X_test."
assert get_length(X_test) == get_length(
test_ids
), f"Mismatch in length of test images and test IDs: X_test ({get_length(X_test)}) and test_ids ({get_length(test_ids)})"
assert get_length(X) == get_length(
y
), f"Mismatch in length of training images and labels: X ({get_length(X)}) and y ({get_length(y)})"
assert get_length(X) != 0, f"Training data is empty."
assert get_length(y) != 0, f"Training labels are empty."
assert get_length(X_test) != 0, f"Test data is empty."
assert get_width(X) == get_width(
X_test
), "Mismatch in width of training and test data. Width means the number of features."
if isinstance(X, pd.DataFrame) and isinstance(X_test, pd.DataFrame):
assert get_column_list(X) == get_column_list(X_test), "Mismatch in column names of training and test data."
if isinstance(X, pd.DataFrame):
def normalize_dtype(dtype):
return "numeric" if np.issubdtype(dtype, np.number) else str(dtype)
X_dtypes_unique_sorted = sorted(set(normalize_dtype(dt) for dt in X.dtypes.unique()))
X_loaded_dtypes_unique_sorted = sorted(set(normalize_dtype(dt) for dt in X_loaded.dtypes.unique()))
X_dtypes_unique_sorted_new = [
dt for dt in X_dtypes_unique_sorted if dt not in X_loaded_dtypes_unique_sorted and dt != "object"
]
assert (
np.dtypes.ObjectDType in X_loaded_dtypes_unique_sorted or len(X_dtypes_unique_sorted_new) == 0
), f"feature engineering has produced new data types which is not allowed, data loader data types are {X_loaded_dtypes_unique_sorted} and feature engineering data types are {X_dtypes_unique_sorted}"
print(
"Feature Engineering test passed successfully. All checks including length, width, and data types have been validated."
)
@@ -0,0 +1,13 @@
import pickle
import site
import traceback
from pathlib import Path
from typing import Dict, Optional
from rdagent.components.coder.CoSTEER.task import CoSTEERTask
from rdagent.core.utils import cache_with_pickle
# Because we use isinstance to distinguish between different types of tasks, we need to use sub classes to represent different types of tasks
class FeatureTask(CoSTEERTask):
pass
@@ -0,0 +1,131 @@
feature_coder:
system: |-
You are a world-class data scientist and machine learning engineer with deep expertise in statistics, mathematics, and computer science.
Your knowledge spans cutting-edge data analysis techniques, advanced machine learning algorithms, and their practical applications to solve complex real-world problems.
## Task Description
{{ task_desc }}
## Competition Information for This Task
{{ competition_info }}
{% if queried_similar_successful_knowledge|length != 0 or queried_former_failed_knowledge|length != 0 %}
## Relevant Information for This Task
{% endif %}
{% if queried_similar_successful_knowledge|length != 0 %}
--------- Successful Implementations for Similar Models ---------
====={% for similar_successful_knowledge in queried_similar_successful_knowledge %} Model {{ loop.index }}:=====
{{ similar_successful_knowledge.target_task.get_task_information() }}
=====Code:=====
{{ similar_successful_knowledge.implementation.file_dict["feature.py"] }}
{% endfor %}
{% endif %}
{% if queried_former_failed_knowledge|length != 0 %}
--------- Previous Failed Attempts ---------
{% for former_failed_knowledge in queried_former_failed_knowledge %} Attempt {{ loop.index }}:
=====Code:=====
{{ former_failed_knowledge.implementation.file_dict["feature.py"] }}
=====Feedback:=====
{{ former_failed_knowledge.feedback }}
{% endfor %}
{% endif %}
## Guidelines
1. If feature engineering is unnecessary or should be combined with model training, you may skip this step.
2. Be cautious of any column drop in the code. Dropping a column easily without any more attempts, it may not be a good practice.
3. The function input is the output of the following data loader:
```python
{{ data_loader_code }}
```
4. **Additional Guidance:**
- If a previous attempt exists, improve upon it without repeating mistakes.
- If errors indicate a missing file, find a way to download it or implement an alternative solution.
- You should avoid using logging module to output information in your generated code, and instead use the print() function.
5. You should use the following cache decorator to cache the results of the function:
```python
from joblib import Memory
memory = Memory(location='{% include "scenarios.data_science.share:scen.cache_path" %}', verbose=0)
@memory.cache```
6. Coding tricks:
- If the input consists of a batch of file paths and you need to modify the file contents to complete your feature engineering task, you can accomplish your feature engineering task by modifying these files and creating new files in a subfolder within "{% include "scenarios.data_science.share:scen.cache_path" %}" (this path is persistent, otherwise you may lose your created file). Then the new file paths are returned.
{% include "scenarios.data_science.share:guidelines.coding" %}
## Output Format
{% if out_spec %}
{{ out_spec }}
{% else %}
Please response the code in the following json format. Here is an example structure for the JSON output:
{
"code": "The Python code as a string."
}
{% endif %}
user: |-
--------- Code Specification ---------
{{ code_spec }}
{% if latest_code %}
--------- Former code ---------
{{ latest_code }}
{% if latest_code_feedback is not none %}
--------- Feedback to former code ---------
{{ latest_code_feedback }}
{% endif %}
The former code contains errors. You should correct the code based on the provided information, ensuring you do not repeat the same mistakes.
{% endif %}
feature_eval:
system: |-
You are a data scientist responsible for evaluating feature engineering code generation.
## Task Description
{{ task_desc }}
## Feature Engineering Code
```python
{{ code }}
```
## Testing Process
The feature engineering code is tested using the following script:
```python
{{ test_code }}
```
You will analyze the execution results based on the test output provided.
{% if workflow_stdout is not none %}
### Whole Workflow Consideration
The feature engineering code is part of the whole workflow. The user has executed the entire pipeline and provided additional stdout.
**Workflow Code:**
```python
{{ workflow_code }}
```
You should evaluate both the feature engineering test results and the overall workflow results. **Approve the code only if both tests pass.**
{% endif %}
## Evaluation Criteria
You will be given the standard output (`stdout`) from the feature engineering test and, if applicable, the workflow test.
Please respond with your feedback in the following JSON format and order
```json
{
"execution": "Describe how well the feature engineering executed, including any errors or issues encountered. Append all error messages and full traceback details without summarizing or omitting any information.",
"return_checking": "Evaluate the correctness and integrity of processed data, checking for missing values, incorrect transformations, and data consistency.",
"code": "Assess code quality, readability, and adherence to specifications. Consider efficiency, including whether the code utilizes multi-threading or GPU acceleration for optimization.",
"final_decision": <true/false>
}
```
user: |-
--------- Feature engineering test stdout ---------
{{ stdout }}
{% if workflow_stdout is not none %}
--------- Whole workflow test stdout ---------
{{ workflow_stdout }}
{% endif %}
@@ -0,0 +1,37 @@
"""
Helper functions for testing the feature coder(CoSTEER-based) component.
- Does the developer loop work correctly
It is NOT:
- it is not interface unittest(i.e. workspace evaluator in the CoSTEER Loop)
"""
from rdagent.components.coder.data_science.feature import FeatureCoSTEER
from rdagent.components.coder.data_science.feature.exp import FeatureTask
from rdagent.scenarios.data_science.experiment.experiment import DSExperiment
from rdagent.scenarios.data_science.scen import KaggleScen
def develop_one_competition(competition: str): # -> experiment
scen = KaggleScen(competition=competition)
feature_coder = FeatureCoSTEER(scen)
with open("./rdagent/scenarios/kaggle/tpl_ex/aerial-cactus-identification/spec/feature.md", "r") as file:
feat_spec = file.read()
# Create the experiment
ft = FeatureTask(name="FeatureTask", description=scen.get_competition_full_desc())
exp = DSExperiment(
sub_tasks=[ft],
)
with open("./rdagent/scenarios/kaggle/tpl_ex/aerial-cactus-identification/load_data.py", "r") as file:
load_data_code = file.read()
exp.experiment_workspace.inject_files(**{"load_data.py": load_data_code, "spec/feature.md": feat_spec})
# Develop the experiment
exp = feature_coder.develop(exp)
if __name__ == "__main__":
develop_one_competition("aerial-cactus-identification")
@@ -0,0 +1,174 @@
from pathlib import Path
from typing import Dict
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER import CoSTEER
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEERMultiEvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.CoSTEER.evolving_strategy import (
MultiProcessEvolvingStrategy,
)
from rdagent.components.coder.CoSTEER.knowledge_management import (
CoSTEERQueriedKnowledge,
)
from rdagent.components.coder.data_science.conf import DSCoderCoSTEERSettings
from rdagent.components.coder.data_science.model.eval import (
ModelGeneralCaseSpecEvaluator,
)
from rdagent.components.coder.data_science.model.exp import ModelTask
from rdagent.core.exception import CoderError
from rdagent.core.experiment import FBWorkspace
from rdagent.core.scenario import Scenario
from rdagent.oai.llm_utils import APIBackend
from rdagent.utils.agent.ret import PythonBatchEditOut
from rdagent.utils.agent.tpl import T
DIRNAME = Path(__file__).absolute().resolve().parent
class ModelMultiProcessEvolvingStrategy(MultiProcessEvolvingStrategy):
def implement_one_task(
self,
target_task: ModelTask,
queried_knowledge: CoSTEERQueriedKnowledge | None = None,
workspace: FBWorkspace | None = None,
prev_task_feedback: CoSTEERSingleFeedback | None = None,
) -> dict[str, str]:
model_information_str = target_task.get_task_information()
# 1. query
queried_similar_successful_knowledge = (
queried_knowledge.task_to_similar_task_successful_knowledge[model_information_str]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
queried_knowledge.task_to_former_failed_traces[model_information_str]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
[
knowledge
for knowledge in queried_former_failed_knowledge[0]
if knowledge.implementation.file_dict.get(f"{target_task.name}.py")
!= workspace.file_dict.get(f"{target_task.name}.py")
],
queried_former_failed_knowledge[1],
)
# 2. code
system_prompt = T(".prompts:model_coder.system").r(
task_desc=model_information_str,
competition_info=self.scen.get_scenario_all_desc(eda_output=workspace.file_dict.get("EDA.md", None)),
data_loader_code=workspace.file_dict.get("load_data.py"),
feature_code=workspace.file_dict["feature.py"],
queried_similar_successful_knowledge=queried_similar_successful_knowledge,
queried_former_failed_knowledge=queried_former_failed_knowledge[0],
out_spec=PythonBatchEditOut.get_spec(),
)
# user_prompt = T(".prompts:model_coder.user").r(
# model_spec=workspace.file_dict["spec/model.md"],
# feature_code=workspace.file_dict["feature.py"],
# latest_code=workspace.file_dict.get(f"{target_task.name}.py", None),
# )
# We want to use a simpler way to
code_spec = (
workspace.file_dict["spec/model.md"]
if DS_RD_SETTING.spec_enabled
else T("scenarios.data_science.share:component_spec.general").r(
spec=T("scenarios.data_science.share:component_spec.Model").r(),
test_code=(DIRNAME / "eval_tests" / "model_test.txt").read_text().replace("model01", target_task.name),
)
)
user_prompt = T(".prompts:model_coder.user_general").r(
code_spec=code_spec,
latest_model_code=workspace.get_codes(
r"^model_(?!test)\w+\.py$"
), # TODO: If we have high failure rate here, we should clean this step with less information.
latest_code_feedback=prev_task_feedback,
)
for _ in range(5):
batch_edit = PythonBatchEditOut.extract_output(
APIBackend().build_messages_and_create_chat_completion(
user_prompt=user_prompt,
system_prompt=system_prompt,
)
)
if not all(i.startswith("model_") for i in batch_edit.keys()):
user_prompt += "\nYou should only update model codes!"
continue
# 3. post process to align file name to the task name
# we assumpt batch_edit only contains one model file update.
batch_edit = {
(f"{target_task.name}.py" if value != "__DEL__" and key != f"{target_task.name}.py" else key): value
for key, value in batch_edit.items()
}
user_prompt = user_prompt + "\nPlease avoid generating same code to former code!"
# TODO: besides same code problem, we should also consider other problems lead to retry.
if f"{target_task.name}.py" not in batch_edit:
continue
if batch_edit and max(len(i.encode("utf-8")) for i in batch_edit.keys()) > 255:
continue
if batch_edit[f"{target_task.name}.py"] != "__DEL__" and batch_edit[
f"{target_task.name}.py"
] != workspace.file_dict.get(f"{target_task.name}.py"):
break
# If the task involves model removal, assume it can only process one model at a time.
if len(batch_edit) == 1 and batch_edit[f"{target_task.name}.py"] == "__DEL__":
break
else:
raise CoderError("Failed to generate a new model code.")
return batch_edit
def assign_code_list_to_evo(self, code_list: list[dict[str, str]], evo):
"""
Assign the code list to the evolving item.
The code list is aligned with the evolving item's sub-tasks.
If a task is not implemented, put a None in the list.
"""
for index in range(len(evo.sub_tasks)):
if code_list[index] is None:
continue
if evo.sub_workspace_list[index] is None:
# evo.sub_workspace_list[index] = FBWorkspace(target_task=evo.sub_tasks[index])
evo.sub_workspace_list[index] = evo.experiment_workspace
evo.sub_workspace_list[index].inject_files(**code_list[index])
return evo
class ModelCoSTEER(CoSTEER):
def __init__(
self,
scen: Scenario,
*args,
**kwargs,
) -> None:
settings = DSCoderCoSTEERSettings()
eva = CoSTEERMultiEvaluator(
ModelGeneralCaseSpecEvaluator(scen=scen), scen=scen
) # Please specify whether you agree running your eva in parallel or not
# eva = ModelGeneralCaseSpecEvaluator(scen=scen)
es = ModelMultiProcessEvolvingStrategy(scen=scen, settings=settings)
super().__init__(
*args,
settings=settings,
eva=eva,
es=es,
evolving_version=2,
scen=scen,
max_loop=DS_RD_SETTING.coder_max_loop,
**kwargs,
)
@@ -0,0 +1,118 @@
"""
Beyond previous tests
-
"""
import json
import re
from pathlib import Path
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEEREvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.data_science.conf import get_ds_env
from rdagent.components.coder.data_science.utils import remove_eda_part
from rdagent.core.evolving_framework import QueriedKnowledge
from rdagent.core.exception import CoderError
from rdagent.core.experiment import FBWorkspace, Task
from rdagent.oai.llm_utils import APIBackend
from rdagent.utils.agent.tpl import T
from rdagent.utils.agent.workflow import build_cls_from_json_with_retry
DIRNAME = Path(__file__).absolute().resolve().parent
ModelSingleFeedback = CoSTEERSingleFeedback
# Below are unit tests for testing the specification of the implemented model ------------------
class ModelGeneralCaseSpecEvaluator(CoSTEEREvaluator):
"""
Motivation case:
- Simplest case, we already split the data into train_data, valid_data, and test_data. We require the model to learn (optionally validate on valid data), and infer on test data.
Test workflow:
- Build train, valid, and test data to run it, and test the output (e.g., shape, etc.)
"""
def evaluate(
self,
target_task: Task,
implementation: FBWorkspace,
gt_implementation: FBWorkspace,
queried_knowledge: QueriedKnowledge = None,
**kwargs,
) -> ModelSingleFeedback:
target_task_information = target_task.get_task_information()
if (
queried_knowledge is not None
and target_task_information in queried_knowledge.success_task_to_knowledge_dict
):
return queried_knowledge.success_task_to_knowledge_dict[target_task_information].feedback
elif queried_knowledge is not None and target_task_information in queried_knowledge.failed_task_info_set:
return ModelSingleFeedback(
execution="This task has failed too many times, skip implementation.",
return_checking="This task has failed too many times, skip implementation.",
code="This task has failed too many times, skip implementation.",
final_decision=False,
)
env = get_ds_env(extra_volumes={self.scen.debug_path: T("scenarios.data_science.share:scen.input_path").r()})
if_model_removed = False
if f"{target_task.name}.py" in implementation.file_dict:
fname = "test/model_test.py"
test_code = (
(DIRNAME / "eval_tests" / "model_test.txt").read_text().replace("model01", target_task.name)
) # only check the model changed this time
implementation.inject_files(**{fname: test_code})
stdout, ret_code = implementation.execute_ret_code(env=env, entry=f"python {fname}")
if stdout is None:
raise CoderError(
"The execution output contains too many progress bars and results in the LLM's token size exceeding the limit."
)
else:
ret_code = 0
if_model_removed = True
stdout = f"Model {target_task.name} removal succeeded."
if "main.py" in implementation.file_dict and ret_code == 0:
workflow_stdout = implementation.execute(env=env, entry="python main.py")
workflow_stdout = remove_eda_part(workflow_stdout)
else:
workflow_stdout = None
if if_model_removed:
system_prompt = T(".prompts:model_eval_rm.system").r(
task_desc=target_task.get_task_information(),
workflow_stdout=workflow_stdout,
workflow_code=implementation.all_codes,
)
user_prompt = T(".prompts:model_eval_rm.user").r(
stdout=stdout,
workflow_stdout=workflow_stdout,
)
else:
system_prompt = T(".prompts:model_eval.system").r(
task_desc=target_task.get_task_information(),
test_code=test_code,
code=implementation.file_dict[f"{target_task.name}.py"],
workflow_stdout=workflow_stdout,
workflow_code=implementation.all_codes,
)
user_prompt = T(".prompts:model_eval.user").r(
stdout=stdout,
workflow_stdout=workflow_stdout,
)
fb = build_cls_from_json_with_retry(
ModelSingleFeedback,
system_prompt=system_prompt,
user_prompt=user_prompt,
init_kwargs_update_func=ModelSingleFeedback.val_and_update_init_dict,
)
fb.final_decision = fb.final_decision and ret_code == 0
return fb
@@ -0,0 +1,105 @@
"""
Tests for `model_workflow` in model01.py
"""
import sys
import time
from feature import feat_eng
from load_data import load_data
from model01 import model_workflow
from sklearn.model_selection import train_test_split
def log_execution_results(start_time, val_pred, test_pred, hypers, execution_label):
"""Log the results of a single model execution."""
feedback_str = f"{execution_label} end.\n"
feedback_str += f"Validation predictions shape: {val_pred.shape if val_pred is not None else 'None'}\n"
feedback_str += f"Test predictions shape: {test_pred.shape if test_pred is not None else 'None'}\n"
feedback_str += f"Hyperparameters: {hypers if hypers is not None else 'None'}\n"
feedback_str += f"Execution time: {time.time() - start_time:.2f} seconds.\n"
print(feedback_str)
import reprlib
aRepr = reprlib.Repr()
aRepr.maxother=300
# Load and preprocess data
X, y, test_X, test_ids = load_data()
X, y, test_X = feat_eng(X, y, test_X)
print(f"X.shape: {X.shape}" if hasattr(X, 'shape') else f"X length: {len(X)}")
print(f"y.shape: {y.shape}" if hasattr(y, 'shape') else f"y length: {len(y)}")
print(f"test_X.shape: {test_X.shape}" if hasattr(test_X, 'shape') else f"test_X length: {len(test_X)}")
print(f"test_ids length: {len(test_ids)}")
train_X, val_X, train_y, val_y = train_test_split(X, y, test_size=0.8, random_state=42)
import sys
import reprlib
from joblib.memory import MemorizedFunc
def get_original_code(func):
if isinstance(func, MemorizedFunc):
return func.func.__code__
return func.__code__
print("train_X:", aRepr.repr(train_X))
print("train_y:", aRepr.repr(train_y))
print("val_X:", aRepr.repr(val_X))
print("val_y:", aRepr.repr(val_y))
print(f"train_X.shape: {train_X.shape}" if hasattr(train_X, 'shape') else f"train_X length: {len(train_X)}")
print(f"train_y.shape: {train_y.shape}" if hasattr(train_y, 'shape') else f"train_y length: {len(train_y)}")
print(f"val_X.shape: {val_X.shape}" if hasattr(val_X, 'shape') else f"val_X length: {len(val_X)}")
print(f"val_y.shape: {val_y.shape}" if hasattr(val_y, 'shape') else f"val_y length: {len(val_y)}")
def debug_info_print(func):
def wrapper(*args, **kwargs):
original_code = get_original_code(func)
def local_trace(frame, event, arg):
if event == "return" and frame.f_code == original_code:
print("\n" + "="*20 + "Running model training code, local variable values:" + "="*20)
for k, v in frame.f_locals.items():
printed = aRepr.repr(v)
print(f"{k}:\n {printed}")
print("="*20 + "Local variable values end" + "="*20)
return local_trace
sys.settrace(local_trace)
try:
return func(*args, **kwargs)
finally:
sys.settrace(None)
return wrapper
# First execution
print("The first execution begins.\n")
start_time = time.time()
val_pred, test_pred, hypers = debug_info_print(model_workflow)(
X=train_X,
y=train_y,
val_X=val_X,
val_y=val_y,
test_X=None,
)
log_execution_results(start_time, val_pred, test_pred, hypers, "The first execution")
# Second execution
print("The second execution begins.\n")
start_time = time.time()
val_pred, test_pred, final_hypers = debug_info_print(model_workflow)(
X=train_X,
y=train_y,
val_X=None,
val_y=None,
test_X=test_X,
hyper_params=hypers,
)
log_execution_results(start_time, val_pred, test_pred, final_hypers, "The second execution")
print("Model code test end.")
@@ -0,0 +1,21 @@
from typing import Dict, Optional
from rdagent.components.coder.CoSTEER.task import CoSTEERTask
# Because we use isinstance to distinguish between different types of tasks, we need to use sub classes to represent different types of tasks
class ModelTask(CoSTEERTask):
def __init__(
self,
name: str,
description: str,
*args,
**kwargs,
) -> None:
super().__init__(name=name, description=description, *args, **kwargs)
def get_task_information(self):
task_desc = f"""name: {self.name}
description: {self.description}
"""
return task_desc
@@ -0,0 +1,186 @@
model_coder:
system: |-
You are a world-class data scientist and machine learning engineer with deep expertise in statistics, mathematics, and computer science.
Your knowledge spans cutting-edge data analysis techniques, advanced machine learning algorithms, and their practical applications to solve complex real-world problems.
## Task Description
{{ task_desc }}
## Competition Information for This Task
{{ competition_info }}
{% if queried_similar_successful_knowledge|length != 0 or queried_former_failed_knowledge|length != 0 %}
## Relevant Information for This Task
{% endif %}
{% if queried_similar_successful_knowledge|length != 0 %}
--------- Successful Implementations for Similar Models ---------
====={% for similar_successful_knowledge in queried_similar_successful_knowledge %} Model {{ loop.index }}:=====
{{ similar_successful_knowledge.target_task.get_task_information() }}
=====Code:=====
{{ similar_successful_knowledge.implementation.file_dict[similar_successful_knowledge.target_task.name ~ '.py'] }}
{% endfor %}
{% endif %}
{% if queried_former_failed_knowledge|length != 0 %}
--------- Previous Failed Attempts ---------
{% for former_failed_knowledge in queried_former_failed_knowledge %} Attempt {{ loop.index }}:
=====Code:=====
{{ former_failed_knowledge.implementation.file_dict[former_failed_knowledge.target_task.name ~ '.py'] }}
=====Feedback:=====
{{ former_failed_knowledge.feedback }}
{% endfor %}
{% endif %}
## Guidelines
1. The function's input is from the output of a feature engineering function whose input is the output of a data loading function. The data loader function and feature engineering function code is as follows:
--------- Data Loader Code ---------
{{ data_loader_code }}
--------- Feature Engineering Code ---------
{{ feature_code }}
2. You should avoid using logging module to output information in your generated code, and instead use the print() function.
3. If the model can both be implemented by PyTorch and Tensorflow, please use pytorch for broader compatibility.
4. You should use the following cache decorator to cache the results of the function:
```python
from joblib import Memory
memory = Memory(location='{% include "scenarios.data_science.share:scen.cache_path" %}', verbose=0)
@memory.cache``
{% include "scenarios.data_science.share:guidelines.coding" %}
## Output Format
{% if out_spec %}
{{ out_spec }}
The file name should be the model name described in the model task in the format "{task_name}.py". You should always follow this name format.
{% else %}
Please response the code in the following json format. Here is an example structure for the JSON output:
{
"code": "The Python code as a string."
}
{% endif %}
user_general: |-
--------- Code Specification ---------
{{ code_spec }}
--------- Former model code ---------
{% if latest_model_code|length == 0 %}
So far the workspace is empty. No model code has been implemented yet.
{% else %}
{{ latest_model_code }}
{% if latest_code_feedback is not none %}
--------- Feedback to former code ---------
{{ latest_code_feedback }}
{% endif %}
{% endif %}
model_eval:
system: |-
You are a data scientist responsible for evaluating model building code generation.
## Task Description
{{ task_desc }}
## Model Building Code
```python
{{ code }}
```
## Testing Process
The model building code is tested using the following script:
```python
{{ test_code }}
```
### Execution Phases
The model is tested in two phases:
1. Initial Training Phase:
- The model receives **train and valid inputs** with **empty hyperparameters**.
- The focus is on verifying whether the model successfully trains and produces **valid outputs and hyperparameter outputs**.
2. Retraining Phase:
- The model receives **train and test inputs** (without valid inputs).
- The hyperparameters generated from the first phase are passed back for **retraining**.
### Key Requirements for Approval
A model can only be approved if it meets all of the following conditions:
1. Hyperparameter Handling
- If hyperparameters are returned, they must include an early stop round.
- The hyperparameters must be correctly utilized in the model for retraining.
- If the early stop round is provided, it must be used in the model implementation.
2. The model output shape must strictly match the specifications in `spec.md`.
{% if workflow_stdout is not none %}
### Whole Workflow Consideration
The model building code is part of the whole workflow. The user has executed the entire pipeline and provided additional stdout.
**Workflow Code:**
```python
{{ workflow_code }}
```
You should evaluate both the model building test results and the overall workflow results. **Approve the code only if both tests pass.**
{% endif %}
## Evaluation Criteria
You will be given the standard output (`stdout`) from the model building test and, if applicable, the workflow test.
[Note] If no stdout for model buidling test is provided, the model failed due to a timeout or out-of-memory error. You should analyze potential optimizations.
Please respond with your feedback in the following JSON format and order
```json
{
"execution": "Describe how well the model building executed, including any errors or issues encountered. Append all error messages and full traceback details without summarizing or omitting any information.",
"return_checking": "Check the generated value, including whether the value is generated and comparing the shape of the model output with the requirement in spec.md. You also need to check whether the hyperparameters used for retraining are correctly returned during the test execution of the model.",
"code": "Assess code quality, readability, and adherence to specifications. Consider efficiency, including whether the code utilizes multi-threading or GPU acceleration for optimization.",
"final_decision": <true/false>
}
```
user: |-
--------- Model building test stdout ---------
{{ stdout }}
{% if workflow_stdout is not none %}
--------- Whole workflow test stdout ---------
{{ workflow_stdout }}
{% endif %}
model_eval_rm:
system: |-
You are a data scientist responsible for evaluating model removal process.
## Task Description
{{ task_desc }}
{% if workflow_stdout is not none %}
## Whole Workflow Consideration
The model building code is part of the whole workflow. The user has executed the entire pipeline and provided additional stdout.
**Workflow Code:**
```python
{{ workflow_code }}
```
You should evaluate both the model removal test results and the overall workflow results. **Approve the code only if both tests pass.**
{% endif %}
## Evaluation Criteria
You will be given the standard output (`stdout`) from the model removal test and, if applicable, the workflow test.
Please respond with your feedback in the following JSON format and order
```json
{
"execution": "Describe how well the model removal executed, including any errors or issues encountered. Append all error messages and full traceback details without summarizing or omitting any information.",
"return_checking": "Check the generated value, including whether the value is generated and comparing the shape of the model output with the requirement in spec.md.",
"code": "Assess code quality, readability, and adherence to specifications.",
"final_decision": <true/false>
}
```
user: |-
--------- Model removal test stdout ---------
{{ stdout }}
{% if workflow_stdout is not none %}
--------- Whole workflow test stdout ---------
{{ workflow_stdout }}
{% endif %}
@@ -0,0 +1,67 @@
"""
Generate dataset to test the model workflow output
"""
from pathlib import Path
from rdagent.components.coder.CoSTEER.config import CoSTEER_SETTINGS
from rdagent.components.coder.data_science.model import ModelCoSTEER
from rdagent.components.coder.data_science.model.eval import (
ModelGeneralCaseSpecEvaluator,
)
from rdagent.components.coder.data_science.model.exp import ModelTask
from rdagent.core.experiment import FBWorkspace
from rdagent.scenarios.data_science.experiment.experiment import DSExperiment
from rdagent.scenarios.data_science.scen import KaggleScen
# Take tasks, spec.md and feat as input, generate a feedback as output
def develop_one_competition(competition: str):
scen = KaggleScen(competition=competition)
model_coder = ModelCoSTEER(scen)
# Create the task
mt = ModelTask(
name="ModelTask",
description="A CNN Model",
model_type="CNN",
architecture="\hat{y}_u = CNN(X_u)",
# variables="variables: {'\\hat{y}_u': 'The predicted output for node u', 'X_u': 'The input features for node u'}",
hyperparameters="...",
base_code="",
)
tpl_ex_path = Path(__file__).resolve() / Path("rdagent/scenarios/kaggle/tpl_ex").resolve() / competition
injected_file_names = ["spec/model.md", "load_data.py", "feature.py", "model01.py"]
modelexp = FBWorkspace()
for file_name in injected_file_names:
file_path = tpl_ex_path / file_name
modelexp.inject_files(**{file_name: file_path.read_text()})
mt.base_code += modelexp.file_dict["model01.py"]
exp = DSExperiment(
sub_tasks=[mt],
)
# Test the evaluator:
"""eva = ModelGeneralCaseSpecEvaluator(scen=scen)
exp.feedback = eva.evaluate(target_task=mt, queried_knowledge=None, implementation=modelexp, gt_implementation=None)
print(exp.feedback)"""
# Test the evolving strategy:
"""es = ModelMultiProcessEvolvingStrategy(scen=scen, settings=CoSTEER_SETTINGS)
new_code = es.implement_one_task(target_task=mt, queried_knowledge=None, workspace=modelexp)
print(new_code)"""
# Run the experiment
for file_name in injected_file_names:
file_path = tpl_ex_path / file_name
exp.experiment_workspace.inject_files(**{file_name: file_path.read_text()})
exp = model_coder.develop(exp)
if __name__ == "__main__":
develop_one_competition("aerial-cactus-identification")
# dotenv run -- python rdagent/components/coder/data_science/model/test.py
@@ -0,0 +1,169 @@
"""
Loop should not large change exclude
- Action Choice[current data loader & spec]
- other should share
- Propose[choice] => Task[Choice] => CoSTEER =>
-
Extra feature:
- cache
File structure
- ___init__.py: the entrance/agent of coder
- evaluator.py
- conf.py
- exp.py: everything under the experiment, e.g.
- Task
- Experiment
- Workspace
- test.py
- Each coder could be tested.
"""
import json
import re
from pathlib import Path
from typing import Dict
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER import CoSTEER
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEERMultiEvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.CoSTEER.evolving_strategy import (
MultiProcessEvolvingStrategy,
)
from rdagent.components.coder.CoSTEER.knowledge_management import (
CoSTEERQueriedKnowledge,
)
from rdagent.components.coder.data_science.conf import (
DSCoderCoSTEERSettings,
get_ds_env,
)
from rdagent.components.coder.data_science.pipeline.eval import PipelineCoSTEEREvaluator
from rdagent.components.coder.data_science.raw_data_loader.eval import (
DataLoaderCoSTEEREvaluator,
)
from rdagent.components.coder.data_science.raw_data_loader.exp import DataLoaderTask
from rdagent.components.coder.data_science.share.eval import ModelDumpEvaluator
from rdagent.core.exception import CoderError
from rdagent.core.experiment import FBWorkspace
from rdagent.core.scenario import Scenario
from rdagent.oai.llm_utils import APIBackend
from rdagent.utils.agent.ret import PythonAgentOut
from rdagent.utils.agent.tpl import T
DIRNAME = Path(__file__).absolute().resolve().parent
class PipelineMultiProcessEvolvingStrategy(MultiProcessEvolvingStrategy):
def implement_one_task(
self,
target_task: DataLoaderTask,
queried_knowledge: CoSTEERQueriedKnowledge | None = None,
workspace: FBWorkspace | None = None,
prev_task_feedback: CoSTEERSingleFeedback | None = None,
) -> dict[str, str]:
competition_info = self.scen.get_scenario_all_desc(eda_output=workspace.file_dict.get("EDA.md", None))
runtime_environment = self.scen.get_runtime_environment()
data_folder_info = self.scen.processed_data_folder_description
pipeline_task_info = target_task.get_task_information()
queried_similar_successful_knowledge = (
queried_knowledge.task_to_similar_task_successful_knowledge[pipeline_task_info]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
queried_knowledge.task_to_former_failed_traces[pipeline_task_info] if queried_knowledge is not None else []
)
queried_former_failed_knowledge = (
[
knowledge
for knowledge in queried_former_failed_knowledge[0]
if knowledge.implementation.file_dict.get("main.py") != workspace.file_dict.get("main.py")
],
queried_former_failed_knowledge[1],
)
system_prompt = T(".prompts:pipeline_coder.system").r(
task_desc=pipeline_task_info,
queried_similar_successful_knowledge=queried_similar_successful_knowledge,
queried_former_failed_knowledge=queried_former_failed_knowledge[0],
out_spec=PythonAgentOut.get_spec(),
runtime_environment=runtime_environment,
spec=T("scenarios.data_science.share:component_spec.Pipeline").r(),
enable_model_dump=DS_RD_SETTING.enable_model_dump,
)
user_prompt = T(".prompts:pipeline_coder.user").r(
competition_info=competition_info,
folder_spec=data_folder_info,
latest_code=workspace.file_dict.get("main.py"),
latest_code_feedback=prev_task_feedback,
)
for _ in range(5):
pipeline_code = PythonAgentOut.extract_output(
APIBackend().build_messages_and_create_chat_completion(
user_prompt=user_prompt,
system_prompt=system_prompt,
)
)
if pipeline_code != workspace.file_dict.get("main.py"):
break
else:
user_prompt = user_prompt + "\nPlease avoid generating same code to former code!"
else:
raise CoderError("Failed to generate a new pipeline code.")
return {
"main.py": pipeline_code,
}
def assign_code_list_to_evo(self, code_list: list[dict[str, str]], evo):
"""
Assign the code list to the evolving item.
The code list is aligned with the evolving item's sub-tasks.
If a task is not implemented, put a None in the list.
"""
for index in range(len(evo.sub_tasks)):
if code_list[index] is None:
continue
if evo.sub_workspace_list[index] is None:
# evo.sub_workspace_list[index] = FBWorkspace(target_task=evo.sub_tasks[index])
evo.sub_workspace_list[index] = evo.experiment_workspace
evo.sub_workspace_list[index].inject_files(**code_list[index])
return evo
class PipelineCoSTEER(CoSTEER):
def __init__(
self,
scen: Scenario,
*args,
**kwargs,
) -> None:
settings = DSCoderCoSTEERSettings()
eval_l = [PipelineCoSTEEREvaluator(scen=scen)]
if DS_RD_SETTING.enable_model_dump:
eval_l.append(ModelDumpEvaluator(scen=scen, data_type="sample"))
eva = CoSTEERMultiEvaluator(
single_evaluator=eval_l, scen=scen
) # Please specify whether you agree running your eva in parallel or not
es = PipelineMultiProcessEvolvingStrategy(scen=scen, settings=settings)
super().__init__(
*args,
settings=settings,
eva=eva,
es=es,
evolving_version=2,
scen=scen,
max_loop=DS_RD_SETTING.coder_max_loop,
**kwargs,
)
@@ -0,0 +1,155 @@
# tess successfully running.
# (GPT) if it aligns with the spec & rationality of the spec.
import json
import re
from pathlib import Path
import pandas as pd
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER import CoSTEERMultiFeedback
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEEREvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.CoSTEER.knowledge_management import (
CoSTEERQueriedKnowledgeV2,
)
from rdagent.components.coder.data_science.conf import get_clear_ws_cmd, get_ds_env
from rdagent.components.coder.data_science.utils import remove_eda_part
from rdagent.core.experiment import FBWorkspace, Task
from rdagent.scenarios.data_science.test_eval import get_test_eval
from rdagent.utils.agent.tpl import T
from rdagent.utils.agent.workflow import build_cls_from_json_with_retry
DIRNAME = Path(__file__).absolute().resolve().parent
PipelineSingleFeedback = CoSTEERSingleFeedback
PipelineMultiFeedback = CoSTEERMultiFeedback
class PipelineCoSTEEREvaluator(CoSTEEREvaluator):
def evaluate(
self,
target_task: Task,
implementation: FBWorkspace,
gt_implementation: FBWorkspace,
queried_knowledge: CoSTEERQueriedKnowledgeV2 = None,
**kwargs,
) -> PipelineSingleFeedback:
target_task_information = target_task.get_task_information()
if (
queried_knowledge is not None
and target_task_information in queried_knowledge.success_task_to_knowledge_dict
):
return queried_knowledge.success_task_to_knowledge_dict[target_task_information].feedback
elif queried_knowledge is not None and target_task_information in queried_knowledge.failed_task_info_set:
return PipelineSingleFeedback(
execution="This task has failed too many times, skip implementation.",
return_checking="This task has failed too many times, skip implementation.",
code="This task has failed too many times, skip implementation.",
final_decision=False,
)
env = get_ds_env(extra_volumes={self.scen.debug_path: T("scenarios.data_science.share:scen.input_path").r()})
# Clean the scores.csv & submission.csv.
implementation.execute(env=env, entry=get_clear_ws_cmd())
stdout, execute_ret_code = implementation.execute_ret_code(env=env, entry=f"python -m coverage run main.py")
stdout = remove_eda_part(stdout)
stdout += f"The code executed {'successfully' if execute_ret_code == 0 else 'failed'}."
score_fp = implementation.workspace_path / "scores.csv"
score_ret_code = 0
score_check_text = ""
if not score_fp.exists():
score_check_text = "[Error] Metrics file (scores.csv) is not generated!"
score_ret_code = 1
else:
try:
score_df = pd.read_csv(score_fp, index_col=0)
model_set_in_scores = set(score_df.index)
# Check model names (index)
if not score_df.index.is_unique:
score_check_text += "\n[Error] The file 'scores.csv' contains duplicate model names."
score_ret_code = 1
if "ensemble" not in model_set_in_scores:
score_check_text += "\n[Error] The file 'scores.csv' doesn't contain the ensemble model."
score_ret_code = 1
if score_ret_code != 0:
score_check_text += f"The dataframe in file 'scores.csv' is:\n{score_df}"
# Check metric name (columns)
if score_df.columns.tolist() != [self.scen.metric_name]:
score_check_text += f"\n[Error] The scores dataframe does not contain the correct column names.\nCorrect columns is: ['{self.scen.metric_name}']\nBut got: {score_df.columns.tolist()}"
score_ret_code = 1
# Check if scores contain NaN (values)
if score_df.isnull().values.any():
nan_locations = score_df[score_df.isnull().any(axis=1)]
score_check_text += f"\n[Error] The scores dataframe contains NaN values at the following locations:\n{nan_locations}"
score_ret_code = 1
except Exception as e:
score_check_text += f"\n[Error] in checking the scores.csv file: {e}\nscores.csv's content:\n-----\n{score_fp.read_text()}\n-----"
score_ret_code = 1
test_eval = get_test_eval()
if not test_eval.is_sub_enabled(self.scen.competition):
submission_ret_code = 0
else:
# Check submission file
base_check_code = T(".eval_tests.submission_format_test", ftype="txt").r()
implementation.inject_files(**{"test/submission_format_test.py": base_check_code})
# stdout += "----Submission Check 1-----\n"
submission_check_out, submission_ret_code = implementation.execute_ret_code(
env=env, entry="python test/submission_format_test.py"
)
if DS_RD_SETTING.rule_base_eval:
if execute_ret_code == 0 and score_ret_code == 0 and submission_ret_code == 0:
return PipelineSingleFeedback(
execution=stdout,
return_checking=score_check_text + "\n" + submission_check_out,
code="Code evaluation is not available.",
final_decision=True,
)
else:
return PipelineSingleFeedback(
execution=stdout,
return_checking=score_check_text + "\n" + submission_check_out,
code="Code evaluation is not available.",
final_decision=False,
)
stdout += "\n" + submission_check_out
if not isinstance(implementation, FBWorkspace):
eda_output = None
else:
eda_output = implementation.file_dict.get("EDA.md", None)
system_prompt = T(".prompts:pipeline_eval.system").r(
scenario=self.scen.get_scenario_all_desc(eda_output=eda_output),
task_desc=target_task.get_task_information(),
is_sub_enabled=test_eval.is_sub_enabled(self.scen.competition),
spec=T("scenarios.data_science.share:component_spec.Pipeline").r(),
)
user_prompt = T(".prompts:pipeline_eval.user").r(
stdout=stdout.strip(),
code=implementation.file_dict["main.py"],
)
wfb = build_cls_from_json_with_retry(
PipelineSingleFeedback,
system_prompt=system_prompt,
user_prompt=user_prompt,
init_kwargs_update_func=PipelineSingleFeedback.val_and_update_init_dict,
)
if score_ret_code != 0:
wfb.final_decision = False
wfb.return_checking += "\n" + score_check_text
if submission_ret_code != 0:
wfb.final_decision = False
wfb.return_checking += "\nSubmission file check failed."
return wfb
@@ -0,0 +1,86 @@
import hashlib
from pathlib import Path
import pandas as pd
def calculate_md5(file_path):
with open(file_path, "rb") as f:
file_hash = hashlib.md5(f.read()).hexdigest()
return file_hash
file_md5 = calculate_md5("scores.csv")
"""
find . | grep -i sample | grep -i submission | grep -v sample_submission.csv | grep -v zip_files | grep -v 'sample/'
./denoising-dirty-documents/sampleSubmission.csv
./the-icml-2013-whale-challenge-right-whale-redux/sampleSubmission.csv
./text-normalization-challenge-russian-language/ru_sample_submission_2.csv.zip
./text-normalization-challenge-russian-language/ru_sample_submission_2.csv
./random-acts-of-pizza/sampleSubmission.csv
./text-normalization-challenge-english-language/en_sample_submission_2.csv.zip
./text-normalization-challenge-english-language/en_sample_submission_2.csv
./detecting-insults-in-social-commentary/sample_submission_null.csv
"""
# Find sample submission file dynamically
input_dir = Path("{% include "scenarios.data_science.share:scen.input_path" %}")
# Look for common variations of sample submission filenames
sample_submission_files = list(input_dir.glob("*sample_submission*.csv")) + list(
input_dir.glob("*sampleSubmission*.csv")
)
assert sample_submission_files, "Error: No sample submission file found in {% include "scenarios.data_science.share:scen.input_path" %}"
# Use first matching file
sample_submission_name = sample_submission_files[0].name
SAMPLE_SUBMISSION_PATH = str(sample_submission_files[0])
print(f"Using sample submission file: {sample_submission_name}")
# Check if the sample submission file exists
assert Path(SAMPLE_SUBMISSION_PATH).exists(), f"Error: {sample_submission_name} not found at {SAMPLE_SUBMISSION_PATH}"
# Check if our submission file exists
assert Path("submission.csv").exists(), "Error: submission.csv not found"
sample_submission = pd.read_csv(SAMPLE_SUBMISSION_PATH)
our_submission = pd.read_csv("submission.csv")
success = True
# Print the columns of the sample submission file
print(f"Columns in {sample_submission_name}:", sample_submission.columns)
print("Columns in our_submission.csv:", our_submission.columns)
for col in sample_submission.columns:
if col not in our_submission.columns:
success = False
print(f"Column {col} not found in submission.csv")
if success:
print(f"submission.csv's columns aligns with {sample_submission_name} .")
else:
raise AssertionError(f"submission.csv's columns does not align with {sample_submission_name} .")
# Print the first 5 rows of the two submission files, with columns separated by commas.
def print_first_rows(file_path, file_name, num_rows=5):
print(f"\nFirst {num_rows} rows of {file_name}:")
try:
with open(file_path, "r") as file:
for i, line in enumerate(file):
if i < num_rows:
print(line.strip())
else:
break
except FileNotFoundError:
print(f"Error: {file_name} not found.")
print_first_rows(SAMPLE_SUBMISSION_PATH, sample_submission_name)
print_first_rows("submission.csv", "submission.csv")
assert calculate_md5("scores.csv") == file_md5, "scores.csv should not be rewritten"
print(
f"\nPlease Checked the content of the submission file(submission.csv should has the same format with {sample_submission_name} but might not the same index with {sample_submission_name}). "
)
@@ -0,0 +1,7 @@
from rdagent.components.coder.CoSTEER.task import CoSTEERTask
# Because we use isinstance to distinguish between different types of tasks, we need to use sub classes to represent different types of tasks
class PipelineTask(CoSTEERTask):
def __init__(self, name: str = "Pipeline", *args, **kwargs) -> None:
super().__init__(name=name, *args, **kwargs)
@@ -0,0 +1,176 @@
pipeline_coder:
system: |-
You are a world-class data scientist and machine learning engineer with deep expertise in statistics, mathematics, and computer science.
Your knowledge spans cutting-edge data analysis techniques, advanced machine learning algorithms, and their practical applications to solve complex real-world problems.
## Task Description
{{ task_desc }}
## The runtime environment your code will running on
{{ runtime_environment }}
## Specification your code should follow
{{ spec }}
{% if queried_similar_successful_knowledge|length != 0 or queried_former_failed_knowledge|length != 0 %}
## Relevant Information for This Task
{% endif %}
{% if queried_similar_successful_knowledge|length != 0 %}
--------- Successful Implementations for Similar Models ---------
====={% for similar_successful_knowledge in queried_similar_successful_knowledge %} Model {{ loop.index }}:=====
{{ similar_successful_knowledge.target_task.get_task_information() }}
=====Code:=====
{{ similar_successful_knowledge.implementation.all_codes }}
{% endfor %}
{% endif %}
{% if queried_former_failed_knowledge|length != 0 %}
--------- Previous Failed Attempts ---------
{% for former_failed_knowledge in queried_former_failed_knowledge %} Attempt {{ loop.index }}:
=====Code:=====
{{ former_failed_knowledge.implementation.all_codes }}
=====Feedback:=====
{{ former_failed_knowledge.feedback }}
{% endfor %}
{% endif %}
## Guidelines
1. Ensure that the dataset is loaded strictly from `{% include "scenarios.data_science.share:scen.input_path" %}`, following the exact folder structure described in the **Data Folder Description**, and do not attempt to load data from the current directory (`./`).
2. You should avoid using logging module to output information in your generated code, and instead use the print() function.
## Exploratory Data Analysis (EDA) part(Required):
- Before returning the data, you should always add an EDA part describing the data to help the following steps understand the data better.
- The EDA part should include but not limited in the following information in plain text:
- The shape of the data.
- The first 5 rows of the data.
- The data types of each column.
- The number of missing values in each column.
- The number of unique values in each column.
- The distribution of the target variable.
- Any other information that you think is important for the following steps.
- The EDA part should be drafted in plain text sending to standard output with command print or other similar functions with no more than ten thousand characters in the following schema:
=== Start of EDA part ===
{ You EDA output content }
=== End of EDA part ===
User will use the following code to match: re.search(r"(.*?)=== Start of EDA part ===(.*)=== End of EDA part ===", stdout, re.DOTALL).groups()[1]
- An evaluation agent will help to check whether the EDA part is added correctly.
- During the EDA part, you should try to avoid any irrelevant information sending to the standard output.
{% include "scenarios.data_science.share:guidelines.coding" %}
{% if enable_model_dump %}
## Model Dumping
{% include "components.coder.data_science.share.prompts:dump_model_coder.guideline" %}
{% endif %}
## Output Format
{% if out_spec %}
{{ out_spec }}
{% else %}
Please response the code in the following json format. Here is an example structure for the JSON output:
{
"code": "The Python code as a string."
}
{% endif %}
user: |-
--------- Competition Information ---------
{{ competition_info }}
--------- Data Folder Description (All path are relative to the data folder) ---------
{{ folder_spec }}
{% if latest_code %}
--------- Former code ---------
{{ latest_code }}
{% if latest_code_feedback is not none %}
--------- Feedback to former code ---------
{{ latest_code_feedback }}
The former code contains errors. You should correct the code based on the provided information, ensuring you do not repeat the same mistakes.
Keep the part that already seem correct intact. Avoid modifying them to refrain from introducing new errors.
{% else %}
The former code is correct. You should try to improve the code based on the provided task while not changing the irrelevant parts.
{% endif %}
{% endif %}
You should strictly follow the code specifications provided by the specification to implement the function.
pipeline_eval:
system: |-
You are a data scientist responsible for evaluating code generation.
## Task Description
The user is trying to build a code in the following scenario:
{{ scenario }}
The main code generation task is as follows:
{{ task_desc }}
The details on how to structure the code are given in the specification:
{{ spec }}
{% if is_sub_enabled %}
## Evaluation Scope
Your focus is to check whether the workflow code:
Step 1: Executes successfully without any errors. Please distinguish between the errors and warnings.
Step 2: Correctly generates a final submission in the correct format, ensuring: they align with the submission structure, the index names and column names should match the sample, and the items should not be empty or apparently incorrect.
Step 3: Aligns with the competition requirements. This includes:
- CAREFULLY ANALYZE WHETHER THE EXPERIMENTAL SETUP AND CODE MAY CAUSE MISALIGNMENT BETWEEN VALIDATION AND TEST PERFORMANCE.
- Confirm strict adherence to the competition's evaluation rules listed in `scenario`:
- Exact match between the implementation code of metric and the requirements of the scenario. The metric number is not the focus.
- Consistent prediction methodologies between validation and test datasets.
- No shortcuts or fold-specific strategies applied inconsistently.
- Rigorous checks for corner-case consistency.
- If such discrepancies or risks are found:
- Clearly document these issues in `code`.
- Begin your `code` with `[Evaluation error]`, explicitly stating the evaluation alignment issues causing experiment failure.
- If no issues are found, begin your `code` with `[Code analysis]`, providing a detailed analysis of the code quality, readability, and adherence to specifications.
## Evaluation Criteria
You will be given the execution output (`stdout`) to determine correctness.
[Note]
1. Model performance is NOT a concern in this evaluation—only correct execution and formatting matter.
2. You only check the format of the submission since we only feed you part of the data, so the submission might has different index to the sample submission data.
Please respond with your feedback in the following JSON format and order
```json
{
"execution": "Describe whether the code executed successfully, correctly integrating all components and generating the final submission. Include any errors or issues encountered, and append all error messages and full traceback details without summarizing or omitting any information.",
"return_checking": "Verify the generated files, particularly the submission file. Ensure that its format matches the sample submission, checking the index, column names, and CSV content.",
"code": "Begin explicitly with [Code analysis] or [Evaluation error]. Provide feedback on code quality, readability, adherence to the given specifications, and alignment with competition requirements.",
"final_decision": <true/false>
}
```
{% else %}
## Evaluation Scope
Your focus is to check whether the workflow code executes successfully.
You will be given the execution output (`stdout`) to determine correctness.
[Note]
1. Model performance is NOT a concern in this evaluation—only correct execution and formatting matter.
Please respond with your feedback in the following JSON format and order
```json
{
"execution": "Describe whether the code executed successfully. Include any errors or issues encountered, and append all error messages and full traceback details without summarizing or omitting any information.",
"return_checking": "Describe the expected file to be generated.",
"code": "Provide feedback on code quality, readability, and adherence to the given specifications.",
"final_decision": <true/false>
}
```
{% endif %}
# NOTE: when is_sub_enabled == False, we don't have any checking about the return. So it is just placeholder currently
user: |-
--------- code generated by user ---------
{{ code }}
--------- code running stdout ---------
{{ stdout }}
@@ -0,0 +1,15 @@
# CoSTEER
- subworkspace使用主experiment_workspace `RD-Agent/rdagent/scenarios/data_science/experiment/experiment.py`
## evolving_strategy ( implement_one_task() )
1. xxxTask (in exp.py)
- spec
- description
2.
## evaluator
1. queried_knowledge部分 共用
2. eval_test脚本
@@ -0,0 +1,245 @@
"""
Loop should not large change exclude
- Action Choice[current data loader & spec]
- other should share
- Propose[choice] => Task[Choice] => CoSTEER =>
-
Extra feature:
- cache
File structure
- ___init__.py: the entrance/agent of coder
- evaluator.py
- conf.py
- exp.py: everything under the experiment, e.g.
- Task
- Experiment
- Workspace
- test.py
- Each coder could be tested.
"""
import json
import re
from pathlib import Path
from typing import Dict
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER import CoSTEER
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEERMultiEvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.CoSTEER.evolving_strategy import (
MultiProcessEvolvingStrategy,
)
from rdagent.components.coder.CoSTEER.knowledge_management import (
CoSTEERQueriedKnowledge,
)
from rdagent.components.coder.data_science.conf import (
DSCoderCoSTEERSettings,
get_ds_env,
)
from rdagent.components.coder.data_science.raw_data_loader.eval import (
DataLoaderCoSTEEREvaluator,
)
from rdagent.components.coder.data_science.raw_data_loader.exp import DataLoaderTask
from rdagent.core.exception import CoderError
from rdagent.core.experiment import FBWorkspace
from rdagent.core.scenario import Scenario
from rdagent.oai.llm_utils import APIBackend
from rdagent.utils.agent.ret import PythonAgentOut
from rdagent.utils.agent.tpl import T
DIRNAME = Path(__file__).absolute().resolve().parent
class DataLoaderMultiProcessEvolvingStrategy(MultiProcessEvolvingStrategy):
def implement_one_task(
self,
target_task: DataLoaderTask,
queried_knowledge: CoSTEERQueriedKnowledge | None = None,
workspace: FBWorkspace | None = None,
prev_task_feedback: CoSTEERSingleFeedback | None = None,
) -> dict[str, str]:
# return a workspace with "load_data.py", "spec/load_data.md" inside
# assign the implemented code to the new workspace.
competition_info = self.scen.get_scenario_all_desc(eda_output=workspace.file_dict.get("EDA.md", None))
runtime_environment = self.scen.get_runtime_environment()
data_folder_info = self.scen.processed_data_folder_description
data_loader_task_info = target_task.get_task_information()
queried_similar_successful_knowledge = (
queried_knowledge.task_to_similar_task_successful_knowledge[data_loader_task_info]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
queried_knowledge.task_to_former_failed_traces[data_loader_task_info]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
[
knowledge
for knowledge in queried_former_failed_knowledge[0]
if knowledge.implementation.file_dict.get("load_data.py") != workspace.file_dict.get("load_data.py")
],
queried_former_failed_knowledge[1],
)
# 1. specifications
# TODO: We may move spec into a separated COSTEER task
if DS_RD_SETTING.spec_enabled:
if "spec/data_loader.md" not in workspace.file_dict: # Only generate the spec once
system_prompt = T(".prompts:spec.system").r(
runtime_environment=runtime_environment,
task_desc=data_loader_task_info,
competition_info=competition_info,
folder_spec=data_folder_info,
)
data_loader_prompt = T(".prompts:spec.user.data_loader").r(
latest_spec=workspace.file_dict.get("spec/data_loader.md")
)
feature_prompt = T(".prompts:spec.user.feature").r(
latest_spec=workspace.file_dict.get("spec/feature.md")
)
model_prompt = T(".prompts:spec.user.model").r(latest_spec=workspace.file_dict.get("spec/model.md"))
ensemble_prompt = T(".prompts:spec.user.ensemble").r(
latest_spec=workspace.file_dict.get("spec/ensemble.md")
)
workflow_prompt = T(".prompts:spec.user.workflow").r(
latest_spec=workspace.file_dict.get("spec/workflow.md")
)
spec_session = APIBackend().build_chat_session(session_system_prompt=system_prompt)
data_loader_spec = spec_session.build_chat_completion(user_prompt=data_loader_prompt)
feature_spec = spec_session.build_chat_completion(user_prompt=feature_prompt)
model_spec = spec_session.build_chat_completion(user_prompt=model_prompt)
ensemble_spec = spec_session.build_chat_completion(user_prompt=ensemble_prompt)
workflow_spec = spec_session.build_chat_completion(user_prompt=workflow_prompt)
else:
data_loader_spec = workspace.file_dict["spec/data_loader.md"]
feature_spec = workspace.file_dict["spec/feature.md"]
model_spec = workspace.file_dict["spec/model.md"]
ensemble_spec = workspace.file_dict["spec/ensemble.md"]
workflow_spec = workspace.file_dict["spec/workflow.md"]
# 2. code
system_prompt = T(".prompts:data_loader_coder.system").r(
task_desc=data_loader_task_info,
queried_similar_successful_knowledge=queried_similar_successful_knowledge,
queried_former_failed_knowledge=queried_former_failed_knowledge[0],
out_spec=PythonAgentOut.get_spec(),
)
code_spec = (
data_loader_spec
if DS_RD_SETTING.spec_enabled
else T("scenarios.data_science.share:component_spec.general").r(
spec=T("scenarios.data_science.share:component_spec.DataLoadSpec").r(),
test_code=(DIRNAME / "eval_tests" / "data_loader_test.txt").read_text(),
)
)
user_prompt = T(".prompts:data_loader_coder.user").r(
competition_info=competition_info,
code_spec=code_spec,
folder_spec=data_folder_info,
latest_code=workspace.file_dict.get("load_data.py"),
latest_code_feedback=prev_task_feedback,
)
for _ in range(5):
data_loader_code = PythonAgentOut.extract_output(
APIBackend().build_messages_and_create_chat_completion(
user_prompt=user_prompt,
system_prompt=system_prompt,
)
)
if data_loader_code != workspace.file_dict.get("load_data.py"):
break
else:
user_prompt = user_prompt + "\nPlease avoid generating same code to former code!"
else:
raise CoderError("Failed to generate a new data loader code.")
return (
{
"spec/data_loader.md": data_loader_spec,
"spec/feature.md": feature_spec,
"spec/model.md": model_spec,
"spec/ensemble.md": ensemble_spec,
"spec/workflow.md": workflow_spec,
"load_data.py": data_loader_code,
}
if DS_RD_SETTING.spec_enabled
else {
"load_data.py": data_loader_code,
}
)
def assign_code_list_to_evo(self, code_list: list[dict[str, str]], evo):
"""
Assign the code list to the evolving item.
The code list is aligned with the evolving item's sub-tasks.
If a task is not implemented, put a None in the list.
"""
for index in range(len(evo.sub_tasks)):
if code_list[index] is None:
continue
if evo.sub_workspace_list[index] is None:
# evo.sub_workspace_list[index] = FBWorkspace(target_task=evo.sub_tasks[index])
evo.sub_workspace_list[index] = evo.experiment_workspace
evo.sub_workspace_list[index].inject_files(**code_list[index])
return evo
class DataLoaderCoSTEER(CoSTEER):
def __init__(
self,
scen: Scenario,
*args,
**kwargs,
) -> None:
settings = DSCoderCoSTEERSettings()
eva = CoSTEERMultiEvaluator(
DataLoaderCoSTEEREvaluator(scen=scen), scen=scen
) # Please specify whether you agree running your eva in parallel or not
es = DataLoaderMultiProcessEvolvingStrategy(scen=scen, settings=settings)
super().__init__(
*args,
settings=settings,
eva=eva,
es=es,
evolving_version=2,
scen=scen,
max_loop=DS_RD_SETTING.coder_max_loop,
**kwargs,
)
def develop(self, exp):
new_exp = super().develop(exp)
env = get_ds_env(
extra_volumes={
f"{DS_RD_SETTING.local_data_path}/{self.scen.competition}": T(
"scenarios.data_science.share:scen.input_path"
).r()
},
running_timeout_period=DS_RD_SETTING.full_timeout,
)
stdout = new_exp.experiment_workspace.execute(env=env, entry=f"python test/data_loader_test.py")
match = re.search(r"(.*?)=== Start of EDA part ===(.*)=== End of EDA part ===", stdout, re.DOTALL)
eda_output = match.groups()[1] if match else None
if eda_output is not None:
new_exp.experiment_workspace.inject_files(**{"EDA.md": eda_output})
else:
eda_output = "No EDA output."
new_exp.experiment_workspace.inject_files(**{"EDA.md": eda_output})
return new_exp
@@ -0,0 +1,89 @@
# tess successfully running.
# (GPT) if it aligns with the spec & rationality of the spec.
import json
import re
from pathlib import Path
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEEREvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.CoSTEER.knowledge_management import (
CoSTEERQueriedKnowledgeV2,
)
from rdagent.components.coder.data_science.conf import get_ds_env
from rdagent.components.coder.data_science.utils import remove_eda_part
from rdagent.core.experiment import FBWorkspace, Task
from rdagent.utils.agent.tpl import T
from rdagent.utils.agent.workflow import build_cls_from_json_with_retry
DIRNAME = Path(__file__).absolute().resolve().parent
DataLoaderEvalFeedback = CoSTEERSingleFeedback
class DataLoaderCoSTEEREvaluator(CoSTEEREvaluator):
def evaluate(
self,
target_task: Task,
implementation: FBWorkspace,
gt_implementation: FBWorkspace,
queried_knowledge: CoSTEERQueriedKnowledgeV2 = None,
**kwargs,
) -> DataLoaderEvalFeedback:
target_task_information = target_task.get_task_information()
if (
queried_knowledge is not None
and target_task_information in queried_knowledge.success_task_to_knowledge_dict
):
return queried_knowledge.success_task_to_knowledge_dict[target_task_information].feedback
elif queried_knowledge is not None and target_task_information in queried_knowledge.failed_task_info_set:
return DataLoaderEvalFeedback(
execution="This task has failed too many times, skip implementation.",
return_checking="This task has failed too many times, skip implementation.",
code="This task has failed too many times, skip implementation.",
final_decision=False,
)
env = get_ds_env(extra_volumes={self.scen.debug_path: T("scenarios.data_science.share:scen.input_path").r()})
# TODO: do we need to clean the generated temporary content?
fname = "test/data_loader_test.py"
test_code = (DIRNAME / "eval_tests" / "data_loader_test.txt").read_text()
implementation.inject_files(**{fname: test_code})
stdout, ret_code = implementation.execute_ret_code(env=env, entry=f"python {fname}")
match = re.search(r"(.*?)=== Start of EDA part ===(.*)=== End of EDA part ===(.*)", stdout, re.DOTALL)
stdout_part_1, eda_output, stdout_part_2 = match.groups() if match else (stdout, None, "")
stdout = stdout_part_1 + stdout_part_2
if eda_output is not None and len(eda_output.split(" ")) > 10000:
eda_output += "Length of EDA output is too long, truncated. Please reject this implementation and motivate it to reduce the length of EDA output."
if "main.py" in implementation.file_dict and ret_code == 0:
workflow_stdout = implementation.execute(env=env, entry="python main.py")
workflow_stdout = remove_eda_part(workflow_stdout)
else:
workflow_stdout = None
system_prompt = T(".prompts:data_loader_eval.system").r(
task_desc=target_task.get_task_information(),
test_code=test_code,
code=implementation.file_dict["load_data.py"],
workflow_stdout=workflow_stdout,
workflow_code=implementation.all_codes,
)
user_prompt = T(".prompts:data_loader_eval.user").r(
stdout=stdout,
eda_output=eda_output,
workflow_stdout=workflow_stdout,
)
fb = build_cls_from_json_with_retry(
DataLoaderEvalFeedback,
system_prompt=system_prompt,
user_prompt=user_prompt,
init_kwargs_update_func=DataLoaderEvalFeedback.val_and_update_init_dict,
)
fb.final_decision = fb.final_decision and ret_code == 0
return fb
@@ -0,0 +1,83 @@
"""
Tests for `load_data` in load_data.py
"""
import pickle
import pandas as pd
from load_data import load_data
import sys
import reprlib
from joblib.memory import MemorizedFunc
def get_original_code(func):
if isinstance(func, MemorizedFunc):
return func.func.__code__
return func.__code__
def debug_info_print(func):
aRepr = reprlib.Repr()
aRepr.maxother=300
def wrapper(*args, **kwargs):
original_code = get_original_code(func)
def local_trace(frame, event, arg):
if event == "return" and frame.f_code == original_code:
print("\n" + "="*20 + "Running data_load code, local variable values:" + "="*20)
for k, v in frame.f_locals.items():
printed = aRepr.repr(v)
print(f"{k}:\n {printed}")
print("="*20 + "Local variable values end" + "="*20)
return local_trace
sys.settrace(local_trace)
try:
return func(*args, **kwargs)
finally:
sys.settrace(None)
return wrapper
X, y, X_test, test_ids = debug_info_print(load_data)()
def get_length(data):
return data.shape[0] if hasattr(data, 'shape') else len(data)
def get_width(data):
return data.shape[1:] if hasattr(data, 'shape') else 1
def get_column_list(data):
return data.columns.tolist() if isinstance(data, pd.DataFrame) else None
assert X is not None, "Training data (X) is None."
assert y is not None, "Training labels (y) are None."
assert X_test is not None, "Test data (X_test) is None."
assert test_ids is not None, "Test IDs (test_ids) are None."
assert get_length(X_test) == get_length(
test_ids
), f"Mismatch in length of test images and test IDs: X_test ({get_length(X_test)}) and test_ids ({get_length(test_ids)})"
assert get_length(X) == get_length(
y
), f"Mismatch in length of training images and labels: X ({get_length(X)}) and y ({get_length(y)})"
assert get_length(X) != 0, f"Training data is empty."
assert get_length(y) != 0, f"Training labels are empty."
assert get_length(X_test) != 0, f"Test data is empty."
assert get_width(X) == get_width(
X_test
), "Mismatch in width of training and test data. Width means the number of features."
if isinstance(X, pd.DataFrame) and isinstance(X_test, pd.DataFrame):
assert get_column_list(X) == get_column_list(X_test), "Mismatch in column names of training and test data."
assert get_width(X) == get_width(
X_test
), "Mismatch in width of training and test data. Width means the number of features."
print("Data loader test passed successfully. Length of test images matches length of test IDs.")
@@ -0,0 +1,6 @@
from rdagent.components.coder.CoSTEER.task import CoSTEERTask
# Because we use isinstance to distinguish between different types of tasks, we need to use sub classes to represent different types of tasks
class DataLoaderTask(CoSTEERTask):
pass
@@ -0,0 +1,402 @@
spec:
system: |-
You are a world-class data scientist and machine learning engineer with deep expertise in statistics, mathematics, and computer science.
Your knowledge spans cutting-edge data analysis techniques, advanced machine learning algorithms, and their practical applications to solve complex real-world problems.
Currently, you are working on a Kaggle competition project.
This project involves analyzing data and building models to beat other competitors, with the code being generated by large language models.
The runtime environment you are working in includes the following libraries and their respective versions:
{{ runtime_environment }}
Your overall task is provided below:
{{ task_desc }}
Your task is to write five specification texts (in markdown format) for the following tasks, based on the competition information provided
- Data loading (and preprocessing)
- Feature Engineering
- Model Building
- Ensemble
- The overall workflow
The specifications for each step should be tailored to the competition information provided.
Your specification should consists two parts:
1. The function definition in code format, including type annotations and a clear, complete docstring that describes the function's purpose, input parameters, return value, and any relevant exceptions.
2. Additional information or notes that the coder should consider while implementing the function.
Your specifications should include only the function definition and docstring, without any code implementation or inline comments.
## Competition Information for This Task
{{ competition_info }}
----------- Folder Description (All path are relative to the data folder) ---------
- Ensure that all columns in sample_submission can be generated.
{{ folder_spec }}
user:
data_loader: |-
Data loader specification text should follow these detailed requirements:
1. Function Interface:
- Function Name: `load_data`
- Input: No input arguments.
- Output:
- `X` (DT, define based on competition information): Feature matrix for training data.
- `y` (DT): Target vector for training data.
- `X_test` (DT): Feature matrix for test data.
- `test_ids` (DT): Identifiers for the test data.
- Docstring Requirements:
- Describe the purpose of the function.
- Specify the data source location (`{% include "scenarios.data_science.share:scen.input_path" %}`).
- Clearly define the structure and type of the output.
- Inferred data shape to each input and output data variables. To uncertain dimension, use -1.
2. Notes:
- Update `DT` (data type) based on the specific competition dataset. This can include `pd.DataFrame`, `np.array`, `torch.Tensor`, etc.
- Only set the DT of variables without inferring the shape of these variables since you don't know the shape of the data.
Responsibilities and notes of an implemented data loader that aligns with the generated specification.
{% include "scenarios.data_science.share:component_spec.DataLoadSpec" %}
{% if latest_spec %}
6. Former Specification:
{{ latest_spec }}
You should follow the provided specifications to improve this task.
{% endif %}
## Output Format
You should return the specification in markdown format directly, while the **function definition** within it should be in code format, tailored to the Competition Information, with detailed explanations provided in the docstring.
feature: |-
Feature engineering specification text should adhere to the following requirements:
1. Function Interface:
- Function Name: `feat_eng`
- Parameters:
- `X` (DT): Train data to be transformed.
- `y` (DT): Train label data.
- `X_test` (DT): Test data.
- Output:
- `X_transformed` (DT): Transformed train data.
- `y_transformed` (DT): Transformed train label data.
- `X_test_transformed` (DT): Transformed test data.
- Docstring Requirements:
- Describe the purpose of the function.
- Clarify the input parameters and their data types.
- Define the structure and format of the output.
- Inferred data shape to each input and output data variables. To uncertain dimension, use -1.
2. Precautions for Feature Engineering:
- Well handle the shape of the data:
- The sample size of the train data and the test data should be the same in all scenarios.
- To some tabular or time-series data, you may add or remove some columns so your inferred column number may be unsure.
- For scenarios where each dimension does not have a special meaning (like image, audio, and so on), the input shape and the output shape should be exactly the same in most cases unless there is a compelling reason to change them.
- Integration with the Model Pipeline:
- If feature engineering is deferred to the model pipeline for better overall performance, state explicitly that it will be handled at the model stage.
- Model-related operations should not be implemented in this step. (e.g., it uses tools combined with models like torch.Dataset with rich data transformation/augmentation)
- Otherwise, ensure this function applies all required transformations while avoiding data leakage.
- General Considerations:
- Ensure scalability for large datasets.
- Handle missing values and outliers appropriately (e.g., impute, remove, or replace).
- Ensure consistency between feature data types and transformations.
- Prevent data leakage: Do not use information derived from the test set when transforming training data.
- Domain-Specific Features:
- Apply logic for competition-specific features (e.g., text vectorization, image augmentations, categorical encoding).
3. Code Standards:
- Avoid using progress bars (e.g., `tqdm`) in the implementation.
4. Notes:
- Align `DT` (data type) definitions with those in the Data Loader specification.
- GPU and multiprocessing are available and are encouraged to use for accelerating transformations.
- Only set the DT of variables without inferring the shape of these variables since you don't know the shape of the data.
{% if latest_spec %}
5. Former Specification:
{{ latest_spec }}
You should follow the provided specifications to improve this task.
{% endif %}
## Output Format
You should return the specification in markdown format directly, while the **function definition** within it should be in code format, tailored to the Competition Information, with detailed explanations provided in the docstring.
model: |-
Model building specification text should adhere to the following requirements:
1. Function Interface:
- Function Name: `model_workflow`
- Parameters:
- `X` (DT): Training feature data.
- `y` (DT): Training label data.
- `val_X` (Optional[DT]): Validation feature data.
- `val_y` (Optional[DT]): Validation label data.
- `test_X` (Optional[DT]): Test feature data.
- `hyper_params` (dict): Dictionary of hyperparameters for model configuration.
- Output:
- `pred_val` (Optional[DT]): Predictions on validation data.
- `pred_test` (Optional[DT]): Predictions on test data.
- `hyper_params` (dict): Updated dictionary of hyperparameters after training.
- Docstring Requirements:
- Describe the purpose of the function.
- Clarify the input parameters and their data types.
- Define the structure and format of the output.
- Inferred data shape to each input and output data variables. To uncertain dimension, use -1.
2. Code Standards:
- Do not use progress bars (e.g., `tqdm`) in the implementation.
3. Precautions:
- Ensure input arrays (`X`, `y`, `val_X`, `val_y`, `test_X`) have consistent dimensions and shapes.
- Use default values for hyperparameters if `hyper_params` is not provided.
- Train the model on `X` and `y`.
- Evaluate the model using `val_X` and `val_y` if validation data is available.
- If `test_X` is provided, generate predictions for it.
4. Notes:
- Align `DT` (data type) with the definitions used in Feature Engineering specifications.
- The device has GPU support, so you are encouraged to use it for training if necessary to accelerate the process.
- Some data transformations/augmentations can be included in this step (e.g., data tools provided by TensorFlow and Torch)
{% if latest_spec %}
5. Former Specification:
{{ latest_spec }}
You should follow the provided specifications to improve this task.
{% endif %}
## Output Format
You should return the specification in markdown format directly, while the **function definition** within it should be in code format, tailored to the Competition Information, with detailed explanations provided in the docstring.
ensemble: |-
Ensemble specification text adhere to the following requirements:
1. Function Interface:
- Function Name: `ensemble_workflow`
- Parameters:
- `test_preds_dict` (Dict[str, DT]): A dictionary of test predictions from different models. The key is the model file name.
- `val_preds_dict` (Dict[str, DT]): A dictionary of validation predictions from different models. The key is the model file name.
- `val_label` (DT): Validation label.
- Output:
- `final_pred` (DT): Ensemble prediction for the test data.
- Docstring Requirements:
- Describe the purpose of the function.
- Clarify the input parameters and their data types.
- Define the structure and format of the output.
- Inferred data shape to each input and output data variables. To uncertain dimension, use -1.
2. Precautions:
- Input Validation:
- Ensure all predictions in `test_preds_dict` and `val_preds_dict` have consistent shapes and dimensions.
- Verify that `val_label` is provided and matches the length of `val_preds_dict` predictions.
- Handle empty or invalid inputs gracefully with appropriate error messages.
- Metric Calculation and Storage:
- Calculate the metric (mentioned in the evaluation section of the competition information) for each model and ensemble strategy on valid, and save the results in `scores.csv`, e.g.:
```python
scores = {}
for model_name, val_pred in val_preds_dict.items():
scores[model_name] = calculate_metric(val_label, val_pred)
...
some code about ensemble strategy
...
ensemble_val_pred = ...
ensemble_score = calculate_metric(val_label, ensemble_val_pred)
scores["ensemble"] = ensemble_score # Ensure "ensemble" is explicitly stored
scores_df = pd.DataFrame(scores.items(), columns=["Model", <metric_name>])
scores_df.to_csv("scores.csv", index=False)
```
- Even if only one model is present, compute the ensemble score and store it under `"ensemble"`.
3. Code Standards:
- Do not use progress bars (e.g., tqdm) in the code.
4. Notes:
- Align `DT` (data type) definitions with those used in model specifications.
- Ensure flexibility to handle multiple ensemble strategies based on competition requirements.
- Only set the DT of variables without inferring the shape of these variables since you don't know the shape of the data.
{% if latest_spec %}
5. Former Specification:
{{ latest_spec }}
You should follow the provided specifications to improve this task.
{% endif %}
## Output Format
You should return the specification in markdown format directly, while the **function definition** within it should be in code format, tailored to the Competition Information, with detailed explanations provided in the docstring.
workflow: |-
{% include "scenarios.data_science.share:component_spec.Workflow" %}
{% if latest_spec %}
7. Former Specification:
{{ latest_spec }}
You should follow the provided specifications to improve this task.
{% endif %}
## Output Format
You should return the specification in markdown format directly.
You should create the rules based on the competition information instead of copying the requirements.
data_loader_coder:
system: |-
You are a world-class data scientist and machine learning engineer with deep expertise in statistics, mathematics, and computer science.
Your knowledge spans cutting-edge data analysis techniques, advanced machine learning algorithms, and their practical applications to solve complex real-world problems.
## Task Description
{{ task_desc }}
{% if queried_similar_successful_knowledge|length != 0 or queried_former_failed_knowledge|length != 0 %}
## Relevant Information for This Task
{% endif %}
{% if queried_similar_successful_knowledge|length != 0 %}
--------- Successful Implementation Examples for Similar Task ---------
====={% for similar_successful_knowledge in queried_similar_successful_knowledge %} Example {{ loop.index }}:=====
{{ similar_successful_knowledge.target_task.get_task_information() }}
=====Code:=====
{{ similar_successful_knowledge.implementation.all_codes }}
{% endfor %}
{% endif %}
{% if queried_former_failed_knowledge|length != 0 %}
--------- Previous Failed Attempts ---------
{% for former_failed_knowledge in queried_former_failed_knowledge %} Attempt {{ loop.index }}:
=====Code:=====
{{ former_failed_knowledge.implementation.all_codes }}
=====Feedback:=====
{{ former_failed_knowledge.feedback }}
{% endfor %}
{% endif %}
## Guidelines
1. Ensure that the dataset is loaded strictly from `{% include "scenarios.data_science.share:scen.input_path" %}`, following the exact folder structure described in the **Data Folder Description**, and do not attempt to load data from the current directory (`./`).
2. You should avoid using logging module to output information in your generated code, and instead use the print() function.
3. You should use the following cache decorator to cache the results of the function:
```python
from joblib import Memory
memory = Memory(location='{% include "scenarios.data_science.share:scen.cache_path" %}', verbose=0)
@memory.cache```
{% include "scenarios.data_science.share:guidelines.coding" %}
## Exploratory Data Analysis (EDA) part(Required):
- Before returning the data, you should always add an EDA part describing the data to help the following steps understand the data better.
- The EDA part should include but not limited in the following information in plain text:
- The shape of the data.
- The first 5 rows of the data.
- The data types of each column.
- The number of missing values in each column.
- The number of unique values in each column.
- The distribution of the target variable.
- Any other information that you think is important for the following steps.
- The EDA part should be drafted in plain text sending to standard output with command print or other similar functions with no more than ten thousand characters in the following schema:
=== Start of EDA part ===
{ You EDA output content }
=== End of EDA part ===
User will use the following code to match: re.search(r"(.*?)=== Start of EDA part ===(.*)=== End of EDA part ===", stdout, re.DOTALL).groups()[1]
- An evaluation agent will help to check whether the EDA part is added correctly.
- During the EDA part, you should try to avoid any irrelevant information sending to the standard output.
## Output Format
{% if out_spec %}
{{ out_spec }}
{% else %}
Please response the code in the following json format. Here is an example structure for the JSON output:
{
"code": "The Python code as a string."
}
{% endif %}
user: |-
--------- Competition Information ---------
{{ competition_info }}
--------- Code Specification ---------
{{ code_spec }}
--------- Data Folder Description (All path are relative to the data folder) ---------
{{ folder_spec }}
{% if latest_code %}
--------- Former code ---------
{{ latest_code }}
{% if latest_code_feedback is not none %}
--------- Feedback to former code ---------
{{ latest_code_feedback }}
{% endif %}
The former code contains errors. You should correct the code based on the provided information, ensuring you do not repeat the same mistakes.
{% endif %}
You should strictly follow the code specifications provided by the specification to implement the function.
data_loader_eval:
system: |-
You are a data scientist responsible for evaluating data loader code for a Kaggle-style machine learning competition project.
## Task Description
{{ task_desc }}
## Data Loader Code
The data loader code is located in `load_data.py`:
```python
{{ code }}
```
## Testing Process
The data loader is tested using the following script:
```python
{{ test_code }}
```
{% if workflow_stdout is not none %}
### Whole Workflow Consideration
The data loader is part of the whole workflow. The user has executed the entire pipeline and provided additional stdout.
**Workflow Code:**
{{ workflow_code }}
You should evaluate both the data loader test results and the overall workflow execution. **Approve the code only if both tests pass.**
{% endif %}
## Evaluation Criteria
You will be given the standard output (`stdout`) from the data loader test and, if applicable, the workflow test.
## Exploratory Data Analysis (EDA) Part evaluation
- The code has also generated some EDA output to help understand the data better.
- The EDA part should be drafted in plain text sending to standard output with command print or other similar functions with no more than ten thousand characters in the following schema:
=== Start of EDA part ===
{ You EDA output content }
=== End of EDA part ===
User will use the following code to match: re.search(r"(.*?)=== Start of EDA part ===(.*)=== End of EDA part ===", stdout, re.DOTALL).groups()[1]
- The EDA part should include but not limited in the following information in plain text:
- The shape of the data.
- The first 5 rows of the data.
- The data types of each column.
- The number of missing values in each column.
- The number of unique values in each column.
- The distribution of the target variable.
- Any other information that you think is important for the following steps.
You will be given the EDA output, your job is to check whether the output contains the required and sufficient information. If no EDA output is provided, you should consider it as a failure. Put this evaluation result in the return_checking part.
Your response must follow this structured JSON format:
```json
{
"execution": "Describe how well the data loader executed, including any errors or issues encountered. Append all error messages and full traceback details without summarizing or omitting any information.",
"return_checking": "Evaluate the correctness and integrity of the loaded data. Check for issues like missing values, incorrect data types, outliers, or formatting inconsistencies.",
"code": "Assess code quality, readability, and adherence to best practices. Consider efficiency, including whether the code utilizes multi-threading or GPU acceleration for faster data loading.",
"final_decision": <true/false>
}
```
user: |-
--------- Data loader test stdout ---------
{{ stdout }}
--------- Data loader EDA stdout ---------
{% if eda_output is not none %}
{{ eda_output }}
{% else %}
No EDA output is provided.
{% endif %}
{% if workflow_stdout is not none %}
--------- Whole workflow test stdout ---------
{{ workflow_stdout }}
{% endif %}
@@ -0,0 +1,30 @@
"""
Helper functions for testing the raw_data_loader coder(CoSTEER-based) component.
- Does the developer loop work correctly
It is NOT:
- it is not interface unittest(i.e. workspace evaluator in the CoSTEER Loop)
"""
from rdagent.components.coder.data_science.raw_data_loader import DataLoaderCoSTEER
from rdagent.components.coder.data_science.raw_data_loader.exp import DataLoaderTask
from rdagent.scenarios.data_science.experiment.experiment import DSExperiment
from rdagent.scenarios.data_science.scen import KaggleScen
def develop_one_competition(competition: str): # -> experiment
scen = KaggleScen(competition=competition)
data_loader_coder = DataLoaderCoSTEER(scen)
# Create the experiment
dlt = DataLoaderTask(name="DataLoaderTask", description="")
exp = DSExperiment(
sub_tasks=[dlt],
)
# Develop the experiment
exp = data_loader_coder.develop(exp)
if __name__ == "__main__":
develop_one_competition("aerial-cactus-identification")
@@ -0,0 +1,37 @@
"""
Developers concentrating on writing documents for a workspace
"""
from rdagent.core.developer import Developer
from rdagent.core.experiment import Experiment, FBWorkspace
from rdagent.oai.llm_utils import APIBackend
from rdagent.utils.agent.ret import MarkdownAgentOut
from rdagent.utils.agent.tpl import T
class DocDev(Developer[Experiment]):
"""
The developer is responsible for writing documents for a workspace.
"""
def develop(self, exp: Experiment) -> None:
"""
Write documents for the workspace.
"""
ws: FBWorkspace = exp.experiment_workspace
file_li = [str(file.relative_to(ws.workspace_path)) for file in ws.workspace_path.rglob("*") if file.is_file()]
key_file_list = ["main.py", "scores.csv"]
system_prompt = T(".prompts:docdev.system").r()
user_prompt = T(".prompts:docdev.user").r(
file_li=file_li,
key_files={f: (ws.workspace_path / f).read_text() for f in key_file_list},
)
resp = APIBackend().build_messages_and_create_chat_completion(
user_prompt=user_prompt, system_prompt=system_prompt
)
markdown = MarkdownAgentOut.extract_output(resp)
ws.inject_files(**{"README.md": markdown})
@@ -0,0 +1,147 @@
from pathlib import Path
from typing import Literal
import pandas as pd
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER import CoSTEERMultiFeedback
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEEREvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.data_science.conf import get_clear_ws_cmd, get_ds_env
from rdagent.components.coder.data_science.utils import remove_eda_part
from rdagent.core.experiment import FBWorkspace, Task
from rdagent.core.scenario import Scenario
from rdagent.utils.agent.tpl import T
from rdagent.utils.agent.workflow import build_cls_from_json_with_retry
DIRNAME = Path(__file__).absolute().resolve().parent
PipelineSingleFeedback = CoSTEERSingleFeedback
PipelineMultiFeedback = CoSTEERMultiFeedback
NO_SUB = "<No submission.csv file found.>"
NO_SCORE = "<No scores.csv file found.>"
class ModelDumpEvaluator(CoSTEEREvaluator):
"""This evaluator assumes that it runs after the model"""
def __init__(self, scen: Scenario, data_type: Literal["sample", "full"]):
super().__init__(scen)
self.data_type = data_type
def evaluate(
self, target_task: Task, implementation: FBWorkspace, gt_implementation: FBWorkspace, *kargs, **kwargs
) -> CoSTEERSingleFeedback:
model_folder = implementation.workspace_path / "models"
# 1) Check if the model_folder is not empty
if not model_folder.exists() or not any(model_folder.iterdir()):
err_msg = "Model folder (`models` sub folder) is empty or does not exist. The model is not dumped."
return CoSTEERSingleFeedback(
execution=err_msg,
return_checking=err_msg,
code=err_msg,
final_decision=False,
)
data_source_path = (
f"{DS_RD_SETTING.local_data_path}/{self.scen.competition}"
if self.data_type == "full"
else self.scen.debug_path
)
env = get_ds_env(
extra_volumes={data_source_path: T("scenarios.data_science.share:scen.input_path").r()},
running_timeout_period=(
DS_RD_SETTING.full_timeout if self.data_type == "full" else DS_RD_SETTING.debug_timeout
),
)
# 2) check the result and stdout after reruning the model.
# Read the content of files submission.csv and scores.csv before execution
submission_content_before = (
(implementation.workspace_path / "submission.csv").read_text()
if (implementation.workspace_path / "submission.csv").exists()
else NO_SUB
)
scores_content_before = (
(implementation.workspace_path / "scores.csv").read_text()
if (implementation.workspace_path / "scores.csv").exists()
else NO_SCORE
)
# Remove the files submission.csv and scores.csv
implementation.execute(env=env, entry=get_clear_ws_cmd(stage="before_inference"))
# Execute the main script
stdout = remove_eda_part(implementation.execute(env=env, entry="python main.py"))
# walk model_folder and list the files
model_folder_files = [
str(file.relative_to(implementation.workspace_path)) for file in model_folder.iterdir() if file.is_file()
]
# this will assert the generation of necessary files
for f in ["submission.csv", "scores.csv"]:
if not (implementation.workspace_path / f).exists():
err_msg = f"{f} does not exist. The model is not dumped. Make sure that the required files, like submission.csv and scores.csv, are created even if you bypass the model training step by loading the saved model file directly."
return CoSTEERSingleFeedback(
execution=err_msg,
return_checking=err_msg,
code=err_msg,
final_decision=False,
)
# Check if scores contain NaN (values)
score_df = pd.read_csv((implementation.workspace_path / "scores.csv"), index_col=0)
if score_df.isnull().values.any():
nan_locations = score_df[score_df.isnull().any(axis=1)]
err_msg = f"\n[Error] The scores dataframe contains NaN values at the following locations:\n{nan_locations}"
return CoSTEERSingleFeedback(
execution=err_msg,
return_checking=err_msg,
code=err_msg,
final_decision=False,
)
submission_content_after = (
(implementation.workspace_path / "submission.csv").read_text()
if (implementation.workspace_path / "submission.csv").exists()
else NO_SUB
)
scores_content_after = (
(implementation.workspace_path / "scores.csv").read_text()
if (implementation.workspace_path / "scores.csv").exists()
else NO_SCORE
)
system_prompt = T(".prompts:dump_model_eval.system").r()
user_prompt = T(".prompts:dump_model_eval.user").r(
stdout=stdout.strip(),
code=implementation.all_codes,
model_folder_files=model_folder_files,
scores_content_before=scores_content_before,
scores_content_after=scores_content_after,
)
csfb = build_cls_from_json_with_retry(
CoSTEERSingleFeedback,
system_prompt=system_prompt,
user_prompt=user_prompt,
)
if DS_RD_SETTING.model_dump_check_level == "high":
# Read the content of files submission.csv and scores.csv after execution
# Check if the content has changed
# excactly same checking. But it will take more user's time
if scores_content_before != scores_content_after:
return_msg = "\n[Error] The content of scores.csv has changed. Please check the code to ensure that the model is dumped correctly, and rerun the code to use the model directly without retraining it."
return_msg += f"\nBefore:\n{scores_content_before}\nAfter:\n{scores_content_after}"
if submission_content_before != submission_content_after:
# If the scores file changes, display the two contents and append it into the return_checking
return_msg = "[Error] The content of submission.csv has changed. Please check the code to ensure that the model is dumped correctly, and rerun the code to use the model directly without retraining it."
csfb.return_checking = (csfb.return_checking or "") + return_msg
return csfb
@@ -0,0 +1,91 @@
dump_model_coder:
guideline: |-
Please dump the model in a "models/" subfolder in the first running, and the script rerun performs inference without needing to retrain the model when running the code again.
If there are parameters generated from the training data that might be needed for inference on test data, please save them in the "models/" subfolder as well.
If no test set is provided, reserve a portion of the data as your test set and save the generated test files in the models/ subfolder for use in submission and inference.
Make sure that the required files, like submission.csv and scores.csv, are created without model training step through loading the saved model and test data file directly.
dump_model_eval:
system: |-
You are a data scientist tasked with evaluating code generation. You've developed a Kaggle competition code that can produce a submission file.
The code should follow the guideline below:
{% include "components.coder.data_science.share.prompts:dump_model_coder.guideline" %}
You will receive the following information:
- The implemented code
- The stdout from running the code
- The file list in "models/" subfolder
- The scores.csv file generated during both training and inference (if it exists)
Focus on these aspects:
- Check if the code saves the model in the "models/" subfolder.
- Check if the code saves the test data in the "models/" subfolder when there is no test data specified.
- Ensure that when the code is rerun, it skips the training process and loads the model from the "models/" subfolder for direct inference.
- Verify that there is no training activity in the output.
- Ensure that even if you skip the model training by loading saved models, the files like scores.csv and submission.csv are still correctly created.
- The model's performance should remain consistent and not vary unreasonably between training and inference.
Please respond with your feedback in the following JSON format and order
```json
{
"execution": "Describe whether the code executed successfully. Include any errors or issues encountered, and append all error messages and full traceback details without summarizing or omitting any information. Carefully check the stdout to ensure that when the code is rerun, it skips the training process and loads the model from the 'models/' subfolder for direct inference. Append the information that makes you think that the model is still being retrained when rerunning the code."
"return_checking": "Verify the generated files include necessary files. Make sure scores.csv file does not change unreasonably between training and inference",
"code": "The code has explicity dump the model into 'models/' subfolder; When the modes files are already in 'models/' subfolder, the code will explicity skip the training process.",
"final_decision": <true or false in boolean type; only return true when ensuring that the code saves the model in a 'models/' subfolder, and the script rerun performs inference without needing to retrain the model.>
}
```
user: |-
------------ The implemented code ------------
{{code}}
------------ The stdout from running the code ------------
{{stdout}}
------------ The file list in "models/" subfolder ------------
{% for f in model_folder_files %}
- {{ f }}
{% endfor %}
------------ The scores.csv file generated ------------
# Training:
{{scores_content_before}}
# Inference:
{{scores_content_after}}
docdev:
system: |-
{% include "scenarios.data_science.share:scen.role" %} Your task is to create documentation for a data science solution.
You will be given:
- a list of files in the folder.
- content from some important files.
Please explain the trained models in the "models/" folder. The training and inference processes are detailed in the `main.py` file. The models' evaluation results are in `scores.csv`. Please respond with a markdown file that includes the following information:
- Explain the purpose of each model. If some models are part of a group (like those from cross-validation), describe them together.
- Provide key details for each model group:
- Important training parameters
- Model details
- Performance of each model
Be brief. Mention the file path when you introduce files.
Don't introduce anything other than models.
{% include "utils.agent.tpl:MarkdownOut" %}
user: |-
--------------- The file list in the workspace ---------------
{% for f in file_li %}
- {{ f }}
{% endfor %}
--------------- File content of each file ---------------
{% for fname, content in key_files.items() %}
File Path: {{fname}}
```
{{content}}
```
{% endfor %}
@@ -0,0 +1,6 @@
import re
def remove_eda_part(stdout: str) -> str:
"""Data Science scenario have a LLM-based EDA feature. We can remove it when current task does not involve EDA"""
return re.sub(r"=== Start of EDA part ===(.*)=== End of EDA part ===", "", stdout, flags=re.DOTALL)
@@ -0,0 +1,135 @@
import json
from typing import Dict
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER import CoSTEER
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEERMultiEvaluator,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.CoSTEER.evolving_strategy import (
MultiProcessEvolvingStrategy,
)
from rdagent.components.coder.CoSTEER.knowledge_management import (
CoSTEERQueriedKnowledge,
)
from rdagent.components.coder.data_science.conf import DSCoderCoSTEERSettings
from rdagent.components.coder.data_science.workflow.eval import (
WorkflowGeneralCaseSpecEvaluator,
)
from rdagent.components.coder.data_science.workflow.exp import WorkflowTask
from rdagent.core.exception import CoderError
from rdagent.core.experiment import FBWorkspace
from rdagent.core.scenario import Scenario
from rdagent.oai.llm_utils import APIBackend
from rdagent.utils.agent.ret import PythonAgentOut
from rdagent.utils.agent.tpl import T
class WorkflowMultiProcessEvolvingStrategy(MultiProcessEvolvingStrategy):
def implement_one_task(
self,
target_task: WorkflowTask,
queried_knowledge: CoSTEERQueriedKnowledge | None = None,
workspace: FBWorkspace | None = None,
prev_task_feedback: CoSTEERSingleFeedback | None = None,
) -> dict[str, str]:
workflow_information_str = target_task.get_task_information()
# 1. query
queried_similar_successful_knowledge = (
queried_knowledge.task_to_similar_task_successful_knowledge[workflow_information_str]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
queried_knowledge.task_to_former_failed_traces[workflow_information_str]
if queried_knowledge is not None
else []
)
queried_former_failed_knowledge = (
[
knowledge
for knowledge in queried_former_failed_knowledge[0]
if knowledge.implementation.file_dict.get("main.py") != workspace.file_dict.get("main.py")
],
queried_former_failed_knowledge[1],
)
# 2. code
system_prompt = T(".prompts:workflow_coder.system").r(
task_desc=workflow_information_str,
competition_info=self.scen.get_scenario_all_desc(eda_output=workspace.file_dict.get("EDA.md", None)),
queried_similar_successful_knowledge=queried_similar_successful_knowledge,
queried_former_failed_knowledge=queried_former_failed_knowledge[0],
out_spec=PythonAgentOut.get_spec(),
)
user_prompt = T(".prompts:workflow_coder.user").r(
load_data_code=workspace.file_dict["load_data.py"],
feature_code=workspace.file_dict["feature.py"],
model_codes=workspace.get_codes(r"^model_(?!test)\w+\.py$"),
ensemble_code=workspace.file_dict["ensemble.py"],
latest_code=workspace.file_dict.get("main.py"),
code_spec=(
workspace.file_dict["spec/workflow.md"]
if DS_RD_SETTING.spec_enabled
else T("scenarios.data_science.share:component_spec.Workflow").r()
),
latest_code_feedback=prev_task_feedback,
)
for _ in range(5):
workflow_code = PythonAgentOut.extract_output(
APIBackend().build_messages_and_create_chat_completion(
user_prompt=user_prompt,
system_prompt=system_prompt,
)
)
if workflow_code != workspace.file_dict.get("main.py"):
break
else:
user_prompt = user_prompt + "\nPlease avoid generating same code to former code!"
else:
raise CoderError("Failed to generate a new workflow code.")
return {"main.py": workflow_code}
def assign_code_list_to_evo(self, code_list: list[dict[str, str]], evo):
"""
Assign the code list to the evolving item.
The code list is aligned with the evolving item's sub-tasks.
If a task is not implemented, put a None in the list.
"""
for index in range(len(evo.sub_tasks)):
if code_list[index] is None:
continue
if evo.sub_workspace_list[index] is None:
# evo.sub_workspace_list[index] = FBWorkspace(target_task=evo.sub_tasks[index])
evo.sub_workspace_list[index] = evo.experiment_workspace
evo.sub_workspace_list[index].inject_files(**code_list[index])
return evo
class WorkflowCoSTEER(CoSTEER):
def __init__(
self,
scen: Scenario,
*args,
**kwargs,
) -> None:
settings = DSCoderCoSTEERSettings()
eva = CoSTEERMultiEvaluator(
WorkflowGeneralCaseSpecEvaluator(scen=scen), scen=scen
) # Please specify whether you agree running your eva in parallel or not
es = WorkflowMultiProcessEvolvingStrategy(scen=scen, settings=settings)
super().__init__(
*args,
settings=settings,
eva=eva,
es=es,
evolving_version=2,
scen=scen,
max_loop=DS_RD_SETTING.coder_max_loop,
**kwargs,
)
@@ -0,0 +1,155 @@
import json
import re
from pathlib import Path
import pandas as pd
from rdagent.app.data_science.conf import DS_RD_SETTING
from rdagent.components.coder.CoSTEER.evaluators import (
CoSTEEREvaluator,
CoSTEERMultiFeedback,
CoSTEERSingleFeedback,
)
from rdagent.components.coder.data_science.conf import get_clear_ws_cmd, get_ds_env
from rdagent.components.coder.data_science.utils import remove_eda_part
from rdagent.core.evolving_framework import QueriedKnowledge
from rdagent.core.experiment import FBWorkspace, Task
from rdagent.log import rdagent_logger as logger
from rdagent.utils.agent.tpl import T
from rdagent.utils.agent.workflow import build_cls_from_json_with_retry
DIRNAME = Path(__file__).absolute().resolve().parent
WorkflowSingleFeedback = CoSTEERSingleFeedback
WorkflowMultiFeedback = CoSTEERMultiFeedback
class WorkflowGeneralCaseSpecEvaluator(CoSTEEREvaluator):
"""
Motivation case:
- Simplest case, we already split the data into train_data, valid_data, and test_data. We require the model to learn (optionally validate on valid data), and infer on test data.
Test workflow:
- Build train, valid, and test data to run it, and test the output (e.g., shape, etc.)
"""
def evaluate(
self,
target_task: Task,
implementation: FBWorkspace,
gt_implementation: FBWorkspace,
queried_knowledge: QueriedKnowledge = None,
**kwargs,
) -> CoSTEERSingleFeedback:
target_task_information = target_task.get_task_information()
if (
queried_knowledge is not None
and target_task_information in queried_knowledge.success_task_to_knowledge_dict
):
return queried_knowledge.success_task_to_knowledge_dict[target_task_information].feedback
elif queried_knowledge is not None and target_task_information in queried_knowledge.failed_task_info_set:
return WorkflowSingleFeedback(
execution="This task has failed too many times, skip implementation.",
return_checking="This task has failed too many times, skip implementation.",
code="This task has failed too many times, skip implementation.",
final_decision=False,
)
env = get_ds_env(extra_volumes={self.scen.debug_path: T("scenarios.data_science.share:scen.input_path").r()})
# # DockerEnv for MLEBench submission validation
# mle_de_conf = MLEBDockerConf()
# mle_de_conf.extra_volumes = {
# f"{DS_RD_SETTING.local_data_path}/zip_files": "/mle/data",
# }
# mde = DockerEnv(conf=mle_de_conf)
# mde.prepare()
# Clean the scores.csv & submission.csv.
implementation.execute(env=env, entry=get_clear_ws_cmd())
stdout = implementation.execute(env=env, entry=f"python -m coverage run main.py")
# remove EDA part
stdout = remove_eda_part(stdout)
# Check score file
score_fp = implementation.workspace_path / "scores.csv"
score_ret_code = 0
score_check_text = ""
if not score_fp.exists():
score_check_text = "[Error] Metrics file (scores.csv) is not generated!"
score_ret_code = 1
implementation.execute(env=env, entry="python -m coverage json -o coverage.json")
coverage_report_path = implementation.workspace_path / "coverage.json"
if coverage_report_path.exists():
used_files = set(json.loads(coverage_report_path.read_text())["files"].keys())
coverage_report_path.unlink()
logger.info(f"All used scripts: {used_files}")
if len(used_files) == 1:
score_check_text += f"\n[Error] The only used script is {used_files}.\nPlease check if you have implemented entry point in 'main.py'."
else:
try:
score_df = pd.read_csv(score_fp, index_col=0)
model_set_in_scores = set(score_df.index)
# We assume that model names in `score_df` are stored without the '.py' file extension.
model_set_in_folder = set(
f[:-3] for f in implementation.file_dict.keys() if re.match(r"^model_(?!test)\w+\.py$", f)
)
# Check model names (index)
if model_set_in_scores != model_set_in_folder.union({"ensemble"}):
score_check_text += f"\n[Error] The scores dataframe does not contain the correct model names as index.\ncorrect model names are: {model_set_in_folder.union({'ensemble'})}\nscore_df is:\n{score_df}"
score_ret_code = 1
# Check metric name (columns)
if score_df.columns.tolist() != [self.scen.metric_name]:
score_check_text += f"\n[Error] The scores dataframe does not contain the correct column names.\nCorrect columns is: ['{self.scen.metric_name}']\nBut got: {score_df.columns.tolist()}"
score_ret_code = 1
# Check if scores contain NaN (values)
if score_df.isnull().values.any():
nan_locations = score_df[score_df.isnull().any(axis=1)]
score_check_text += f"\n[Error] The scores dataframe contains NaN values at the following locations:\n{nan_locations}"
score_ret_code = 1
except Exception as e:
score_check_text += f"\n[Error] in checking the scores.csv file: {e}\nscores.csv's content:\n-----\n{score_fp.read_text()}\n-----"
score_ret_code = 1
# Check submission file
base_check_code = T(".eval_tests.submission_format_test", ftype="txt").r()
implementation.inject_files(**{"test/submission_format_test.py": base_check_code})
# stdout += "----Submission Check 1-----\n"
submission_check_out, submission_ret_code = implementation.execute_ret_code(
env=env, entry="python test/submission_format_test.py"
)
stdout += "\n" + submission_check_out
system_prompt = T(".prompts:workflow_eval.system").r(
# here we pass `None` to `eda_output` because we do not have nor need EDA output for workflow.
scenario=self.scen.get_scenario_all_desc(eda_output=None),
task_desc=target_task.get_task_information(),
spec=(
implementation.file_dict["spec/workflow.md"]
if DS_RD_SETTING.spec_enabled
else T("scenarios.data_science.share:component_spec.Workflow").r()
),
)
user_prompt = T(".prompts:workflow_eval.user").r(
stdout=stdout.strip(),
code=implementation.file_dict["main.py"],
)
wfb = build_cls_from_json_with_retry(
WorkflowSingleFeedback,
system_prompt=system_prompt,
user_prompt=user_prompt,
init_kwargs_update_func=WorkflowSingleFeedback.val_and_update_init_dict,
)
if score_ret_code != 0:
wfb.final_decision = False
wfb.return_checking += "\n" + score_check_text
if submission_ret_code != 0:
wfb.final_decision = False
wfb.return_checking += "\nSubmission file check failed."
return wfb
@@ -0,0 +1,77 @@
from pathlib import Path
import pandas as pd
import hashlib
def calculate_md5(file_path):
with open(file_path, "rb") as f:
file_hash = hashlib.md5(f.read()).hexdigest()
return file_hash
file_md5 = calculate_md5("scores.csv")
"""
find . | grep -i sample | grep -i submission | grep -v sample_submission.csv | grep -v zip_files | grep -v 'sample/'
./denoising-dirty-documents/sampleSubmission.csv
./the-icml-2013-whale-challenge-right-whale-redux/sampleSubmission.csv
./text-normalization-challenge-russian-language/ru_sample_submission_2.csv.zip
./text-normalization-challenge-russian-language/ru_sample_submission_2.csv
./random-acts-of-pizza/sampleSubmission.csv
./text-normalization-challenge-english-language/en_sample_submission_2.csv.zip
./text-normalization-challenge-english-language/en_sample_submission_2.csv
./detecting-insults-in-social-commentary/sample_submission_null.csv
"""
# Find sample submission file dynamically
input_dir = Path("{% include "scenarios.data_science.share:scen.input_path" %}")
# Look for common variations of sample submission filenames
sample_submission_files = list(input_dir.glob("*sample_submission*.csv")) + \
list(input_dir.glob("*sampleSubmission*.csv"))
assert sample_submission_files, "Error: No sample submission file found in {% include "scenarios.data_science.share:scen.input_path" %}"
# Use first matching file
sample_submission_name = sample_submission_files[0].name
SAMPLE_SUBMISSION_PATH = str(sample_submission_files[0])
print(f"Using sample submission file: {sample_submission_name}")
# Check if the sample submission file exists
assert Path(SAMPLE_SUBMISSION_PATH).exists(), f"Error: {sample_submission_name} not found at {SAMPLE_SUBMISSION_PATH}"
# Check if our submission file exists
assert Path('submission.csv').exists(), "Error: submission.csv not found"
sample_submission = pd.read_csv(SAMPLE_SUBMISSION_PATH)
our_submission = pd.read_csv('submission.csv')
success = True
# Print the columns of the sample submission file
print(f"Columns in {sample_submission_name}:", sample_submission.columns)
print("Columns in our_submission.csv:", our_submission.columns)
for col in sample_submission.columns:
if col not in our_submission.columns:
success = False
print(f'Column {col} not found in submission.csv')
if success:
print(f'submission.csv\'s columns aligns with {sample_submission_name} .')
# Print the first 5 rows of the two submission files, with columns separated by commas.
def print_first_rows(file_path, file_name, num_rows=5):
print(f"\nFirst {num_rows} rows of {file_name}:")
try:
with open(file_path, 'r') as file:
for i, line in enumerate(file):
if i < num_rows:
print(line.strip())
else:
break
except FileNotFoundError:
print(f"Error: {file_name} not found.")
print_first_rows(SAMPLE_SUBMISSION_PATH, sample_submission_name)
print_first_rows('submission.csv', 'submission.csv')
assert calculate_md5("scores.csv") == file_md5, "scores.csv should not be rewritten"
print(f"\nPlease Checked the content of the submission file(submission.csv should align with {sample_submission_name}). ")
@@ -0,0 +1,14 @@
import pickle
import site
import traceback
from pathlib import Path
from typing import Dict, Optional
from rdagent.components.coder.CoSTEER.task import CoSTEERTask
from rdagent.core.utils import cache_with_pickle
# Because we use isinstance to distinguish between different types of tasks, we need to use sub classes to represent different types of tasks
class WorkflowTask(CoSTEERTask):
def __init__(self, name: str = "Workflow", *args, **kwargs) -> None:
super().__init__(name=name, *args, **kwargs)
@@ -0,0 +1,137 @@
workflow_coder:
system: |-
You are a world-class data scientist and machine learning engineer with deep expertise in statistics, mathematics, and computer science.
Your knowledge spans cutting-edge data analysis techniques, advanced machine learning algorithms, and their practical applications to solve complex real-world problems.
## Task Description
{{ task_desc }}
Here is the competition information for this task:
{{ competition_info }}
{% if queried_similar_successful_knowledge|length != 0 or queried_former_failed_knowledge|length != 0 %}
## Relevant Information for This Task
{% endif %}
{% if queried_similar_successful_knowledge|length != 0 %}
--------- Successful Implementations for Similar Models ---------
====={% for similar_successful_knowledge in queried_similar_successful_knowledge %} Model {{ loop.index }}:=====
{{ similar_successful_knowledge.target_task.get_task_information() }}
=====Code:=====
{{ similar_successful_knowledge.implementation.file_dict["main.py"] }}
{% endfor %}
{% endif %}
{% if queried_former_failed_knowledge|length != 0 %}
--------- Previous Failed Attempts ---------
{% for former_failed_knowledge in queried_former_failed_knowledge %} Attempt {{ loop.index }}:
=====Code:=====
{{ former_failed_knowledge.implementation.file_dict["main.py"] }}
=====Feedback:=====
{{ former_failed_knowledge.feedback }}
{% endfor %}
{% endif %}
## Guidelines
1. Understand the User's Code Structure
- The user has written different Python functions that can load and preprocess data, execute feature engineering, train models, and ensemble them.
- Each functionality is in a separate Python file.
2. Your task is only to integrate the existing processes of load_data, feature, model, and ensemble into a complete workflow. Do not edit or modify the existing Python files. The final step should output the predictions in the required format.
3. The user may provide specific code organization rules and instructions. Ensure that the integration follows the given framework and structure.
4. After predicting the output, print the shape and other information of the output to stdout to help the evaluator assess the code.
5. You should avoid using logging module to output information in your generated code, and instead use the print() function.
{% include "scenarios.data_science.share:guidelines.coding" %}
## Output Format
{% if out_spec %}
{{ out_spec }}
{% else %}
Please response the code in the following json format. Here is an example structure for the JSON output:
{
"code": "The Python code as a string."
}
{% endif %}
user: |-
--------- Code Specification ---------
{{ code_spec }}
--------- load data code ---------
file: load_data.py
{{ load_data_code }}
--------- feature engineering code ---------
file: feature.py
{{ feature_code }}
--------- model training code ---------
Attention: The input and output of the model function is flexible. Training dataset is necessary, but validation and test dateset might be optional. The hyperparameters can either be passed as arguments or be set as default values in the function. You need to use the function correctly.
All model files share the same function name. Please import the model files with their name like: from {file_name} import {function_name}
{{ model_codes }}
--------- ensemble code ---------
Note, we will check the index of the score.csv, so please use the model name as the index to feed into ensemble function.
file: ensemble.py
{{ ensemble_code }}
{% if latest_code %}
--------- Former code ---------
{{ latest_code }}
{% if latest_code_feedback is not none %}
--------- Feedback to former code ---------
{{ latest_code_feedback }}
{% endif %}
The former code contains errors. You should correct the code based on the provided information, ensuring you do not repeat the same mistakes.
{% endif %}
workflow_eval:
system: |-
You are a data scientist responsible for evaluating workflow code generation.
## Task Description
The user is trying to build a workflow in the following scenario:
{{ scenario }}
The main code generation task is as follows:
{{ task_desc }}
The user provides workflow information and its components.
The details on how to structure the workflow are given in the specification file:
```markdown
{{ spec }}
```
This workflow integrates multiple stages, including:
- Data loading
- Feature engineering
- Model training
- Ensembling
## Evaluation Scope
Your focus is to check whether the workflow code:
1. Executes successfully, correctly organizing components and generating a final submission.
2. Generates predictions in the correct format, ensuring they align with the **sample submission** structure!
[Note]
1. The individual components (data loading, feature engineering, model tuning, etc.) have already been evaluated by the user. You should only evaluate and improve the workflow code, unless there are critical issues in the components.
2. Model performance is NOT a concern in this evaluation—only correct execution and formatting matter.
3. As long as the execution does not exceed the time limit, ensure that the code uses cross-validation to split the training data and train the model. If cross-validation is not used, mention it in the execution section and set `final_decision` to `false`.
## Evaluation Criteria
You will be given the workflow execution output (`stdout`) to determine correctness.
Please respond with your feedback in the following JSON format and order
```json
{
"execution": "Describe whether the main workflow executed successfully, correctly integrating all components and generating the final submission. Include any errors or issues encountered, and append all error messages and full traceback details without summarizing or omitting any information.",
"return_checking": "Verify the generated files, particularly the submission file. Ensure that its format matches the sample submission, checking the index, column names, and CSV content.",
"code": "Provide feedback on code quality, readability, and adherence to the given specifications.",
"final_decision": <true/false>
}
```
user: |-
--------- Workflow test stdout ---------
{{ stdout }}
--------- Workflow code generated by user ---------
{{ code }}
@@ -0,0 +1,59 @@
"""
Generate dataset to test the workflow output
"""
from pathlib import Path
from rdagent.components.coder.CoSTEER.config import CoSTEER_SETTINGS
from rdagent.components.coder.data_science.workflow import WorkflowCoSTEER
from rdagent.components.coder.data_science.workflow.eval import (
WorkflowGeneralCaseSpecEvaluator,
)
from rdagent.components.coder.data_science.workflow.exp import WorkflowTask
from rdagent.core.experiment import FBWorkspace
from rdagent.scenarios.data_science.experiment.experiment import DSExperiment
from rdagent.scenarios.data_science.scen import KaggleScen
def develop_one_competition(competition: str):
scen = KaggleScen(competition=competition)
workflow_coder = WorkflowCoSTEER(scen)
wt = WorkflowTask(
name="WorkflowTask",
description="Integrate the existing processes of load_data, feature, model, and ensemble into a complete workflow.",
base_code="",
)
tpl_ex_path = Path(__file__).resolve() / Path("rdagent/scenarios/kaggle/tpl_ex").resolve() / competition
injected_file_names = ["spec/workflow.md", "load_data.py", "feature.py", "model01.py", "ensemble.py", "main.py"]
workflowexp = FBWorkspace()
for file_name in injected_file_names:
file_path = tpl_ex_path / file_name
workflowexp.inject_files(**{file_name: file_path.read_text()})
wt.base_code += workflowexp.file_dict["main.py"]
exp = DSExperiment(
sub_tasks=[wt],
)
"""es = WorkflowMultiProcessEvolvingStrategy(scen=scen, settings=CoSTEER_SETTINGS)
new_code = es.implement_one_task(target_task=wt, queried_knowledge=None, workspace = workflowexp)
print(new_code)"""
"""eva = WorkflowGeneralCaseSpecEvaluator(scen=scen)
exp.feedback = eva.evaluate(target_task=wt, queried_knowledge=None, implementation=workflowexp, gt_implementation=None)
print(exp.feedback)"""
# Run the experiment
for file_name in injected_file_names:
file_path = tpl_ex_path / file_name
exp.experiment_workspace.inject_files(**{file_name: file_path.read_text()})
exp = workflow_coder.develop(exp)
if __name__ == "__main__":
develop_one_competition("aerial-cactus-identification")
# dotenv run -- python rdagent/components/coder/data_science/workflow/test.py

Some files were not shown because too many files have changed in this diff Show More