如何用Dify与Qwen搭建MySQL智能NL2SQL工作流教程

作者:袖梨 2026-06-30
用Dify+Qwen本地模型可5分钟实现自然语言转MySQL查询,全程离线运行;需配置Docker环境、Ollama/vLLM接入Qwen模型、创建NL2SQL工作流并调试验证。

当业务同事发来“查一下上个月华东区销量最高的3个产品”这类需求时,你不再需要手动写SQL或反复确认字段名——用Dify拖拽编排+Qwen本地模型,5分钟内就能让自然语言直接生成可执行的MySQL查询语句。整个流程不依赖公网API、不上传任何业务数据,所有推理和查询都在你自己的机器上完成。

准备本地运行环境

先确保Docker已安装并正常运行,Ubuntu 22.04或WSL2环境最稳定。若使用Windows,请确认WSL2已启用且Docker Desktop配置为使用WSL2后端。

克隆Dify最新代码并进入Docker部署目录:

git clone https://github.com/langgenius/dify.git → cd dify/docker

复制示例环境文件:【cp .env.example .env】,这一步不能跳过,否则后续服务会因缺失环境变量启动失败。

执行一键启动:【docker compose up -d】。首次运行需拉取镜像,约2~3分钟。完成后访问 http://localhost:3000 即可看到Dify登录页。

配置Qwen模型接入Dify

方法一:通过Ollama本地托管(推荐小白)

在终端运行:【ollama run qwen2.5-coder:7b】,等待模型下载完成并自动加载。Ollama默认监听 http://localhost:11434。

进入Dify后台 → 右上角头像 → 设置 → 模型供应商 → 添加模型 → 填写:模型名称填 qwen2.5-coder,基础URL填 http://host.docker.internal:11434,点击保存。

注意:Docker容器内无法用 localhost 访问宿主机服务,必须用 host.docker.internal 这个别名,否则连接会超时。

方法二:用vLLM部署Qwen3-1.5B(适合有GPU的用户)

执行命令:【vllm serve Qwen/Qwen2.5-1.5B-Instruct --port 9999 --dtype float16】,启动后基础URL改为 http://host.docker.internal:9999/v1。

创建NL2SQL工作流

第一步:新建应用 → 选择“聊天编排” → 命名为“MySQL智能问数”。

第二步:删除默认LLM节点,在开始节点后添加工具节点 → 选择“rookie_text2data”插件(需提前从GitHub安装:https://github.com/jaguarliuu/rookie_text2data)。

第三步:配置rookie_text2data参数:

数据库类型选 MySQL;

主机地址填你的MySQL容器名或宿主机IP(如Docker网络中MySQL容器名为 mysql-db,则填 mysql-db);

端口、用户名、密码、数据库名按实际填写;

表结构描述粘贴进“Schema Description”栏——这是生成准确SQL的关键,必须包含主键、外键、字段类型及注释。

第四步:在rookie_text2data节点后接一个LLM节点,System提示词设为:

“你是一位MySQL专家,只输出标准SQL语句。检查输入SQL是否符合MySQL 8.0语法,修正表名/字段名大小写、反引号缺失、函数误用等问题。输出必须是单条可执行语句,不含解释、不含```标记。”

第五步:再接一个rookie_excute_sql工具节点,输入变量选上一步LLM输出的text字段,执行结果将自动返回JSON格式数据。

调试与验证

点击右上角“测试”按钮,输入自然语言问题:“查出销售额大于10万的商品名称和销量”。观察各节点输出:

rookie_text2data节点应输出类似 SELECT name, sales FROM products WHERE sales > 100000 的原始SQL;

LLM节点输出应为修正后的标准SQL,比如字段加了反引号、WHERE条件加了括号;

rookie_excute_sql节点输出应为JSON数组,含字段名和数据行;

若某节点报错,重点检查rookie_text2data的数据库连接参数和Schema描述是否与真实表结构完全一致——【字段名拼写错误或类型描述不符会导致SQL生成失败】

在rookie_excute_sql节点后添加一个模板转换节点,将JSON转为易读文本,变量填 {{#节点ID.output#}},格式设为“{{item.name}}: {{item.sales}}”。

相关文章

精彩推荐