1. 项目概览
现代应用越来越多地采用自然语言交互界面,让用户更轻松地操作系统。这在数据查询场景中尤为实用,非技术人员可以直接用日常语言提问。 文本转 SQL 聊天机器人正是这样的典型应用。它在人类语言和数据库之间搭建了沟通桥梁。我们通常借助大语言模型(LLM)将用户的自然语言问题转换为可执行的 SQL 查询语句,然后在数据库中执行查询并返回结果。 本教程将指导你使用 Spring AI 框架构建一个文本转 SQL 聊天机器人。我们会先配置数据库架构并填入测试数据,然后实现支持自然语言查询的聊天机器人功能。2. 项目搭建
2.1. 添加依赖
首先在项目的pom.xml
文件中添加必要的依赖:
- OpenAI 兼容启动器依赖,可以与 DeepSeek API 兼容使用
- Spring Boot JDBC 启动器,提供
JdbcClient
支持 - MySQL 驱动程序
- Flyway 数据库迁移工具
application.yaml
文件中配置 DeepSeek API 密钥、聊天模型和数据库连接:
${}
占位符语法从环境变量中读取 API 密钥和数据库配置。
同时指定使用 DeepSeek Chat 模型,并配置 DeepSeek 的 API 基础 URL。DeepSeek 提供了强大的中文和代码理解能力,非常适合文本转 SQL 的场景。数据库配置包括连接 URL、用户名和密码,以及 Flyway 迁移设置。
配置完成后,Spring AI 会自动创建 ChatModel
类型的 Bean,让我们能够与指定的模型进行交互。
2.2. 使用 Flyway 设计数据库表结构
接下来配置数据库结构。我们使用 Flyway 来管理数据库迁移脚本。 我们将创建一个简单的学校管理数据库,使用 MySQL 作为数据库。和 AI 模型选择一样,数据库类型对实现方案没有影响。 首先,在src/main/resources/db/migration
目录下创建名为 V01__creating_database_tables.sql
的迁移脚本来建立主要数据库表:
classes
表存储班级信息courses
表存储课程信息students
表存储学生信息,通过外键与班级关联student_courses
表作为学生和课程的多对多关联表,存储选课信息和成绩
V02__adding_classes_data.sql
文件来填充 classes
表:
V03__adding_courses_data.sql
迁移脚本填充 courses
表:
V04__adding_students_data.sql
迁移脚本填充 students
表:
3. 配置 AI 提示词
接下来,为了确保 LLM 能够针对我们的数据库架构生成准确的 SQL 查询,需要定义详细的系统提示词。 在src/main/resources
目录下创建 system-prompt.st
文件:
ddl
占位符用于数据库架构。稍后我们会用实际值替换它。
此外,为了进一步保护数据库免受修改,应该只给配置的 MySQL 用户必要的权限。
4. 构建文本转 SQL 聊天机器人
完成配置后,让我们使用配置好的 DeepSeek 模型构建文本转 SQL 聊天机器人。4.1. 定义聊天机器人 Bean
首先定义聊天机器人所需的 Bean:PromptTemplate
Bean。通过 @Value
注解注入系统提示词模板文件和数据库架构 DDL 迁移脚本。同时,我们用数据库架构内容填充 ddl
占位符。这确保了 LLM 在生成 SQL 查询时始终能访问我们的数据库结构。
接下来,我们使用 ChatModel
和 PromptTemplate
Bean 创建一个 ChatClient
Bean。ChatClient
类是我们与配置的 DeepSeek 模型交互的主要入口点。
4.2. 实现服务类
现在,让我们实现服务类来处理 SQL 生成和执行过程。 首先,创建一个SqlGenerator
服务类,将自然语言问题转换为 SQL 查询:
generate()
方法中,我们接收自然语言问题作为输入,使用 chatClient
Bean 将其发送给配置的 LLM。
接下来,我们验证响应确实是 SELECT 查询。如果 LLM 返回 SELECT 查询以外的任何内容,我们抛出带有错误消息的自定义 InvalidQueryException
。
接下来,为了对数据库执行生成的 SQL 查询,创建一个 SqlExecutor
服务类:
execute()
方法中,我们使用 Spring Boot 3.1+ 引入的 JdbcClient
来运行原生 SQL 查询并返回结果。JdbcClient
提供了更简洁的 API 和更好的类型安全性。如果查询没有返回结果,我们抛出自定义的 EmptyResultException
。
4.3. 暴露 REST API
现在我们已经实现了服务层,让我们在其上暴露一个 REST API:POST /query
端点接受自然语言问题,使用 sqlGenerator
Bean 生成相应的 SQL 查询,将其传递给 sqlExecutor
Bean 从数据库获取结果,最后将数据包装在 QueryResponse
记录中并返回。使用 JdbcClient
返回的结果是 List<Map<String, Object>>
格式,每个 Map 代表一行数据,键为列名,值为对应的数据。
5. 与聊天机器人交互
最后,让我们使用暴露的 API 端点与文本转 SQL 聊天机器人进行交互。 但首先,在application.yaml
文件中启用 SQL 日志记录,以在日志中查看生成的查询:
students
和 classes
表来查找高三年级的学生信息。DeepSeek 模型展现了出色的中文理解和 SQL 生成能力。
6. 总结
本教程展示了如何使用 Spring AI 框架构建一个功能完整的文本转 SQL 聊天机器人。 虽然我们已经构建了一个基础的文本转 SQL 系统,但仍有许多改进空间:- 权限控制:根据用户角色限制可访问的数据范围
- 结果可视化:将查询结果以图表形式展示
- LLM生成优化:通过JSON格式化和JSON修复支持稳定输出