DB-GPT 实战:用自然语言查询数据库的 Text-to-SQL 框架
简介DB-GPT数据库大语言模型资源包聚焦于自然语言与数据库查询的结合面向希望降低SQL使用门槛的开发者、数据分析师及AI应用研究者。资源完整收录了模型源码、预训练与微调相关脚本、部署配置和说明文档包含Python实现、SQL示例、Dockerfile、Shell脚本以及Markdown分析笔记能够支撑从环境搭建、数据预处理、模型训练到自然语言转SQL测试的完整流程。压缩包共441个文件约14.97MB其中252个Python文件为核心代码另有40个JavaScript文件、36个Markdown文档、8个SQL脚本及多种格式的配置与辅助材料目录结构清晰便于按模块学习。目前已有1576人学习内容覆盖多表连接、子查询、聚合函数等复杂查询场景可直接用于理解DB-GPT的模型架构与调优思路也可作为二次开发或课程设计的参考资料。1. 为什么 DB-GPT 值得你花一个下午重新认识DB-GPT 这个名字看起来像数据库大模型的又一个套壳项目但真正把关系型数据库、向量数据库和大语言模型串成一条可用链路之后你会发现它解决的是最实际的问题业务方不懂 SQL懂 SQL 的人又没时间天天陪业务方改报表口径。DB-GPT 要做的事情是让你用自然语言直接问数据库比如上个月华东区退货率最高的三个品类是什么它负责把这句话翻译成 SQL、执行、再把结果用自然语言答回来。适合谁手里有真实业务数据、想给团队交付一个内网版 ChatBI但又不想从零写 Agent 编排的人。它不是一个对话 Demo而是一套可以接私有数据、可以调模型、可以走 API 被业务系统复用的半成品框架——这意味着你能改也能扩展。我最早接触它是因为某次接了一个用大模型做经营分析的模拟项目当时团队里没有一个能稳定生成多表 JOIN 的 Text-to-SQL 方案。后来把 DB-GPT 部署到内网接上测试库和开源模型从装环境到出第一个可用问答页面大概用了一个下午。这篇文章就按这条落地的路径来写先讲清楚它的架构思路再讲最小部署、建库、调优和避坑最后聊一聊怎么把它嵌进你自己的业务系统里。2. DB-GPT 的核心思路数据库能力是怎么被大模型接管的2.1 不是让模型直接连数据库而是让模型学会使用工具很多人第一次听到用自然语言查数据库第一反应是直接把数据库连接串和 Schema 丢给大模型让它自己生成 SQL 并执行。这在实验环境能跑通到真实环境就翻车生产库的权限控制、敏感字段脱敏、超长 SQL 的稳定性、以及模型把上月理解成上一自然月还是最近30天没有一个环节是白送的。DB-GPT 的架构思路不是模型直连数据库而是把数据库操作封装成一组工具模型只负责理解问题 规划步骤 调用工具真正的查询由数据源层去执行。这个设计带来的直接好处是你可以在模型和数据库之间插入鉴权、脱敏、审计、超时控制甚至把多数据源统一到一个入口后面。Text-to-SQL 在大模型应用里其实只是中间一环前面有意图识别和参数抽取后面有结果解释和追问澄清。DB-GPT 把这一整条链路串成了默认流程这也是它相比自己写几句 Prompt 调 OpenAI 接口最核心的差异点——它给的是一个可落地的框架不是一个一次性脚本。2.2 双模型架构为什么生成模型和推理模型要分开它的默认架构里值得注意的一点是区分了生成模型和推理模型。生成模型负责做 Embedding、做 SQL 结果的自然语言总结这类任务推理模型负责做 Text-to-SQL、做问题理解这类复杂推理。为什么要分开因为这两类任务对模型能力的要求不一样Embedding 任务只要稳定、快、便宜推理任务则需要参数更大、指令跟随能力更强的模型。如果你只用一个小模型同时扛这两类任务会发现问简单问题还行问带子查询和窗口函数的问题就胡编 SQL如果全用大模型又太慢太贵。实际部署的时候这种设计让你能按预算混搭Embedding 用本地的小模型推理用 API 模型或者稍大的本地模型。在模拟项目X里我还试过另一种组合——推理模型用中等规模的开源模型Embedding 用更小的模型整体效果和全上大模型差距不大但显存占用低了一个量级。这个双模型分工不只是一种配置技巧它决定了你后续做模型选型时的取舍逻辑。2.3 从问答到Agent为什么它不只是一个 SQL 翻译器DB-GPT 的野心不止于 Text-to-SQL。它把数据库操作、知识库检索、模型调用都做成了 Agent 可调用的能力这意味着你可以让模型先查一下有哪些表再根据表结构决定 SQL 怎么写最后把结果画成趋势说明。这一个能力链条很重要因为真实业务问题往往是模糊的帮我看看这个月业绩怎么回事——你得先拆出指标、拆出维度、定位到表和字段才能写 SQL。它做的另外一件事是插件化。官方内置的插件包括知识库问答、数据库查询、报表生成等你可以按需打开或关闭。这种插件化设计带来的实际价值是你可以先只开放数据库查询这一个能力做试点防止模型在业务方乱跑其他工具。能力模块作用落地建议数据库查询Text-to-SQL 与结果解释先只开放这一个跑通再扩展知识库问答基于文档/历史口径的 RAG用于沉淀指标口径、业务术语报表生成结果可视化与说明适合管理驾驶舱场景Agent 编排多步骤任务规划适合复杂分析但需设定边界3. 从零到可用DB-GPT 的最小部署与本地跑通3.1 环境准备显卡、系统和依赖项怎么选先给结论如果想在本地跑通完整链路一张 24G 显存的卡是最舒服的起步配置能同时跑 7B~8B 量级的推理模型和一个 Embedding 模型如果只有 16G就得接受速度慢一截或者让推理部分走 API。我见过有人用纯 CPU 跑 7B 模型做 Text-to-SQL一条查询等三分钟属于能跑但没人愿意用的状态。如果你之前部署过其他大模型应用DB-GPT 的环境要求并不算特殊——Python 3.10 以上、PyTorch、CUDA 这几个大头准备好基本就畅通了。操作系统方面Ubuntu 系和 CentOS 系我都跑过Ubuntu 体验更顺主要是依赖编译工具链齐全少踩很多缺这个头文件、缺那个库的坑。Windows 也能跑但建议用 WSL2 而不是原生环境否则光编译一些 Python 扩展就够折腾半天的。下面是启动 DB-GPT 服务的最小命令集。# 创建虚拟环境避免和系统 Python 环境互相污染 python3 -m venv .venv source .venv/bin/activate # 安装核心依赖以 0.6.x 版本为例具体以官方 tag 为准 pip install -e . # 运行一键安装脚本初始化默认配置和依赖项 bash ./scripts/install_all_dependencies.sh # 启动服务默认端口 5670 python -m dbgpt.server第一条命令创建虚拟环境这一步不是为了走形式而是 DB-GPT 依赖的包很多且版本要求偏新直接装到系统环境里很容易和已有项目打架。pip install -e . 是开发模式安装能让你改完代码不用重新安装就能生效。install_all_dependencies.sh 这个脚本会把服务端、前端构建和核心 Python 依赖一次性装好。最后一条启动命令起来之后访问 http://localhost:5670 就能看到管理界面。如果你有特定的推理模型要走 API等服务起来后去界面里的模型管理页配置即可。3.2 配置模型本地模型和 API 模型该填什么服务能起来只是第一步真正决定能不能用的是模型配置。DB-GPT 的模型配置有两种常见路径一是通过管理界面的模型管理页面添加二是直接改配置文件。我建议新手用界面操作因为配置项的校验和提示都更友好。配置本地模型时你需要填模型名称、模型路径、推理后端类型还要指定它跑在 GPU 还是 CPU 上配置 API 模型时则需要填 API 地址、API Key 和模型名。这里面最容易搞混的两个概念是模型名称和模型路径。模型名称是你在系统里给它起的逻辑名字比如chat_model模型路径是实际权重文件的路径比如/data/models/Qwen2.5-7B-Instruct。后面建应用、连数据库时引用的都是逻辑名称不是路径。如果你后续要换一个同类型的模型只需重新配置这个逻辑名称对应的路径不用改业务配置。配置项本地模型API 模型模型名称自定义别名如 sql_model自定义别名如 api_model模型路径权重目录绝对路径不需要填推理后端vLLM / llama.cpp / Transformers对应平台 API需要显存取决于模型大小不需要本地显存一个实操经验初始配置时先把 Embedding 模型固定用本地小模型推理模型用 API 或中等规模本地模型跑通后再逐步调整。这样做的好处是降低首跑的不确定因素——如果一上来就两个模型都是本地的任何一个环节失败你很难判断是哪一段出了问题。3.3 第一次连接数据库建数据源时的关键选项在界面的数据源管理里添加数据库连接时除了常规的主机地址、端口、用户名、密码之外有两处需要多留意。一个是数据库类型要选对比如 MySQL 就选 MySQL不要选成其他因为不同类型走的是不同的方言适配器直接影响后面 Text-to-SQL 的生成效果。另一个是Schema 信息是否自动同步建议勾上。这个选项会自动把库里的表结构、字段注释、索引信息同步到 DB-GPT 的元数据里模型生成 SQL 时才能看到有哪些表和字段可用。# 用命令行方式创建数据源的等价做法通过 API curl -X POST http://localhost:5670/api/v1/datasource/add \ -H Content-Type: application/json \ -d { db_type: mysql, db_host: 127.0.0.1, db_port: 3306, db_user: readonly_user, db_pwd: your_password, db_name: business_analytics, sync_schema: true }上面这个 API 调用演示了用脚本批量建数据源的方式适合你有多个测试库要一次性接进来的场景。db_type 指定数据库类型readonly_user 那个账号是专门为这套系统创建的只读账号这个习惯值得保持——不要用生产库的高权限账号去接大模型应用因为它生成的 SQL 你无法完全预判至少也要保证账号只有 SELECT 权限。sync_schema 参数就是前面说的自动同步表结构建议第一次就打开省得后面一个个手填字段。同步完成后你可以在界面的数据源详情里看到每个表的字段列表和字段注释这些就是模型生成 SQL 时的上下文。3.4 验证链路让模型回答一个真实问题链路是否通了不要问你好这种寒暄直接问一个带业务语义的问题。比如查询每个产品线最近三个月的销售额按月份展示。如果配置正确你会看到执行计划里出现了识别需求 → 生成 SQL → 执行 → 总结结果这样一串步骤。第一次跑的时候建议在界面里打开执行详情看它生成的 SQL 到底是什么不要只看最终文字结果——文字结果看起来对SQL 可能 JOIN 错了表这个习惯从第一天就要养。-- 这是 DB-GPT 针对上述问题生成的一条典型 SQL -- 注意看 GROUP BY 和日期筛选条件是否符合业务口径 SELECT p.product_line, DATE_FORMAT(o.order_date, %Y-%m) AS month, SUM(o.amount) AS total_sales FROM orders o JOIN products p ON o.product_id p.id WHERE o.order_date DATE_SUB(CURDATE(), INTERVAL 3 MONTH) GROUP BY p.product_line, DATE_FORMAT(o.order_date, %Y-%m) ORDER BY month DESC;这条 SQL 看着中规中矩但注意两处容易出问题的细节。一个是对最近三个月的解读这里用了 CURDATE() 往前推三个月但业务上最近三个月有时指这三个月完整月份比如现在是 6 月 15 号业务要的是 3、4、5 月整月数据这种场景下这条 SQL 会把 6 月 1 号到 15 号的数据也算进去。另一个是销售额的口径是订单金额还是实付金额是含税还是不含税模型的判断依据完全来自字段名和注释。所以你会发现DB-GPT 的准确率上限其实不取决于模型取决于你的元数据质量。字段没注释、表名混乱、同一含义字段在不同表里叫不同名字这些才是真正拖垮效果的因素。4. 把领域知识喂进去知识库与提示词的双重调优4.1 为什么要建知识库让模型理解你们公司的说法Text-to-SQL 的上限由元数据决定但元数据只能告诉模型有哪些表和字段告诉不了它你们公司的退货率是按签收时间算而不是下单时间算也告诉不了它VIP 客户的定义是近 90 天消费超过 5000 元。这些业务口径如果不告诉模型它就只能按字面意思猜猜错就是一堆看起来正常但口径不对的 SQL。DB-GPT 解决这个问题的方式是引入知识库——你可以把业务指标文档、历史口径说明、甚至 DBA 平时写的 SQL 规范文档都传进去模型在生成 SQL 前会先去知识库里检索相关片段作为参照。这一步我建议别跳过。我第一次部署时偷懒没建知识库结果退货率被模型生成了退货订单数/总订单数而业务方实际定义是退货金额/销售额完全两个数字。建了知识库并写入口径说明之后这类问题明显减少。知识库的本质是给模型一本你们公司专属的 SQL 手册它回答问题时先去翻手册再动手。4.2 知识库入库与召回测试你会遇到的三个细节建知识库的过程在界面上不复杂新建知识库、上传文档、选择切分方式、触发向量化。但有几个细节会影响最终效果。第一个是文档格式Markdown 和纯文本的解析效果好于 PDF扫描版 PDF 是纯图片向量化之后基本搜不出来建议先转成文本再上传。第二个是切分长度默认的切分参数对大部分场景都适用但如果你文档里有大量表格切分点正好落在表格中间会导致语义不完整需要调小切分长度并开启按段落切分。第三个细节最容易忽略——召回测试。入库之后不要直接去问复杂问题先在知识库管理页面里搜索一个关键词看看召回的片段到底是不是你想要的。比如你上传了退货率口径说明搜索退货率应该召回这段如果召回的是其他不相干片段说明切分或向量化有问题。DB-GPT 支持在知识库页面直接测试召回效果这一步 30 秒就能做完但能帮你省下后面一小时的排错时间。# 通过 SDK 方式向知识库追加文档适合批量处理 from dbgpt.rag import KnowledgeLoader loader KnowledgeLoader( knowledge_space_namebusiness_terms, file_path/data/docs/return_rate_rule.md, chunk_size512, # 切分长度表格多时调小 chunk_overlap64, # 相邻片段重叠保持上下文连续 separators[\n\n, \n, 。, ], # 优先按段落切分 ) loader.load_and_vectorize()这段代码演示的是批量追加文档的姿势。chunk_size 设置的是每个切分片段的最大长度512 个字符对中文场景是个还算稳妥的起点如果文档里表格密集我会调到 256 并配合分隔符。来切避免表格被截断成无意义碎片。chunk_overlap 是相邻片段的重叠长度太小会让被切断的语义接不上太大会让重复内容占满向量空间一般设在 chunk_size 的 10%~20% 之间。separators 的优先级很重要传了 [\n\n, \n, 。, ] 意思是先按空行切空行不够再按换行切再不够按句号切这个顺序可以让段落完整度最大化。跑完这段代码后回到界面搜退货率能召回到对应段落就说明入库成功。4.3 提示词模板把模型装进你们的业务语境里DB-GPT 允许你自定义 Text-to-SQL 的提示词模板默认模板是通用场景的但对特定业务需要做定制。最值得改的两个地方一是角色设定告诉模型你是一名精通 MySQL 的数据分析师熟悉电商零售业务口径二是输出约束明确要求只能使用只读查询、禁止 DELETE/UPDATE、如果问题不明确需要先问清楚再生成 SQL。这里有个小技巧不要把提示词写得像法律条文一样长模型对过长提示词的遵循度反而会下降。把你最核心的口径约束压缩成三五条放在提示词靠前的位置效果远好于写在长篇背景说明后面。我在模拟项目X里实践下来提示词调优的收益常常比换更大的模型还明显——毕竟 Text-to-SQL 的任务难点不在智力在对齐。5. 避坑手册部署与使用中的 7 个典型问题5.1 问题一模型目录填对了但服务一直报找不到模型现象模型配置页显示模型存在但发起对话时报model not found或模型加载失败。原因这个坑我踩过三次基本都是同一个原因——模型配置里的模型名称和前端调用时引用的名称不一致。比如你在模型管理里把名字写成sql_model但数据库问答应用里默认引用的是chat_model自然找不到。如果你配置过多个模型默认模型和应用实际调用的模型是两个不同的概念很多人只配了默认模型忘了改应用那里的引用。解决到模型管理页面核对两处——当前默认模型是谁数据库问答应用的模型引用是谁。让这两者保持一致或者在应用配置里显式指定你新建的模型名称。一个习惯建义给模型起名时直接叫default_llm避免每次建新应用都要重新指定。5.2 问题二生成的 SQL 语法正确但查不到数据或者报字段不存在现象模型生成的 SQL 看起来结构完整执行时却报 Unknown column。原因数据库表结构在你建完数据源之后发生过变更新加的字段没有同步到 DB-GPT 的元数据里。模型只看得到建数据源时同步的 Schema之后你加字段它也不知道自然生成出不存在的字段名。解决在数据源管理里对对应数据源触发一次重新同步 Schema之后模型就能看到新字段。如果你经常改表结构建议做一个定时任务每天凌晨同步一次全量数据源的元数据。5.3 问题三部署后界面能开但问答一直转圈没有响应现象前端页面正常加载发消息后一直 loading后端日志无报错。原因推理模型没有真正启动成功或者模型加载进了显存但在推理时崩溃。常见诱因是显存不足模型加载时显示成功真正推理时 OOM 被系统杀掉进程还在但服务不可用。解决先看nvidia-smi确认显存占用如果显存满了换更小的模型或开启量化再看后端日志里有没有 CUDA out of memory 字样。如果模型是首次加载第一次问答会慢到像卡死这其实是正常的——模型权重在加载到显存等一分钟后就好了。5.4 问题四知识库上传了文档但问答时好像完全没用到现象知识库里文档已经入库且召回测试正常但问答时模型的回答里没有任何知识库内容。原因知识库和数据库问答不是一个自动绑定的关系。你需要在数据库问答应用或 Agent 配置里明确挂载知识库模型才会在生成 SQL 前去检索它。很多人以为传了文档就会自动生效其实还要在应用侧开知识库增强的开关。解决在对应的应用/Agent 配置里找到知识库关联的选项把建好的知识库挂上去。再测试才能看到效果。如果你的场景里知识库和数据库都要用确认两个能力都挂在了同一个 Agent 上。5.5 问题五SQL 执行很慢甚至把数据库拖卡现象某条问答触发了全表扫描或嵌套子查询数据库 CPU 飙高。原因模型生成的 SQL 不一定会主动加索引条件尤其当字段名没有明确语义时它倾向于写范围查询或扫描。这在测试库无所谓在生产库就是事故。解决一是给数据库账号设置最大执行时间max_execution_time超时自动 kill二是通过提示词约束必须使用索引字段作为筛选条件三是在数据源侧把生产库设置为只读账号并启用语句超时。5.6 问题六多轮对话后上下文被带偏现象前面几轮答得好好的追问几个问题后模型开始把上一轮的表名或字段用到当前的问题里。原因多轮对话时历史信息会被拼接进上下文如果历史里有错误 SQL 或无关表名模型会被带跑偏这在长对话里很常见。解决DB-GPT 支持配置多轮对话的记忆策略可以限制只保留最近一轮或两轮。对数据库问答场景建议把历史轮次设小一点——你只需要它能承接上一题的筛选条件再排除某个品类这种轻量依赖不需要它记住十轮前的所有细节。5.7 问题七Embedding 模型用中英文混用导致检索效果差现象知识库召回结果不稳定有时候相关文档排在很后面。原因Embedding 模型按训练语料分了语系有些模型英文效果好中文差或者反过来。知识库文档如果是中文为主默认配置的模型可能不是最优。解决把 Embedding 模型换成中文优化过的模型。判断方法很简单——建一个只有一两个文档的小知识库搜索中文关键词看召回排序是否合理。这一步 5 分钟就能验证值得在正式投入前做一次。6. 进阶用法把 DB-GPT 接入现有业务系统做内网 ChatBI6.1 从界面到 API一个可被业务系统调用的问答接口界面问答只是第一步真正让 DB-GPT 产生业务价值的是把它封装成 API 给现有系统调用。它提供的接口里最核心的是对话补全接口你可以用任意语言发起 HTTP 请求传入问题、会话 ID 和可选的上下文参数拿到模型生成的结果。这意味着你可以把自然语言查数能力嵌入到已有的报表系统、企业微信机器人或者内部工作台里让业务方在原本的办公流里直接问数不必再打开一个单独的界面。# 调用 DB-GPT 的问答接口HTTP 方式 curl -X POST http://localhost:5670/api/v1/chat/completions \ -H Content-Type: application/json \ -d { model: default_llm, messages: [ {role: user, content: 华东区上季度各品类退货率按退货金额口径} ], chat_mode: chat_with_db_execute, datasource: business_analytics, user_input: 华东区上季度各品类退货率 }参数说明model 字段明确指定走哪个模型chat_mode 用chat_with_db_execute表示走数据库查询并执行链路datasource 指定数据源别名。值得提醒的是这里的 datasource 名称要和建数据源时的命名一致。返回结果里会有 SQL、执行结果和最终的自然语言总结三个部分业务系统可以只展示总结也可以把 SQL 存下来做审计。6.2 把模型生成的结果和业务已有的可信结果做比对AI 生成的 SQL 准确率再高也不能直接替代正式报表。真正稳妥的推进方式是AI 生成 SQL 人工确认后执行或者AI 生成 SQL 与已有报表数据做自动比对。后者是我比较推荐的第一步——把 DB-GPT 生成的结果导出和现有报表数据按月对拍差异率低于阈值再逐步放开权限。这本质上是在给模型建立一份可信度账本没有这份账本你很难说服业务方真正信任它。另一个值得做的动作是保存历史问答和对应 SQL。DB-GPT 支持将对话记录持久化你可以定期翻一翻模型生成过哪些低质量 SQL把它沉淀成知识库里的负面案例。这比调十次提示词都有效——因为模型会从正确示例里学也会从被纠正的历史里学。6.3 敏捷落地的节奏从只读库到全量数据源需要几步走如果你想把这件事真正做成一个内网 ChatBI我的建议是分三步。第一步只接入一个只读库开放给 3~5 个核心用户试用目标是验证模型生成的 SQL 有没有低级错误。第二步接入知识库把业务口径文档喂进去用一周的真实问题做回归测试目标是让准确率稳定在可用线以上。第三步再接入第二个数据源测试跨库查询和多轮对话的稳定性。这里有一个经常被忽略的细节你的第一步和第二步之间至少要留出口径收集的时间。业务方真正在意的是你算的数字和我平时看的不一样而这个不一样绝大部分来自口径差异不是 SQL 语法错误。把收集口径当成和调模型一样重要的事来做DB-GPT 项目才真正算是完成了从技术验证到业务交付的转身。我自己的教训是第一次做这类项目时花了大量时间调提示词后来发现只要把口径文档喂进知识库效果立刻上一个台阶——模型本身不缺智力缺的是你给它划定的业务边界。希望这套从部署到嵌入的路径能帮到你至少能让你少踩几个我已经替你趟过的坑。本文还有配套的精品资源点击获取