背景
在構建一個支持多輪對話的 Text2SQL 系統過程中,我完成了以下關鍵功能:
已完成
- 基礎 Text2SQL 功能實現
實現用戶輸入自然語言問題后,系統能夠自動生成 SQL 并執行返回結果。 - 用戶交互優化
支持用戶通過補充信息對查詢進行調整,提升易用性。 - 模糊時間處理機制
對“最近”“近期”等模糊時間關鍵詞進行補全或引導,提升時間表達準確性。 - 預定義高頻問題與回答
對一些可預見的問題設置高質量回復,提高響應質量和效率。
后續優化
- 構建高質量知識庫
針對數據結構、字段定義、樣例問題等,持續完善知識庫,確保 SQL 生成的準確率。 - 引入持續學習機制
通過用戶反饋和歷史數據,不斷優化模型能力與表現。 - 高質量測試集
- 引入高質量的測試集來測試Text2SQL的效果與準確率
- 智能體節點,自動糾錯
- 避免現在一次性生成SQL,多次生成糾錯,提高質量
編排
工作流核心概覽
- 檢索預定義模板
- 選擇預定義模板
提取用戶選擇的模板
提示詞:
以下是之前提供給用戶的選項: 會話變量 / template_choose_question ;用戶選擇了: 開始 / sys.query ;請從上面的選項中提取并輸出用戶選擇對應的內容,不要輸出任何額外解釋。
生成完整的SQL
提示詞:
你是一個專業的 SQL 助理。請根據以下兩種情況之一進行處理:
情況一:提供的是完整 SQL 語句
如果你判斷 SQL 已經是完整的、可直接執行的查詢語句(例如包含完整的 SELECT、FROM、WHERE、ORDER BY 等),請直接原樣輸出它,不進行任何修改,不要輸出\n字符。
情況二:提供的是SQL 模板(不完整)
如果 SQL 是一個模板或部分語句(如缺少 WHERE 條件、ORDER BY 等),請結合用戶問題的描述,補全并輸出完整 SQL 查詢語句;
生成語句時,請僅使用模板中已有的字段、表結構,不要添加不合理字段;
輸出格式為純 SQL 語句,不加解釋,不要輸出\n字符。
輸入內容:
SQL 輸入(模板或完整 SQL): 檢索SQL模板 / result ; 用戶問題: 會話變量 / last_question ;請根據上述規則,輸出最終 SQL 查詢語句。
預定義模板
編號 | 問題描述 | SQL 模板 | 類型 |
---|---|---|---|
Q1 | 查詢某城市的客戶公司名稱 | SELECT company_name, city FROM customers WHERE city = '{{city}}'; | SQL模板 |
Q2 | 查詢某一年的訂單數量 | SELECT COUNT(*) FROM orders WHERE EXTRACT(YEAR FROM order_date) = {{year}}; | SQL模板 |
Q3 | 查詢某個客戶的所有訂單 | SELECT * FROM orders WHERE customer_id = '{{customer_id}}'; | SQL模板 |
Q4 | 查詢每個產品的總銷售數量 | SELECT p.product_name, SUM(od.quantity) AS total_sold FROM products p JOIN order_details od ON p.product_id = od.product_id GROUP BY p.product_name ORDER BY total_sold DESC; | 完整SQL |
Q5 | 查詢某庫存閾值以下的產品 | SELECT product_name, units_in_stock FROM products WHERE units_in_stock < {{stock_threshold}}; | SQL模板 |
Q6 | 查詢某員工經手的訂單 | SELECT * FROM orders WHERE employee_id = {{employee_id}}; | SQL模板 |
Q7 | 查詢某時間段內的訂單數 | SELECT COUNT(*) FROM orders WHERE order_date BETWEEN '{{start_date}}' AND '{{end_date}}'; | SQL模板 |
Q8 | 查詢某類產品的銷售明細 | SELECT p.product_name, od.quantity, od.unit_price FROM products p JOIN order_details od ON p.product_id = od.product_id JOIN categories c ON p.category_id = c.category_id WHERE c.category_name = '{{category_name}}'; | SQL模板 |
Q9 | 查詢某個供應商提供的產品 | SELECT product_name FROM products WHERE supplier_id = {{supplier_id}}; | SQL模板 |
Q10 | 查詢某年每個月的訂單數 | SELECT EXTRACT(MONTH FROM order_date) AS month, COUNT(*) AS order_count FROM orders WHERE EXTRACT(YEAR FROM order_date) = {{year}} GROUP BY month ORDER BY month; | SQL模板 |
第二輪對話選擇
需要記錄第一輪的提供選項,然后通過LLM判斷用戶是選擇的哪個選項,然后進行模板匹配
第二輪對話根據模板生成SQL
Decimal結果報錯
這邊精確度不要求太高,需要在LLM節點中指出不讓生成decimal結果。
解決方案:
- LLM指出解決
- 在SQLexcute節點中,選擇使用markdown格式返回
偶爾抽風提取參數出錯
檢索測試:提示詞提取參數
有一些參數提取沒有輸入示例,導致提取效果不佳,通過輸入示例來提高成功率
換行符報錯
后續生成的SQL帶有換行符,需要在Prompt里面限制一下
測試報告
1. 查詢某城市的客戶公司名稱
- “Berlin有哪些客戶公司?”(執行成功)√
- “請列出在Berlin的客戶公司名稱。”(執行成功)√
- “Berlin的客戶都叫什么公司?”(執行成功)√
2. 查詢某一年的訂單數量
- “2021 年一共下了多少訂單?”(執行成功)√
- “請統計 2022 年的訂單總量。”(執行成功)√
- “去年(2024)的訂單數是多少?”(執行成功)√
3. 查詢某個客戶的所有訂單
- “客戶HANAR的訂單有哪些?”(執行成功)√
- “幫我查一下 HANAR 公司所有訂單。”(執行成功)√
- “HANAR這個客戶買過什么?”(執行成功)√
4. 查詢每個產品的總銷售數量
- “每種產品賣了多少?”(執行成功)√
- “按產品統計總銷量。”(執行成功)√
- “各個商品的銷售總量是多少?”(執行成功)√
5. 查詢某庫存閾值以下的產品
- “庫存少于 50 的產品有哪些?”(執行成功)√
- “哪些商品的庫存量低于 10?”(執行成功)√
- “請列出庫存不足 100 的所有貨品。”(執行成功)√
6. 查詢某員工經手的訂單
- “員工4處理過哪些訂單?”(執行成功)√
- “員工 ID 為 4 的訂單記錄。”(執行成功)√
- “員工4負責的訂單有哪些?”(執行成功)√
7. 查詢某時間段內的訂單數
- “2023 年 1 月到 3 月有多少訂單?”(執行成功)√
- “今年上半年下了多少單?”(執行成功)√
- “5 月 1 日到 5 月 10 日的訂單量。”(執行成功)√
8. 查詢某類產品的銷售明細
- “Seafood的銷售情況如何?”(執行成功)√
- “Seafood類產品的詳細銷量。”(執行成功)√
- “Seafood類別的銷售記錄。”(執行成功)√
9. 查詢某個供應商提供的產品
- “供應商 8 提供哪些商品?”(執行成功)√
- “8供應商的供貨明細。”(執行成功)√
- “8供應商供應了什么產品?”(執行成功)√
10. 查詢某年每個月的訂單數
- “2022 年每個月有多少訂單?”(執行成功)√
- “去年各月的訂單統計。”(執行成功)√
- “2023 年月度訂單量。”(執行成功)√
11. 每位員工處理的訂單數量
- “每個員工處理了多少訂單?”(執行成功)√
- “按員工統計訂單數量。”(執行成功)√
- “員工訂單量排行榜。”(執行成功)√