NL2SQL 正确率怎么提升:ChatBI 的 `<error-msg>` 错误反馈闭环

NL2SQL 正确率怎么提升:ChatBI 的 <error-msg> 错误反馈闭环

标签:NL2SQL Text2SQL LLM Prompt Engineering ChatBI

背景

Text-to-SQL 工程里,LLM 生成的 SQL 常见三类错误:

类型 示例
语法错误 关键字拼错、引号/方言不匹配
语义错误 字段不存在、JOIN 条件错误
权限错误 访问了不该碰的表

ChatBI 在首轮生成前,已通过 M-Schema 表结构、术语库、SQL 样例训练降低错误率。但对复杂查询,仍需要第二层保障:执行 → 失败 → 捕获原生报错 → 注入 Prompt → 再生成


整体架构

flowchart TD A[用户提问] --> B[LLM 生成 SQL] B --> C[exec_sql 执行] C --> D{结果} D -->|成功| E[返回数据] D -->|失败| F[save_error exec-sql-err] F --> G[用户再次提问] G --> H[get_last_execute_sql_error] H --> I[注入 error-msg] I --> B

核心实现

1. 执行失败:捕获并结构化存储

backend/apps/chat/task/llm.py

python 复制代码
elif isinstance(e, ChatBIDBError):
    error_msg = orjson.dumps({
        'message': 'Execute SQL Failed',
        'traceback': str(e),
        'type': 'exec-sql-err'
    }).decode()
self.save_error(message=error_msg)

traceback 是数据库原生报错,不是 LLM 生成的解释。

2. 下轮读取:只取 exec-sql-err

backend/apps/chat/curd/chat.py

python 复制代码
def get_last_execute_sql_error(session, chart_id):
    obj = orjson.loads(res)
    if obj.get('type') == 'exec-sql-err':
        return obj.get('traceback')
    return None

连接错误(db-connection-err)不会进入 SQL 修正闭环。

3. Prompt 注入

llm.py 初始化时:

python 复制代码
if last_execute_sql_error:
    self.chat_question.error_msg = f'''<error-msg>
{last_execute_sql_error}
</error-msg>'''

backend/template.yaml 用户 Prompt:

yaml 复制代码
user: |
  <background-infos>
    <current-time>{current_time}</current-time>
  </background-infos>
  {error_msg}
  <user-question>{question}</user-question>

System Prompt 已说明:<error-msg> 提供上次执行 SQL 的错误信息。

4. 多轮上下文控制

  • 历史消息通过 generate_sql_logs 保留
  • base_message_count_limit = 6 限制上下文,控制 token
  • 当前为用户触发的多轮修正,非服务端静默自动重试

时序图

sequenceDiagram participant U as 用户 participant FE as 前端 participant LLM as LLMService participant DB as 数据库 participant Store as ChatRecord U->>FE: 提问 FE->>LLM: 发起问数请求 LLM->>LLM: 读取上次 exec-sql-err LLM->>LLM: 组装 Prompt(含 error-msg) LLM->>LLM: 生成 SQL LLM->>DB: exec_sql DB-->>LLM: 执行失败 + 原生报错 LLM->>Store: save_error(traceback) LLM-->>FE: 返回错误 FE-->>U: 展示错误详情 U->>FE: 再次提问 Note over LLM,Store: 下轮自动带上 error-msg

错误分类策略

flowchart LR A[异常] --> B{类型} B -->|连接| C[db-connection-err → 提示检查连接] B -->|执行| D[exec-sql-err → 注入 error-msg] B -->|解析| E[ParseSQLResultError → 单独处理] B -->|业务| F[SingleMessageError → 直接返回]
错误 处理
syntax error at or near 修正关键字/引号,1--2 轮通常可解决
column does not exist 回查 M-Schema,可能需换字段或补 JOIN
permission denied 不重试,直接降级提示

前端 ErrorInfo.vue 区分展示:db-connection-err 显示数据源无效,exec-sql-err 显示执行失败并可展开 traceback。


重试上限与降级(演进方向)

现状:用户驱动 + 6 条历史上限,无自动重试计数器。

建议演进:

python 复制代码
MAX_AUTO_RETRY = 3

RETRYABLE = ['syntax error', 'does not exist', 'unknown column']
NON_RETRYABLE = ['permission denied', 'access denied']

def should_retry(error: str, count: int) -> bool:
    if count >= MAX_AUTO_RETRY:
        return False
    if any(k in error.lower() for k in NON_RETRYABLE):
        return False
    return any(k in error.lower() for k in RETRYABLE)

超限降级:友好提示 + 展示最后 SQL + 推荐简化问题。


设计 Checklist

  1. 捕获原生报错 --- 不用 LLM 翻译错误
  2. 结构化存储 --- JSON 区分 exec-sql-err / db-connection-err
  3. 专用标签注入 --- <error-msg> 与用户问题分离
  4. 按类型分流 --- 权限/连接错误不进修正闭环
  5. 重试上限 + 降级 --- 避免无限烧 token

相关代码路径

模块 路径
错误注入 backend/apps/chat/task/llm.py
错误读取 backend/apps/chat/curd/chat.py
Prompt 模板 backend/template.yaml
异常定义 backend/common/error.py
前端错误展示 frontend/src/views/chat/ErrorInfo.vue

总结

NL2SQL 工程化的核心,是把正确SQL从训练数据搬到运行时:数据库说错了什么,就把什么喂回模型。

ChatBI 的 <error-msg> 闭环不复杂,但抓住了「错了能改、改时有据」这个关键点。

相关推荐
BD_Marathon3 小时前
SQL学习指南——视图
数据库·sql
2601_962072554 小时前
李梦娇常识4600问|题库|打印版
sql·华为od·华为·c#·华为云·.net·harmonyos
HackTwoHub5 小时前
Sqli-Scanner SQL注入SKILL自动化挖掘SQL注入,零依赖自动化SQL注入挖掘,赏金猎人
数据库·人工智能·sql·web安全·网络安全·自动化·系统安全
Volunteer Technology6 小时前
Flink Table API与SQL(一)
大数据·sql·flink
持敬chijing7 小时前
Web渗透之SQL注入-常用sql语句
sql·安全·web安全·网络安全
Theo·Chan8 小时前
更换 Kingbase V9 License 踩坑记
sql·信创·kingbase
yangshicong9 小时前
第16章:AI数据分析与Text-to-SQL
人工智能·python·sql·数据分析·langchain
Chengbei119 小时前
AISec真正拟人化全自动渗透工具!支持浏览器交互全自动化挖掘,SQL注入、XSS、越权等。
sql·安全·web安全·网络安全·自动化·系统安全·xss
审判长烧鸡10 小时前
数据库字段命名规范速查表
数据库·sql
吴声子夜歌1 天前
SQL经典实例——元数据查询
数据库·sql