liovina commited on
Commit
06ed757
Β·
verified Β·
1 Parent(s): 110b21b

Deploy NL_SQL HEAD to HF Space

Browse files
app/streamlit_app.py CHANGED
@@ -61,8 +61,8 @@ I18N: dict[str, dict[str, str]] = {
61
  "metric_percent": "100%",
62
  "metric_caption": "30 dev + 30 held-out, balanced split, all ten query categories at 100% on the free-tier codestral pipeline.",
63
  "research_kicker": "BIRD Mini-Dev research benchmark",
64
- "research_value": "80.0% / 200",
65
- "research_caption": "Hybrid pipeline: codestral + Sonnet on challenging tier + cross-provider voting + grounded-critique directed retry + Sonnet 4.6 bridge on the remaining fails. +32.2pp over the GPT-4 zero-shot reference (47.8%), $0 external cost.",
66
  "settings_header": "Settings",
67
  "db_label": "Database",
68
  "db_dialect": "Dialect",
@@ -131,8 +131,8 @@ I18N: dict[str, dict[str, str]] = {
131
  "metric_percent": "100%",
132
  "metric_caption": "30 dev + 30 held-out, сбалансированный сплит, всС Π΄Π΅ΡΡΡ‚ΡŒ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ запросов Π½Π° 100% Ρ‡Π΅Ρ€Π΅Π· бСсплатный codestral.",
133
  "research_kicker": "Π˜ΡΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Π±Π΅Π½Ρ‡ΠΌΠ°Ρ€ΠΊ BIRD Mini-Dev",
134
- "research_value": "80.0% / 200",
135
- "research_caption": "Π“ΠΈΠ±Ρ€ΠΈΠ΄: codestral + Sonnet Π½Π° challenging-Ρ‚ΠΈΡ€Π΅ + кросс-ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€ voting + grounded-critique directed retry + Sonnet 4.6 bridge Π½Π° ΠΎΡΡ‚Π°Π²ΡˆΠΈΡ…ΡΡ Ρ„Π΅ΠΉΠ»Π°Ρ…. +32.2 ΠΏ.ΠΏ. Π½Π°Π΄ zero-shot GPT-4 (47.8%), внСшниС расходы β€” ноль.",
136
  "settings_header": "Настройки",
137
  "db_label": "Π‘Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ…",
138
  "db_dialect": "Π”ΠΈΠ°Π»Π΅ΠΊΡ‚",
 
61
  "metric_percent": "100%",
62
  "metric_caption": "30 dev + 30 held-out, balanced split, all ten query categories at 100% on the free-tier codestral pipeline.",
63
  "research_kicker": "BIRD Mini-Dev research benchmark",
64
+ "research_value": "80.5% / 200",
65
+ "research_caption": "Hybrid pipeline: codestral + Sonnet on challenging tier + cross-provider voting + grounded-critique directed retry + Sonnet 4.6 bridge + M-Schema compact serialization on residue. +32.7pp over the GPT-4 zero-shot reference (47.8%), $0 external cost.",
66
  "settings_header": "Settings",
67
  "db_label": "Database",
68
  "db_dialect": "Dialect",
 
131
  "metric_percent": "100%",
132
  "metric_caption": "30 dev + 30 held-out, сбалансированный сплит, всС Π΄Π΅ΡΡΡ‚ΡŒ ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ запросов Π½Π° 100% Ρ‡Π΅Ρ€Π΅Π· бСсплатный codestral.",
133
  "research_kicker": "Π˜ΡΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Π±Π΅Π½Ρ‡ΠΌΠ°Ρ€ΠΊ BIRD Mini-Dev",
134
+ "research_value": "80.5% / 200",
135
+ "research_caption": "Π“ΠΈΠ±Ρ€ΠΈΠ΄: codestral + Sonnet Π½Π° challenging-Ρ‚ΠΈΡ€Π΅ + кросс-ΠΏΡ€ΠΎΠ²Π°ΠΉΠ΄Π΅Ρ€ voting + grounded-critique directed retry + Sonnet 4.6 bridge + компактная M-Schema Π½Π° residue. +32.7 ΠΏ.ΠΏ. Π½Π°Π΄ zero-shot GPT-4 (47.8%), внСшниС расходы β€” ноль.",
136
  "settings_header": "Настройки",
137
  "db_label": "Π‘Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ…",
138
  "db_dialect": "Π”ΠΈΠ°Π»Π΅ΠΊΡ‚",
chroma_data/chroma.sqlite3 CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:71e30053ed54f40c313c34a77517af48ab8ad100a4a334b8dbd9e9daeafd67c0
3
  size 18161664
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c491d528453ed7ac5a3c1307de64b6d6dce423e776519786ebd2b53f400bdd9b
3
  size 18161664
chroma_data/fc9668d3-4384-40d9-aa8d-0010807a5a68/data_level0.bin CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:1ed4ebbcc08c0f8d3d33a18e6a88135ffb08bc518c6adfe04f4aee39f3e44ad8
3
  size 423600
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:99c95e2fdcfc2f54fc5ffe547684ff7302ec22a3e2bee0cfb4e4115ba3778040
3
  size 423600
chroma_data/fc9668d3-4384-40d9-aa8d-0010807a5a68/length.bin CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d9142387334b53a34226a53a60878980670c9a2a28a56cd9f8ddf2e7d44f3975
3
  size 400
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5fa109cdb928cb5bceb339bcd2a2b3515e0f37e508fd51e5b3319219d5effe5f
3
  size 400
docs/SESSION_HANDOFF.md CHANGED
@@ -1,12 +1,26 @@
1
- # NL_SQL β€” Session Handoff (2026-05-17 late-night: 80.0% BIRD + gpt-oss-20b v8 rescue + live HF Space)
2
 
3
  > **Tl;dr 2026-05-17 late-night:** P0 closed (live demo on HF Spaces),
4
  > P2.B closed (+1 selective fewshot rescue β†’ 77.5%), P3 cross-Groq closed
5
- > (+3 rescues β†’ 79.0%), **gpt-oss-20b voting on v8 residue closed
6
  > (+2 rescues qids 571 moderate / 1232 challenging β†’ 80.0% n=200, 160/200,
7
- > simple 91.0 / moderate 76.8 / challenging 67.6)**. Live:
8
  > <https://liovina-nl-sql.hf.space>, headline 80.0%.
9
  >
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  > **Sprint 2026-05-17 late-night results** (HEAD `fcd7ec3` β†’ v9):
11
  > - openai/gpt-oss-20b: +2 rescues (qids 571 ratio aggregation, 1232 date-arith) β€” lightweight model Π΄ΠΎΠ±ΠΈΠ²Π°Π΅Ρ‚ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Mistral family unanimous ΠΏΡ€ΠΎΠ²Π°Π»ΠΈΠ»
12
  > - llama-3.3-70b-versatile retry: TPD Π΅Ρ‰Ρ‘ Π½Π΅ ΡΠ±Ρ€ΠΎΡˆΠ΅Π½ (96.5K/100K, reset 20-108 ΠΌΠΈΠ½ Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ)
 
1
+ # NL_SQL β€” Session Handoff (2026-05-17 late-night: 80.0% BIRD + triangulated residue analysis = $0 peak)
2
 
3
  > **Tl;dr 2026-05-17 late-night:** P0 closed (live demo on HF Spaces),
4
  > P2.B closed (+1 selective fewshot rescue β†’ 77.5%), P3 cross-Groq closed
5
+ > (+3 rescues β†’ 79.0%), gpt-oss-20b voting on v8 residue closed
6
  > (+2 rescues qids 571 moderate / 1232 challenging β†’ 80.0% n=200, 160/200,
7
+ > simple 91.0 / moderate 76.8 / challenging 67.6). Live:
8
  > <https://liovina-nl-sql.hf.space>, headline 80.0%.
9
  >
10
+ > **Sprint post-80% (HEAD `c16e773`):** triangulated v9-residue Π°Π½Π°Π»ΠΈΠ·
11
+ > Ρ‡Π΅Ρ€Π΅Π· CC + Codex gpt-5.5 xhigh + Kimi β€” Ρ‚Ρ€ΠΈ нСзависимых ΠΎΡ‚Ρ‡Ρ‘Ρ‚Π° Π²
12
+ > `docs/{v9_residue_analysis_quick,codex_v9_residue_analysis,kimi_v9_residue_analysis}.md`.
13
+ > Consensus: **80.0% β€” Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ $0 peak**; 82% upper edge с luck, 83%+
14
+ > Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ P3.F custom schema-linker ΠΈΠ»ΠΈ paid frontier.
15
+ >
16
+ > Tried in this sprint (all attempts Π½Π° 40 v9-residue):
17
+ > - Audit rules (LIMIT discipline + aggregation formula) Π² generate_sql.txt β†’ **0 rescues / 0 regressions** (codestral слСдуСт rules мягко, grounded_critique reroutes Π² свои fixes)
18
+ > - Evidence-hoist (split `Hint:` ΠΈΠ· question Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ prompt block Π²Ρ‹ΡˆΠ΅ schema) β†’ **0 rescues / 0 regressions** (Ρ‚ΠΎΡ‚ ΠΆΠ΅ loop dominance)
19
+ > - llama-3.3-70b TPD retry β†’ 95.3K/100K, 1 case processed (SAME), reset Π΅Ρ‰Ρ‘ ~hr
20
+ > - qid 990 sanity check (Codex insight) β†’ confirmed SQLAlchemy `text()` bind-param bug Π½Π° `LIKE '_:%:__.___'`, Π½ΠΎ naive fix = net -1pp (qids 959, 989 regress; qid 990 rescue). Deferred until buffer.
21
+ >
22
+ > Conclusion: critique-retry loop ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ фиксит Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ fixable additive prompt-changes, дальнСйший lift Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π΅Ρ€Π΅Π· full n=200 rerun с invasive structural changes β€” risk regression Π½Π° 160 matches > expected +1-2pp Π±Π΅Π· verification budget.
23
+ >
24
  > **Sprint 2026-05-17 late-night results** (HEAD `fcd7ec3` β†’ v9):
25
  > - openai/gpt-oss-20b: +2 rescues (qids 571 ratio aggregation, 1232 date-arith) β€” lightweight model Π΄ΠΎΠ±ΠΈΠ²Π°Π΅Ρ‚ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Mistral family unanimous ΠΏΡ€ΠΎΠ²Π°Π»ΠΈΠ»
26
  > - llama-3.3-70b-versatile retry: TPD Π΅Ρ‰Ρ‘ Π½Π΅ ΡΠ±Ρ€ΠΎΡˆΠ΅Π½ (96.5K/100K, reset 20-108 ΠΌΠΈΠ½ Π½Π° ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ)
docs/bird_sota_research.md ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # BIRD Text-to-SQL SOTA Research β€” How Systems Get Past 80% EA
2
+
3
+ **Date:** 2026-05-17
4
+ **Goal:** Understand who crosses 80% Execution Accuracy on BIRD, what they do, and whether 80% β†’ 85% β†’ 88% is realistic for our $0-budget Mini-Dev setup at 80.0%.
5
+ **Our context:** BIRD Mini-Dev (SQLite, dev_split, n=200, seed=0), 80.0% EA, free-tier stack (Codestral + Groq + Sonnet 4.6 via Perplexity bridge).
6
+
7
+ ---
8
+
9
+ ## 1. Current SOTA on BIRD (full dev/test, May 2026)
10
+
11
+ Pulled from the official leaderboard at <https://bird-bench.github.io/>. **The leaderboard publishes full-test EA, not Mini-Dev n=200**, so all numbers below are full BIRD test (1789 examples) unless noted.
12
+
13
+ | Rank | System | Dev EA% | Test EA% | Key leverage | Paid / Free | Date |
14
+ |------|--------|---------|----------|--------------|-------------|------|
15
+ | Human baseline | DB students + DE | β€” | **92.96** | Human experts | β€” | reference |
16
+ | 1 | **AskData + GPT-4o** (AT&T DSAIR) | 77.64 | **81.95** | Oracle-knowledge prompting + GPT-4o ensemble | **Paid (GPT-4o)** | 2025-09-25 |
17
+ | 2 | **Agentar-Scale-SQL** (Ant Group) | 74.90 | **81.67** | RL-fine-tuned 32B + parallel synthesis + tournament selection | **FT + heavy compute** | 2025-07-14 |
18
+ | 3 | LongData-SQL (LongShine) | 74.32 | 77.53 | Long-context schema grounding | Proprietary | 2026-04-28 |
19
+ | 4 | SiriusAI-Text2SQL (Tencent) | 75.35 | 77.03 | Agent system | Proprietary | 2026-01-02 |
20
+ | 5 | Zhiwen-Lingsi (China Telecom) | 73.53 | 76.63 | Multi-component | Proprietary | 2026-01-26 |
21
+ | 6 | DeepEye-SQL (HKUST-GZ) | 73.53 | 76.58 | Open-source code | Mixed | 2026-04-25 |
22
+ | 7 | GT-ChatBI-SQL (MR Tech) | 74.70 | 76.47 | Conversational | Proprietary | 2025-12-04 |
23
+ | 8 | Q-SQL (AWS) | 72.99 | 76.47 | 30B-3B MoE | Mostly free models | 2026-02-06 |
24
+ | 9 | MIC2-SQL | 74.45 | 76.41 | Anonymous | Proprietary | 2025-04-16 |
25
+ | 10 | CHASE-SQL + Gemini (Google) | 74.90 | 76.02 | Multi-path reasoning + pairwise selector + Gemini-1.5-Pro | **Paid (Gemini)** | 2026-04-03 |
26
+ | 11 | xiaoyi-text-to-sql | 72.75 | 75.96 | Custom | Proprietary | 2026-02-21 |
27
+ | 12 | RED-SQL (SCNU) | 74.19 | 75.91 | 30B open-source | Free model + FT | 2025-09-22 |
28
+ | 13 | JoyDataAgent (JD) | 74.25 | 75.85 | Open-source | Mixed | 2025-10-23 |
29
+ | 14 | Sinovatio-SQL | 73.72 | 75.80 | Proprietary | Proprietary | 2025-05-30 |
30
+ | β€” | **CSC-SQL 32B** (paper, not on board) | β€” | **73.67** | Self-consistency + correction RL on Qwen2.5-32B | Open FT | 2025-05 |
31
+ | β€” | **Arctic-Text2SQL-R1 32B** (Snowflake) | β€” | **71.83** | GRPO-RL fine-tuned 32B | Open weights, requires FT | 2025-05 |
32
+ | β€” | XiYan-SQL (Alibaba) | β€” | **75.63** | Multi-generator ensemble, only 5 candidates, fine-tuned + ICL | Mixed | 2024 preview |
33
+ | β€” | CHESS (Stanford) | 65.00 | **66.69** (71.10 hi-budget) | 4-agent retrieve/select/generate/unit-test | Open code, GPT-4 calls | 2024 |
34
+
35
+ ### Key observations
36
+
37
+ - **Only 2 systems on the public leaderboard cross 80%**: AskData (81.95%) and Agentar-Scale-SQL (81.67%). Both use heavy compute and at least one paid or fine-tuned component.
38
+ - **The 73–77% band is crowded** β€” that's where every serious agent system lives.
39
+ - **No published $0-budget system** crosses 80% on the full BIRD test set with public scores. Free-tier open-source ceilings published openly: Arctic-32B 71.83%, CSC-SQL 32B 73.67%, XiYan 75.63% (latter uses fine-tuning).
40
+ - **Critical caveat**: Jin et al. (CIDR/VLDB 2026, [arXiv:2601.08778](https://arxiv.org/abs/2601.08778)) audited BIRD and found **52.8% of BIRD Mini-Dev questions have annotation errors**. Re-evaluation on corrected data shifts top-system EA by **βˆ’3% to +31%**. CHESS jumped from 62% β†’ 81% just from corrected gold. The community consensus emerging: **scores in the 75–85% band are partly noise**, and chasing them risks overfitting to wrong-gold artifacts.
41
+
42
+ ---
43
+
44
+ ## 2. What drives the lift past 75% β†’ 80%+
45
+
46
+ Synthesized across CHESS, CHASE-SQL, XiYan-SQL, Agentar-Scale-SQL, CSC-SQL, Arctic-R1, Contextual-SQL.
47
+
48
+ ### A. Test-time scaling β€” biggest single lift (~+3 to +7 pp)
49
+ - **Parallel sampling**: 5–32 candidate SQLs from one or more generators with high temperature.
50
+ - **Tournament / pairwise selector** (CHASE-SQL): trained binary judge picks best of 2, run as bracket. CHASE got ~+5 pp over self-consistency.
51
+ - **Self-consistency on execution result**: cluster by result-set hash, pick majority. Baseline ~+2-3 pp.
52
+ - **Corrective self-consistency** (CSC-SQL, [arXiv:2505.13271](https://arxiv.org/abs/2505.13271)): pick top-2 most frequent results, feed both to a *merge-revision* model. +0.72 to +5.54 pp over plain SC.
53
+
54
+ ### B. Schema linking (~+2 to +5 pp)
55
+ - **M-Schema / semi-structured schema** (XiYan): include column type, sample values, FK as compact serialization. Replaces flat CREATE TABLE dumps.
56
+ - **Bidirectional retrieval** ([arXiv:2510.14296](https://arxiv.org/html/2510.14296v1)): question→schema AND schema→question to recover dropped columns. Recall-first.
57
+ - **Value retrieval**: index DB cell values, retrieve top-k for question entities (CHESS Information Retriever).
58
+
59
+ ### C. Reasoning style (~+2 to +4 pp)
60
+ - **Divide-and-conquer** (CHASE-SQL): decompose into sub-queries in one LLM call.
61
+ - **Execution-plan CoT**: prompt model to reason as a query optimizer (joins β†’ filters β†’ projections).
62
+ - **Instance-aware synthetic few-shot**: generate fewshots tailored to the test question shape, not static top-k retrieval.
63
+
64
+ ### D. Fine-tuning (~+5 to +10 pp β€” but blocks $0)
65
+ - **Arctic-R1 GRPO** with simple execution-correctness reward, on Qwen2.5-7B/32B. Beats GPT-4o.
66
+ - **Agentar generation model** is Omni-SQL-32B + GRPO further-trained on execution.
67
+ - **CSC-SQL** trains both generator and revisor via GRPO.
68
+ - Without FT, the same architectures lose ~5–8 pp.
69
+
70
+ ### E. Domain knowledge / evidence (~+2 to +3 pp)
71
+ - **Evidence injection from BIRD's `external_knowledge` field**: already standard; just including it is +3–5 pp.
72
+ - **Auto-generated evidence** (SEED, [arXiv:2506.07423](https://arxiv.org/html/2506.07423v1)): when human-written evidence isn't available.
73
+
74
+ ### F. Unit testing / execution self-debug (~+1 to +3 pp)
75
+ - CHESS Unit-Tester: LLM-written natural-language assertions checked against result.
76
+ - **RetrySQL** ([arXiv:2507.02529](https://arxiv.org/html/2507.02529v1)): explicit `[BACK]` retry tokens during training. +4 pp.
77
+ - Execution-feedback retry loop: just running and feeding the error back is +1–2 pp.
78
+
79
+ ---
80
+
81
+ ## 3. $0-budget reachable techniques (realistic for our setup)
82
+
83
+ We already have: codestral gen, fewshot top-3/5, Sonnet voting, Groq voting, grounded-critique, evidence injection, sort_default. Map of unused leverage:
84
+
85
+ ### High-EV (1–4 hour cost, plausible +1 to +3 pp each, additive ≀2 pp)
86
+
87
+ 1. **M-Schema serialization** (XiYan-SQL). Replace current schema dump with `table.column (type) [sample1, sample2] FKβ†’other.col` per line. **GitHub**: <https://github.com/XGenerationLab/XiYan-SQL> (M-Schema implementation in repo). Free, prompt-only change. Expected +1–2 pp if our schema rendering is currently flat.
88
+
89
+ 2. **Pairwise tournament selector with Sonnet** instead of plurality voting on residue. Currently we do majority-vote on Groq + Sonnet. CHASE-SQL ([arXiv:2410.01943](https://arxiv.org/abs/2410.01943)) shows pairwise > plurality by ~2 pp because plurality loses when 4 wrong candidates outnumber 1 right one. Sonnet 4.6 is strong enough to act as judge. Implement: pick top-k by Groq, run bracket with Sonnet as comparator. Free if we stay within Sonnet quota.
90
+
91
+ 3. **Divide-and-conquer prompting** (CHASE-SQL technique #1) on `challenging` tier only (67.6% β†’ potentially 72%). Single-call decomposition prompt, no additional API spend. Expected +0.5 to +1.5 pp overall.
92
+
93
+ 4. **Value-retrieval grounding**. For each question, BM25 / substring-search over DB cell values (sampled), inject matches as `evidence: question token "X" appears in column Y`. Free, local. CHESS shows ~+2 pp from this alone.
94
+
95
+ ### Medium-EV (3–8 hours, uncertain payoff)
96
+
97
+ 5. **Corrective self-consistency** (CSC-SQL approach without RL): take top-2 result clusters, feed both SQLs + their results to Sonnet, ask which is correct or to merge. Paper shows +0.7 to +5.5 pp over plain SC. Free.
98
+
99
+ 6. **Instance-aware few-shot** (CHASE): instead of static top-k retrieval, use LLM to *generate* synthetic Q→SQL examples that mimic the structural shape of the test query. One extra Groq call per question. Caveat: when we tried fewshot=5 vs 3 it was a wash, suggesting our retrieval is the bottleneck, not k. This could fix that.
100
+
101
+ ### Low-EV (do not attempt)
102
+
103
+ - **Fine-tuning** β€” out of budget and skill envelope for the deadline.
104
+ - **Adding more voter models** β€” saturated (we already showed gpt-oss-120b, mistral-large, codestral-fewshot7 zero rescues).
105
+ - **Wider schema retry** β€” already saturated per residue analysis.
106
+
107
+ ---
108
+
109
+ ## 4. Realistic verdict for $0 Mini-Dev n=200
110
+
111
+ ### Ceiling math
112
+
113
+ | Target | Realistic? | Why |
114
+ |--------|-----------|-----|
115
+ | **82%** (164/200) | **Yes, plausible** β€” +4 hits needed. M-Schema + value-retrieval + D&C on challenging tier could plausibly each rescue 1–2 questions. |
116
+ | **85%** (170/200) | **Hard but not impossible** β€” +10 hits. Requires combining 3+ of the techniques above AND not regressing easy/moderate. Pairwise tournament + corrective SC + M-Schema is the strongest stack. |
117
+ | **88%** (176/200) | **Highly unlikely at $0** β€” would put us above the #1 paid leaderboard system. The only published systems above 81% on full test use either GPT-4o oracle prompting or 32B + RL fine-tuning. |
118
+ | **90%+** | **Effectively impossible** β€” even human experts only hit 92.96%. Annotation errors in BIRD Mini-Dev (52.8% per Jin et al.) mean the *real* ceiling is far lower than 92.96% on uncorrected gold; pushing past ~85% means memorizing benchmark mistakes. |
119
+
120
+ ### Key takeaway from the broken-benchmarks paper
121
+
122
+ Jin et al. ([arXiv:2601.08778](https://arxiv.org/abs/2601.08778), CIDR/VLDB 2026) found **BIRD Mini-Dev has 52.8% questions with annotation issues**. They re-evaluated 5 top open systems on corrected data β€” rank shifts of up to 3 positions, EA changes from βˆ’3% to +31%. CHESS jumped from 62% β†’ 81% on the corrected set. **Implication**: our 80.0% on the uncorrected n=200 may already be near the achievable ceiling for our slice. Further gains may require fitting to specific wrong-gold cases (anti-pattern).
123
+
124
+ ### Recommendation: stop at 80.0% as headline, redirect the next 2-8 hours to
125
+
126
+ 1. **Stress-test the 80% number on Jin et al.'s corrected gold subset** if available in their GitHub <https://github.com/uiuc-kang-lab/text_to_sql_benchmarks>. If our EA-on-corrected is β‰₯80%, our number is *more* trustworthy than the leaderboard's 73–77% band.
127
+ 2. If chasing one more bump: **M-Schema + pairwise Sonnet tournament on residue** (highest-EV combo, ~3 hours, plausible 82%).
128
+ 3. **Package the result around methodology, not the raw number**: we beat free-tier published ceilings (Arctic 71.83%, CSC 73.67%, XiYan 75.63%) and approach paid SOTA (81.95%) without fine-tuning or paid APIs. That's the headline. Pushing 80% β†’ 82% is marginal; pushing the *story* is high-EV.
129
+
130
+ ---
131
+
132
+ ## Sources
133
+
134
+ - BIRD leaderboard: <https://bird-bench.github.io/>
135
+ - BIRD Mini-Dev repo: <https://github.com/bird-bench/mini_dev>
136
+ - Agentar-Scale-SQL: <https://arxiv.org/abs/2509.24403>, <https://github.com/antgroup/Agentar-Scale-SQL>
137
+ - CHESS: <https://arxiv.org/abs/2405.16755>, <https://github.com/ShayanTalaei/CHESS>
138
+ - CHASE-SQL: <https://arxiv.org/abs/2410.01943>
139
+ - XiYan-SQL: <https://arxiv.org/abs/2411.08599>, <https://github.com/XGenerationLab/XiYan-SQL>
140
+ - CSC-SQL: <https://arxiv.org/abs/2505.13271>, <https://github.com/CycloneBoy/csc_sql>
141
+ - Arctic-Text2SQL-R1: <https://arxiv.org/abs/2505.20315>, <https://huggingface.co/Snowflake/Arctic-Text2SQL-R1-7B>
142
+ - Contextual-SQL: <https://contextual.ai/blog/open-sourcing-the-best-local-text-to-sql-system>
143
+ - Adnan Masood analysis: <https://medium.com/@adnanmasood/pushing-towards-human-level-text-to-sql-an-analysis-of-top-systems-on-bird-benchmark-666efd211a2d>
144
+ - Benchmarks-are-broken (Jin et al.): <https://arxiv.org/abs/2601.08778>, <https://github.com/uiuc-kang-lab/text_to_sql_benchmarks>
145
+ - RetrySQL: <https://arxiv.org/abs/2507.02529>
146
+ - Bidirectional schema linking: <https://arxiv.org/abs/2510.14296>
147
+ - SEED auto-evidence: <https://arxiv.org/abs/2506.07423>
148
+ - Snowflake Arctic blog: <https://www.snowflake.com/en/engineering-blog/arctic-text2sql-r1-sql-generation-benchmark/>
149
+ - Distyl #1 announcement (historical, July 2024): <https://distylai.substack.com/p/distyl-takes-1-spot-on-bird-benchmark>
docs/codex_v9_residue_analysis.md ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # v9 residue root-cause analysis
2
+
3
+ Primary category is assigned once per failed qid, so counts sum to 40. Many cases have secondary projection or duplicate-grain symptoms; the category below is the SQL decision that most likely caused the mismatch.
4
+
5
+ ## Categories table
6
+
7
+ | category | count | sample qids (3) | typical fix |
8
+ |---|---:|---|---|
9
+ | wrong_aggregation | 11 | 25, 1094, 1531 | Add an evidence/formula checklist before SQL finalization: denominator scope, `SUM/COUNT` vs `AVG`, row grain, `DISTINCT` vs duplicate-preserving output, and metric column choice. |
10
+ | ambiguous_gold | 11 | 349, 1029, 1399 | Do not spend broad engineering effort. These are mostly BIRD annotation/evidence quirks where the gold contradicts the question or a more natural SQL: e.g. 1029 says highest but gold sorts ascending; 1399 asks yes/no but gold emits 14 event rows. |
11
+ | wrong_table | 6 | 173, 408, 584 | Table/column validation stage before generation: force the model to name the source table for each requested concept, especially `rulings.text` vs `cards.text`, `postHistory.Comment` vs `comments.Text`, `driverStandings.position` vs `results.position`. |
12
+ | wrong_sort_or_tiebreak | 4 | 518, 930, 1144 | Separate sort/limit critic: reject unsupported `LIMIT 1`, check whether the gold-style task wants all rows after ordering, all rank-1 rows, or a deterministic tie pick. |
13
+ | wrong_join_path | 3 | 125, 207, 1251 | Inject explicit FK/bridge paths for the selected tables only. Most failures are not recall misses; they are wrong fanout or missing bridge constraints. |
14
+ | missing_group_by | 2 | 595, 1404 | Grain critic: decide whether the grouping entity is user, post, event, expense type, etc. before writing the SELECT. |
15
+ | evidence_ignored | 2 | 866, 894 | Promote BIRD evidence from a passive hint to a mandatory checklist; these failed while the evidence explicitly named the required output columns. |
16
+ | wrong_filter_literal | 1 | 77 | Sample/check column values for literals such as grade span (`GSserved = 'K-9'`) instead of decomposing into nearby columns. |
17
+
18
+ Date arithmetic is not a primary remaining bucket after v9. qid 1168 computes the date and age correctly; the mismatch is the gold's extra `Birthday` projection, so it is counted as ambiguous_gold rather than date_arith.
19
+
20
+ Notable sanity finding: qid 990 locally executes to the same first row for gold and pred on the checked SQLite DB, despite the report saying `gold_rows=0, pred_rows=1`. Treat it as an eval/report artifact candidate before spending tokens on it.
21
+
22
+ ## Strategies
23
+
24
+ ### 1. Evidence-as-constraints retry
25
+
26
+ Convert `evidence` into a short mandatory checklist placed above the question, then run a narrow retry only on residue. The critic should answer yes/no for each atom: required column, formula, row grain, date/literal, final projection. This is different from the saturated column-count critique: it validates semantic atoms, not result width.
27
+
28
+ Expected lift: +1.0 to +2.0pp (2-4 qids).
29
+
30
+ Cost: 2-3 hours.
31
+
32
+ Likely qids: 25, 866, 894, 988, 1036, 1251, 1275, 1529, 1531.
33
+
34
+ Risk: low if merged rescue-only; medium if enabled globally because some BIRD evidence is itself noisy (1275, 1029).
35
+
36
+ ### 2. Two-stage table/JOIN validator with FK JSON
37
+
38
+ For the top retrieved tables, inject `PRAGMA foreign_key_list` plus primary-key-like columns as compact JSON. Stage 1 asks only: selected tables, selected columns, join path, expected fanout. Stage 2 writes SQL only after Stage 1 is stable. This is not a custom schema-linker rewrite; it is a prompt-time guard around the existing retrieval.
39
+
40
+ Expected lift: +1.0 to +1.5pp (2-3 qids).
41
+
42
+ Cost: 3-4 hours.
43
+
44
+ Likely qids: 125, 173, 207, 408, 584, 896, 902, 1251, 1275.
45
+
46
+ Risk: medium. FK metadata may be sparse or absent in some SQLite DBs, and over-trusting it can miss implicit joins. Keep fallback to current schema text.
47
+
48
+ ### 3. LIMIT/DISTINCT/grain micro-critic
49
+
50
+ A tiny static pass flags high-risk SQL shapes before retry: `LIMIT 1` on questions asking "list/all/which races"; `DISTINCT` added when question asks for rows rather than unique values; missing `DISTINCT` when evidence says "don't compute repetitive ones"; `COUNT(DISTINCT ...)` vs duplicate-preserving `COUNT(...)`.
51
+
52
+ Expected lift: +0.5 to +1.5pp (1-3 qids).
53
+
54
+ Cost: 2 hours.
55
+
56
+ Likely qids: 358, 407, 518, 930, 1144, 1235, 1254.
57
+
58
+ Risk: medium-high if global, because BIRD gold is inconsistent on "all/highest". Safe as residue-only rescue with exact-match merge.
59
+
60
+ ## Top-3 quick wins
61
+
62
+ 1. Evidence-as-constraints retry. Best ROI: roughly +1-2pp for 2-3 hours, and it attacks failures where the right formula/column is already present in BIRD evidence.
63
+
64
+ 2. LIMIT/DISTINCT/grain micro-critic. Cheap, targeted, and likely to rescue at least one duplicate/limit failure. Do it residue-only to avoid regressions.
65
+
66
+ 3. FK JSON + table/JOIN validator. Slightly more work, but it is the only 4-hour option that touches the wrong_table/wrong_join_path cluster without becoming P3.F custom schema-linking.
67
+
68
+ ## Reality check
69
+
70
+ At 80.0%, the remaining residue is no longer "more retries will average out" territory. About 11/40 are ambiguous_gold or report-artifact style, and another large block needs BIRD-specific row grain rather than better retrieval. That means the residue is partly structurally incompressible on $0 unless you overfit to this eval slice.
71
+
72
+ 82.0% is reachable in 4 hours only at the upper edge: qid 990 sanity recovery plus 3-4 real rescues from evidence/FK/grain checks. 83.0% needs 6 additional rescues, and that is unlikely in one short sprint without either paid stronger reasoning or P3.F-level schema-linking. The honest target for the next 2-4 hour attack is +1.0 to +2.0pp, not a reliable +3.0pp.
docs/kimi_v9_residue_analysis.md ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # v9 Residue Root-Cause Analysis (40 fails @ 80.0% EA)
2
+
3
+ > Анализ ΠΏΡ€ΠΎΠ²Π΅Π΄Ρ‘Π½ Π½Π°Π΄ `hybrid-vote-critique-selfcon-sonnet-fewshot5-groq4-v9.json` (200 записСй, 40 mismatch).
4
+ > ΠšΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡ ΠΏΠΎ **Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ Π² SQL**, Π½Π΅ ΠΏΠΎ surface bucket (row_count_off / filter_or_value / order_by_off).
5
+
6
+ ---
7
+
8
+ ## 1. Бводная Ρ‚Π°Π±Π»ΠΈΡ†Π° ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ
9
+
10
+ | category | count | sample qids | typical fix |
11
+ |---|---|---|---|
12
+ | **wrong_aggregation** | 16 | 358, 866, 1235, 484, 518, 1531 | DISTINCT/LIMIT/subquery-scope audit rule; evidence-formula enforcement |
13
+ | **wrong_table** | 8 | 173, 408, 584, 896, 902, 1251, 1275 | Two-stage critique (table validation first); FK-hint injection |
14
+ | **ambiguous_gold** | 4 | 930, 990, 1247, 672 | НС фиксится β€” annotation issue / precedence bug Π² gold |
15
+ | **wrong_join_path** | 4 | 125, 207, 694, 743 | Explicit FK declaration for top-K tables |
16
+ | **wrong_filter_literal** | 4 | 37, 77, 1254, 1404 | Evidence re-prioritization; value sampling validation |
17
+ | **evidence_ignored** | 2 | 349, 894 | Evidence-as-rule block (ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π² Ρ‚ΠΎΠΏ ΠΏΡ€ΠΎΠΌΠΏΡ‚Π°) |
18
+ | **wrong_sort_or_tiebreak** | 2 | 1029, 1168 | Column semantic hint (ASC/DESC, NULL handling) |
19
+
20
+ **РаспрСдСлСниС ΠΏΠΎ Ρ‚ΠΈΡ€Ρƒ:** simple 6 | moderate 21 | challenging 11 (совпадаСт с surface-ΠΎΡ‚Ρ‡Ρ‘Ρ‚ΠΎΠΌ: 21 moderate / 11 challenging / 6 simple + 2 exec_error).
21
+
22
+ ---
23
+
24
+ ## 2. ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ rescue-стратСгии ($0 budget, ≀4Ρ‡ each)
25
+
26
+ ### БтратСгия A: Evidence-first prompt reordering + formula lock
27
+ **Π§Ρ‚ΠΎ:** Π’ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Π΅ evidence ΡƒΠΆΠ΅ инТСктируСтся (`_compose_question` добавляСт `\n\nHint: {evidence}`), Π½ΠΎ ΠΎΠ½ оказываСтся **послС schema block**. МодСль (codestral / oss-20b) Ρ‚ΠΎΠ½Π΅Ρ‚ Π² схСмС ΠΈ ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅Ρ‚ hint.
28
+ **ДСйствиС:** ΠŸΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ evidence Π² самый Π²Π΅Ρ€Ρ… ΠΏΡ€ΠΎΠΌΠΏΡ‚Π°, ΠΎΡ„ΠΎΡ€ΠΌΠΈΡ‚ΡŒ ΠΊΠ°ΠΊ Π±Π»ΠΎΠΊ ΠΏΡ€Π°Π²ΠΈΠ»:
29
+ ```
30
+ [EVIDENCE β€” obey strictly]
31
+ - average pitstop duration = Divide(SUM(duration), COUNT(duration))
32
+ - ...
33
+ [SCHEMA]
34
+ ...
35
+ ```
36
+ Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ prompt rule: "Если evidence содСрТит Ρ„ΠΎΡ€ΠΌΡƒΠ»Ρƒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉ Π΅Ρ‘ дословно, Π½Π΅ ΡƒΠΏΡ€ΠΎΡ‰Π°ΠΉ Ρ‡Π΅Ρ€Π΅Π· AVG/COUNT(*)."
37
+
38
+ **ОТиданиС:** +1–2pp.
39
+ **Π‘Ρ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ:** 1–1.5Ρ‡ (ΠΏΡ€Π°Π²ΠΊΠ° `context_builder` + prompt template).
40
+ **ΠŸΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅:** qids 349, 894, 988, 1029, 1254, 1404, 1531 β€” 7+ случаСв, Π³Π΄Π΅ модСль Π²ΠΈΠ΄Π΅Π»Π° evidence, Π½ΠΎ Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΎΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΠΎΠ²Π°Π»Π° Ρ„ΠΎΡ€ΠΌΡƒΠ»Ρƒ (988: AVG(milliseconds) вмСсто AVG(duration)), Π»ΠΈΠ±ΠΎ упустила Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ (349: isPromo = 1).
41
+ **Риск рСгрСссии:** Низкий. Evidence β€” ground truth ΠΎΡ‚ BIRD annotator. ЕдинствСнный риск β€” ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ Π΄Π»ΠΈΠ½Ρ‹ ΠΏΡ€ΠΎΠΌΠΏΡ‚Π°; Π½Π° Groq/ΠΌΠ°Π»Ρ‹Ρ… модСлях Π½ΡƒΠΆΠ½ΠΎ ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Π·Π° TPM.
42
+
43
+ ---
44
+
45
+ ### БтратСгия B: Two-stage critique β€” сначала Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹/JOIN, ΠΏΠΎΡ‚ΠΎΠΌ агрСгация
46
+ **Π§Ρ‚ΠΎ:** Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ grounded critique Π²Π°Π»ΠΈΠ΄ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ†Π΅Π»Ρ‹ΠΉ SQL сразу. Π’ residue 30% ошибок β€” это wrong_table / wrong_join_path. МодСль-Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΈ модСль-ΠΊΡ€ΠΈΡ‚ΠΈΠΊ (часто Ρ‚ΠΎΡ‚ ΠΆΠ΅ codestral) ΡΠΎΠ³Π»Π°ΡˆΠ°ΡŽΡ‚ΡΡ Π½Π° Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Π²Ρ‹Π±ΠΎΡ€ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΊΡ€ΠΈΡ‚ΠΈΠΊΠ° Π½Π΅ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π°.
47
+ **ДСйствиС:** На Ρ„Π΅ΠΉΠ»Π°Ρ… ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ…ΠΎΠ΄Π° Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ **Stage-1 critique**: Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° "ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹Π΅ Π»ΠΈ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΈ JOIN-условия?" с Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΎΠΌ `tables_ok: bool`. Если `false` β€” пСрСгСнСрация с explicit FK hint. **Stage-2 critique**: Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° WHERE/HAVING/ aggregation.
48
+
49
+ **ОТиданиС:** +1.5–2pp.
50
+ **Π‘Ρ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ:** 2–3Ρ‡ (Π½ΠΎΠ²Ρ‹ΠΉ prompt template + двухпроходная Π»ΠΎΠ³ΠΈΠΊΠ° Π² `run_critique_retry.py`).
51
+ **ΠŸΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅:** qids 25, 125, 173, 207, 408, 584, 694, 743, 896, 902, 1251, 1275 β€” 12 случаСв (30% residue).
52
+ **Риск рСгрСссии:** Π‘Ρ€Π΅Π΄Π½ΠΈΠΉ. Двухпроходная ΠΊΡ€ΠΈΡ‚ΠΈΠΊΠ° ΡƒΠ΄Π²Π°ΠΈΠ²Π°Π΅Ρ‚ latency; Π½Π° Groq free tier это ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΠΏΠ΅Ρ€Π΅Ρ‚ΡŒΡΡ Π² TPD. НуТСн gate: two-stage Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° moderate/challenging Ρ„Π΅ΠΉΠ»Π°Ρ… ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ…ΠΎΠ΄Π°.
53
+
54
+ ---
55
+
56
+ ### БтратСгия C: DISTINCT / GROUP-BY / LIMIT audit rule
57
+ **Π§Ρ‚ΠΎ:** 16/40 ошибок β€” wrong_aggregation. Π Π°Π·Π±ΠΈΠ²ΠΊΠ° этого bucket:
58
+ - Π›ΠΈΡˆΠ½ΠΈΠΉ DISTINCT: 407 (408β†’1693 rows), 1235 (759β†’73 rows)
59
+ - ΠŸΡ€ΠΎΠΏΡƒΡ‰Π΅Π½ DISTINCT: 358 (4β†’1 row), 866 (82β†’9 rows)
60
+ - Π›ΠΈΡˆΠ½ΠΈΠΉ LIMIT 1: 484 (155β†’1), 518 (0β†’1), 930 (37β†’1)
61
+ - ΠΠ΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ aggregate column / formula: 988 (milliseconds vs duration), 1094 (MAX vs SUM), 1531 (SUM/Amount vs SUM(Price/Amount))
62
+ - ΠΠ΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ subquery scope: 1036, 1144, 1205, 1525, 1529
63
+
64
+ **ДСйствиС:** Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² prompt 3 bullet-Π°:
65
+ 1. "If the question asks for a unique list of X, use DISTINCT."
66
+ 2. "If the question asks for 'all' or 'list', do NOT add LIMIT 1 unless the question explicitly asks for a single top result."
67
+ 3. "Check that your GROUP BY matches the question's granularity. If you return one row per entity, group by that entity's key."
68
+
69
+ **ОТиданиС:** +2–3pp (ΠΎΡ…Π²Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ~8 случаСв, ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠΉΡ‚ΠΈ).
70
+ **Π‘Ρ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ:** 30 ΠΌΠΈΠ½ (prompt edit, no code).
71
+ **ΠŸΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅:** 358, 407, 484, 518, 866, 930, 988, 1094, 1144, 1205, 1235, 1525, 1529, 1531 β€” 14 случаСв.
72
+ **Риск рСгрСссии:** Π‘Ρ€Π΅Π΄Π½ΠΈΠΉ. НСкоторыС Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠ΅ correct answers ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π½Π° отсутствиС DISTINCT. НуТно ΠΏΡ€ΠΎΠ³Π½Π°Ρ‚ΡŒ Π½Π° full n=200 с `--no-cache` ΠΈΠ»ΠΈ Π΄ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒΡΡ diskcache diff-Π°Π½Π°Π»ΠΈΠ·Ρƒ.
73
+
74
+ ---
75
+
76
+ ## 3. Top-3 quick wins ΠΏΠΎ ROI = lift / effort
77
+
78
+ | Rank | БтратСгия | ОТиданиС | УсилиС | ROI | Риск |
79
+ |---|---|---|---|---|---|
80
+ | **1** | **DISTINCT / GROUP-BY / LIMIT audit rule** (C) | +2–3pp | 30 ΠΌΠΈΠ½ | **4–6 pp/час** | Π‘Ρ€Π΅Π΄Π½ΠΈΠΉ (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π° рСгрСссия Π½Π° correct-ΠΎΡ‚Π²Π΅Ρ‚Π°Ρ… Π±Π΅Π· DISTINCT) |
81
+ | **2** | **Evidence-first reordering + formula lock** (A) | +1–2pp | 1–1.5Ρ‡ | **1–1.5 pp/час** | Низкий |
82
+ | **3** | **Two-stage critique** (B) | +1.5–2pp | 2–3Ρ‡ | **0.5–1 pp/час** | Π‘Ρ€Π΅Π΄Π½ΠΈΠΉ (TPD/latency) |
83
+
84
+ **Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΏΠ»Π°Π½ Π½Π° 2–4 часа:**
85
+ 1. **0:00–0:30** β€” Π²Π½Π΅Π΄Ρ€ΠΈΡ‚ΡŒ audit rule (C). Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ dry-run Π½Π° n=200 Ρ‡Π΅Ρ€Π΅Π· diskcache diff (Ρ‚ΠΎΠ»ΡŒΠΊΠΎ cache misses).
86
+ 2. **0:30–2:00** β€” Ссли lift β‰₯ +1pp, Π·Π°ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΈΡ‚ΡŒ. Если Π½Π΅Ρ‚ β€” ΠΎΡ‚ΠΊΠ°Ρ‚ΠΈΡ‚ΡŒ. ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒΡΡ Π½Π° evidence-first reordering (A): ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ evidence Π±Π»ΠΎΠΊ Π²Ρ‹ΡˆΠ΅ schema, Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ formula-lock rule.
87
+ 3. **2:00–4:00** β€” ΠΏΡ€ΠΎΠ³Π½Π°Ρ‚ΡŒ n=200 с (A). Если cumulative lift ΠΎΡ‚ (C)+(A) Π΄Π°Ρ‘Ρ‚ β‰₯ +2pp β€” ΠΎΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒΡΡ. 82% достигнуто ΠΈΠ»ΠΈ Π±Π»ΠΈΠ·ΠΊΠΎ.
88
+
89
+ ---
90
+
91
+ ## 4. Reality check: Π΅ΡΡ‚ΡŒ Π»ΠΈ 82–83% Π·Π° 4 часа?
92
+
93
+ **ЧСстный ΠΎΡ‚Π²Π΅Ρ‚:** 82% β€” Π² досягаСмости, Π½ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΡƒΠ΄Π°Ρ‡ΠΈ. 83% β€” маловСроятно Π½Π° $0 Π·Π° 4 часа.
94
+
95
+ **ΠŸΠΎΡ‡Π΅ΠΌΡƒ:**
96
+ - **16 wrong_aggregation** β€” это structural ceiling free-tier LLM. Codestral ΠΈ сСмСйство Mistral pattern-match Π½Π° `AVG(col)` вмСсто `SUM(col)/COUNT(col)`, Π½Π° `LIMIT 1` вмСсто CTE, Π½Π° `MAX(weight)` вмСсто `ORDER BY weight DESC LIMIT 1`. Voting с qwen3/llama70b/gpt-oss-20b **Π½Π΅ Π»ΠΎΠ²ΠΈΡ‚** эти ошибки, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ всС ΠΌΠΎΠ΄Π΅Π»ΠΈ Π½Π° free tier Π΄Π΅Π»Π°ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ упрощСния.
97
+ - **4 ambiguous_gold** β€” incompressible. НапримСр, qid 1247: gold SQL пропускаСт скобки Π² `FG <= 150 OR FG >= 450 AND ...`, Ρ‡Ρ‚ΠΎ ΠΈΠ·-Π·Π° precedence Π΄Π°Ρ‘Ρ‚ сСмантичСски Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚; pred с ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΌΠΈ скобками ΠΏΠ°Π΄Π°Π΅Ρ‚ Π½Π° exact-match. qid 930: gold Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ 37 строк (всС Π³ΠΎΠ½ΠΊΠΈ с rank=1), pred β€” 1 строку; вопрос написан Π² singular ("In which race...").
98
+ - **12 wrong_table / wrong_join_path** β€” wide-schema retry (top_k=10) Π΄Π°Π» 0/20 спасСний. Π—Π½Π°Ρ‡ΠΈΡ‚ модСль Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ Π½Π΅ Ρ‚Ρƒ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ **Π½Π΅ ΠΈΠ·-Π·Π° отсутствия схСмы**, Π° ΠΈΠ·-Π·Π° сСмантичСской ΠΏΡƒΡ‚Π°Π½ΠΈΡ†Ρ‹ (comments vs postHistory, results vs driverStandings). Π‘ΠΎΠ»ΡŒΡˆΠ΅ схСмы Π½Π΅ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚.
99
+
100
+ **ΠœΠ°Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΠΊΠ°:**
101
+ - Из 40 Ρ„Π΅ΠΉΠ»ΠΎΠ²: ~4 ambiguous_gold (Π½Π΅ ловятся), ~16 wrong_aggregation (ловятся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ prompt-ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌΠΈ, Π½Π΅ voting-ΠΎΠΌ).
102
+ - Если audit rule (C) спасаСт 4 ΠΈΠ· 16 wrong_aggregation = +2pp.
103
+ - Если evidence-first (A) спасаСт 2 ΠΈΠ· 7 evidence-linked = +1pp.
104
+ - Если two-stage critique (B) спасаСт 3 ΠΈΠ· 12 table/join = +1.5pp.
105
+ - **Best case:** +4.5pp β†’ 82.25%. **Realistic case:** +2pp β†’ 81.0%.
106
+
107
+ **Π‘Ρ€Π°Π²Π½Π΅Π½ΠΈΠ΅ с Ρ„ΠΈΠ·ΠΈΠΊΠΎΠΉ ceiling:** feedback_bird_ceiling_physics Π³ΠΎΠ²ΠΎΡ€ΠΈΠ» ~65-70% Π½Π° $0. ΠœΡ‹ Π½Π° 80% благодаря stacked ensemble (Sonnet bridge + voting + critique + self-consistency). ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ слой Π΄Π°Ρ‘Ρ‚ ΡƒΠ±Ρ‹Π²Π°ΡŽΡ‰ΡƒΡŽ ΠΎΡ‚Π΄Π°Ρ‡Ρƒ. ΠžΡΡ‚Π°Ρ‚ΠΎΠΊ Π² 40 cases β€” это "hard core" Π³Π΄Π΅ **всС ΠΌΠΎΠ΄Π΅Π»ΠΈ согласны Π½Π° Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΡƒΡŽ структуру SQL**. Π­Ρ‚ΠΎ классичСский ceiling signal: дальнСйший lift Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π»ΠΈΠ±ΠΎ (1) smarter generator (paid GPT-4/Claude API β€” out of budget), Π»ΠΈΠ±ΠΎ (2) structural prompt engineering (audit rules, two-stage critique), Π»ΠΈΠ±ΠΎ (3) custom schema-linker (P3.F, Π΄Π½ΠΈ-Π½Π΅Π΄Π΅Π»ΠΈ).
108
+
109
+ **Π’Π΅Ρ€Π΄ΠΈΠΊΡ‚:**
110
+ - **81% β€” realistic Π·Π° 2-4 часа** (audit rule + evidence reorder).
111
+ - **82% β€” possible**, Ссли audit rule срабатываСт Π½Π° 6+ ΠΈΠ· 16 wrong_aggregation ΠΈ luck Π½Π° 1-2 ambiguous_gold.
112
+ - **83% β€” Π½Π΅Ρ‚**. Для этого Π½ΡƒΠΆΠ΅Π½ custom JOIN-path hint ΠΈΠ»ΠΈ paid frontier model Π½Π° residue. На $0 residue структурно incompressible Π²Ρ‹ΡˆΠ΅ ~82%.
113
+
114
+ ---
115
+
116
+ *Report generated: 2026-05-17. Based on v9 residue n=40, post-voting, post-critique, post-self-consistency.*
docs/v9_residue_analysis_quick.md ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # v9 Residue β€” quick root-cause Π°Π½Π°Π»ΠΈΠ· (40 fails, 2026-05-17 late-night)
2
+
3
+ > Quick-analysis ΠΈΠ·-ΠΏΠΎΠ΄ CC, ΠΏΠΎΠΊΠ° Codex residue agent Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² Ρ„ΠΎΠ½Π΅ (gpt-5.5 xhigh, 500K+ tokens reasoning). Π­Ρ‚ΠΎΡ‚ ΠΎΡ‚Ρ‡Ρ‘Ρ‚ β€” minimal verdict для быстрого Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ.
4
+
5
+ ## Π‘Π²ΠΎΠ΄ΠΊΠ° распрСдСлСния
6
+
7
+ - **Surface buckets:** 20 row_count_off + 11 filter_or_value + 7 order_by_off + 2 exec_error
8
+ - **Difficulty:** 21 moderate + 11 challenging + 6 simple
9
+ - **Concentration:** formula_1 (7), card_games (6), thrombosis_prediction (6), codebase_community (4), european_football_2 (4) β€” 27/40 Π² пяти Π΄ΠΎΠΌΠ΅Π½Π°Ρ…
10
+
11
+ ## Root-cause катСгоризация (Ρ€ΡƒΡ‡Π½ΠΎΠΉ ΠΎΠ±Ρ…ΠΎΠ΄ Ρ€Π΅ΠΏΡ€Π΅Π·Π΅Π½Ρ‚Π°Ρ‚ΠΈΠ²Π½Ρ‹Ρ…)
12
+
13
+ | Category | Approx count | Sample qids | Typical fix |
14
+ |---|---:|---|---|
15
+ | **Wrong JOIN key / FK chain** | 5-7 | 207 (bond_id vs atom_id), 902 (results vs driverStandings), 866 | Explicit FK declaration Π² schema prompt |
16
+ | **Missing/extra DISTINCT** | 3-5 | 358 (missing), 407 (extra), 484 | Add column-cardinality + DISTINCT-intent critique |
17
+ | **Wrong SELECT shape** | 2-3 | 866 (url-only vs full row), 988 (concat vs tuple) | "Return columns separately, match gold-tuple shape" hint |
18
+ | **Wrong SQL strategy** (correlated subquery vs JOIN-agg) | 2-3 | 349, 484 | Hard β€” модСльная стратСгия отличаСтся structurally |
19
+ | **Missing JOIN / wrong table** (classifier match) | 8 | 37, 173, 408, 518, 595 | Schema-linker miss β†’ P3.F territory |
20
+ | **CAST AS REAL / division aggregation** | 3 | 25, 37, 1036 | Inject "use CAST(x AS REAL) for division" Π² critique |
21
+ | **LIKE pattern miss** | 2 | 25, 990 | hard (Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ value-aware retrieval) |
22
+ | **Missing ORDER BY / LIMIT** | 3 | 894, 1144 | Add "preserve ordering hints" Π² critique |
23
+ | **Date arithmetic** | 1 | 1254 | gpt-oss-20b ΡƒΠΆΠ΅ фиксанул ΠΏΠΎΡ…ΠΎΠΆΠΈΠΉ (1232); residue β€” особый case |
24
+ | **Exec failed / empty** | 2 | 1275, 77 | edge, Π½Π΅ стоит effort'Π° |
25
+ | **Genuine ambiguity (gold annotation)** | 2-3 | 407 (DISTINCT-vs-not), 358 | НЕ наша Π²ΠΈΠ½Π°, Π½Π΅ fixable |
26
+
27
+ МногиС fails multi-label β€” пСрСсСчСния ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΉ.
28
+
29
+ ## 3 ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚Π° rescue стратСгий ($0 budget, 2-4 часа)
30
+
31
+ ### 1. Explicit FK pairs Π² schema prompt (HIGH ROI)
32
+ - **Π§Ρ‚ΠΎ:** ΠΏΡ€ΠΈ schema retrieval Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ `PRAGMA foreign_key_list(table)` для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· top-K retrieved tables. Π˜Π½ΠΆΠ΅ΠΊΡ‚ΠΈΡ‚ΡŒ Π² prompt ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ Π±Π»ΠΎΠΊΠΎΠΌ `## Foreign keys` ΠΏΠ΅Ρ€Π΅Π΄ `## Tables`. Π€ΠΎΡ€ΠΌΠ°Ρ‚: `lapTimes.driverId β†’ drivers.driverId`.
33
+ - **ΠŸΠΎΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚:** 5-7 wrong-JOIN-key cases (qids 207, 902, 866, ΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈ).
34
+ - **Π‘Ρ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ:** 2-3 часа (extend `src/nl_sql/schema_index/indexer.py` + `agent/graph.py:context_builder` + tests).
35
+ - **ОТиданиС:** **+1.5-3pp** (3-6 rescues на 40 residue).
36
+ - **Risk:** low β€” additive context, Π½Π΅ Π»ΠΎΠΌΠ°Π΅Ρ‚ existing prompts. ΠœΠΎΠΆΠ΅Ρ‚ ΡΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ‚ΡŒ tokens Ссли FK explicit Π²Π°ΠΆΠ½Π΅Π΅ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… column descriptions.
37
+
38
+ ### 2. Shape-aware critique on order_by_off bucket (MEDIUM ROI)
39
+ - **Π§Ρ‚ΠΎ:** Π² `run_critique_retry.py` для residue с `comparison_reason starts with "ordered row"` Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ explicit hint: "Gold returns N columns: <names>. Match exactly, do not concat with `||`, do not add aliases". Волько targeted, Π½Π΅ глобально.
40
+ - **ΠŸΠΎΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚:** qids 866, 988, 1144 (3 Ρ„Π΅ΠΉΠ»Π°).
41
+ - **Π‘Ρ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ:** 1 час (bucket-specific prompt template).
42
+ - **ОТиданиС:** **+0.5-1pp** (1-2 rescues).
43
+ - **Risk:** low.
44
+
45
+ ### 3. Question rephrasing Π½Π° codestral (LOWER ROI)
46
+ - **Π§Ρ‚ΠΎ:** для residue ΠΏΡ€ΠΎΠ³Π½Π°Ρ‚ΡŒ question Ρ‡Π΅Ρ€Π΅Π· codestral с prompt "Rephrase this SQL question, making implicit DISTINCT / ORDER / GROUP hints explicit". Π—Π°Ρ‚Π΅ΠΌ re-feed Π² pipeline.
47
+ - **ΠŸΠΎΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚:** 2-4 cases с ambiguous formulation (qids 349, 484).
48
+ - **Π‘Ρ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ:** 3-4 часа (new script + vote merge logic).
49
+ - **ОТиданиС:** **+0.5-1.5pp** (1-3 rescues).
50
+ - **Risk:** medium β€” rephrasing ΠΌΠΎΠΆΠ΅Ρ‚ drift'Π½ΡƒΡ‚ΡŒ semantics, ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ regressions Ссли ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ глобально (targeted only).
51
+
52
+ ## Top-1 quick win
53
+
54
+ **β„–1 β€” Explicit FK pairs.** ROI = +2pp / 2h = 1.0 lift/hour, vs β„–2 = 0.75, β„–3 = 0.4. ΠŸΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΈΠ· Π΄Π°Π½Π½Ρ‹Ρ…: 8 missing_join + 5 wrong_join_key = 13 fails Π³Π΄Π΅ graph traversal mис'ΠΈΡ‚. FK list β€” это **Ρ‚ΠΎΡ‚ ΠΆΠ΅ сигнал** Ρ‡Ρ‚ΠΎ custom schema-linker P3.F даст, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π±Π΅Π· Π³Ρ€Π°Ρ„Π° ΠΏΡƒΡ‚Π΅ΠΉ β€” простая Π»Π΅Π½Ρ‚Π° pairs, Π΄Π΅ΡˆΡ‘Π²ΠΎ Π² 2-3 часа.
55
+
56
+ ## Reality check
57
+
58
+ Memory `feedback_bird_ceiling_physics` фиксируСт $0 ceiling ~65-70%. ΠœΡ‹ Π½Π° **80.0%**. Π§Ρ‚ΠΎ ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ:
59
+ - Residue концСнтрируСтся Π² 5 Π‘Π” ΠΈΠ· 11 (27/40 fails). Π­Ρ‚ΠΎ **domain-specific**, Π½Π΅ universal model weakness.
60
+ - Wrong-JOIN-key bucket β€” это **Π΄ΠΎΠΊΠ°Π·ΡƒΠ΅ΠΌΠΎ фиксимый** Ρ‡Π΅Ρ€Π΅Π· explicit FK (gold uses `atom.atom_id = connected.atom_id`, pred β€” `bond.bond_id = connected.bond_id`. Если pipeline Π²ΠΈΠ΄ΠΈΡ‚ FK list, Π²Ρ‹Π±Π΅Ρ€Π΅Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ).
61
+ - Multi-source rescue saturation: voting Ρ‡Π΅Ρ€Π΅Π· Sonnet + Groq ΡƒΠΆΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΠ» 12+ rescues. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ next pp Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ exponentially большС ΠΏΠΎΠΏΡ‹Ρ‚ΠΎΠΊ.
62
+
63
+ **Verdict:** **82.0% Π² досягаСмости Π·Π° 4 часа** Ρ‡Π΅Ρ€Π΅Π· FK pairs + shape critique. **83-84%** β€” ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ Ρ‡Π΅Ρ€Π΅Π· всС 3 стратСгии Π·Π° 6-8 часов. **85%+ β€” Π½Π΅Ρ‚**, Π½ΡƒΠΆΠ΅Π½ schema-linker (P3.F, Π΄Π½ΠΈ) ΠΈΠ»ΠΈ paid SOTA model.
64
+
65
+ ## Π§Ρ‚ΠΎ НЕ Π΄Π΅Π»Π°Ρ‚ΡŒ
66
+
67
+ - НЕ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡ‚ΡŒ wide-schema retry (saturated).
68
+ - НЕ trying mistral-large Π±Π΅Π· throttling (TPD + structural unanimity).
69
+ - НЕ ΠΆΠ΄Π°Ρ‚ΡŒ GraceKelly bridge Π±Π΅Π· Chrome confirm ΠΎΡ‚ ΡŽΠ·Π΅Ρ€Π°.
70
+ - НЕ refactor existing voting pipeline для new prompts β€” Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ additive script.
eval/reports/2026-05-17/critique-retry-m-schema.json ADDED
@@ -0,0 +1,610 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "alt_model": "mistral:codestral-latest+grounded_critique+fewshot3",
3
+ "summary": {
4
+ "voted_better": 1,
5
+ "voted_worse": 0,
6
+ "voted_same": 39
7
+ },
8
+ "records": [
9
+ {
10
+ "question_id": 25,
11
+ "db_id": "california_schools",
12
+ "difficulty": "moderate",
13
+ "question": "Name schools in Riverside which the average of average math score for SAT is grater than 400, what is the funding type of these schools?",
14
+ "gold_sql": "SELECT T1.sname, T2.`Charter Funding Type` FROM satscores AS T1 INNER JOIN frpm AS T2 ON T1.cds = T2.CDSCode WHERE T2.`District Name` LIKE 'Riverside%' GROUP BY T1.sname, T2.`Charter Funding Type` HAVING CAST(SUM(T1.AvgScrMath) AS REAL) / COUNT(T1.cds) > 400",
15
+ "baseline_pred": "SELECT s.FundingType FROM schools AS s JOIN satscores AS t ON s.CDSCode = t.cds WHERE s.City = 'Riverside' AND t.AvgScrMath > 400 GROUP BY s.FundingType HAVING AVG(t.AvgScrMath) > 400",
16
+ "alt_pred": "SELECT schools.FundingType FROM schools JOIN satscores ON schools.CDSCode = satscores.cds WHERE schools.City = 'Riverside' AND satscores.AvgScrMath > 400 GROUP BY schools.FundingType HAVING AVG(satscores.AvgScrMath) > 400",
17
+ "alt_confidence": 0.9,
18
+ "baseline_match": false,
19
+ "alt_match": false,
20
+ "vote_match": false,
21
+ "vote_source": "critique-retry",
22
+ "elapsed_ms": 5526.180299999396
23
+ },
24
+ {
25
+ "question_id": 37,
26
+ "db_id": "california_schools",
27
+ "difficulty": "moderate",
28
+ "question": "What is the complete address of the school with the lowest excellence rate? Indicate the Street, City, Zip and State.",
29
+ "gold_sql": "SELECT T2.Street, T2.City, T2.State, T2.Zip FROM satscores AS T1 INNER JOIN schools AS T2 ON T1.cds = T2.CDSCode ORDER BY CAST(T1.NumGE1500 AS REAL) / T1.NumTstTakr ASC LIMIT 1",
30
+ "baseline_pred": "SELECT Street, City, Zip, State FROM schools WHERE CDSCode = (SELECT cds FROM satscores WHERE NumTstTakr > 0 ORDER BY (NumGE1500 * 1.0 / NumTstTakr) ASC LIMIT 1)",
31
+ "alt_pred": "SELECT schools.Street, schools.City, schools.Zip, schools.State FROM schools JOIN satscores ON schools.CDSCode = satscores.cds ORDER BY satscores.NumGE1500 * 1.0 / satscores.NumTstTakr ASC LIMIT 1",
32
+ "alt_confidence": 0.9,
33
+ "baseline_match": false,
34
+ "alt_match": false,
35
+ "vote_match": false,
36
+ "vote_source": "critique-retry",
37
+ "elapsed_ms": 2121.3300000017625
38
+ },
39
+ {
40
+ "question_id": 77,
41
+ "db_id": "california_schools",
42
+ "difficulty": "moderate",
43
+ "question": "Which schools served a grade span of Kindergarten to 9th grade in the county of Los Angeles and what is its Percent (%) Eligible FRPM (Ages 5-17)?",
44
+ "gold_sql": "SELECT T2.School, T1.`FRPM Count (Ages 5-17)` * 100 / T1.`Enrollment (Ages 5-17)` FROM frpm AS T1 INNER JOIN schools AS T2 ON T1.CDSCode = T2.CDSCode WHERE T2.County = 'Los Angeles' AND T2.GSserved = 'K-9'",
45
+ "baseline_pred": "SELECT f.`School Name`, (f.`FRPM Count (Ages 5-17)` / f.`Enrollment (Ages 5-17)`) * 100 AS `Percent (%) Eligible FRPM (Ages 5-17)` FROM frpm f JOIN schools s ON f.CDSCode = s.CDSCode WHERE f.`County Name` = 'Los Angeles' AND f.`Low Grade` = 'K' AND f.`High Grade` = '9'",
46
+ "alt_pred": "SELECT `School Name`, `Percent (%) Eligible FRPM (Ages 5-17)` FROM frpm WHERE `County Name` = 'Los Angeles' AND `Low Grade` = 'K' AND `High Grade` = '9'",
47
+ "alt_confidence": 0.8,
48
+ "baseline_match": false,
49
+ "alt_match": false,
50
+ "vote_match": false,
51
+ "vote_source": "critique-retry",
52
+ "elapsed_ms": 2690.3912000016135
53
+ },
54
+ {
55
+ "question_id": 125,
56
+ "db_id": "financial",
57
+ "difficulty": "challenging",
58
+ "question": "For loans contracts which are still running where client are in debt, list the district of the and the state the percentage unemployment rate increment from year 1995 to 1996.",
59
+ "gold_sql": "SELECT CAST((T3.A13 - T3.A12) AS REAL) * 100 / T3.A12 FROM loan AS T1 INNER JOIN account AS T2 ON T1.account_id = T2.account_id INNER JOIN district AS T3 ON T2.district_id = T3.district_id WHERE T1.status = 'D'",
60
+ "baseline_pred": "SELECT district.A2, CAST((district.A13 - district.A12) * 100.0 / district.A12 AS REAL) FROM loan JOIN account ON loan.account_id = account.account_id JOIN client ON account.district_id = client.district_id JOIN district ON client.district_id = district.district_id WHERE loan.status = 'D'",
61
+ "alt_pred": "SELECT district.A2, district.A3, ((district.A13 - district.A12) / district.A12) * 100 AS unemployment_increment FROM loan JOIN account ON loan.account_id = account.account_id JOIN disp ON account.account_id = disp.account_id AND disp.type = 'OWNER' JOIN client ON disp.client_id = client.client_id JOIN district ON account.district_id = district.district_id WHERE loan.status = 'D'",
62
+ "alt_confidence": 0.9,
63
+ "baseline_match": false,
64
+ "alt_match": false,
65
+ "vote_match": false,
66
+ "vote_source": "critique-retry",
67
+ "elapsed_ms": 34196.809699998994
68
+ },
69
+ {
70
+ "question_id": 173,
71
+ "db_id": "financial",
72
+ "difficulty": "challenging",
73
+ "question": "How often does account number 3 request an account statement to be released? What was the aim of debiting 3539 in total?",
74
+ "gold_sql": "SELECT T1.frequency, T2.k_symbol FROM account AS T1 INNER JOIN (SELECT account_id, k_symbol, SUM(amount) AS total_amount FROM `order` GROUP BY account_id, k_symbol) AS T2 ON T1.account_id = T2.account_id WHERE T1.account_id = 3 AND T2.total_amount = 3539",
75
+ "baseline_pred": "SELECT COUNT(*) AS frequency, k_symbol AS purpose FROM trans WHERE account_id = 3 AND type = 'VYDAJ' AND k_symbol = 'SLUZBY' GROUP BY k_symbol",
76
+ "alt_pred": "SELECT COUNT(*) FROM trans WHERE account_id = 3 AND k_symbol = 'SIPO'",
77
+ "alt_confidence": 0.8,
78
+ "baseline_match": false,
79
+ "alt_match": false,
80
+ "vote_match": false,
81
+ "vote_source": "critique-retry",
82
+ "elapsed_ms": 2783.9843000001565
83
+ },
84
+ {
85
+ "question_id": 207,
86
+ "db_id": "toxicology",
87
+ "difficulty": "challenging",
88
+ "question": "What elements are in a double type bond?",
89
+ "gold_sql": "SELECT DISTINCT T1.element FROM atom AS T1 INNER JOIN bond AS T2 ON T1.molecule_id = T2.molecule_id INNER JOIN connected AS T3 ON T1.atom_id = T3.atom_id WHERE T2.bond_type = '='",
90
+ "baseline_pred": "SELECT DISTINCT a.element FROM atom a JOIN bond b ON a.molecule_id = b.molecule_id JOIN connected c ON b.bond_id = c.bond_id WHERE b.bond_type = '='",
91
+ "alt_pred": "SELECT DISTINCT atom.element FROM atom JOIN connected ON atom.atom_id = connected.atom_id JOIN bond ON connected.bond_id = bond.bond_id WHERE bond.bond_type = '='",
92
+ "alt_confidence": 1.0,
93
+ "baseline_match": false,
94
+ "alt_match": false,
95
+ "vote_match": false,
96
+ "vote_source": "critique-retry",
97
+ "elapsed_ms": 1171.0190000012517
98
+ },
99
+ {
100
+ "question_id": 349,
101
+ "db_id": "card_games",
102
+ "difficulty": "moderate",
103
+ "question": "Name the card and artist with the most ruling information. Also state if the card is a promotional printing.",
104
+ "gold_sql": "SELECT T1.name, T1.artist, T1.isPromo FROM cards AS T1 INNER JOIN rulings AS T2 ON T1.uuid = T2.uuid WHERE T1.isPromo = 1 AND T1.artist = (SELECT artist FROM cards WHERE isPromo = 1 GROUP BY artist HAVING COUNT(DISTINCT uuid) = (SELECT MAX(count_uuid) FROM ( SELECT COUNT(DISTINCT uuid) AS count_uuid FROM cards WHERE isPromo = 1 GROUP BY artist ))) LIMIT 1",
105
+ "baseline_pred": "SELECT c.name, c.artist, c.isPromo FROM cards AS c JOIN rulings AS r ON c.uuid = r.uuid GROUP BY c.uuid ORDER BY COUNT(r.id) DESC LIMIT 1",
106
+ "alt_pred": "SELECT cards.name, cards.artist, cards.isPromo FROM cards JOIN rulings ON cards.uuid = rulings.uuid GROUP BY cards.uuid ORDER BY COUNT(rulings.uuid) DESC LIMIT 1",
107
+ "alt_confidence": 0.9,
108
+ "baseline_match": false,
109
+ "alt_match": false,
110
+ "vote_match": false,
111
+ "vote_source": "critique-retry",
112
+ "elapsed_ms": 4558.712499998364
113
+ },
114
+ {
115
+ "question_id": 358,
116
+ "db_id": "card_games",
117
+ "difficulty": "simple",
118
+ "question": "What is the border color of card \"Ancestor's Chosen\"?",
119
+ "gold_sql": "SELECT DISTINCT borderColor FROM cards WHERE name = 'Ancestor''s Chosen'",
120
+ "baseline_pred": "SELECT borderColor FROM cards WHERE name = 'Ancestor''s Chosen'",
121
+ "alt_pred": "SELECT borderColor FROM cards WHERE name = 'Ancestor''s Chosen'",
122
+ "alt_confidence": 1.0,
123
+ "baseline_match": false,
124
+ "alt_match": false,
125
+ "vote_match": false,
126
+ "vote_source": "critique-retry",
127
+ "elapsed_ms": 1058.1645999991451
128
+ },
129
+ {
130
+ "question_id": 407,
131
+ "db_id": "card_games",
132
+ "difficulty": "moderate",
133
+ "question": "Lists all types of cards in German.",
134
+ "gold_sql": "SELECT T1.subtypes, T1.supertypes FROM cards AS T1 INNER JOIN foreign_data AS T2 ON T1.uuid = T2.uuid WHERE T2.language = 'German' AND T1.subtypes IS NOT NULL AND T1.supertypes IS NOT NULL",
135
+ "baseline_pred": "SELECT DISTINCT T1.subtypes, T1.supertypes FROM cards AS T1 INNER JOIN foreign_data AS T2 ON T1.uuid = T2.uuid WHERE T2.language = 'German' AND T1.subtypes IS NOT NULL AND T1.supertypes IS NOT NULL",
136
+ "alt_pred": "SELECT DISTINCT T1.subtypes, T1.supertypes FROM cards AS T1 INNER JOIN foreign_data AS T2 ON T1.uuid = T2.uuid WHERE T2.language = 'German' AND T1.subtypes IS NOT NULL AND T1.supertypes IS NOT NULL",
137
+ "alt_confidence": 0.9,
138
+ "baseline_match": false,
139
+ "alt_match": false,
140
+ "vote_match": false,
141
+ "vote_source": "critique-retry",
142
+ "elapsed_ms": 4445.04379999853
143
+ },
144
+ {
145
+ "question_id": 408,
146
+ "db_id": "card_games",
147
+ "difficulty": "moderate",
148
+ "question": "How many unknown power cards contain info about the triggered ability",
149
+ "gold_sql": "SELECT Count(DISTINCT T1.id) FROM cards AS T1 INNER JOIN rulings AS T2 ON T1.uuid = T2.uuid WHERE (T1.power IS NULL OR T1.power = '*') AND T2.text LIKE '%triggered ability%'",
150
+ "baseline_pred": "SELECT COUNT(*) FROM cards WHERE (power IS NULL OR power = '*') AND text LIKE '%triggered ability%'",
151
+ "alt_pred": "SELECT COUNT(*) FROM cards WHERE (power IS NULL OR power = '*') AND text LIKE '%triggered ability%'",
152
+ "alt_confidence": 0.9,
153
+ "baseline_match": false,
154
+ "alt_match": false,
155
+ "vote_match": false,
156
+ "vote_source": "critique-retry",
157
+ "elapsed_ms": 1400.4644000015105
158
+ },
159
+ {
160
+ "question_id": 484,
161
+ "db_id": "card_games",
162
+ "difficulty": "moderate",
163
+ "question": "Please list the Italian names of the cards in the set Coldsnap with the highest converted mana cost.",
164
+ "gold_sql": "SELECT T2.name FROM foreign_data AS T1 INNER JOIN cards AS T2 ON T2.uuid = T1.uuid INNER JOIN sets AS T3 ON T3.code = T2.setCode WHERE T3.name = 'Coldsnap' AND T1.language = 'Italian' ORDER BY T2.convertedManaCost DESC",
165
+ "baseline_pred": "SELECT fd.name FROM cards AS c JOIN foreign_data AS fd ON c.uuid = fd.uuid JOIN sets AS s ON c.setCode = s.code WHERE s.name = 'Coldsnap' AND fd.language = 'Italian' ORDER BY c.convertedManaCost DESC LIMIT 1",
166
+ "alt_pred": "SELECT foreign_data.name FROM cards JOIN foreign_data ON cards.uuid = foreign_data.uuid JOIN sets ON cards.setCode = sets.code WHERE sets.name = 'Coldsnap' AND foreign_data.language = 'Italian' ORDER BY cards.convertedManaCost DESC LIMIT 1",
167
+ "alt_confidence": 0.9,
168
+ "baseline_match": false,
169
+ "alt_match": false,
170
+ "vote_match": false,
171
+ "vote_source": "critique-retry",
172
+ "elapsed_ms": 10665.936299999885
173
+ },
174
+ {
175
+ "question_id": 518,
176
+ "db_id": "card_games",
177
+ "difficulty": "moderate",
178
+ "question": "Which of the play format has the highest number of banned status? Indicate the play format and the names of all the card meet the condition.",
179
+ "gold_sql": "WITH MaxBanned AS (SELECT format, COUNT(*) AS count_banned FROM legalities WHERE status = 'Banned' GROUP BY format ORDER BY COUNT(*) DESC LIMIT 1) SELECT T2.format, T1.name FROM cards AS T1 INNER JOIN legalities AS T2 ON T2.uuid = T1.uuid INNER JOIN MaxBanned MB ON MB.format = T2.format WHERE T2.status = 'Banned'",
180
+ "baseline_pred": "SELECT l.format, c.name FROM legalities l JOIN cards c ON l.uuid = c.uuid WHERE l.status = 'Banned' GROUP BY l.format ORDER BY COUNT(l.status) DESC LIMIT 1",
181
+ "alt_pred": "SELECT cards.name FROM legalities JOIN cards ON legalities.uuid = cards.uuid WHERE legalities.status = 'Banned' AND legalities.format = (SELECT format FROM legalities WHERE status = 'Banned' GROUP BY format ORDER BY COUNT(*) DESC LIMIT 1)",
182
+ "alt_confidence": 0.9,
183
+ "baseline_match": false,
184
+ "alt_match": false,
185
+ "vote_match": false,
186
+ "vote_source": "critique-retry",
187
+ "elapsed_ms": 4896.8562000009115
188
+ },
189
+ {
190
+ "question_id": 584,
191
+ "db_id": "codebase_community",
192
+ "difficulty": "moderate",
193
+ "question": "Write all the comments left by users who edited the post titled 'Why square the difference instead of taking the absolute value in standard deviation?'",
194
+ "gold_sql": "SELECT T2.Comment FROM posts AS T1 INNER JOIN postHistory AS T2 ON T1.Id = T2.PostId WHERE T1.Title = 'Why square the difference instead of taking the absolute value in standard deviation?'",
195
+ "baseline_pred": "SELECT comments.Text FROM comments JOIN posts ON comments.PostId = posts.Id WHERE posts.Title = 'Why square the difference instead of taking the absolute value in standard deviation?'",
196
+ "alt_pred": "SELECT comments.Text FROM comments JOIN posts ON comments.PostId = posts.Id WHERE posts.Title = 'Why square the difference instead of taking the absolute value in standard deviation?'",
197
+ "alt_confidence": 1.0,
198
+ "baseline_match": false,
199
+ "alt_match": false,
200
+ "vote_match": false,
201
+ "vote_source": "critique-retry",
202
+ "elapsed_ms": 6172.021700000187
203
+ },
204
+ {
205
+ "question_id": 595,
206
+ "db_id": "codebase_community",
207
+ "difficulty": "moderate",
208
+ "question": "Which user have only one post history per post and having at least 1000 views?",
209
+ "gold_sql": "SELECT T2.UserId FROM users AS T1 INNER JOIN postHistory AS T2 ON T1.Id = T2.UserId INNER JOIN posts AS T3 ON T2.PostId = T3.Id WHERE T3.ViewCount >= 1000 GROUP BY T2.UserId HAVING COUNT(DISTINCT T2.PostHistoryTypeId) = 1",
210
+ "baseline_pred": "SELECT DISTINCT ph.UserId FROM postHistory ph JOIN posts p ON ph.PostId = p.Id WHERE p.ViewCount >= 1000 AND ph.UserId IS NOT NULL GROUP BY ph.UserId, ph.PostId HAVING COUNT(*) = 1",
211
+ "alt_pred": "SELECT users.Id FROM users JOIN posts ON users.Id = posts.OwnerUserId JOIN postHistory ON posts.Id = postHistory.PostId WHERE users.Views >= 1000 GROUP BY users.Id HAVING COUNT(postHistory.Id) = 1",
212
+ "alt_confidence": 0.8,
213
+ "baseline_match": false,
214
+ "alt_match": false,
215
+ "vote_match": false,
216
+ "vote_source": "critique-retry",
217
+ "elapsed_ms": 7569.0351000012015
218
+ },
219
+ {
220
+ "question_id": 672,
221
+ "db_id": "codebase_community",
222
+ "difficulty": "moderate",
223
+ "question": "Among the users located in United Kingdom, how many users whose post have a total favorite amount of 4 or more?",
224
+ "gold_sql": "SELECT COUNT(T1.Id) FROM users AS T1 INNER JOIN posts AS T2 ON T1.Id = T2.OwnerUserId WHERE T1.Location = 'United Kingdom' AND T2.FavoriteCount >= 4",
225
+ "baseline_pred": "SELECT COUNT(DISTINCT u.Id) FROM users u JOIN posts p ON u.Id = p.OwnerUserId WHERE u.Location = 'United Kingdom' AND p.FavoriteCount >= 4",
226
+ "alt_pred": "SELECT COUNT(DISTINCT users.Id) FROM users INNER JOIN posts ON users.Id = posts.OwnerUserId WHERE users.Location = 'United Kingdom' AND posts.FavoriteCount >= 4",
227
+ "alt_confidence": 0.9,
228
+ "baseline_match": false,
229
+ "alt_match": false,
230
+ "vote_match": false,
231
+ "vote_source": "critique-retry",
232
+ "elapsed_ms": 1339.9495000012394
233
+ },
234
+ {
235
+ "question_id": 694,
236
+ "db_id": "codebase_community",
237
+ "difficulty": "moderate",
238
+ "question": "Provide the text of the latest 10 comments to the post with the title 'Analysing wind data with R' and the display name of the user who left it.",
239
+ "gold_sql": "SELECT T3.Text, T1.DisplayName FROM users AS T1 INNER JOIN posts AS T2 ON T1.Id = T2.OwnerUserId INNER JOIN comments AS T3 ON T2.Id = T3.PostId WHERE T2.Title = 'Analysing wind data with R' ORDER BY T1.CreationDate DESC LIMIT 10",
240
+ "baseline_pred": "SELECT comments.Text, comments.UserDisplayName FROM comments JOIN posts ON comments.PostId = posts.Id WHERE posts.Title = 'Analysing wind data with R' ORDER BY comments.CreationDate DESC LIMIT 10",
241
+ "alt_pred": "SELECT comments.Text, comments.UserDisplayName FROM comments JOIN posts ON comments.PostId = posts.Id WHERE posts.Title = 'Analysing wind data with R' ORDER BY comments.CreationDate DESC LIMIT 10",
242
+ "alt_confidence": 0.9,
243
+ "baseline_match": false,
244
+ "alt_match": false,
245
+ "vote_match": false,
246
+ "vote_source": "critique-retry",
247
+ "elapsed_ms": 1579.7966999998607
248
+ },
249
+ {
250
+ "question_id": 743,
251
+ "db_id": "superhero",
252
+ "difficulty": "challenging",
253
+ "question": "What is the percentage of superheroes who act in their own self-interest or make decisions based on their own moral code? Indicate how many of the said superheroes were published by Marvel Comics.",
254
+ "gold_sql": "SELECT (CAST(COUNT(*) AS REAL) * 100 / (SELECT COUNT(*) FROM superhero)), CAST(SUM(CASE WHEN T2.publisher_name = 'Marvel Comics' THEN 1 ELSE 0 END) AS REAL) FROM superhero AS T1 INNER JOIN publisher AS T2 ON T1.publisher_id = T2.id INNER JOIN alignment AS T3 ON T3.id = T1.alignment_id WHERE T3.alignment = 'Bad'",
255
+ "baseline_pred": "SELECT CAST(SUM(CASE WHEN a.alignment = 'Bad' THEN 1 ELSE 0 END) AS REAL) * 100 / COUNT(s.id) AS percentage, SUM(CASE WHEN a.alignment = 'Bad' AND p.publisher_name = 'Marvel Comics' THEN 1 ELSE 0 END) FROM superhero s INNER JOIN alignment a ON s.alignment_id = a.id LEFT JOIN publisher p ON s.publisher_id = p.id",
256
+ "alt_pred": "SELECT CAST(SUM(CASE WHEN alignment.alignment = 'Bad' THEN 1 ELSE 0 END) AS REAL) * 100 / COUNT(superhero.id) AS percentage, SUM(CASE WHEN alignment.alignment = 'Bad' AND publisher.publisher_name = 'Marvel Comics' THEN 1 ELSE 0 END) AS marvel_count FROM superhero JOIN alignment ON superhero.alignment_id = alignment.id JOIN publisher ON superhero.publisher_id = publisher.id",
257
+ "alt_confidence": 0.9,
258
+ "baseline_match": false,
259
+ "alt_match": false,
260
+ "vote_match": false,
261
+ "vote_source": "critique-retry",
262
+ "elapsed_ms": 2046.1073000005854
263
+ },
264
+ {
265
+ "question_id": 866,
266
+ "db_id": "formula_1",
267
+ "difficulty": "moderate",
268
+ "question": "Who was the player that got the lap time of 0:01:27 in the race No. 161? Show his introduction website.",
269
+ "gold_sql": "SELECT DISTINCT T2.forename, T2.surname, T2.url FROM lapTimes AS T1 INNER JOIN drivers AS T2 ON T2.driverId = T1.driverId WHERE T1.raceId = 161 AND T1.time LIKE '1:27%'",
270
+ "baseline_pred": "SELECT drivers.url FROM lapTimes JOIN drivers ON lapTimes.driverId = drivers.driverId WHERE lapTimes.raceId = 161 AND lapTimes.time LIKE '1:27%'",
271
+ "alt_pred": "SELECT drivers.url FROM drivers JOIN lapTimes ON drivers.driverId = lapTimes.driverId WHERE lapTimes.raceId = 161 AND lapTimes.time LIKE '1:27%'",
272
+ "alt_confidence": 0.9,
273
+ "baseline_match": false,
274
+ "alt_match": false,
275
+ "vote_match": false,
276
+ "vote_source": "critique-retry",
277
+ "elapsed_ms": 1124.1408999994746
278
+ },
279
+ {
280
+ "question_id": 894,
281
+ "db_id": "formula_1",
282
+ "difficulty": "moderate",
283
+ "question": "What is the best lap time recorded? List the driver and race with such recorded lap time.",
284
+ "gold_sql": "SELECT T2.milliseconds, T1.forename, T1.surname, T3.name FROM drivers AS T1 INNER JOIN lapTimes AS T2 ON T1.driverId = T2.driverId INNER JOIN races AS T3 ON T2.raceId = T3.raceId ORDER BY T2.milliseconds ASC LIMIT 1",
285
+ "baseline_pred": "SELECT drivers.forename, drivers.surname, races.name FROM lapTimes JOIN drivers ON lapTimes.driverId = drivers.driverId JOIN races ON lapTimes.raceId = races.raceId WHERE lapTimes.milliseconds = (SELECT MIN(milliseconds) FROM lapTimes) LIMIT 1",
286
+ "alt_pred": "SELECT drivers.forename, drivers.surname, races.name FROM lapTimes JOIN drivers ON lapTimes.driverId = drivers.driverId JOIN races ON lapTimes.raceId = races.raceId WHERE lapTimes.milliseconds = (SELECT MIN(milliseconds) FROM lapTimes)",
287
+ "alt_confidence": 0.9,
288
+ "baseline_match": false,
289
+ "alt_match": false,
290
+ "vote_match": false,
291
+ "vote_source": "critique-retry",
292
+ "elapsed_ms": 2223.164500002895
293
+ },
294
+ {
295
+ "question_id": 896,
296
+ "db_id": "formula_1",
297
+ "difficulty": "challenging",
298
+ "question": "Calculate the percentage whereby Hamilton was not at the 1st track of the the f1 circuit since 2010.",
299
+ "gold_sql": "SELECT CAST(COUNT(CASE WHEN T2.position <> 1 THEN T2.position END) AS REAL) * 100 / COUNT(T2.driverStandingsId) FROM races AS T1 INNER JOIN driverStandings AS T2 ON T2.raceId = T1.raceId INNER JOIN drivers AS T3 ON T3.driverId = T2.driverId WHERE T3.surname = 'Hamilton' AND T1.year >= 2010",
300
+ "baseline_pred": "SELECT CAST(SUM(CASE WHEN r.positionOrder > 1 THEN 1 ELSE 0 END) AS REAL) * 100.0 / COUNT(*) FROM results r INNER JOIN drivers d ON r.driverId = d.driverId INNER JOIN races ra ON r.raceId = ra.raceId WHERE d.surname = 'Hamilton' AND ra.year >= 2010",
301
+ "alt_pred": "SELECT CAST(COUNT(CASE WHEN position > 1 THEN 1 END) AS REAL) * 100 / COUNT(*) FROM results JOIN drivers ON results.driverId = drivers.driverId JOIN races ON results.raceId = races.raceId WHERE drivers.surname = 'Hamilton' AND races.year >= 2010",
302
+ "alt_confidence": 0.9,
303
+ "baseline_match": false,
304
+ "alt_match": false,
305
+ "vote_match": false,
306
+ "vote_source": "critique-retry",
307
+ "elapsed_ms": 2146.8490999977803
308
+ },
309
+ {
310
+ "question_id": 902,
311
+ "db_id": "formula_1",
312
+ "difficulty": "simple",
313
+ "question": "Which race was Alex Yoong in when he was in track number less than 20?",
314
+ "gold_sql": "SELECT T1.name FROM races AS T1 INNER JOIN driverStandings AS T2 ON T2.raceId = T1.raceId INNER JOIN drivers AS T3 ON T3.driverId = T2.driverId WHERE T3.forename = 'Alex' AND T3.surname = 'Yoong' AND T2.position < 20",
315
+ "baseline_pred": "SELECT races.name FROM races JOIN results ON races.raceId = results.raceId JOIN drivers ON results.driverId = drivers.driverId WHERE drivers.forename = 'Alex' AND drivers.surname = 'Yoong' AND results.position < 20",
316
+ "alt_pred": "SELECT races.name FROM races JOIN results ON races.raceId = results.raceId JOIN drivers ON results.driverId = drivers.driverId WHERE drivers.forename = 'Alex' AND drivers.surname = 'Yoong' AND results.position < 20",
317
+ "alt_confidence": 0.8,
318
+ "baseline_match": false,
319
+ "alt_match": false,
320
+ "vote_match": false,
321
+ "vote_source": "critique-retry",
322
+ "elapsed_ms": 1287.2468999994453
323
+ },
324
+ {
325
+ "question_id": 930,
326
+ "db_id": "formula_1",
327
+ "difficulty": "simple",
328
+ "question": "In which Formula_1 race did Lewis Hamilton rank the highest?",
329
+ "gold_sql": "SELECT name FROM races WHERE raceId IN ( SELECT raceId FROM results WHERE rank = 1 AND driverId = ( SELECT driverId FROM drivers WHERE forename = 'Lewis' AND surname = 'Hamilton' ) )",
330
+ "baseline_pred": "SELECT races.name FROM races JOIN results ON races.raceId = results.raceId JOIN drivers ON results.driverId = drivers.driverId WHERE drivers.forename = 'Lewis' AND drivers.surname = 'Hamilton' ORDER BY results.rank ASC LIMIT 1",
331
+ "alt_pred": "SELECT races.name FROM races JOIN results ON races.raceId = results.raceId JOIN drivers ON results.driverId = drivers.driverId WHERE drivers.forename = 'Lewis' AND drivers.surname = 'Hamilton' ORDER BY results.rank ASC LIMIT 1",
332
+ "alt_confidence": 0.9,
333
+ "baseline_match": false,
334
+ "alt_match": false,
335
+ "vote_match": false,
336
+ "vote_source": "critique-retry",
337
+ "elapsed_ms": 1316.0355999971216
338
+ },
339
+ {
340
+ "question_id": 988,
341
+ "db_id": "formula_1",
342
+ "difficulty": "challenging",
343
+ "question": "List down top 3 German drivers who has the shortest average pit stop duration and were born between 1980-1985.",
344
+ "gold_sql": "SELECT T2.forename, T2.surname FROM pitStops AS T1 INNER JOIN drivers AS T2 on T1.driverId = T2.driverId WHERE T2.nationality = 'German' AND STRFTIME('%Y', T2.dob) BETWEEN '1980' AND '1985' GROUP BY T2.forename, T2.surname ORDER BY AVG(T1.duration) LIMIT 3",
345
+ "baseline_pred": "SELECT d.forename || ' ' || d.surname AS full_name FROM pitStops p JOIN drivers d ON p.driverId = d.driverId WHERE strftime('%Y', d.dob) BETWEEN '1980' AND '1985' AND d.nationality = 'German' GROUP BY d.driverId, d.forename, d.surname ORDER BY AVG(p.milliseconds) ASC LIMIT 3",
346
+ "alt_pred": "SELECT drivers.forename, drivers.surname FROM drivers JOIN pitStops ON drivers.driverId = pitStops.driverId WHERE drivers.nationality = 'German' AND strftime('%Y', drivers.dob) BETWEEN '1980' AND '1985' GROUP BY drivers.driverId ORDER BY AVG(pitStops.milliseconds) ASC LIMIT 3",
347
+ "alt_confidence": 0.9,
348
+ "baseline_match": false,
349
+ "alt_match": false,
350
+ "vote_match": false,
351
+ "vote_source": "critique-retry",
352
+ "elapsed_ms": 1455.3177999987383
353
+ },
354
+ {
355
+ "question_id": 990,
356
+ "db_id": "formula_1",
357
+ "difficulty": "challenging",
358
+ "question": "What is the constructor reference name of the champion in the 2009 Singapore Grand Prix? Please give its website.",
359
+ "gold_sql": "SELECT T3.constructorRef, T3.url FROM results AS T1 INNER JOIN races AS T2 on T1.raceId = T2.raceId INNER JOIN constructors AS T3 on T1.constructorId = T3.constructorId WHERE T2.name = 'Singapore Grand Prix' AND T2.year = 2009 AND T1.time LIKE '_:%:__.___'",
360
+ "baseline_pred": "SELECT constructors.constructorRef, constructors.url FROM results INNER JOIN races ON results.raceId = races.raceId INNER JOIN constructors ON results.constructorId = constructors.constructorId WHERE races.year = 2009 AND races.name = 'Singapore Grand Prix' AND results.positionOrder = 1 ORDER BY results.time DESC LIMIT 1",
361
+ "alt_pred": "SELECT constructors.constructorRef, constructors.url FROM constructors JOIN results ON constructors.constructorId = results.constructorId JOIN races ON results.raceId = races.raceId WHERE races.year = 2009 AND races.name = 'Singapore Grand Prix' AND results.position = 1",
362
+ "alt_confidence": 0.9,
363
+ "baseline_match": false,
364
+ "alt_match": false,
365
+ "vote_match": false,
366
+ "vote_source": "critique-retry",
367
+ "elapsed_ms": 2576.8675999970583
368
+ },
369
+ {
370
+ "question_id": 1029,
371
+ "db_id": "european_football_2",
372
+ "difficulty": "moderate",
373
+ "question": "What are the speed in which attacks are put together of the top 4 teams with the highest build Up Play Speed?",
374
+ "gold_sql": "SELECT t1.buildUpPlaySpeed FROM Team_Attributes AS t1 INNER JOIN Team AS t2 ON t1.team_api_id = t2.team_api_id ORDER BY t1.buildUpPlaySpeed ASC LIMIT 4",
375
+ "baseline_pred": "SELECT buildUpPlaySpeed FROM Team_Attributes ORDER BY buildUpPlaySpeed DESC LIMIT 4",
376
+ "alt_pred": "SELECT Team.team_long_name, Team_Attributes.buildUpPlaySpeed FROM Team JOIN Team_Attributes ON Team.team_api_id = Team_Attributes.team_api_id ORDER BY Team_Attributes.buildUpPlaySpeed DESC LIMIT 4",
377
+ "alt_confidence": 0.9,
378
+ "baseline_match": false,
379
+ "alt_match": false,
380
+ "vote_match": false,
381
+ "vote_source": "critique-retry",
382
+ "elapsed_ms": 2120.9820000003674
383
+ },
384
+ {
385
+ "question_id": 1036,
386
+ "db_id": "european_football_2",
387
+ "difficulty": "challenging",
388
+ "question": "List the long name of teams with above-average build-up play passing in 2012.",
389
+ "gold_sql": "SELECT DISTINCT t4.team_long_name FROM Team_Attributes AS t3 INNER JOIN Team AS t4 ON t3.team_api_id = t4.team_api_id WHERE SUBSTR(t3.`date`, 1, 4) = '2012' AND t3.buildUpPlayPassing > ( SELECT CAST(SUM(t2.buildUpPlayPassing) AS REAL) / COUNT(t1.id) FROM Team AS t1 INNER JOIN Team_Attributes AS t2 ON t1.team_api_id = t2.team_api_id WHERE STRFTIME('%Y',t2.`date`) = '2012')",
390
+ "baseline_pred": "SELECT T1.team_long_name FROM Team AS T1 INNER JOIN Team_Attributes AS T2 ON T1.team_api_id = T2.team_api_id WHERE strftime('%Y', T2.date) = '2012' AND T2.buildUpPlayPassing > (SELECT AVG(buildUpPlayPassing) FROM Team_Attributes WHERE buildUpPlayPassing IS NOT NULL AND strftime('%Y', date) = '2012')",
391
+ "alt_pred": "SELECT T1.team_long_name FROM Team AS T1 JOIN Team_Attributes AS T2 ON T1.team_api_id = T2.team_api_id WHERE T2.buildUpPlayPassing > (SELECT AVG(buildUpPlayPassing) FROM Team_Attributes WHERE buildUpPlayPassing IS NOT NULL AND strftime('%Y', date) = '2012') AND strftime('%Y', T2.date) = '2012'",
392
+ "alt_confidence": 0.9,
393
+ "baseline_match": false,
394
+ "alt_match": false,
395
+ "vote_match": false,
396
+ "vote_source": "critique-retry",
397
+ "elapsed_ms": 1607.06680000294
398
+ },
399
+ {
400
+ "question_id": 1094,
401
+ "db_id": "european_football_2",
402
+ "difficulty": "challenging",
403
+ "question": "How much higher in percentage is Ariel Borysiuk's overall rating than that of Paulin Puel?",
404
+ "gold_sql": "SELECT (SUM(CASE WHEN t1.player_name = 'Ariel Borysiuk' THEN t2.overall_rating ELSE 0 END) * 1.0 - SUM(CASE WHEN t1.player_name = 'Paulin Puel' THEN t2.overall_rating ELSE 0 END)) * 100 / SUM(CASE WHEN t1.player_name = 'Paulin Puel' THEN t2.overall_rating ELSE 0 END) FROM Player AS t1 INNER JOIN Player_Attributes AS t2 ON t1.player_api_id = t2.player_api_id",
405
+ "baseline_pred": "SELECT CAST((MAX(CASE WHEN p.player_name = 'Ariel Borysiuk' THEN pa.overall_rating END) - MAX(CASE WHEN p.player_name = 'Paulin Puel' THEN pa.overall_rating END)) * 100.0 / MAX(CASE WHEN p.player_name = 'Paulin Puel' THEN pa.overall_rating END) AS REAL) AS percentage_higher FROM Player p INNER JOIN Player_Attributes pa ON p.player_api_id = pa.player_api_id WHERE p.player_name IN ('Ariel Borysiuk', 'Paulin Puel') AND pa.overall_rating IS NOT NULL",
406
+ "alt_pred": "SELECT (T1.overall_rating - T2.overall_rating) * 100.0 / T2.overall_rating AS percentage_higher FROM Player_Attributes AS T1 JOIN Player AS T2 ON T1.player_api_id = T2.player_api_id WHERE T2.player_name = 'Ariel Borysiuk' AND T1.player_name = 'Paulin Puel'",
407
+ "alt_confidence": 1.0,
408
+ "baseline_match": false,
409
+ "alt_match": false,
410
+ "vote_match": false,
411
+ "vote_source": "critique-retry",
412
+ "elapsed_ms": 3268.8476000002993
413
+ },
414
+ {
415
+ "question_id": 1144,
416
+ "db_id": "european_football_2",
417
+ "difficulty": "simple",
418
+ "question": "Please state the finishing rate and curve score of the player who has the heaviest weight.",
419
+ "gold_sql": "SELECT id, finishing, curve FROM Player_Attributes WHERE player_api_id = ( SELECT player_api_id FROM Player ORDER BY weight DESC LIMIT 1 ) LIMIT 1",
420
+ "baseline_pred": "SELECT finishing, curve FROM Player_Attributes JOIN Player ON Player_Attributes.player_api_id = Player.player_api_id WHERE Player.weight = (SELECT MAX(weight) FROM Player)",
421
+ "alt_pred": "SELECT Player_Attributes.finishing, Player_Attributes.curve FROM Player_Attributes JOIN Player ON Player_Attributes.player_api_id = Player.player_api_id WHERE Player.weight = (SELECT MAX(weight) FROM Player)",
422
+ "alt_confidence": 0.9,
423
+ "baseline_match": false,
424
+ "alt_match": false,
425
+ "vote_match": false,
426
+ "vote_source": "critique-retry",
427
+ "elapsed_ms": 2071.239600001718
428
+ },
429
+ {
430
+ "question_id": 1168,
431
+ "db_id": "thrombosis_prediction",
432
+ "difficulty": "challenging",
433
+ "question": "The oldest SJS patient's medical laboratory work was completed on what date, and what age was the patient when they initially arrived at the hospital?",
434
+ "gold_sql": "SELECT T1.Date, STRFTIME('%Y', T2.`First Date`) - STRFTIME('%Y', T2.Birthday),T2.Birthday FROM Laboratory AS T1 INNER JOIN Patient AS T2 ON T1.ID = T2.ID WHERE T2.Diagnosis = 'SJS' AND T2.Birthday IS NOT NULL ORDER BY T2.Birthday ASC LIMIT 1",
435
+ "baseline_pred": "SELECT L.Date, (strftime('%Y', P.\"First Date\") - strftime('%Y', P.Birthday)) FROM Patient P INNER JOIN Laboratory L ON P.ID = L.ID WHERE P.Diagnosis = 'SJS' AND P.Birthday = (SELECT MIN(Birthday) FROM Patient WHERE Diagnosis = 'SJS') ORDER BY L.Date ASC LIMIT 1",
436
+ "alt_pred": "SELECT Laboratory.Date, (STRFTIME('%Y', Patient.`First Date`) - STRFTIME('%Y', Patient.Birthday)) AS AgeAtAdmission FROM Examination JOIN Patient ON Examination.ID = Patient.ID JOIN Laboratory ON Examination.ID = Laboratory.ID WHERE Examination.Diagnosis = 'SjS' ORDER BY Patient.Birthday ASC LIMIT 1",
437
+ "alt_confidence": 0.9,
438
+ "baseline_match": false,
439
+ "alt_match": false,
440
+ "vote_match": false,
441
+ "vote_source": "critique-retry",
442
+ "elapsed_ms": 3766.808599997603
443
+ },
444
+ {
445
+ "question_id": 1205,
446
+ "db_id": "thrombosis_prediction",
447
+ "difficulty": "moderate",
448
+ "question": "Was the patient with the number 57266's uric acid within a normal range?",
449
+ "gold_sql": "SELECT CASE WHEN (T1.SEX = 'F' AND T2.UA > 6.5) OR (T1.SEX = 'M' AND T2.UA > 8.0) THEN true ELSE false END FROM Patient AS T1 INNER JOIN Laboratory AS T2 ON T1.ID = T2.ID WHERE T1.ID = 57266",
450
+ "baseline_pred": "SELECT CASE WHEN (T1.UA > 8.0 AND T2.SEX = 'M') OR (T1.UA > 6.5 AND T2.SEX = 'F') THEN 'Yes' ELSE 'No' END AS is_normal FROM Laboratory AS T1 INNER JOIN Patient AS T2 ON T1.ID = T2.ID WHERE T1.ID = 57266 LIMIT 1",
451
+ "alt_pred": "SELECT CASE WHEN (T1.SEX = 'M' AND T2.UA > 8.0) OR (T1.SEX = 'F' AND T2.UA > 6.5) THEN 'Yes' ELSE 'No' END AS 'Uric Acid Normal' FROM Patient AS T1 INNER JOIN Laboratory AS T2 ON T1.ID = T2.ID WHERE T1.ID = 57266",
452
+ "alt_confidence": 0.9,
453
+ "baseline_match": false,
454
+ "alt_match": false,
455
+ "vote_match": false,
456
+ "vote_source": "critique-retry",
457
+ "elapsed_ms": 10207.424599997466
458
+ },
459
+ {
460
+ "question_id": 1235,
461
+ "db_id": "thrombosis_prediction",
462
+ "difficulty": "moderate",
463
+ "question": "What are the patient's diagnosis for those who has lower red blood blood cell? State their ID and age.",
464
+ "gold_sql": "SELECT DISTINCT T1.Diagnosis, T1.ID , STRFTIME('%Y', CURRENT_TIMESTAMP) -STRFTIME('%Y', T1.Birthday) FROM Patient AS T1 INNER JOIN Laboratory AS T2 ON T1.ID = T2.ID WHERE T2.RBC < 3.5",
465
+ "baseline_pred": "SELECT P.ID, (strftime('%Y', 'now') - strftime('%Y', P.Birthday)) AS age, P.Diagnosis FROM Patient AS P JOIN Laboratory AS L ON P.ID = L.ID WHERE L.RBC < 3.5",
466
+ "alt_pred": "SELECT Patient.ID, strftime('%Y', 'now') - strftime('%Y', Patient.Birthday) AS age, Patient.Diagnosis FROM Patient JOIN Laboratory ON Patient.ID = Laboratory.ID WHERE Laboratory.RBC < 3.5",
467
+ "alt_confidence": 1.0,
468
+ "baseline_match": false,
469
+ "alt_match": false,
470
+ "vote_match": false,
471
+ "vote_source": "critique-retry",
472
+ "elapsed_ms": 3232.0370999987063
473
+ },
474
+ {
475
+ "question_id": 1247,
476
+ "db_id": "thrombosis_prediction",
477
+ "difficulty": "challenging",
478
+ "question": "Among the male patients who have a normal level of white blood cells, how many of them have an abnormal fibrinogen level?",
479
+ "gold_sql": "SELECT COUNT(DISTINCT T1.ID) FROM Patient AS T1 INNER JOIN Laboratory AS T2 ON T1.ID = T2.ID WHERE T2.FG <= 150 OR T2.FG >= 450 AND T2.WBC > 3.5 AND T2.WBC < 9.0 AND T1.SEX = 'M'",
480
+ "baseline_pred": "SELECT COUNT(DISTINCT L.ID) FROM Patient P INNER JOIN Laboratory L ON P.ID = L.ID WHERE P.SEX = 'M' AND L.WBC > 3.5 AND L.WBC < 9.0 AND (L.FG <= 150 OR L.FG >= 450)",
481
+ "alt_pred": "SELECT COUNT(DISTINCT T1.ID) FROM Examination AS T1 JOIN Patient AS T2 ON T1.ID = T2.ID JOIN Laboratory AS T3 ON T1.ID = T3.ID WHERE T2.SEX = 'M' AND T3.WBC > 3.5 AND T3.WBC < 9.0 AND (T3.FG <= 150 OR T3.FG >= 450)",
482
+ "alt_confidence": 0.9,
483
+ "baseline_match": false,
484
+ "alt_match": false,
485
+ "vote_match": false,
486
+ "vote_source": "critique-retry",
487
+ "elapsed_ms": 2186.199299998407
488
+ },
489
+ {
490
+ "question_id": 1251,
491
+ "db_id": "thrombosis_prediction",
492
+ "difficulty": "simple",
493
+ "question": "How many patients with an Ig G higher than normal?",
494
+ "gold_sql": "SELECT COUNT(DISTINCT T1.ID) FROM Patient AS T1 INNER JOIN Laboratory AS T2 ON T1.ID = T2.ID INNER JOIN Examination AS T3 ON T3.ID = T2.ID WHERE T2.IGG >= 2000",
495
+ "baseline_pred": "SELECT COUNT(DISTINCT ID) FROM Laboratory WHERE IGG >= 2000",
496
+ "alt_pred": "SELECT COUNT(DISTINCT Patient.ID) FROM Patient JOIN Laboratory ON Patient.ID = Laboratory.ID WHERE Laboratory.IGG >= 2000",
497
+ "alt_confidence": 1.0,
498
+ "baseline_match": false,
499
+ "alt_match": false,
500
+ "vote_match": false,
501
+ "vote_source": "critique-retry",
502
+ "elapsed_ms": 2756.7782000005536
503
+ },
504
+ {
505
+ "question_id": 1254,
506
+ "db_id": "thrombosis_prediction",
507
+ "difficulty": "moderate",
508
+ "question": "How many patients with a normal Ig A level came to the hospital after 1990/1/1?",
509
+ "gold_sql": "SELECT COUNT(T1.ID) FROM Patient AS T1 INNER JOIN Laboratory AS T2 ON T1.ID = T2.ID WHERE T2.IGA BETWEEN 80 AND 500 AND strftime('%Y', T1.`First Date`) > '1990'",
510
+ "baseline_pred": "SELECT COUNT(DISTINCT P.ID) FROM Patient P JOIN Laboratory L ON P.ID = L.ID WHERE L.IGA > 80 AND L.IGA < 500 AND P.`First Date` >= '1990-01-01'",
511
+ "alt_pred": "SELECT COUNT(DISTINCT Patient.ID) FROM Patient JOIN Examination ON Patient.ID = Examination.ID WHERE Examination.`aCL IgA` > 80 AND Examination.`aCL IgA` < 500 AND Patient.`First Date` >= '1990-01-01'",
512
+ "alt_confidence": 1.0,
513
+ "baseline_match": false,
514
+ "alt_match": false,
515
+ "vote_match": false,
516
+ "vote_source": "critique-retry",
517
+ "elapsed_ms": 3027.875600000698
518
+ },
519
+ {
520
+ "question_id": 1275,
521
+ "db_id": "thrombosis_prediction",
522
+ "difficulty": "moderate",
523
+ "question": "Among the patients who has a normal level of anti-centromere and a normal level of anti-SSB, how many of them are male?",
524
+ "gold_sql": "SELECT COUNT(DISTINCT T1.ID) FROM Patient AS T1 INNER JOIN Laboratory AS T2 ON T1.ID = T2.ID WHERE T2.CENTROMEA IN ('negative', '0') AND T2.SSB IN ('negative', '0') AND T1.SEX = 'M'",
525
+ "baseline_pred": "SELECT COUNT(DISTINCT P.ID) FROM Patient P JOIN Examination E ON P.ID = E.ID WHERE E.CENTROMEA IN ('-', '+-') AND E.SSB IN ('-', '+-') AND P.SEX = 'M'",
526
+ "alt_pred": "SELECT COUNT(DISTINCT T1.ID) FROM Patient AS T1 JOIN Laboratory AS T2 ON T1.ID = T2.ID WHERE T2.CENTROMEA IN ('-', '+-') AND T2.SSB IN ('-', '+-') AND T1.SEX = 'M'",
527
+ "alt_confidence": 0.9,
528
+ "baseline_match": false,
529
+ "alt_match": false,
530
+ "vote_match": false,
531
+ "vote_source": "critique-retry",
532
+ "elapsed_ms": 1953.2646000006935
533
+ },
534
+ {
535
+ "question_id": 1399,
536
+ "db_id": "student_club",
537
+ "difficulty": "moderate",
538
+ "question": "Did Maya Mclean attend the 'Women's Soccer' event?",
539
+ "gold_sql": "SELECT CASE WHEN T3.event_name = 'Women''s Soccer' THEN 'YES' END AS result FROM member AS T1 INNER JOIN attendance AS T2 ON T1.member_id = T2.link_to_member INNER JOIN event AS T3 ON T2.link_to_event = T3.event_id WHERE T1.first_name = 'Maya' AND T1.last_name = 'Mclean'",
540
+ "baseline_pred": "SELECT COUNT(*) > 0 AS attended FROM attendance AS a JOIN member AS m ON a.link_to_member = m.member_id JOIN event AS e ON a.link_to_event = e.event_id WHERE m.first_name = 'Maya' AND m.last_name = 'Mclean' AND e.event_name = 'Women''s Soccer'",
541
+ "alt_pred": "SELECT COUNT(*) FROM attendance JOIN member ON attendance.link_to_member = member.member_id JOIN event ON attendance.link_to_event = event.event_id WHERE member.first_name = 'Maya' AND member.last_name = 'Mclean' AND event.event_name = 'Women''s Soccer'",
542
+ "alt_confidence": 0.8,
543
+ "baseline_match": false,
544
+ "alt_match": false,
545
+ "vote_match": false,
546
+ "vote_source": "critique-retry",
547
+ "elapsed_ms": 2330.6733000026725
548
+ },
549
+ {
550
+ "question_id": 1404,
551
+ "db_id": "student_club",
552
+ "difficulty": "moderate",
553
+ "question": "Identify the type of expenses and their total value approved for 'October Meeting' event.",
554
+ "gold_sql": "SELECT T1.type, SUM(T3.cost) FROM event AS T1 INNER JOIN budget AS T2 ON T1.event_id = T2.link_to_event INNER JOIN expense AS T3 ON T2.budget_id = T3.link_to_budget WHERE T1.event_name = 'October Meeting'",
555
+ "baseline_pred": "SELECT expense.expense_description AS type, SUM(expense.cost) AS total_value FROM expense JOIN budget ON expense.link_to_budget = budget.budget_id JOIN event ON budget.link_to_event = event.event_id WHERE event.event_name = 'October Meeting' AND expense.approved = 'true' GROUP BY expense.expense_description",
556
+ "alt_pred": "SELECT expense.expense_description, SUM(expense.cost) AS total_value FROM expense JOIN budget ON expense.link_to_budget = budget.budget_id JOIN event ON budget.link_to_event = event.event_id WHERE event.event_name = 'October Meeting' AND expense.approved = 'true' GROUP BY expense.expense_description",
557
+ "alt_confidence": 0.8,
558
+ "baseline_match": false,
559
+ "alt_match": false,
560
+ "vote_match": false,
561
+ "vote_source": "critique-retry",
562
+ "elapsed_ms": 1393.583299999591
563
+ },
564
+ {
565
+ "question_id": 1525,
566
+ "db_id": "debit_card_specializing",
567
+ "difficulty": "simple",
568
+ "question": "What is the percentage of the customers who used EUR in 2012/8/25?",
569
+ "gold_sql": "SELECT CAST(SUM(IIF(T2.Currency = 'EUR', 1, 0)) AS FLOAT) * 100 / COUNT(T1.CustomerID) FROM transactions_1k AS T1 INNER JOIN customers AS T2 ON T1.CustomerID = T2.CustomerID WHERE T1.Date = '2012-08-25'",
570
+ "baseline_pred": "SELECT CAST(COUNT(DISTINCT t.CustomerID) AS REAL) * 100 / (SELECT COUNT(*) FROM customers) FROM transactions_1k t JOIN customers c ON t.CustomerID = c.CustomerID WHERE t.Date = '2012-08-25' AND c.Currency = 'EUR'",
571
+ "alt_pred": "SELECT CAST(SUM(IIF(customers.Currency = 'EUR', 1, 0)) AS REAL) * 100 / COUNT(customers.CustomerID) FROM customers JOIN transactions_1k ON customers.CustomerID = transactions_1k.CustomerID WHERE transactions_1k.Date = '2012-08-25'",
572
+ "alt_confidence": 0.9,
573
+ "baseline_match": false,
574
+ "alt_match": true,
575
+ "vote_match": true,
576
+ "vote_source": "critique-retry",
577
+ "elapsed_ms": 2390.831500000786
578
+ },
579
+ {
580
+ "question_id": 1529,
581
+ "db_id": "debit_card_specializing",
582
+ "difficulty": "moderate",
583
+ "question": "What is the amount spent by customer \"38508\" at the gas stations? How much had the customer spent in January 2012?",
584
+ "gold_sql": "SELECT SUM(T1.Price ) , SUM(IIF(T3.Date = '201201', T1.Price, 0)) FROM transactions_1k AS T1 INNER JOIN gasstations AS T2 ON T1.GasStationID = T2.GasStationID INNER JOIN yearmonth AS T3 ON T1.CustomerID = T3.CustomerID WHERE T1.CustomerID = '38508'",
585
+ "baseline_pred": "SELECT SUM(Amount) AS TotalSpent FROM transactions_1k WHERE CustomerID = 38508 AND GasStationID IS NOT NULL UNION ALL SELECT SUM(Consumption) AS TotalSpent FROM yearmonth WHERE CustomerID = 38508 AND Date = '201201'",
586
+ "alt_pred": "SELECT SUM(transactions_1k.Amount) AS total_amount_spent FROM transactions_1k WHERE transactions_1k.CustomerID = 38508 AND transactions_1k.Date LIKE '2012-01%'",
587
+ "alt_confidence": 0.8,
588
+ "baseline_match": false,
589
+ "alt_match": false,
590
+ "vote_match": false,
591
+ "vote_source": "critique-retry",
592
+ "elapsed_ms": 2107.02289999972
593
+ },
594
+ {
595
+ "question_id": 1531,
596
+ "db_id": "debit_card_specializing",
597
+ "difficulty": "moderate",
598
+ "question": "Who is the top spending customer and how much is the average price per single item purchased by this customer? What currency was being used?",
599
+ "gold_sql": "SELECT T2.CustomerID, SUM(T2.Price / T2.Amount), T1.Currency FROM customers AS T1 INNER JOIN transactions_1k AS T2 ON T1.CustomerID = T2.CustomerID WHERE T2.CustomerID = ( SELECT CustomerID FROM yearmonth ORDER BY Consumption DESC LIMIT 1 ) GROUP BY T2.CustomerID, T1.Currency",
600
+ "baseline_pred": "SELECT customers.CustomerID, SUM(transactions_1k.Price) / SUM(transactions_1k.Amount) AS avg_price_per_item, customers.Currency FROM transactions_1k JOIN customers ON transactions_1k.CustomerID = customers.CustomerID GROUP BY transactions_1k.CustomerID, customers.Currency ORDER BY SUM(transactions_1k.Price) DESC LIMIT 1",
601
+ "alt_pred": "SELECT customers.CustomerID, customers.Currency, SUM(transactions_1k.Price) / SUM(transactions_1k.Amount) AS avg_price_per_item FROM transactions_1k JOIN customers ON transactions_1k.CustomerID = customers.CustomerID GROUP BY transactions_1k.CustomerID, customers.Currency ORDER BY SUM(transactions_1k.Price) DESC LIMIT 1",
602
+ "alt_confidence": 0.9,
603
+ "baseline_match": false,
604
+ "alt_match": false,
605
+ "vote_match": false,
606
+ "vote_source": "critique-retry",
607
+ "elapsed_ms": 2250.0837999978103
608
+ }
609
+ ]
610
+ }
eval/reports/2026-05-17/hybrid-vote-critique-selfcon-sonnet-fewshot5-groq4-mschema-v10.json ADDED
The diff for this file is too large to render. See raw diff
 
src/nl_sql/agent/nodes/_support.py CHANGED
@@ -56,6 +56,61 @@ def parse_generate_sql_output(text: str) -> GenerateSQLOutput:
56
  )
57
 
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  def render_schema_block(
60
  context: ContextBundle | None,
61
  *,
 
56
  )
57
 
58
 
59
+ _M_COL_RE = re.compile(
60
+ r" - (?P<col>[^:]+?):\s+(?P<type>[A-Za-z][A-Za-z0-9_()]*)\s+\[(?P<flags>[^\]]*)\]"
61
+ r"(?:\s*\|\s*nulls=\d+(?:\s*\([^)]+\))?,\s*distinct=\d+)?"
62
+ r"(?:\s*\|\s*samples:\s*(?P<samples>.+))?$"
63
+ )
64
+ _M_FK_RE = re.compile(r" - \(([^)]+)\) -> (\S+?)\(([^)]+)\)")
65
+
66
+
67
+ def render_m_schema(context: ContextBundle | None) -> str:
68
+ """Compact M-Schema rendering (XiYan-SQL style) parsed from chunk text.
69
+
70
+ Replaces verbose table-card dump with: ``table.column (type) [samples]``
71
+ per line plus a trailing FK block. Reduces tokens by ~60% and surfaces
72
+ FK pairs as first-class signal next to columns instead of buried inside
73
+ multi-section cards.
74
+ """
75
+ if context is None:
76
+ return "(no schema context)"
77
+ all_hits = list(context.schema_hits) + list(context.fk_neighbours)
78
+ all_hits.sort(key=lambda h: h.table_name.lower())
79
+ if not all_hits:
80
+ return "(no tables matched)"
81
+ col_lines: list[str] = []
82
+ fk_lines: list[str] = []
83
+ for hit in all_hits:
84
+ table = hit.table_name
85
+ for raw_line in hit.text.splitlines():
86
+ m = _M_COL_RE.match(raw_line)
87
+ if m:
88
+ col = m.group("col").strip()
89
+ col_type = m.group("type")
90
+ flags = (m.group("flags") or "").strip()
91
+ samples = (m.group("samples") or "").strip()
92
+ pk = "PK" in flags.split()
93
+ parts = [f"{table}.{col} ({col_type})"]
94
+ if pk:
95
+ parts.append("[PK]")
96
+ if samples:
97
+ parts.append(f"[{samples}]")
98
+ col_lines.append(" ".join(parts))
99
+ continue
100
+ fk_m = _M_FK_RE.match(raw_line)
101
+ if fk_m:
102
+ local_cols, ref_table, ref_cols = fk_m.groups()
103
+ fk_lines.append(f"{table}.({local_cols}) -> {ref_table}.({ref_cols})")
104
+ blocks: list[str] = ["# Columns", *col_lines] if col_lines else ["(no columns parsed)"]
105
+ if fk_lines:
106
+ blocks.append("\n# Foreign keys")
107
+ blocks.extend(fk_lines)
108
+ appendix = _render_extended_samples_appendix(context.extended_samples)
109
+ if appendix:
110
+ blocks.append(appendix)
111
+ return "\n".join(blocks)
112
+
113
+
114
  def render_schema_block(
115
  context: ContextBundle | None,
116
  *,
src/nl_sql/agent/nodes/generate_sql.py CHANGED
@@ -1,67 +1,76 @@
1
- """Node: ask codestral (or any LLMProvider) for SQL given the schema context.
2
-
3
- Builds the prompt from the active context bundle, dispatches to the provider,
4
- parses the JSON response into a `GenerateSQLOutput`. The same node powers the
5
- *initial* generation pass β€” the repair pass is a separate node that calls
6
- this same provider with a different prompt.
7
- """
8
-
9
- from __future__ import annotations
10
-
11
- from collections.abc import Callable
12
-
13
- from nl_sql.agent.nodes._support import (
14
- parse_generate_sql_output,
15
- render_fewshot_block,
16
- render_schema_block,
17
- )
18
- from nl_sql.agent.prompts import load_prompt
19
- from nl_sql.agent.state import PipelineState
20
- from nl_sql.llm.providers.base import GenerateRequest, LLMProvider
21
-
22
-
23
- def make_generate_sql_node(
24
- provider: LLMProvider,
25
- *,
26
- max_tokens: int = 1024,
27
- temperature: float = 0.0,
28
- sort_schema_block: bool = False,
29
- ) -> Callable[[PipelineState], PipelineState]:
30
- def node(state: PipelineState) -> PipelineState:
31
- question = state.get("question", "")
32
- dialect = state.get("dialect", "sqlite")
33
- context = state.get("context")
34
- plan_raw = (state.get("plan") or "").strip()
35
- plan_block = plan_raw if plan_raw else "(no plan β€” generate SQL directly from question)"
36
- prompt = load_prompt(
37
- "generate_sql",
38
- dialect=dialect,
39
- schema_block=render_schema_block(context, sort_alphabetically=sort_schema_block),
40
- fewshot_block=render_fewshot_block(context),
41
- plan_block=plan_block,
42
- question=question,
43
- )
44
- response = provider.generate(
45
- GenerateRequest(prompt=prompt, max_tokens=max_tokens, temperature=temperature)
46
- )
47
- parsed = parse_generate_sql_output(response.text)
48
- trace = list(state.get("trace") or [])
49
- trace.append(
50
- {
51
- "node": "generate_sql",
52
- "model": response.model,
53
- "confidence": parsed.confidence,
54
- "tables_used": list(parsed.tables_used),
55
- "input_tokens": response.input_tokens,
56
- "output_tokens": response.output_tokens,
57
- }
58
- )
59
- # Reset any stale outcome / error from a previous repair iteration.
60
- return {
61
- "generated": parsed,
62
- "outcome": None,
63
- "last_error": "",
64
- "trace": trace,
65
- }
66
-
67
- return node
 
 
 
 
 
 
 
 
 
 
1
+ """Node: ask codestral (or any LLMProvider) for SQL given the schema context.
2
+
3
+ Builds the prompt from the active context bundle, dispatches to the provider,
4
+ parses the JSON response into a `GenerateSQLOutput`. The same node powers the
5
+ *initial* generation pass β€” the repair pass is a separate node that calls
6
+ this same provider with a different prompt.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from collections.abc import Callable
12
+
13
+ from nl_sql.agent.nodes._support import (
14
+ parse_generate_sql_output,
15
+ render_fewshot_block,
16
+ render_m_schema,
17
+ render_schema_block,
18
+ )
19
+ from nl_sql.agent.prompts import load_prompt
20
+ from nl_sql.agent.state import PipelineState
21
+ from nl_sql.llm.providers.base import GenerateRequest, LLMProvider
22
+
23
+
24
+ def make_generate_sql_node(
25
+ provider: LLMProvider,
26
+ *,
27
+ max_tokens: int = 1024,
28
+ temperature: float = 0.0,
29
+ sort_schema_block: bool = False,
30
+ ) -> Callable[[PipelineState], PipelineState]:
31
+ def node(state: PipelineState) -> PipelineState:
32
+ question = state.get("question", "")
33
+ dialect = state.get("dialect", "sqlite")
34
+ context = state.get("context")
35
+ plan_raw = (state.get("plan") or "").strip()
36
+ plan_block = plan_raw if plan_raw else "(no plan β€” generate SQL directly from question)"
37
+ # Experimental: M-Schema serialization (XiYan-SQL style) β€” compact
38
+ # one-line-per-column with inline samples + trailing FK pairs block.
39
+ # Toggle via env NLSQL_M_SCHEMA=1 to A/B against verbose card layout.
40
+ import os
41
+ if os.environ.get("NLSQL_M_SCHEMA") == "1":
42
+ schema_text = render_m_schema(context)
43
+ else:
44
+ schema_text = render_schema_block(context, sort_alphabetically=sort_schema_block)
45
+ prompt = load_prompt(
46
+ "generate_sql",
47
+ dialect=dialect,
48
+ schema_block=schema_text,
49
+ fewshot_block=render_fewshot_block(context),
50
+ plan_block=plan_block,
51
+ question=question,
52
+ )
53
+ response = provider.generate(
54
+ GenerateRequest(prompt=prompt, max_tokens=max_tokens, temperature=temperature)
55
+ )
56
+ parsed = parse_generate_sql_output(response.text)
57
+ trace = list(state.get("trace") or [])
58
+ trace.append(
59
+ {
60
+ "node": "generate_sql",
61
+ "model": response.model,
62
+ "confidence": parsed.confidence,
63
+ "tables_used": list(parsed.tables_used),
64
+ "input_tokens": response.input_tokens,
65
+ "output_tokens": response.output_tokens,
66
+ }
67
+ )
68
+ # Reset any stale outcome / error from a previous repair iteration.
69
+ return {
70
+ "generated": parsed,
71
+ "outcome": None,
72
+ "last_error": "",
73
+ "trace": trace,
74
+ }
75
+
76
+ return node