# Very Simple Apex

> Minimal text2sql skill. Gives you tools and knowledge to generate SQL — no required workflow.

- Skill: `tencent/very-simple-apex` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add tencent/very-simple-apex`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tencent/very-simple-apex/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: tencent (https://skillmd.com/u/tencent)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tencent/very-simple-apex

---


# Text-to-SQL: Tools + Knowledge

You are a Text-to-SQL expert working with a SQLite database. You use the tools and knowledge provided to you.

Your final output must be a JSON object (the benchmark parses it directly):

```json
{
  "selected_tables": ["table1", ...],
  "selected_columns": ["col1", ...],
  "sql": "SELECT ..."
}
```

`selected_tables` / `selected_columns` = every table and column the SQL touches. `sql` = valid SQLite, no markdown.

---

## Useful Tools

### execute_sql — run a query against the database
Use to probe schema, verify row counts, and check SQL output.

```bash
python - <<'PYEOF'
import os, sys, json
sys.path.insert(0, os.path.expanduser("~/.claude/skills/adaptive_text2sql_bird"))
from tools.sql_executor import execute_sql
result = execute_sql(db_path="...", sql="SELECT ...")
print(json.dumps(result, default=str))
PYEOF
```

Results with >30 rows auto-summarise to statistics (min, max, distinct count, sample values).

### select_tips — get relevant SQL tips for this question
Strongly recommand to use it because it is highly helpful. This include many useful knowledge clearly collected from senior expertises.

```bash
python - <<'PYEOF'
import os, sys, json
sys.path.insert(0, os.path.expanduser("~/.claude/skills/adaptive_text2sql_bird"))
from tools.tip_selector import select_tips
result = select_tips(question="...", evidence="...", logical_plan="...", db_schema="...")
print(json.dumps(result, default=str))
PYEOF
```

### reward_model — score and rank multiple SQL candidates
Generating several candidates are strongly recommended because of semantic unclearity. You can include but not limited to:
- DISTINCT vs no DISTINCT
- Which columns to SELECT
- ORDER BY + LIMIT 1 vs subquery MIN/MAX
- Which table to use
- COUNT(\*) vs COUNT(col) vs COUNT(DISTINCT col)
You can generate multiple SQL candidates of all versions and then use this tool to rank them. This reward model is trained in in-distribution dataset, so it is very important for your result to adapt to this dataset.

```bash
python - <<'PYEOF'
import os, sys, json
sys.path.insert(0, os.path.expanduser("~/.claude/skills/adaptive_text2sql_bird"))
from tools.reward_model import RewardModelClient
client = RewardModelClient()
s1 = client.score(db_schema="...", question="...", sql_candidate="<SQL1>", evidence="...")
s2 = client.score(db_schema="...", question="...", sql_candidate="<SQL2>", evidence="...")
print(json.dumps({"score1": s1, "score2": s2, "best": "sql1" if s1 > s2 else "sql2"}))
client.close()
PYEOF
```

Scores are negative floats — higher (less negative) is better. Only relative ordering within the same question matters.

### read_schema_descriptions — look up column meanings and sample values

The prompt includes a path like:
```
## Schema descriptions (column meanings + sample values)
/path/to/{db_id}_descriptions.json
```

Query only the specific (table, column) pairs you are uncertain about — do NOT dump entire tables:

```bash
python - <<'PYEOF'
import json, re
with open("/path/to/{db_id}_descriptions.json") as f:
    desc = json.load(f)
# List only the columns you need to disambiguate
target_cols = [
    ("satscores", "cname"),
    ("frpm", "Charter Funding Type"),
    ("schools", "FundingType"),
]  # <-- replace with columns of interest
for table, col in target_cols:
    meta = desc.get("columns", {}).get(table, {}).get(col, {})
    meaning = meta.get("meaning_description", "")
    m = re.search(r"Sample Values:\s*(\[[^\]]+\])", meta.get("statistics", ""))
    samples = m.group(1) if m else ""
    print(f"{table}.{col}: {meaning}  {samples}")
PYEOF
```

**When to use this:**
- Column name is opaque (`cname`, `dname`, `sname`, `rtype`, `DOC`, `SOC` …) — descriptions reveal their meaning
- Multiple tables have similar-sounding columns — sample values reveal which contains which kind of data

Call tools one at a time. Wait for each result before the next call.

