把 Text-to-SQL 拆成四個可插拔的 LLM agent — 用「最小但足夠」的脈絡餵給模型,在 BIRD 上達到 71.10% 同時把 LLM 呼叫量砍掉約 83%。
把自然語言問題翻成 SQL,在學術小資料庫上 LLM 已經很強;但一旦面對「工業級」的真實資料庫,準確率就和人類拉開了約 30% 的差距。CHESS 想處理的正是這個落差。
作者把實務上的困難歸納成幾個彼此糾纏的挑戰:
真實資料庫動輒上千個欄位(論文舉例的金融 schema 有 4,337 個欄位),全部塞進 prompt 不但超出 context、成本爆炸,還會用無關欄位干擾模型。
光看欄位名不夠。模型常常不知道某個類別欄位裡實際存的字串長什麼樣(例如 'M' 還是 'Male'),也讀不到 column description。
多階段管線中,前面 schema 選錯一個欄位,後面 SQL 就整個崩掉 — error propagation 是準確率殺手。
領先方法常對單題打上百次 LLM call、灌入完整 schema;這在生產環境既貴又難落地,且把整個資料庫送進專有 API 有隱私疑慮。
「Contextual Harnessing」=「脈絡馴服」。每個子任務只餵給 LLM 最小但足夠 (minimal yet sufficient) 的脈絡 — 對的欄位、對的資料值、對的描述 — 而不是把整個資料庫倒給它。
論文的具體貢獻:把任務拆解成 四個專職 agent(IR / SS / CG / UT),每個對應一個挑戰;提出結合關鍵字抽取 + LSH + 向量資料庫的階層式檢索;設計能依題目複雜度自適應修剪 schema 的選擇器;用注入雜訊微調開源 DeepSeek 來抵抗上游錯誤;並完整開源、強調資料隱私。
CHESS 是一個 multi-agent 工作流。每個 agent 內含若干 tool(工具),agent 負責決定呼叫哪些 tool、以什麼順序。下圖是預設管線。
把問題裡的線索對應到資料庫裡實際存在的值與描述,分三個 tool:
用 few-shot prompt 要 LLM 從問題和 hint 裡抽出關鍵字、關鍵片語、命名實體,輸出成一個 Python list。
把關鍵字拿去比對「資料庫裡實際存的值」。先用 Locality Sensitive Hashing (LSH) 做近似最近鄰,再用 edit distance(語法相似)和 embedding(語意相似)過濾。論文稱這把單題值檢索從 ~5 分鐘壓到 ~5 秒。
對 column / table 的描述(資料目錄)做語意檢索,存在向量資料庫(ChromaDB),取出與問題最相關的描述。
三步漸進式過濾,每步都保留主鍵 / 外鍵(避免後續 JOIN 斷掉):
把「每個欄位是否與問題相關」當成二元分類,孤立評估、可大規模平行,先砍掉海量無關欄位。
在全域 schema 脈絡下用 chain-of-thought 評估每張表是否必要。
進一步收斂到「生成 SQL 真正必要」的最小欄位集,並對每欄給出理由。
為什麼這樣設計:schema 選擇的 precision 是端到端準確率的瓶頸 — 漏掉一欄(低 recall)直接讓題目無解,塞太多欄(低 precision)又干擾生成。三步法在維持高 recall 的同時把 precision 一路拉高(見 §05 Table 5)。
當 CG 產生多個候選時,UT 負責挑出最對的那個:
依「執行結果」把候選分群 — 結果一樣的歸一群。
要 LLM 產生一批自然語言單元測試(例:「答案 SQL 應該要 mention…/ 應該要 use…」),而且這些測試必須能區分不同候選。
對每個候選逐一判定通過/失敗,綜合得分後選出勝者。測試數量在約 10 個時效益飽和。
關鍵巧思:UT 不是拿 gold SQL 來對答案(那是作弊),而是讓 LLM 自己「出考題 + 改考卷」,本質是一種由測試引導的 self-consistency 選擇,取代單純多數投票。
CHESS 最大的賣點不是某個單一 agent,而是這四個 agent 可以像積木一樣按需求拼裝。論文給出兩個代表性組態,落在「準確率↔成本」光譜的兩端。
跳過 Schema Selector,改用強模型(Gemini-1.5-pro)取樣 20 個候選 + 10 個單元測試,讓 UT 把最好的挑出來。
71.10%
BIRD test EX — 與當時領先的專有方法差距 不到 2%,但 LLM 呼叫量約少 83%。
加入 Schema Selector 修剪 schema,單一候選 + 最多 3 次修訂,不跑 UT。單題僅約 6 次 GPT-4-turbo 呼叫(對手常 ~100 次)。
65.00% / 61.5%
BIRD dev EX:專有模型 65.00% · 全開源(Llama-3-70B + 微調 DeepSeek)61.5%,可完全本地部署、不外送資料。
Schema Selector 的工業價值:在一個 4,337 欄位 的真實金融 schema 上,先用 SS 修剪再生成,相比直接塞完整 schema,達到 ×5 的 token 用量縮減,而且準確率還 +2%(Pass@1 / Pass@5 ≈ 61% / 63%)。少即是多。
這也是論文標題「Efficient」的兩個來源:UT 路線靠少呼叫換高分;SS 路線靠修剪 schema 換低 token 與可落地性。使用者可依預算、模型可得性、隱私要求自由選擇。
12,751
question–SQL 配對,橫跨 95 個大型資料庫、合計 33.4 GB、37 個專業領域。主戰場。
2,147
測試樣本(200 個 DB schema)。Spider 沒有欄位描述,故 CHESS 在此關閉 context retrieval。
147
BIRD dev 的 10% 子集:81 simple / 54 moderate / 12 challenging,用於低成本 ablation。
兩條 CHESS 路線在 BIRD 上分居第一梯隊;在更成熟的 Spider 上也位居已發表方法第二。橘色為本文方法。
| 方法 | 基礎模型 | Dev EX | Test EX |
|---|---|---|---|
| CHASE-SQL | Gemini | 73.01 | 73.00 |
| Distillery | GPT-4o | 67.21 | 71.83 |
| CHESS(IR, CG, UT) | Gemini-1.5-pro | 68.31 | 71.10 |
| CHESS(IR, SS, CG) · 專有 | GPT-4-turbo | 65.00 | 66.69 |
| MCS-SQL | GPT-4 | 63.36 | 65.45 |
| CHESS(IR, SS, CG) · 全開源 | Llama-3-70B + FT DeepSeek | 61.5 | – |
| SFT CodeS-15B | CodeS | 58.47 | 60.37 |
| DTS-SQL | DeepSeek 7B | 55.8 | 60.31 |
| MAC-SQL | GPT-4 | 59.59 | 57.56 |
| 方法 | EX |
|---|---|
| MCS-SQL + GPT-4 | 89.6 |
| CHESS(IR, SS, CG) | 87.2 |
| DAIL-SQL + GPT-4 | 86.6 |
| DIN-SQL + GPT-4 | 85.3 |
在 SDS(147 題)上拿掉單一工具,完整管線基準 = 64.62%:
| 管線設定 | EX | ΔEX |
|---|---|---|
| 完整管線 | 64.62 | – |
| − Revise 修訂 | 57.82 | −6.80 |
| − Select Tables 選表 | 58.50 | −6.12 |
| − Final Column Selection 選欄 | 59.18 | −5.44 |
| − Entity & Context Retrieval | 59.86 | −4.76 |
| 僅 1 次 Revise | 61.22 | −3.40 |
| − Individual Column Filtering | 61.90 | −2.72 |
三個欄位 = (Schema Selection 模型, Candidate Generation 模型, 其餘步驟模型):
| 引擎組合 (SS, CG, 其餘) | EX |
|---|---|
| GPT-3.5 · 微調 DeepSeek · GPT-4 | 64.62 |
| Llama-3-70B · 微調 DeepSeek · Llama-3-70B | 59.86 |
| GPT-3.5 · GPT-4 · GPT-4 | 55.78 |
| Llama-3-70B · Llama-3-70B · Llama-3-70B | 54.42 |
| GPT-3.5 · GPT-3.5 · GPT-3.5 | 49.65 |
有意思的對照:把生成器從 GPT-4 換成微調過的 DeepSeek,整體 EX 從 55.78% → 64.62%(+8.84%)。雜訊注入微調出來的小模型,在這個任務上勝過通用大模型。
| 方法 | Easy | Moderate | Challenging | Overall |
|---|---|---|---|---|
| CHESS(含微調) | 65.43 | 64.81 | 58.33 | 64.62 |
| CHESS(不含微調) | 60.49 | 50.00 | 50.00 | 55.78 |
| GPT-4-turbo baseline | 54.32 | 35.18 | 41.66 | 46.25 |
這張表是 SS 三步法的核心證據:每一步都在「幾乎不掉 recall」的前提下大幅拉高 precision。欄位 precision 從 0.11 一路升到 0.71。
| 步驟 | Table Recall | Table Prec. | Col Recall | Col Prec. |
|---|---|---|---|---|
| 未過濾(完整 schema) | 1.00 | 0.33 | 1.00 | 0.11 |
| + 逐欄過濾 | 1.00 | 0.33 | 0.98 | 0.21 |
| + 選表 | 0.97 | 0.89 | 0.96 | 0.45 |
| + 選欄(最終) | 0.96 | 0.90 | 0.94 | 0.71 |
以下 prompt 直接擷取自官方 repo 的 templates/ 目錄,而非論文附錄(兩者常有出入,程式碼為準)。挑選四個最能代表各 agent 風格的模板。
# templates/template_extract_keywords.txt(節錄)
Objective: Analyze the given question and hint to identify and
extract keywords, keyphrases, and named entities. ...
Example 2:
Question: "In the Winter and Summer Olympics of 1988, which game
has the most number of competitors? ..."
Hint: "the most number of competitors refer to MAX(COUNT(person_id)); ..."
["Winter Olympics", "Summer Olympics", "1988", "1988 Summer",
"number of competitors", "MAX(COUNT(person_id))", "games_name", ...]
Question: {QUESTION}
Hint: {HINT}
# Only output the Python list, no explanations needed.
# templates/template_select_tables.txt(節錄)
You are an expert and very smart data analyst. ...
Database Schema Overview:
{DATABASE_SCHEMA}
# 注意:相關值會以 "-- examples" 標在欄位名前面,作為關鍵 hint
Question: {QUESTION}
Hint: {HINT}
# For each selected table, explain why it is necessary.
{
"chain_of_thought_reasoning": "...",
"table_names": ["Table1", "Table2", ...]
}
# Take a deep breath ... If you do the task correctly,
# I will give you 1 million dollars.
# templates/template_revise_two.txt — Database admin instructions(節錄)
1. 找最高/最低值時,ORDER BY + LIMIT 1 優先於 MAX/MIN 子查詢。
3. 沒指定欄位時,name 與 id 之間優先選 id。
9. 用 || ' ' || 串接字串是被禁止的,而且「punishable by death」。
Never concatenate columns in the SELECT clause.
10. 多表 JOIN 時用別名 T1, T2, T3 ... 並用別名引用欄位。
11. 對欄位做運算/排序時,記得過濾該欄的 NULL 值。
Predicted query: {SQL}
Query result: {QUERY_RESULT}
# → 回傳 {"chain_of_thought_reasoning": ..., "revised_SQL": ...}
# templates/template_generate_unit_tests.txt(節錄)
Generate a set of {UNIT_TEST_CAP} unit tests that would evaluate
the correctness of SQL queries that would answer the question.
# 重點:每個測試要能「區分至少兩個候選」
- Format like 'The answer SQL query should mention...',
'... should state...', '... should use...'
- VERY IMPORTANT: 只看 SQL 的「邏輯」,不要管輸出格式或數值。
You are provided with different clusters of candidate responses.
# 候選先依執行結果分群,測試要能區分每群內的候選
<Thinking> ... </Thinking>
<Answer> ['unit test #1', 'unit test #2', ...] </Answer>
repo 還附了配對的 template_evaluate.txt:把候選 + 單元測試一起餵回去,要 LLM 對每個候選輸出 [Passed] / [Failed] 列表 — 這就是 UT「改考卷」的那一步。
與人類仍有差距:在最難的 BIRD 上,人類的查詢合成準確率仍高於 CHESS,作者明言「未來工作應持續縮小這個 gap」。
Schema selection 是瓶頸:作者點名「更高 precision 的 schema 選擇方法」是最具槓桿的研究方向 — 它對端到端準確率有 outsize 的影響。
缺乏大規模 benchmark:現有 benchmark 不足以反映真實「大型資料庫」的挑戰;且 BIRD 本身存在語意模糊的問題與錯誤的 gold SQL,壓低了可達到的天花板。
UT 仍靠通用模型:單元測試的出題與評分目前用通用 LLM;作者計畫未來專門微調測試生成/評估模型,讓 UT 路線更可靠。
CHESS 證明了在 Text-to-SQL 上,「給模型更少、但更對的脈絡」往往勝過「給更多、打更多次」。把任務拆成可插拔的 IR / SS / CG / UT 四個 agent,使用者得以在準確率、成本、隱私之間自由取捨 — 而不是只能用一套昂貴的 monolithic pipeline。