Spaces:
Sleeping
title: Dataclean Env
emoji: π§Ή
colorFrom: blue
colorTo: green
sdk: docker
pinned: false
tags:
- openenv
- data-cleaning
- etl
- real-world
- tabular
- data-drift
- streaming
DataClean OpenEnv
A real-world data cleaning and ETL environment for AI agent RL training, built on the OpenEnv framework by Meta-PyTorch and Hugging Face.
Agents learn to fix messy tabular data β filling nulls, normalising inconsistent values, removing duplicates, filtering outliers, performing multi-table ETL joins, and handling live data drift (novel: fresh dirty rows injected mid-episode every 5 steps).
Why This Environment
Data cleaning is one of the most common, time-consuming tasks in real data engineering. Every company with a data pipeline does this daily. Training an RL agent on this task has immediate real-world value β unlike game-based environments.
What makes this different from other OpenEnv submissions:
- Task 4 (Data Drift) is genuinely novel β no existing OpenEnv environment simulates live streaming row injection mid-episode
- Parallel baseline using
concurrent.futures.ThreadPoolExecutorβ all 4 tasks run simultaneously - Deterministic graders using seeded dataset generation β perfectly reproducible scores
- Dense reward signal: reward = grader(new_state) β grader(prev_state) at every step
Tasks
| Task | Difficulty | Description | Max Steps |
|---|---|---|---|
task1 |
Easy | Fix nulls + dtypes in 50-row customer CSV | 10 |
task2 |
Medium | Dedup + normalize strings + fix dates + fill nulls | 20 |
task3 |
Hard | Multi-table merge + outlier removal + derived column | 30 |
task4_data_drift |
Expert | Live streaming table β 7 dirty rows injected every 5 steps | 40 |
Action Space
Every action is a JSON object with an operation field:
{"operation": "fill_nulls", "column": "age", "strategy": "median"}
{"operation": "cast_column", "column": "age", "dtype": "int"}
{"operation": "remove_duplicates"}
{"operation": "normalize_values", "column": "country", "method": "upper"}
{"operation": "cast_column", "column": "order_date", "dtype": "datetime"}
{"operation": "filter_outliers", "column": "amount", "method": "iqr", "threshold": 1.5}
{"operation": "merge_tables", "left_table": "orders", "right_table": "customers", "on": "customer_id", "output_table": "merged"}
{"operation": "add_derived_column", "column_name": "order_year", "source_column": "order_date", "transform": "year_from_date", "table_name": "merged"}
{"operation": "submit"}
Observation Space
After each reset() / step() the agent receives:
task_id,task_description,step_count,max_steps,messagetablesβ dict of{table_name β JSON string of df.head(10)}column_dtypes,null_counts,duplicate_count,row_countschema_errorsβ list of detected problems to guide the agentreward,done,partial_scoreβ RL signals
Reward Function
step_reward = grader(current_state) β grader(previous_state) # dense delta signal
invalid_op = β0.02 # bad operation penalty
terminal = final grader score on submit or max_steps
Partial credit per sub-dimension. Score range: [0.0, 1.0].
Baseline Scores (llama-3.3-70b-versatile, seed=42, parallel run)
| Task | Score | Time |
|---|---|---|
| task1 (easy) | 1.0000 | 11.8s |
| task2 (medium) | 1.0000 | 34.1s |
| task3 (hard) | 0.8000 | 22.4s |
| task4_data_drift (expert) | 0.9297 | 26.6s |
| mean | 0.9324 | 34.3s wall |
All 4 tasks run in parallel β wall time = slowest task, not sum.
Setup & Local Run
pip install -r requirements.txt
uvicorn server.app:app --host 0.0.0.0 --port 7860 --reload
curl http://localhost:7860/health
curl http://localhost:7860/tasks
export OPENAI_API_KEY=your_key
export OPENAI_BASE_URL=https://api.groq.com/openai/v1
export BASELINE_MODEL=llama-3.3-70b-versatile
python baseline.py
Docker
docker build -t dataclean-env .
docker run -p 7860:7860 -e OPENAI_API_KEY=your_key dataclean-env
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
| POST | /reset |
Start new episode |
| POST | /step |
Execute one cleaning operation |
| GET | /state |
Current episode metadata |
| GET | /tasks |
All tasks + action schema |
| GET | /grader |
Score current episode state |
| GET | /baseline |
Run baseline agent on all tasks |
| GET | /health |
Liveness probe |
| GET | /docs |
Interactive Swagger UI |
Project Structure
dataCleaningProject/
βββ server/
β βββ app.py # FastAPI server β all endpoints
β βββ environment.py # Core env logic β reset/step/state + drift injection
β βββ graders.py # Deterministic scoring for all 4 tasks
β βββ dataset_factory.py # Seeded dirty+expected dataset generation + drift batches
βββ models.py # Pydantic Action + Observation models
βββ baseline.py # Parallel baseline (ThreadPoolExecutor, 4 tasks at once)
βββ client.py # HTTP client
βββ openenv.yaml # OpenEnv manifest
βββ Dockerfile # Port 7860, Python 3.11-slim
βββ requirements.txt