CoolFace
Apppublic

ritzravenweak/data-cleaning-env

sourceHugging Facebsd-3-clauseupdated 5mo agoView on Hugging Face
0likes
App README

๐Ÿงน Data Cleaning OpenEnv

A real-world OpenEnv environment where AI agents learn to detect, diagnose, and fix data quality issues in tabular datasets โ€” a task that data engineers and analysts perform every day.


Deployed Space

  • โ€”Hugging Face Space: https://huggingface.co/spaces/ritzravenweak/data-cleaning-env
  • โ€”Live endpoint: https://ritzravenweak-data-cleaning-env.hf.space

Motivation

Data quality is a universal bottleneck. Industry surveys consistently report that data professionals spend 60โ€“80 % of their time cleaning data, yet there is no widely-used benchmark environment for training or evaluating agents on this task. This environment fills that gap.

Three tasks span an easy-to-hard difficulty range that challenges both small and frontier models:

#TaskDifficultyMax Steps
1Schema ValidationEasy1
2Format StandardizationMedium1
3Multi-step PipelineHard8

Environment Description

All three tasks operate on realistic synthetic tabular datasets (CSV-like row/column data) with known ground-truth issues.

Task 1 โ€“ Schema Validation (easy)

Dataset: 30-row customer CRM export.

Goal: Identify all 13 data quality issues by checking each row against a provided JSON schema.

Issue types present:

  • โ€”missing_required โ€“ required fields that are null
  • โ€”wrong_type โ€“ a string where an integer is expected
  • โ€”invalid_range โ€“ numeric values outside [min, max]
  • โ€”invalid_format โ€“ malformed email / phone number / date strings
  • โ€”invalid_enum โ€“ value not in the allowed set
  • โ€”duplicate โ€“ repeated primary-key values

Action: report_issues โ€” submit a list of DataIssue objects.

Reward: F1 score over (row_index, column, issue_type) tuples. Partial credit (ร—0.3) for correct row+column with wrong issue type.


Task 2 โ€“ Format Standardization (medium)

Dataset: 20-row sales records with 5 columns in wildly inconsistent formats.

ColumnExample inputsTarget
date"01/15/2023", "Jan 15 2023", "2023-01-15"YYYY-MM-DD
phone"555-123-4567", "+15551234567", "555.123.4567"(XXX) XXX-XXXX
state"California", "cal", "CALIFORNIA"CA (2-letter)
amount"$1,234.56", "USD 1234.56", "1,234.56"1234.56 (float)
product_code"sku001", "SKU 001", "001"SKU-001

Action: apply_transforms โ€” submit a ColumnTransform per column. The environment applies the transforms programmatically and compares results to ground-truth expected values.

Reward: Mean per-column accuracy (fraction of rows whose transformed value matches ground truth).


Task 3 โ€“ Multi-step Data Quality Pipeline (hard)

Dataset: 25-row employee records with 10 issues across 6 categories.

The agent must complete 4 pipeline phases in order:

AUDIT โ†’ IDENTIFY โ†’ FIX โ†’ VALIDATE
PhaseAction typeWhat to do
auditauditIdentify which categories of issues are present
identifyreport_issuesEnumerate every specific issue (row, column, type)
fixfixSubmit fix_operations to correct each issue
validatevalidateWrite a validation report; estimate remaining issues

Reward (weighted sum):

  • โ€”Audit: 0.15 ร— category recall
  • โ€”Identify: 0.30 ร— issue F1
  • โ€”Fix: 0.40 ร— fix recall (โˆ’0.05 per spurious fix)
  • โ€”Validate: 0.15 ร— report quality
  • โ€”+0.05 efficiency bonus for exactly 4 phases (no wasted steps)

Action & Observation Spaces

Observation โ€“ DataObservation

python
class DataObservation(BaseModel):
    episode_id:       str
    task_type:        TaskType          # schema_validation | standardization | pipeline
    dataset_name:     str
    dataset_sample:   List[Dict]        # first N rows of the dataset
    total_rows:       int
    schema:           Dict              # JSON schema (validation & pipeline tasks)
    column_stats:     Dict[str, ColumnStats]  # per-column statistics
    current_step:     int
    max_steps:        int
    pipeline_phase:   Optional[PipelineStep]  # pipeline task only
    available_actions: List[str]
    cumulative_reward: float
    context:          Dict              # target formats, hints, etc.

Action โ€“ DataAction

python
class DataAction(BaseModel):
    action_type: str  # report_issues | apply_transforms | audit | fix | validate

    # report_issues
    issues: Optional[List[DataIssue]]

    # apply_transforms
    transforms: Optional[Dict[str, ColumnTransform]]

    # audit
    audit_summary:    Optional[str]
    issue_categories: Optional[List[str]]

    # fix
    fix_operations: Optional[List[FixOperation]]

    # validate
    validation_report:  Optional[str]
    issues_remaining:   Optional[int]

API Endpoints

MethodPathDescription
GET/Health check + env metadata
GET/tasksList all tasks
POST/resetStart a new episode {task_id}
POST/stepAdvance episode {episode_id, action}
GET/state/{episode_id}Inspect episode state
POST/validateRun openenv validation check
GET/docsInteractive Swagger UI

Quick Start

Local Python

bash
pip install -r requirements.txt

# Start the environment server
python app.py          # listens on http://localhost:7860

# In another terminal, run the baseline agent
API_BASE_URL="https://router.huggingface.co/v1" \
MODEL_NAME="Qwen/Qwen2.5-72B-Instruct" \
HF_TOKEN="hf_..." \
python inference.py

Docker

