背景
在构建一个支持多轮对话的 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. 每位员工处理的订单数量
- “每个员工处理了多少订单?”(执行成功)√
- “按员工统计订单数量。”(执行成功)√
- “员工订单量排行榜。”(执行成功)√