首页/文章列表/文章详情

AI实战:Text_To_SQL+Prompt+数据库(MySQL)+MCP

编程知识732025-04-15评论

一、Text-to-SQL应用概述

什么是Text-to-SQL?Text-to-SQL也称为NL2SQL,是将自然语言查询转换为可在关系数据库上执行的SQL查询的技术。

其核心目标是准确捕捉并反映用户意图,生成相应的SQL查询,确保执行后返回符合预期的结果。

 

在前面一篇文章中,链接如下:https://www.cnblogs.com/xiao987334176/p/18816166

需要3个文件ddl.txt,description.txt,qa.xlsx才能实现Text-to-SQL。

其中最重要的qa.xlsx,里面的sql就是黄金语句。但是正常情况下,需要准备2000-5000条sql,才能满足需求。

特别的耗时耗力,如果一旦表结构发生更改,就需要重写。

二、提示工程优化

为解决这些问题,可考虑采用提示工程(Prompt Engineering)、模型微调(Fine-tuning)、

联合检索增强生成和智能代理(RAG & Agent)等方法,以优化模型及应用的Text-to-SQL任务设计。

 

通过设计特定的提示词或语句,引导模型生成更贴合用户意图的输出内容。在处理SQL查询时,

向模型注入特定领域的知识,如SQL规范、数据库架构以及数据字段注释等额外信息,

能够显著提升模型对于SQL语句结构和逻辑的理解能力。

提示工程的关键在于将自然语言问题与必要的数据库信息转化为适用于大语言模型(LLM)的自然语言序列输入,

即问题表示。同时,当允许输入一些样例以利用LLM的上下文学习能力时,

还需要考虑如何选择样例以及如何将这些样例有机地组织到输入序列中。

 

提示工程的关键在于将自然语言问题与必要的数据库信息转化为适用于大语言模型(LLM)的自然语言序列输入,即问题表示。同时,当允许输入一些样例以利用LLM的上下文学习能力时,还需要考虑如何选择样例以及如何将这些样例有机地组织到输入序列中。

 

通过构建包含基本提示、文本表示提示、OpenAI范式提示、代码表示提示、指令微调提示以及上下文学习等综合Prompt策略的方法,在Text-to-SQL的Prompt设计中融入说明、数据结构、示例、提示或约束、领域知识及用户问题等要素,能够取得较好的效果,具体如下:

(1)说明:如,“你是一个SQL生成专家。请参考如下的数据表结构,输出SQL语句。”

(2)数据结构:相当于语言翻译中的字典。即需要使用的数据库表结构,把数据结构组装进Prompt,包括表名、列名、列的类型、列的含义、主外键信息。

(3)示例:作为可选项,也是提示工程的常见方式。即指导大模型生成SQL的参考范本。

(4)提示或约束:其他必要的指示。    

(5)领域知识:可选项,某些特定问题中,对常识描述的解释。

(6)用户问题:用户提出的问题。

融合上述元素,可以得到TEXT-TO-SQL通用Prompt模板框架如下:

# 描述Text-to-SQL任务的说明${示例}# 描述数据库表结构信息${数据库表结构}# 相似用户问题及对应的SQL语句/[可选]${示例}# 用户问题相关的领域知识/[可选]${领域知识}# 提示或其他约束条件[可选]${提示/约束}# 需要生成SQL的用户问题${用户问题}

Agent增强

AI Agent(智能体)是一种模拟人类或其他智能体行为和决策过程的系统。通过引入行动能力、

长期记忆机制和工具整合能力,能够感知环境、处理信息、制定策略并执行行动来完成任务。

AI Agent通过一个框架规划多个方法,这个框架具有一些具体模块,支持整个结构的运行。

在Text-to-SQL任务中,这通常涉及多个步骤,Agent需要了解这些步骤并提前规划,具体的类型包括:

目标和任务分解:Agent将大型任务分解为更小、更易管理的子目标,以便有效地处理复杂任务。

