An OpenEnv-compliant environment for training and evaluating AI agents that write correct, efficient SQL queries.
Agents receive a database schema, sample data, and a natural-language objective. They must produce SQL SELECT queries that satisfy the objective. Rewards are based on correctness, result structure, ordering, filter accuracy, and query efficiency.
Real-World Utility
SQL query writing and optimization is one of the most common tasks in data engineering, analytics, and backend development. Evaluating how well an agent can translate natural-language requirements into correct, efficient SQL — across a range of complexity — is directly useful for:
Write an aggregate query over an employees table. Filter for active employees (is_active = 1), group by department, compute average salary and headcount, order descending by salary.
Three-table CTE query across users, event_logs, and sessions. Find users with ≥5 events, ≥1 purchase event, and average session duration >300 seconds. Requires multi-CTE or subquery structure.
1{2"sql":"SELECT ...",3"explanation":"(optional) Why this approach was chosen"4}
Only SELECT and WITH (CTE) queries are accepted. DML is blocked.
Observation Space
json
1{2"task_id":"task_salary_agg",3"task_name":"Department Salary Aggregation",4"difficulty":"easy",5"description":"...",6"schema":[{"name":"employees","columns":[...],"row_count":500}],7"sample_data":{"employees":[{"id":1,"name":"...", ...}]},8"objective":"Write a SQL query that returns ...",9"constraints":["Only active employees (is_active = 1) ..."],10"hints":["Use GROUP BY department with WHERE is_active = 1."],11"step_count":1,12"max_steps":10,13"last_sql":"SELECT ...",14"last_result":{"columns":[...],"rows":[...],"row_count":6},15"last_plan":{"estimated_cost":0.5,"seq_scans":0,"index_scans":1, ... },16"last_reward":0.75,17"done":false18}
Reward Function
Rewards are continuous in [0.0, 1.0] with partial credit across multiple dimensions:
Component
Weight
Description
Column presence
25–30%
Are all required columns present and correctly named?
Result correctness
25–40%
Row count, data types, positive values, filter correctness
Ordering
10–15%
Is the result ordered correctly (e.g. DESC by revenue)?
Efficiency bonus
up to 25%
Does the query use indexes (from SQLite EXPLAIN QUERY PLAN)?
Graders are deterministic: same SQL + same seed → same score, always.
Setup
Local
bash
1git clone <repo>2cd sql-query-env
3pip install -r requirements.txt
45# Run the API server6uvicorn app:app --host 0.0.0.0 --port 786078# Run tests9python tests/test_env.py
1011# Run baseline inference (requires API credentials)12exportAPI_BASE_URL="https://router.huggingface.co/v1"13exportMODEL_NAME="meta-llama/Llama-3.3-70B-Instruct"14exportHF_TOKEN="hf_..."15python inference.py
1# Start episode2curl -X POST http://localhost:7860/reset \3 -H "Content-Type: application/json"\4 -d '{"task_id": "task_salary_agg"}'56# Submit query (use session_id from reset response)7curl -X POST http://localhost:7860/step \8 -H "Content-Type: application/json"\9 -d '{
10 "session_id": "<from reset>",
11 "sql": "SELECT department, ROUND(AVG(salary), 2) as avg_salary, COUNT(*) as headcount FROM employees WHERE is_active = 1 GROUP BY department ORDER BY avg_salary DESC"
12 }'