首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Text2SQL智能体深度实践:从架构设计到自修正闭环

Text2SQL智能体深度实践:从架构设计到自修正闭环

原创
作者头像
用户12339161
发布2026-09-02 16:31:08
发布2026-09-02 16:31:08
1410
举报

在企业数据资产日益膨胀的今天,“业务人员不懂SQL、数据工程师疲于取数”已成为制约决策效率的核心瓶颈。Text2SQL技术试图用大模型弥合这一鸿沟,然而现实远比想象残酷:曾在Spider 1.0上达到86%准确率的GPT-4,在更贴近真实企业数据的Spider 2.0上,整体成功率骤降至6%。纯黑盒方案的局限性暴露无遗——它本质上是一个“单次翻译”模型,生成错误SQL后既不验证也不修正,用户只能得到错误的查询结果。

本文将从架构设计、核心流程到工程实现,完整构建一个具备自我修正能力的Text2SQL智能体,全部代码基于Python + LangGraph,可直接落地。

一、架构设计:从“一次生成”到“闭环迭代”

传统Text2SQL是一次性的“翻译”,而智能体模式赋予了模型“思考与自我纠错”的能力。完整的执行闭环包含以下阶段:

  • 问题改写:将口语化问题转化为更适配SQL生成的结构化表述
  • Schema检索:基于向量检索从大规模表结构中召回相关表,避免Token爆炸
  • SQL生成:基于裁剪后的Schema生成候选SQL
  • 执行验证:在沙盒事务中试运行,验证语法正确性与结果形态
  • 反思修正:若执行失败,读取错误日志自动修正并重试

二、核心流程实现(LangGraph)

我们基于LangGraph构建状态机,每个节点完成一个环节,边控制流转逻辑。

代码语言:javascript
复制
# graph.py - Text2SQL智能体工作流核心
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
from pydantic import BaseModel

class AgentState(TypedDict):
    question: str                    # 原始问题
    rewritten: str                   # 改写后的问题
    relevant_tables: List[str]       # 召回的关联表
    sql: str                         # 生成的SQL
    execution_result: str            # 执行结果/错误信息
    is_valid: bool                   # SQL是否可执行
    attempts: int                    # 尝试次数
    max_attempts: int                # 最大尝试次数

# 节点1: 问题改写
def rewrite_question(state: AgentState) -> AgentState:
    prompt = f"将以下问题改写为更适合生成SQL的表述:{state['question']}"
    rewritten = llm.invoke(prompt)
    return {**state, "rewritten": rewritten}

# 节点2: Schema检索(向量召回)
def retrieve_schema(state: AgentState) -> AgentState:
    # Chroma向量库检索最相关的K张表
    tables = vector_store.similarity_search(state["rewritten"], k=5)
    return {**state, "relevant_tables": [t.metadata["table_name"] for t in tables]}

# 节点3: SQL生成
def generate_sql(state: AgentState) -> AgentState:
    schema_text = "\n".join(get_table_ddl(t) for t in state["relevant_tables"])
    prompt = f"""
    基于以下表结构,将问题转换为SQL:
    表结构:{schema_text}
    问题:{state['rewritten']}
    仅输出SQL语句。
    """
    sql = llm.invoke(prompt)
    return {**state, "sql": sql}

# 节点4: 执行验证(事务回滚)
def execute_sql(state: AgentState) -> AgentState:
    try:
        conn.begin()
        cursor.execute(state["sql"])
        cursor.fetchall()  # 仅验证可执行性
        conn.rollback()
        return {**state, "execution_result": "成功", "is_valid": True}
    except Exception as e:
        conn.rollback()
        return {**state, "execution_result": str(e), "is_valid": False}

# 节点5: 反思修正
def reflect_and_fix(state: AgentState) -> AgentState:
    if state["attempts"] >= state["max_attempts"]:
        return {**state, "sql": f"-- 重试耗尽,最后错误:{state['execution_result']}"}
    prompt = f"""
    之前生成的SQL执行失败:
    SQL: {state['sql']}
    错误信息:{state['execution_result']}
    请修正SQL,仅输出修正后的SQL。
    """
    fixed_sql = llm.invoke(prompt)
    return {**state, "sql": fixed_sql, "attempts": state["attempts"] + 1}

# 构建状态图
graph = StateGraph(AgentState)
graph.add_node("rewrite", rewrite_question)
graph.add_node("retrieve", retrieve_schema)
graph.add_node("generate", generate_sql)
graph.add_node("execute", execute_sql)
graph.add_node("reflect", reflect_and_fix)

graph.set_entry_point("rewrite")
graph.add_edge("rewrite", "retrieve")
graph.add_edge("retrieve", "generate")
graph.add_edge("generate", "execute")

# 条件边:验证通过则结束,否则进入反思
def should_continue(state: AgentState) -> str:
    if state["is_valid"]:
        return END
    if state["attempts"] >= state["max_attempts"]:
        return END
    return "reflect"

graph.add_conditional_edges("execute", should_continue)
graph.add_edge("reflect", "execute")  # 修正后重新执行验证

app = graph.compile()

三、多智能体协作进阶

对于更复杂的查询场景,单一Agent难以胜任。多智能体框架通过角色分工实现专业化处理:

  • Schema探查器:过滤不相关的表结构,提取关键列值
  • 查询规划器:分步生成复杂SQL(多表JOIN、子查询)
  • 验证器:基于数据库响应评估SQL正确性
  • 修正器:根据验证反馈迭代优化

代码语言:javascript
复制
# 多智能体协作示例(基于smolagents的ReAct框架)
from smolagents import CodeAgent, Tool

class SchemaInspector(Tool):
    name = "schema_inspector"
    description = "探查数据库表结构,返回相关表和列"
    def forward(self, question: str) -> str:
        # 向量检索 + 列值采样
        return relevant_schema

class SQLExecutor(Tool):
    name = "sql_executor"
    description = "执行SQL并返回结果或错误"
    def forward(self, sql: str) -> str:
        return execute_with_rollback(sql)

agent = CodeAgent(
    tools=[SchemaInspector(), SQLExecutor()],
    model=HuggingFaceModel("Qwen/Qwen2.5-Coder-7B-Instruct")
)
result = agent.run("查询上个月销售额最高的前10名销售人员")

四、工程化关键要点

1. Schema级联检索:企业级数据库动辄数百张表,将全量DDL塞入上下文会导致Token爆炸。通过向量检索在毫秒级完成表召回,将Schema裁剪至5-8张核心表。

2. 沙盒验证:生成的SQL必须进入受限沙盒执行语法检查,确认无误后方可推向生产库。

3. 确定性回退:利用数据库的EXPLAIN机制进行执行代价预演,一旦发现全表扫描等灾难性操作,强制触发反思重写。

4. 人机协同熔断:涉及数据修改或高风险聚合查询时,系统应在执行前挂起并通过WebSocket推送二次确权请求。

五、总结

本文从架构设计、LangGraph状态机实现到多智能体协作,完整构建了一个具备自修正能力的Text2SQL智能体。核心启示在于:AI生成SQL不是终点,执行验证-错误反馈-反思修正的闭环才是工业级可用的关键。工程化的Text2SQL系统必须用“白盒”思维将大模型的概率输出约束在可控范围内——让AI负责翻译,让确定性的规则和验证机制负责执行,让人类在关键节点拥有最终裁决权。这不仅是技术的选择,更是对生产环境每一行SQL负责的工程态度。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、架构设计:从“一次生成”到“闭环迭代”
  • 二、核心流程实现(LangGraph)
  • 三、多智能体协作进阶
  • 四、工程化关键要点
  • 五、总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档