六层工程体系:让 AI Agent 稳定输出准确 SQL 的实战指南
六层工程体系:让 AI Agent 稳定输出准确 SQL 的实战指南
引言
让 AI Agent 根据一句自然语言需求就输出准确的 SQL,听起来像是模型能力问题,但实际上是一个工程体系问题。单靠换更强的模型、调更好的 Prompt,效果很快就会碰到天花板。真正能让这套系统在生产环境稳定运行的,是一套由元数据、语义层、案例库、知识库、Skill 系统、校验体系六个模块组成的工程架构。本文将逐一拆解每个模块的设计思路和落地细节,并介绍如何将它们串联成端到端的自动化流程。
一、整体架构概览
整个系统分为三层加一层校验:
- 输入层:接收用户的自然语言需求
- 处理层:完成需求理解、SQL 生成等推理任务
- 支撑层:提供元数据、语义定义、案例、业务知识等事实依据
- 校验层:保障输出 SQL 的正确性与可靠性
各层之间通过标准化接口通信,每一层都可以独立迭代升级。
二、元数据管理——Agent 理解数据的入口
元数据是 Agent 认识数据资产的基石。如果元数据质量差——表名是拼音缩写、字段没有中文注释、血缘关系缺失——那么 Agent 即便推理能力再强,也无法正确找到目标表和字段。
企业元数据通常分为三类:
| 类别 | 内容 | 作用 |
|---|---|---|
| 技术元数据 | 表名、列名、数据类型、主外键 | 告诉 Agent 有哪些表和字段 |
| 业务元数据 | 中文含义、计算口径、负责人 | 解释字段背后的业务含义 |
| 操作元数据 | 血缘关系、更新频率、质量评分 | 帮助 Agent 判断表的可靠性 |
技术元数据可从数据库系统自动采集;业务元数据需要人工标注或从文档中抽取;操作元数据需要在数据 Pipeline 运行过程中积累。
以 OpenMetadata 为例,它为每个高频使用的字段提供完整标注:
{
"field": "order_amount",
"chinese_name": "订单金额",
"business_definition": "包含运费,扣除优惠券后的实付金额",
"calculation_formula": "SUM(商品金额 + 运费 - 优惠券抵扣)",
"data_type": "decimal(10,2)",
"example_query": "SELECT SUM(order_amount) FROM orders WHERE create_date >= '2025-01-01'"
}
数据血缘则解决"这个指标从哪来"的问题。当用户说"我要看 GMV",Agent 需要通过血缘找到 GMV 最终落在哪张宽表里,以及中间经过了哪些加工步骤。
根据 Spider 论文的研究结论,Schema Linking(准确定位相关表和列)是 Text-to-SQL 任务中准确率的最大瓶颈。元数据标注的质量直接决定了这一环节的上限。
三、语义层——在业务语言与数据库之间架桥
元数据解决了"有什么"的问题,但用户口中说的是 GMV、获客成本、复购率,而不是 ws_daily_gmv 或 gmv_amount。语义层的作用就是在业务语言和技术实现之间搭一座桥。
语义层需要做到三件事:
- 指标定义标准化:将 GMV、DAU 等指标的计算逻辑封装成统一定义,保证所有人查出来都是同一个数。
- 维度统一管理:确保"地区"在所有指标中的含义一致。
- 自动导航 Join 路径:Agent 不需要知道底层表是如何关联的,语义层会自动找到正确的路径。
以 MetricFlow 为例,我们可以定义一个语义模型:
semantic_model:
name: orders
entities:
- name: order_id
type: primary
dimensions:
- name: created_at
type: time
- name: channel
type: categorical
measures:
- name: order_total
agg: sum
- name: order_count
agg: count
然后定义指标:
metrics:
- name: revenue
type: simple
measure: order_total
- name: food_revenue_pct
type: derived
expr: food_revenue / total_revenue
定义好后,Agent 生成 SQL 时就不需要自己拼 Join 和聚合逻辑了,直接通过 MetricFlow 的 API 查询指标即可。Cube 则在标准 SQL 基础上增加了指标函数,并提供 MCP Server 接口供 AI Agent 通过 MCP 协议直接接入。
对 Agent 而言,语义层解决了三个实际问题:消除指标歧义、降低复杂度、保证口径一致。
四、案例库——提供推理样本,而非模板
案例库不同于 SQL 模板库。SQL 模板只能处理固定模式的需求,而真实业务需求千变万化。案例库要做的是提供从需求描述到最终 SQL 的完整推理链路,包括需求是如何拆解的、选了哪些表、为什么这么写。
每条案例语料应包含:
- 原始需求
- 需求分析(拆解出的指标、维度、过滤条件、隐含逻辑)
- 涉及的表
- 最终 SQL
- 验证结果
- 标签
案例库有四个主要来源:
- 历史需求:工单和 BI 团队过去处理过的需求
- 人工构造:针对高频业务场景,由分析师主动编写典型案例
- 用户反馈:用户通过 AI 系统提交需求后,人工审核的结果回流
- 错误案例:Agent 写错的 SQL 同样有价值,标注清楚错在哪、如何修改
新需求进来后,如何找到最相关的历史案例?通常结合两种方式:
- 语义相似度:使用 Embedding 做向量检索
- 关键词匹配:提取指标、维度和表名进行精确检索
检索到的案例会作为 Few-shot Examples 放进 Prompt,帮助 Agent 理解当前需求应该映射到哪些表,以及应该使用什么 SQL 模式。
五、知识库——告诉 Agent “为什么”
案例库教 Agent 怎么做,知识库告诉 Agent 为什么这么做。
例如,用户说"查华东区的 GMV"。如果 Agent 不知道华东区包含哪些省份,它可能只查询"华东"这个字段值,漏掉上海、江苏、浙江的数据。又如,GMV 的定义在三个月前改过——之前包含未付款订单,现在只计算已付款订单。如果 Agent 不知道这个变更,查出来的数就会对不上。
知识库主要存放五类内容:
- 业务术语表:解决术语歧义(如 GMV = 成交总额,是否含未付款订单)
- 决策记录:记录口径变更历史(如从 Q3 起,获客成本不再包含品牌广告)
- 组织架构:解决维度理解(华东区 = 上海、江苏、浙江)
- 业务规则:处理时间逻辑(退款完成七天后才从 GMV 中扣除)
- 使用说明:避免选错数据源(某表不包含测试订单)
以结构化 YAML 文件管理为例:
terms:
- term: GMV
full_name: Gross Merchandise Volume
chinese_name: 成交总额
definition: 已付款订单的商品总金额,不含运费和优惠券
exclusions: [未付款订单, 已取消订单]
related_metrics: [revenue, refund_rate]
updated_at: 2025-07-01
owner: data-team
知识库通过 API 方式接入 Agent 的工作流。当 Agent 遇到不确定的业务概念时,先去知识库里查询。这样,Agent 不只是在翻译需求,而是在理解需求。
六、Skill 系统——将能力编排成自动化流水线
前面四个模块都是知识层面的东西,但光有知识还不够,还需要有人把这些知识串起来使用。Skill 系统就是把元数据、语义层、案例库和知识库这些散落的能力,编排成可以自动执行的工作流。
一个典型的 Skill 定义如下(YAML):
skill:
name: text_to_sql
steps:
- step: demand_analysis
description: 提取核心指标、分析维度、过滤条件、时间范围、隐含逻辑
- step: semantic_search
depends_on: [demand_analysis]
service: semantic_layer
- step: case_search
depends_on: [demand_analysis]
service: case_library
- step: metadata_query
depends_on: [demand_analysis]
service: metadata
- step: sql_generation
depends_on: [semantic_search, case_search, metadata_query]
- step: sql_validation
depends_on: [sql_generation]
每个 Step 负责一件事,Step 之间有明确的依赖关系。Agent 按照这个定义一步步执行,遇到问题时可以回溯到上一步重试。
实际运行时,Agent 通过 Function Calling 调用各个 Skill。以 Anthropic 的 Tool Use 模式为例,Agent 根据任务需要自主决定调用哪个工具、传什么参数,以及如何处理返回结果。
七、校验体系——保障输出质量的最后防线
前面几个模块解决的是"怎么生成"的问题,校验体系解决的是"怎么保证质量"的问题。Agent 生成的 SQL 不能直接使用,不是因为它一定会错,而是因为你不知道它什么时候会错。
校验分三层,从自动到人工逐层递进:
1. AI 自动评估
SQL 生成后立即运行检查,包括:
- 语法检查
- 安全性检查(如禁止 DROP 等危险操作)
- Schema 一致性检查(表、字段是否存在)
- 语义一致性检查(用另一个 LLM 审查生成的 SQL 是否真的回答了用户需求)
- 查询性能检查(预估扫描行数、是否有全表扫描风险)
其中语义一致性检查最有价值,能够抓住很多语法正确但逻辑错误的情况。
2. 对抗审查
由一个独立的 Review Agent 专门"找茬",检查:
- 笛卡尔积风险
- Join 条件缺失
- 聚合粒度不正确
- 数据倾斜隐患
这种对抗机制能够显著提高输出质量。
3. 人工核验
涉及财务数据或对外报告的场景,最终需要数据工程师审核一遍。人工看的不是语法,而是业务逻辑是否正确,以及结果是否合理。
校验结果不应只有 Pass 或 Fail。每一次失败都应该回流到系统中:
- 失败案例经过标注后,加入案例库
- 新发现的业务规则,加入知识库
- Prompt 的薄弱环节,进一步加固
系统的准确率,就是在这个闭环里一点点提升的。
八、端到端流程
将以上六个模块串联起来,完整的流程如下:
用户输入自然语言需求
↓
需求理解(提取指标、维度、过滤条件、时间范围、隐含逻辑)
↓
语义检索(从语义层获取指标定义和维度映射)
案例检索(从案例库获取相似推理样本)
元数据查询(从元数据系统获取表结构、血缘)
知识库查询(补充业务规则和术语解释)
↓
SQL 生成(综合以上信息,生成候选 SQL)
↓
AI 自动校验(语法、安全、语义一致性、性能)
对抗审查(Review Agent 找茬)
人工核验(必要时)
↓
输出最终 SQL(或返回错误信息引导用户修正)
整个过程贯穿四个设计原则:
- 分层解耦:每个模块可以独立运行、独立迭代
- 知识驱动:语义层、元数据、案例库、知识库并行检索,构成 Agent 的知识底座
- 校验前置:在核心生成环节设置多重检查点
- 持续迭代:通过反馈闭环,让系统越用越准确
九、落地建议
好消息是,这六个模块都不需要从零开始造轮子。目前已有成熟的开源基础设施:
- 元数据管理:OpenMetadata(支持 70+ 数据源)
- 语义层:MetricFlow、Cube(提供 MCP Server 接口)
- 案例库与知识库:可使用向量数据库(如 Milvus、Weaviate)配合 Embedding 模型构建
- Skill 系统:可通过 LangChain、Semantic Kernel 等框架编排
- 校验体系:可基于 LLM 自身能力加规则引擎实现
你需要做的是把它们串起来,针对自己的业务场景做好标注、积累和校验。当然,开源方案未必能满足所有诉求,需要根据实际情况决定是自研还是使用开源方案。
总结
AI 自主需求开发,不是换一个更强的模型就能解决的问题。它需要元数据管理让 Agent 能看懂数据资产,需要语义层让自然语言准确映射到指标,需要案例库提供推理样本,需要知识库补充业务背景,需要 Skill 系统编排自动化流程,需要校验体系保障输出质量。六个模块协同起来,才能真正实现"用户提需求、Agent 出 SQL"的体验。
六个模块单独看都不复杂,难的是把它们串成一个整体,并持续打磨。希望本文能为正在构建或优化 Text-to-SQL 系统的你提供一些实际的参考。
更多推荐


所有评论(0)