反思与改进:Agent可以对过去的行为进行自我校准和自我反思,从错误中学习并改进未来步骤,从而提高最终结果的质量。

外部工具与资源利用:Agent可以调用各种外部工具集,如搜索引擎、数据库接口等,以扩展其功能并增强解决问题的能力。

对话管理与上下文保持:通过维护对话历史和关键信息,Agent能够在连续提问或修正查询时保持上下文的连贯性,提升用户体验。

 

三、MySQL数据

新建表结构

本文使用的MySQL数据为8.0.41

新建数据库test

CREATE DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

新建5个表

班级表

CREATE TABLE `classes` ( `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '班级ID,示例:202301', `className` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '班级名称,示例:2023级计算机1班', `grade` int NOT NULL COMMENT '年级,示例:2023', `headTeacherId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '班主任ID,外键(teachers.id),示例:T003', `classroom` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '教室位置,示例:1号楼302', `studentCount` int NOT NULL COMMENT '学生人数,示例:35', `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '备注信息,示例:市级优秀班集体', PRIMARY KEY (`id`), KEY `headTeacherId` (`headTeacherId`), CONSTRAINT `headTeacherId` FOREIGN KEY (`headTeacherId`) REFERENCES `teachers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='班级表';

课程表

CREATE TABLE `courses` ( `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '课程ID,示例:C001', `courseName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '课程名称,示例:高等数学', `credit` int NOT NULL COMMENT '学分,示例:4', `teacherId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '授课教师ID,外键(teachers.id),示例:T001', `semester` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '学期,格式"YYYY-N",示例:2023-1', `type` enum('必修','选修') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '选修'COMMENT'课程类型,"必修"或"选修",示例:选修', `prerequisite` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '先修课程ID,可选,外键(courses.id),示例:C003', PRIMARY KEY (`id`), KEY `teacherId` (`teacherId`), CONSTRAINT `teacherId` FOREIGN KEY (`teacherId`) REFERENCES `teachers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='课程表';

成绩表

CREATE TABLE `scores` ( `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '成绩记录ID,示例:S20230101C001', `studentId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '学生ID,外键(students.id),示例:S20230101', `courseId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '课程ID,外键(courses.id),示例:C001', `score` int NOT NULL COMMENT '综合成绩,0-100,示例:85', `examDate` date NOT NULL COMMENT '考试日期,示例:2024-5-20', `usualScore` intDEFAULT'0'COMMENT'平时成绩,0-100,示例:90', `finalScore` intDEFAULT'0'COMMENT'期末成绩,0-100,示例:80', PRIMARY KEY (`id`), KEY `studentId` (`studentId`), KEY `courseId` (`courseId`), CONSTRAINT `courseId` FOREIGN KEY (`courseId`) REFERENCES `courses` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `studentId` FOREIGN KEY (`studentId`) REFERENCES `students` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='成绩表';

学生表

CREATE TABLE `students` ( `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '学号,示例:S20230101', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '学生姓名,示例:王强', `gender` enum('','') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT ''COMMENT'性别,"男"或"女",示例:男', `birthDate` datetime NOT NULL COMMENT '出生日期,示例:2005-01-15', `classId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '班级ID,外键(classes.id),示例:202301', `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '联系电话,示例:13812345678', `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '电子邮箱,示例:20230101@school.edu.cn', `emergencyContact` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '紧急联系人电话,示例:13876543210', `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '家庭住址,示例:北京市海淀区中关村大街1栋101室', `height` int NOT NULL COMMENT '身高(cm),示例:175', `weight` int NOT NULL COMMENT '体重(kg),示例:65', `healthStatus` enum('良好‌','一般‌','较差') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '良好‌'COMMENT'健康状况,示例:良好', PRIMARY KEY (`id`), KEY `classId` (`classId`), CONSTRAINT `classId` FOREIGN KEY (`classId`) REFERENCES `classes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='学生表';

教师表

CREATE TABLE `teachers` ( `id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '教师ID,示例:T001', `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '教师姓名,示例:张建国', `gender` enum('','') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT ''COMMENT'性别,"男"或"女",示例:男', `subject` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '教授科目,示例:数学', `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '职称,示例:教授', `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '联系电话,示例:13812345678', `office` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '办公室位置,示例:博学楼301', `wechat` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '微信,示例:lily_teacher', `isHeadTeacher` enum('true','false') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT 'false'COMMENT'是否为班主任,示例:true', PRIMARY KEY (`id`,`office`) USING BTREE, KEY `id` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='教师表';

录入数据

1. 插入 teachers 表数据

INSERT INTO `teachers` (`id`, `name`, `gender`, `subject`, `title`, `phone`, `office`, `wechat`, `isHeadTeacher`) VALUES('T001','张建国','','数学','教授','13812345678','博学楼301','lily_teacher','true'),('T002','李明','','英语','副教授','13812345679','博学楼302','tom_teacher','false'),('T003','王芳','','物理','讲师','13812345680','博学楼303','lucy_teacher','true'),('T004','赵强','','化学','副教授','13812345681','博学楼304','jack_teacher','false'),('T005','陈静','','计算机','教授','13812345682','博学楼305','rose_teacher','true'),('T006','刘伟','','语文','讲师','13812345683','博学楼306','mike_teacher','false'),('T007','黄丽','','历史','副教授','13812345684','博学楼307','jane_teacher','true'),('T008','周明','','地理','讲师','13812345685','博学楼308','ben_teacher','false'),('T009','吴芳','','生物','教授','13812345686','博学楼309','susan_teacher','true'),('T010','郑强','','政治','副教授','13812345687','博学楼310','david_teacher','false');

2. 插入 classes 表数据

INSERT INTO `classes` (`id`, `className`, `grade`, `headTeacherId`, `classroom`, `studentCount`, `remark`) VALUES('202301','2023级计算机1班',2023,'T005','1号楼302',35,'市级优秀班集体'),('202302','2023级数学1班',2023,'T001','1号楼303',32,'校级优秀班集体'),('202303','2023级英语1班',2023,'T002','1号楼304',30, NULL),('202304','2023级物理1班',2023,'T003','1号楼305',34,'校级先进班集体'),('202305','2023级化学1班',2023,'T004','1号楼306',31, NULL),('202201','2022级计算机1班',2022,'T005','1号楼402',36,'市级优秀班集体'),('202202','2022级数学1班',2022,'T001','1号楼403',33, NULL),('202203','2022级英语1班',2022,'T002','1号楼404',32,'校级优秀班集体'),('202204','2022级物理1班',2022,'T003','1号楼405',30, NULL),('202205','2022级化学1班',2022,'T004','1号楼406',35,'市级先进班集体');

3. 插入 students 表数据

INSERT INTO `students` (`id`, `name`, `gender`, `birthDate`, `classId`, `phone`, `email`, `emergencyContact`, `address`, `height`, `weight`, `healthStatus`) VALUES('S20230101','王强','','2005-01-15 00:00:00','202301','13812345678','20230101@school.edu.cn','13876543210','北京市海淀区中关村大街1栋101室',175,65,'良好'),('S20230102','李华','','2005-02-20 00:00:00','202301','13812345679','20230102@school.edu.cn','13876543211','上海市浦东新区张江高科技园区2栋201室',165,55,'良好'),('S20230201','张明','','2005-03-10 00:00:00','202302','13812345680','20230201@school.edu.cn','13876543212','广州市天河区珠江新城3栋301室',180,70,'良好'),('S20230202','刘芳','','2005-04-05 00:00:00','202302','13812345681','20230202@school.edu.cn','13876543213','深圳市南山区科技园4栋401室',168,58,'良好'),('S20230301','陈伟','','2005-05-15 00:00:00','202303','13812345682','20230301@school.edu.cn','13876543214','南京市玄武区珠江路5栋501室',178,68,'良好'),('S20230302','赵丽','','2005-06-20 00:00:00','202303','13812345683','20230302@school.edu.cn','13876543215','杭州市西湖区文三路6栋601室',162,52,'良好'),('S20230401','黄强','','2005-07-10 00:00:00','202304','13812345684','20230401@school.edu.cn','13876543216','成都市高新区天府软件园7栋701室',176,66,'良好'),('S20230402','周静','','2005-08-05 00:00:00','202304','13812345685','20230402@school.edu.cn','13876543217','武汉市洪山区光谷广场8栋801室',167,57,'良好'),('S20230501','吴伟','','2005-09-15 00:00:00','202305','13812345686','20230501@school.edu.cn','13876543218','西安市雁塔区科技路9栋901室',177,67,'良好'),('S20230502','郑芳','','2005-10-20 00:00:00','202305','13812345687','20230502@school.edu.cn','13876543219','长沙市岳麓区麓谷大道10栋1001室',163,53,'良好');

4. 插入 courses 表数据

INSERT INTO `courses` (`id`, `courseName`, `credit`, `teacherId`, `semester`, `type`, `prerequisite`) VALUES('C001','高等数学',4,'T001','2023-1','必修', NULL),('C002','大学英语',3,'T002','2023-1','必修', NULL),('C003','大学物理',4,'T003','2023-1','必修', NULL),('C004','大学化学',3,'T004','2023-1','必修', NULL),('C005','计算机基础',3,'T005','2023-1','必修', NULL),('C006','数据结构',4,'T005','2023-2','选修','C005'),('C007','线性代数',3,'T001','2023-2','选修','C001'),('C008','概率论与数理统计',4,'T001','2023-2','选修','C001'),('C009','英语口语',2,'T002','2023-2','选修','C002'),('C010','物理实验',2,'T003','2023-2','选修','C003');

5. 插入 scores 表数据

INSERT INTO `scores` (`id`, `studentId`, `courseId`, `score`, `examDate`, `usualScore`, `finalScore`) VALUES('S20230101C001','S20230101','C001',85,'2024-05-20',90,80),('S20230101C002','S20230101','C002',90,'2024-05-20',85,95),('S20230101C005','S20230101','C005',95,'2024-05-20',92,98),('S20230201C001','S20230201','C001',88,'2024-05-20',87,90),('S20230201C003','S20230201','C003',82,'2024-05-20',80,85),('S20230301C002','S20230301','C002',87,'2024-05-20',85,90),('S20230301C004','S20230301','C004',80,'2024-05-20',78,82),('S20230401C003','S20230401','C003',86,'2024-05-20',84,88),('S20230401C005','S20230401','C005',92,'2024-05-20',90,94),('S20230501C004','S20230501','C004',84,'2024-05-20',82,86);

四、MCP设置

mcp代码

参考文章:https://www.cnblogs.com/xiao987334176/p/18822444

这里就不重复了,运行python代码即可

 

五、Cherry Studio测试

mcp设置

 创建agent

 

名称:test

提示词:

使用中文回复。当用户提问中涉及学生、教师、成绩、班级、课程等实体时,需要使用 MySQL MCP 进行数据查询和操作,表结构说明如下:# 学生管理系统数据库表结构说明## 1. 教师表 (teachers)| 字段名 | 类型 | 描述 | 约束 | 示例 ||--------|------|------|------|------|| id | varchar | 教师ID | 主键 | "T001" || name | varchar | 教师姓名 | 必填 | "张建国" || gender | enum | 性别 | """" | "" || subject | varchar | 教授科目 | 必填 | "数学" || title | varchar | 职称 | 必填 | "教授" || phone | varchar | 联系电话 | 必填 | "13812345678" || office | varchar | 办公室位置 | 必填 | "博学楼301" || wechat | varchar | 微信(可选) | 可选 | "lily_teacher" || isHeadTeacher | enum | 是否为班主任,"true""false" | 可选 | true |##2. 班级表 (classes)| 字段名 | 类型 | 描述 | 约束 | 示例 ||--------|------|------|------|------|| id | varchar | 班级ID | 主键 | "202301" || className | varchar | 班级名称 | 必填 | "2023级计算机1班" || grade | int | 年级 | 必填 | 2023 || headTeacherId | varchar | 班主任ID | 外键(teachers.id) | "T003" || classroom | varchar | 教室位置 | 必填 | "1号楼302" || studentCount | int | 学生人数 | 必填 | 35 || remark | varchar | 备注信息 | 可选 | "市级优秀班集体" |##3. 课程表 (courses)| 字段名 | 类型 | 描述 | 约束 | 示例 ||--------|------|------|------|------|| id | varchar | 课程ID | 主键 | "C001" || courseName | varchar | 课程名称 | 必填 | "高等数学" || credit | int | 学分 | 必填 | 4 || teacherId | varchar | 授课教师ID | 外键(teachers.id) | "T001" || semester | varchar | 学期 | 格式"YYYY-N" | "2023-1" || type | enum | 课程类型 | "必修""选修" | "必修" || prerequisite | varchar | 先修课程ID | 可选,外键(courses.id) | "C003" |##4. 学生表 (students)| 字段名 | 类型 | 描述 | 约束 | 示例 ||--------|------|------|------|------|| id | varchar | 学号 | 主键 | "S20230101" || name | varchar | 学生姓名 | 必填 | "王强" || gender | enum | 性别 | """" | "" || birthDate | date | 出生日期 | 必填 | date("2005-01-15") || enrollmentDate | date | 入学日期 | 必填 | date("2023-8-1") || classId | varchar | 班级ID | 外键(classes.id) | "202301" || phone | varchar | 联系电话 | 必填 | "13812345678" || email | varchar | 电子邮箱 | 必填 | "20230101@school.edu.cn" || emergencyContact | varchar | 紧急联系人电话 | 必填 | "13876543210" || address | varchar | 家庭住址 | 必填 | "北京市海淀区中关村大街1栋101室" || height | int | 身高(cm) | 必填 | 175 || weight | int | 体重(kg) | 必填 | 65 || healthStatus | enum | 健康状况 | 必填,"良好""一般‌""较差""良好" |##5. 成绩表 (scores)| 字段名 | 类型 | 描述 | 约束 | 示例 ||--------|------|------|------|------|| id | varchar | 成绩记录ID | 主键 | "S20230101C001" || studentId | varchar | 学生ID | 外键(students.id) | "S20230101" || courseId | varchar | 课程ID | 外键(courses.id) | "C001" || score | int | 综合成绩 | 0-100|85 || examDate | date | 考试日期 | 必填 | date("2024-5-20") || usualScore | int | 平时成绩 | 0-100|90 || finalScore | int | 期末成绩 | 0-100|80|### 补考成绩记录说明补考记录在_id后添加"_M"后缀,如"S20230101C001_M"## 表关系说明1. **一对多关系**:   - 一个班级(classes)对应多个学生(students)   - 一个教师(teachers)可以教授多门课程(courses)   -一个学生(students)有多条成绩记录(scores)2. **外键约束**:   - students.classId → classes.id   - courses.teacherId → teachers.id   - scores.studentId → students.id   - scores.courseId → courses.id   - classes.headTeacherId → teachers.id

重点就是这段提示词了,这里面详细介绍了每个表、字段解释,表对应关系,一对多,外键约束等等。

根据这些,AI模型就可以智能组织sql语句,进行sql查询。

 

效果如下:

 添加到聊天助手

测试agent

 返回到聊天页面,点击test

开启mcp

选择模型,输入问题,就可以得到答案

 

模糊匹配也可以

 

从上面2张图,就可以看到,执行了一个多表查询语句,得到了正确的结果。

重点还是提供词提供的比较详细,所以AI模型,能组织正确的sql进行查询。

单表和多表都是可以的。

 

 

肖祥

这个人很懒...

用户评论 (0)

发表评论

captcha