bash
# Build
docker build -t data-cleaning-env .

# Run the server
docker run -p 7860:7860 data-cleaning-env

# Run inference (in a second terminal)
API_BASE_URL="https://router.huggingface.co/v1" \
MODEL_NAME="Qwen/Qwen2.5-72B-Instruct" \
HF_TOKEN="hf_..." \
OPENENV_BASE_URL="http://localhost:7860" \
python inference.py

cURL example

bash
# Reset a schema_validation episode
curl -s -X POST http://localhost:7860/reset \
  -H "Content-Type: application/json" \
  -d '{"task_id":"schema_validation"}' | python -m json.tool

# Step with a report_issues action
curl -s -X POST http://localhost:7860/step \
  -H "Content-Type: application/json" \
  -d '{
    "episode_id": "<id from reset>",
    "action": {
      "action_type": "report_issues",
      "issues": [
        {"row_index": 2, "column": "email", "issue_type": "invalid_format",
         "description": "missing @ symbol", "value": "invalid-email"}
      ]
    }
  }' | python -m json.tool

Environment Variables

VariableRequiredDescription
API_BASE_URLYesOpenAI-compatible API endpoint
MODEL_NAMEYesModel identifier (e.g. Qwen/Qwen2.5-72B-Instruct)
HF_TOKENYes*Hugging Face token (used as API key)
OPENAI_API_KEYYes*OpenAI API key (alternative to HF_TOKEN)
OPENENV_BASE_URLNoEnvironment server URL (default http://localhost:7860)

\* Either HF_TOKEN or OPENAI_API_KEY must be set. HF_TOKEN takes precedence if both are present.


Baseline Scores

Measured with Qwen/Qwen2.5-72B-Instruct via python inference.py:

TaskScoreNotes
Schema Validation (easy)0.837011/13 exact matches, 1 partial; F1=0.84
Standardization (medium)0.9999Near-perfect transform accuracy (strict open score range)
Pipeline (hard)0.5660Multi-phase reward with partial credit across audit/identify/fix/validate
Overall average0.8010

The hard task has clear headroom โ€” audit and identify phases are the bottleneck, making it a useful training target for RL fine-tuning.


Project Structure

data-cleaning-env/
โ”œโ”€โ”€ app.py            # FastAPI server (OpenEnv HTTP API)
โ”œโ”€โ”€ inference.py      # Baseline inference script ([START]/[STEP]/[END] logging)
โ”œโ”€โ”€ validate.py       # Pre-submission validation script (run before submitting)
โ”œโ”€โ”€ openenv.yaml      # Environment metadata
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ Dockerfile
โ”œโ”€โ”€ README.md
โ””โ”€โ”€ env/
    โ”œโ”€โ”€ __init__.py
    โ”œโ”€โ”€ environment.py  # Core DataCleaningEnv class
    โ”œโ”€โ”€ models.py       # Pydantic typed models
    โ”œโ”€โ”€ datasets.py     # Synthetic datasets with known ground-truth issues
    โ””โ”€โ”€ graders.py      # Deterministic grading functions

Grader Details

All graders are fully deterministic โ€” same action always produces the same score.

Schema Validation Grader

  • โ€”Builds sets of (row_index, column, issue_type) tuples for predicted vs ground truth
  • โ€”Computes F1 over exact matches
  • โ€”Adds 0.3ร— partial credit for correct (row, column) with wrong issue_type
  • โ€”Applies โˆ’15% penalty if reported count > 2ร— ground truth (penalises spam)

Standardization Grader

  • โ€”For each of the 5 columns, applies the agent's transform to every raw value
  • โ€”Compares result to a deterministic ground-truth expected value
  • โ€”Column score = (matching rows) / total rows
  • โ€”Final score = mean column score

Pipeline Grader

  • โ€”Audit: recall over the 5 known issue categories (invalid_enum, invalid_range, duplicate, invalid_format, missing_required)
  • โ€”Identify: F1 with partial credit (reuses schema validation grader)
  • โ€”Fix: recall over (row, column) pairs; โˆ’0.05 per spurious fix (max โˆ’0.30)
  • โ€”Validate: rubric scoring (report length, keyword presence, consistency)
  • โ€”Episode score: weighted average + efficiency bonus

Pre-submission Validation

Run before deploying to confirm all checks pass:

bash
# Static checks only (no server needed)
python validate.py

# Full check including live endpoint tests (server must be running)
OPENENV_BASE_URL=http://localhost:7860 python validate.py --live

Checks performed:

  • โ€”All required files are present
  • โ€”openenv.yaml has required fields and 3+ tasks
  • โ€”Pydantic models are valid
  • โ€”DataCleaningEnv is importable and all 3 tasks work
  • โ€”reset() / step() / state() API functions correctly
  • โ€”inference.py emits [START] / [STEP] / [END] logs and references all required env vars
  • โ€”Dockerfile is valid
  • โ€”All task rewards are in [0.0, 1.0]

Reward Signal Design

The environment is designed to give the agent partial credit at every step, not just binary win/lose:

  • โ€”Schema Validation: F1 over (row, column, issue_type) tuples + 0.3ร— partial credit for right row/column with wrong type โ†’ score varies from 0.0 to 1.0 continuously
  • โ€”Standardization: mean column accuracy โ†’ each column contributes 0.2 to the total; missing columns are penalised individually
  • โ€”Pipeline: 4 independent per-phase scores accumulated across the episode; the agent sees a reward signal after each of the 4 steps (audit โ†’ identify โ†’ fix โ†’ validate), enabling credit assignment across the trajectory

License

BSD 3-Clause โ€” see LICENSE.