Decomposed In-Context Learning of Text-to-SQL with Self-Correction — 把「難題」拆解成 schema linking、分類、生成、自我修正四步,單靠 prompting 就打敗了 fine-tune 的最強模型。
把自然語言問題翻成可執行的 SQL,對人來說直觀,對機器要「完全正確」卻很難。DIN-SQL 問世時,Spider 排行榜的頂端全被 fine-tune 過的模型佔據,LLM 的 in-context prompting 落後一大截。
作者 Pourreza 與 Rafiei 提出一個簡單的疑問:這個差距是「prompting 本質上不行」,還是「大家 prompt 的方式太糟」?先前的 prompting 做法是一步到位——把問題與 schema 一次丟給模型、直接吐 SQL。對單表查詢還算堪用,但一遇到需要多表 JOIN 或巢狀子查詢的題目就崩潰:模型必須同時完成 schema linking、JOIN 推理、子查詢規劃、以及語法正確的程式碼輸出。
核心主張:把單一的生成任務拆成一條由小子問題組成的 pipeline,每個子問題都配上精心設計的 few-shot prompt,並依題目難度調整 prompt。這種「難度感知的拆解」不只追平 fine-tune,還進一步超車。
85.3%
GPT-4,勝過前 SOTA 79.9%(RESDSQL+NatSQL)
55.9%
發表時的新 SOTA
~10%
在三種不同 LLM 上都穩定成立
DIN-SQL 是一條四階段的 prompt chain。每一階段都是獨立的 LLM 呼叫,配自己的 few-shot 範例;前一階段的輸出成為下一階段的 context。
為什麼拆解有用:每個模組面對的是一個更小、定義更清楚的任務,搭配專門針對該任務的示範。分類器的工作不是寫 SQL、只是「路由」;生成器不必猜哪些表相關,因為 schema linking 已經告訴它。錯誤被侷限在局部、可修補,而不是全部糾纏在一起。
每個模組本身就是一個 prompt engineering 的成品。以下說明各模組被要求做什麼,以及作者採用的 prompt 結構。
給定問題與資料庫 schema,模型找出查詢會用到哪些欄位、表、外鍵,以及題目提及的字面值(cell values)。此 prompt 採 chain-of-thought,以經典的 「Let's think step by step」開頭,並用十個 Spider 訓練範例做 grounding。輸出是一個以中括號包住的 Schema_links 清單。
# Schema Linking prompt(結構示意)
Q: "Find the buildings which have rooms with capacity more than 50."
# Let's think step by step. "buildings" -> classroom.building ;
# "capacity" -> classroom.capacity ; "more than 50" -> 50
Schema_links: [classroom.building, classroom.capacity, 50]
為何要獨立出來:消融實驗顯示 schema linking 是最吃重的單一模組。把它拿掉,CodeX 的 EX 從 69.9% 掉到 65.9%——4 個百分點的斷崖(見 §06)。
模型把每個問題路由到三種複雜度類別之一,並對最難的類別把它拆成子問題:
單表。無 JOIN、無巢狀。直接 few-shot 生成。
需要跨表 JOIN,但無子查詢。透過 NatSQL 中間步驟生成。
需要子查詢 / 集合運算(IN、NOT IN、INTERSECT、UNION、EXCEPT)。先拆成子問題。
類別標籤加上要 JOIN 的表集合(巢狀類別還加上子問題列表)一起往下傳。這是整個方法「自適應」的樞紐——生成 prompt 由這個標籤決定。
生成 prompt 的結構隨難度成長:
| 類別 | 示範格式 | 核心想法 |
|---|---|---|
| Easy | <Q, Schema_links, SQL> | 直接對映,無中間步驟。 |
| Non-nested | <Q, Schema_links, NatSQL, SQL> | 先寫 NatSQL,再轉 SQL。 |
| Nested | <Q, Schema_links, {子問題, 子答案}..., NatSQL, SQL> | 先解子查詢,再組合。 |
NatSQL 是什麼?一種建立在 SemQL 之上的中間表示,移除了沒有自然語言對應的 SQL 運算子——JOIN ON、FROM、GROUP BY。因為 NatSQL 更貼近問題的語言,模型做 NL→NatSQL 的橋接比直接 NL→SQL 更可靠,最後再由一個確定性轉換器補完。它同時縮小了 schema linking 的負擔,因為 JOIN 鍵不再需要明寫出來。
把草稿 SQL 回饋給模型,抓那些小 bug:漏了 DISTINCT、掉了 DESC、放錯的聚合函數、多餘的關鍵字。作者用了兩種語氣的 prompt:
語氣要看模型:同一個修正 prompt 幫得了 CodeX,卻會害了 GPT-4。假設一個強模型「有 bug」,會讓它捏造出破壞正確查詢的「修補」。
兩個跨領域 benchmark——Spider(乾淨、學術)與 BIRD(大型、雜亂、貼近真實)——之間共用三種指標。
10,181 題 · 5,693 個相異查詢 · 200 個資料庫、橫跨 138 個領域。切分為 8,659 train / 1,034 dev / 2,147 test,且資料庫互不重疊。依關鍵字數量、巢狀、聚合分成四個難度(easy → extra hard)。
12,751 組問題–SQL · 95 個大型資料庫(33.4 GB)、橫跨 37+ 個專業領域。額外要求外部知識(數值推理、領域事實、同義詞、值的提示)——遠比 Spider 貼近正式生產資料。
把每個 SQL 子句視為集合;每個成分都要與 gold query 相符。對形式嚴格——會懲罰合法的改寫。
執行兩個查詢、比對結果集。只要回傳正確答案的 SQL 都算對。是最主要的頭條指標。
BIRD 專用。以查詢執行的效率去加權「正確的」查詢。只在結果正確時才有定義。
在 Spider test,DIN-SQL + GPT-4 於執行準確率登頂;在 BIRD 上刷新 SOTA。相對於樸素 few-shot prompt 大約多 10 個百分點,而且提升幅度正好集中在題目最難的地方。
| 方法 | EX % | EM % |
|---|---|---|
| DIN-SQL + GPT-4 | 85.3 | 60 |
| RESDSQL-3B + NatSQL (fine-tuned) | 79.9 | 72 |
| DIN-SQL + CodeX Davinci | 78.2 | 57 |
| T5-3B + PICARD (fine-tuned) | 75.1 | 71.9 |
細看這個分裂:DIN-SQL 在 EX 勝出,但在 EM 輸給 fine-tune 過的 RESDSQL。Prompted 模型會寫出正確但形狀不同的 SQL,而 EM 會懲罰這種差異。EX 才是反映真實可用性的指標。
| 方法 | EX % | EM % |
|---|---|---|
| DIN-SQL + GPT-4 | 74.2 | 60.1 |
| DIN-SQL + CodeX Davinci | 69.9 | 57.2 |
| Few-shot GPT-4(baseline) | 67.4 | 54.3 |
| Few-shot CodeX Davinci(baseline) | 61.5 | 50.2 |
| 方法 | Easy | Medium | Hard | Extra | All |
|---|---|---|---|---|---|
| DIN-SQL + GPT-4 | 91.1 | 79.8 | 64.9 | 43.4 | 74.2 |
| Few-shot GPT-4 | 86.7 | 73.1 | 59.2 | 31.9 | 67.4 |
| DIN-SQL + CodeX | 89.1 | 75.6 | 58.0 | 38.6 | 69.9 |
| Few-shot CodeX | 84.7 | 67.3 | 47.1 | 26.5 | 61.5 |
提升集中在難題上。在 Extra hard,GPT-4 從 31.9% → 43.4%(+11.5),CodeX 從 26.5% → 38.6%(+12.1)。Easy 題幾乎沒動(+4)。拆解的價值,正好體現在單一 prompt 溺水的地方。
| 方法 | Dev EX | Dev VES | Test EX | Test VES |
|---|---|---|---|---|
| DIN-SQL + GPT-4 | 50.72 | 58.79 | 55.9 | 59.44 |
| GPT-4(baseline) | 46.35 | 49.77 | 54.89 | 60.77 |
| CodeX | 34.35 | 43.41 | 36.47 | 41.60 |
| T5-3B (fine-tuned) | 23.34 | 25.57 | — | — |
在 BIRD test,DIN-SQL 達到 55.9% EX——新 SOTA——不過注意 GPT-4 baseline 在 test 的 VES 略高(60.77 vs 59.44):DIN-SQL 以些微效率換取明確的準確率勝出。
從 CodeX Davinci pipeline 逐一拿掉模組,顯示出清楚的排序:分類/拆解與 schema linking 最關鍵,自我修正則是較小的打磨。
| 設定 | EX % | Δ |
|---|---|---|
| 完整 DIN-SQL(generic 自我修正) | 69.9 | — |
| − 自我修正 | 67.3 | −2.6 |
| − schema linking | 65.9 | −4.0 |
| 分類 → 僅 decomposed CoT | 68.2 | −1.7 |
| 分類 → 僅 simple few-shot | 63.1 | −6.8 |
結論:把自適應分類器退回成單純 few-shot prompt,代價最大(−6.8);schema linking 是第二根支柱(−4.0);自我修正真實但幅度不大(−2.6)。這套架構的價值在於自適應路由,而不是任何單一巧妙的 prompt。
成本與延遲:作者回報,用 GPT-4 回答一題 Spider,約需 每題 $0.50 與 約 60 秒延遲——這是四次串行 LLM 呼叫、每次都帶著長 few-shot prompt 的後果。對高吞吐量的生產服務並不實際。
靜態示範:few-shot 範例是固定的。作者指出 自適應示範選擇——依進來的問題檢索相符的範例——是有前景的方向。
錯誤傳遞:因為模組是串接的,一次 schema linking 失誤或錯誤的複雜度標籤,會毒害下游所有步驟。自我修正只能抓語法層級的小失誤,抓不到上游的路由錯誤。
作者把 DIN-SQL 定位得比較不像一個最終系統,而更像一個證據:「怎麼」prompt 一個 LLM(拆解、且難度感知),可能比「要不要」fine-tune 它更重要。隨著底層模型進步,他們預期每題成本會下降,而拆解這個想法仍會持續有用。