从 40% 提升到 100% 的 SQL 生成准确率:为什么本地 AI 需要自我纠正,而不是完美提示

发布: (2025年12月3日 GMT+8 06:14)
6 min read
原文: Dev.to

Source: Dev.to

概览

自我纠正循环胜过“完美一次”方法,适用于本地 AI。构建一个完全在笔记本电脑上运行的零售分析副驾驶(使用量化的 24B 模型)听起来对隐私很友好,但在可靠性上却是噩梦。与托管的 GPT 不同,后者能像资深工程师一样遵循指令,本地模型更像热情的实习生:他们努力尝试,却会出现语法幻觉、忘记模式细节,并且在应该写代码时喜欢聊天。

基线

我的最初基线表现糟糕:只有 40 % 的生成 SQL 查询能够实际执行。其余的要么语法错误,要么出现幻觉列,要么充满对话式的废话(“Here is your query …”)。

转变:预期错误,然后修复

我没有尝试阻止错误,而是构建了一个 预期 错误并自动修复的系统。

修复循环工作流

  1. 生成 – 模型编写查询。
  2. 执行 – 在 SQLite 上运行。
  3. 捕获 – 如果失败,获取错误信息(例如 no such column: 'Price')。
  4. 反馈 – 将完整的错误信息反馈给模型:“前一个查询因错误 X 失败。请修复它。”

这种模式可以推广到除 SQL 之外的场景。只要你使用概率系统、可能失败的外部 API,或模糊的用户输入,都应为优雅降级而设计。

来自失败的训练数据

每个 (failed_query, error_message, corrected_query) 三元组都可以成为未来优化的 few‑shot 示例。你不仅在修复 bug;你在构建一个自我改进的系统。

修复循环实现(Python)

def sql_execution_node(state: AgentState) -> AgentState:
    """Execute SQL and handle errors gracefully."""
    query = state["sql_query"]

    try:
        cursor.execute(query)
        state["sql_results"] = cursor.fetchall()
        state["errors"] = []
    except sqlite3.OperationalError as e:
        # Don't crash—capture and route to repair
        state["sql_results"] = []
        state["errors"].append(str(e))
        state["feedback"] = f"SQL execution failed: {e}. Fix the query."
        state["repair_count"] = state.get("repair_count", 0) + 1

    return state

def should_repair(state: AgentState) -> str:
    """Conditional edge: repair or continue?"""
    if state["errors"] and state["repair_count"]  str:
    match = re.search(r"(SELECT\s+.*)", text, re.IGNORECASE)
    return match.group(1).strip() if match else ""

更好的是:强制结构化输出(例如 JSON),这样就可以完全避免自由形式的解析。

从 Prompt Engineering 转向 DSPy

我停止手写提示,转而使用 DSPy,它把提示优化视为可学习的问题。

把传统的提示工程想象成手动调超参数;DSPy 则像反向传播,使用梯度自由优化在你定义的度量上自动搜索最佳提示。

定义度量

“如果查询 能够执行 并且返回非空结果,则认为它是好的。”
使用 BootstrapFewShot 优化器,DSPy 生成多个候选 SQL 查询,执行它们,并仅保留通过度量的作为 few‑shot 示例。

度量改进

度量基线优化后修复循环后
有效 SQL (%)40 %85 %100 %
正确格式 (%)30 %60 %95 %
端到端成功 (%)12 %51 %66 %

*100 % 有效 SQL 与 66 % 端到端成功之间的差距表明,优化单一组件会在其他环节(编排逻辑,而非模型质量)产生新的瓶颈。

实践中的修复模式

在 LLM 状态中添加 feedback 字段。失败时注入错误信息并重试。这大约只会产生 一次额外的 LLM 调用,但可靠性可以提升一个数量级。

“ELECT” 测试

assert clean_sql_output("SQL: SELECT * FROM orders") == "SELECT * FROM orders"
assert clean_sql_output("SELECT * FROM orders") == "SELECT * FROM orders"

如果这些断言失败,说明你误用了字符串方法。

DSPy 入门模板

  1. 将任务定义为 (inputs, output, metric)
  2. 让优化器发现有效的 few‑shot 示例,而不是手动编写它们。

为什么这很重要(超出本项目)

AI 领域正出现两极分化:

方法特点
云优先 (GPT‑5.1、Claude 等)强大但昂贵;隐私风险更高。
边缘优先 (本地模型)更便宜、私密,但更难驾驭。

能够掌握本地 AI 的公司将在受监管行业(医疗、金融、政府)中占据主导,因为云端 LLM 在这些领域是不可行的。瓶颈不在模型权重,而在 可靠性工程

如果你能通过巧妙的编排让 7B 模型表现得像 70B 模型,你就在解决一个 1000 亿美元 的问题。这不仅是技术练习,更是战略护城河。

关键技能

  • 系统思维 – 理解失效模式并围绕它们设计。
  • 优化 – 将提示视为可学习的参数,而非艺术。
  • 防御性工程 – 为概率世界构建系统。

掌握这些,你竞争的将不是提示工程师,而是 AI 原生公司的基础设施工程师。

项目仓库:

Back to Blog

相关文章

阅读更多 »

切换账户

@blink_c5eb0afe3975https://dev.to/blink_c5eb0afe3975 正如大家所知,我正重新开始记录我的进展,我认为最好在一个不同的…

Strands 代理 + Agent Core AWS

入门指南:Amazon Bedrock AgentCore 目录 - 前置要求(requisitos‑previos) - 工具包安装(instalación‑del‑toolkit) - 创建…