LLM大模型如何访问MySQL业务数据库

目录

一、LLM大模型如何访问MySQL业务数据库

1.1 为什么需要SQL Agent?

1.2 什么是 create_sql_agent?

1.3 什么是SQLDatabaseToolkit?

二、SQL Agent智能体操作MySQL数据库

三、本地启动服务 验证效果

四、怎么提高SQL Agent智能体的回复准确性?


文章首先讲解了create_sql_agentSQLDatabaseToolkit的核心作用,展示了如何通过LangChain框架连接数据库并创建具备SQL解析能力的智能代理。随后结合实际应用场景,构建了一个基于FastAPI的文件查询系统,演示了如何将自然语言问题转化为结构化数据响应,并确保数据安全与准确性。最后,探讨了提升SQL Agent回复准确性的关键因素,如提示词工程、表结构描述优化、示例引导(Few-Shot Learning)等方法

一、LLM大模型如何访问MySQL业务数据库

1.1 为什么需要SQL Agent?

用户更倾向于用自然语言提问(如“销售额最高的产品是什么?”),而非编写复杂 SQL。

非技术人员(如产品经理、业务人员)无需学习 SQL 即可查询数据库。

包括开发对应的业务智能体,实现数据库的查询和操作

1.2 什么是 create_sql_agent?

创建能通过自然语言与SQL数据库交互的AI智能体,自动生成/执行SQL查询并解析结果

核心能力:

将用户问题(如“统计每个地区的销量”)转化为 SQL 查询语句。

连接数据库执行 SQL,默认只读模式防止数据误修改。

将数据库返回的原始数据(如 [1500, 2000])转换为用户友好的回答(如“总销售额为 $3500”)。

自动修正 SQL 语法错误或逻辑问题(如字段名拼写错误)。

1.3 什么是SQLDatabaseToolkit?

LangChain 中专门用于 连接 SQL 数据库并集成相关操作工具 的模块包

#使用 SQLDatabase.from_uri 连接数据库,自动读取表结构。
db = SQLDatabase.from_uri(database_uri="数据库连接信息",include_tables=['account_file', 'storage'],custom_table_info={"account": "查询账号相关的表"}) #SQLDatabaseToolkit 封装了查询执行、表结构查看等底层操作。
toolkit = SQLDatabaseToolkit(db=db, llm=ChatOpenAI())agent = create_sql_agent(llm=ChatOpenAI(temperature=0, model="gpt-5"),  # 必需:大模型toolkit=toolkit,    # 必需:数据库工具包agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,  # Agent类型verbose=True,          # 显示详细执行过程prefix="""你是一个专业的MySQL专家...""",  # 自定义提示前缀suffix="""请始终检查你的查询结果..."""     # 自定义提示后缀
)

快速的看一个demo 这会更好理解流程:

import os
from langchain_community.agent_toolkits.sql.base import create_sql_agent
from langchain_community.agent_toolkits.sql.toolkit import SQLDatabaseToolkit
from langchain_community.utilities import SQLDatabase
from langchain_openai import ChatOpenAI
from langchain.agents.agent_types import AgentType# 设置OpenAI API密钥
llm = ChatOpenAI(model_name="qwen-plus",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key="sk-xxxxxxxxxxxx",temperature=0,
)# 1. 连接数据库
db = SQLDatabase.from_uri(f"mysql+pymysql://root:xxxxxxx@93.179.111.1111:3306/mysql",include_tables=["account_file"],custom_table_info={"account_file": "查询文件夹和文件内容相关的表"},  # 自定义表描述
)# 初始化工具包
toolkit = SQLDatabaseToolkit(db=db, llm=llm)
print(f"包含的工具个数:{len(toolkit.get_tools())}")
print("工具列表", [tool.name for tool in toolkit.get_tools()])# 创建SQLAgent
agent = create_sql_agent(llm=llm,toolkit=toolkit,verbose=True,agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,handle_parsing_errors=True,max_iterations=10,prefix="You are a helpful assistant that answers questions about the database.",suffix="",
)def ask_question(question: str) -> str:print(f"问题:{question}")result = agent.invoke({"input": question})return result["output"]questions = ["有多少个文件"]for question in questions:answer = ask_question(question)print(f"答案:{answer}")print("-" * 50)

用户请求->创建代理->执行查询->返回结果

二、SQL Agent智能体操作MySQL数据库

需求:通过自然语言查看文件列表、查看文件详细信息、查看文件夹内容

流程说明:

用户请求: 用户发送自然语言查询、获取用户ID

参数处理:处理查询参数、注入用户ID

创建代理:初始化SQL代理、准备查询环境

执行查询:执行数据库查询、获取查询结果

返回结果:返回JSON格式响应

 先思考几个问题:

问题一:大模型操作Mysql数据库如何做到个人数据隔离,不会查询到别人的数据?

问题二:大模型响应给调用方的内容格式如何限制?

问题三:大模型如何更精确的执行用户的查询需求?

解决方案:【!!!!提示词工程!!!】 

 定义返回结果的实体pan_schemas.py文件 

from pydantic import BaseModel
from typing import Optional, Dict, Any, List
from datetime import datetimeclass PanQueryRequest(BaseModel):"""文件查询请求模型"""account_id: Optional[int] = None  # 从token中获取,请求中可选query: strclass FileInfo(BaseModel):"""文件信息模型"""id: int  # account_file表的IDfile_id: int  # 实际存储的文件IDfile_name: strfile_type: strfile_suffix: strfile_size: intgmt_create: datetimegmt_modified: datetimeclass PanQueryResponse(BaseModel):"""文件查询响应模型"""type: strdata: Dict[str, Any] 

创建路由文件file.py

from fastapi import APIRouter, Depends
from models.pan_schemas import PanQueryRequest
from agents.pan_agent import process_pan_query
from core.auth import get_current_user
import logginglogger = logging.getLogger(__name__)
# 创建路由
router = APIRouter(prefix="/api/pan", tags=["文件查询"])@router.post("/query")
async def pan_query(request: PanQueryRequest):request.account_id = 1logger.info(f"用户{request.account_id}开始查询文件")# 调用智能体进行查询return await process_pan_query(request)

file_agent.py

process_pan_query 这个异步方法主要是创建agent ->构建输入->执行获取输出->解析结果返回

async def process_pan_query(request: PanQueryRequest) -> JsonData:agent = create_pan_agent()# 构建查询输入,可以做更多事情,包括检查过滤用户的输入query_input = f"用户ID为{request.account_id}的{request.query}"# 获取代理的输出response = await agent.ainvoke({"input": query_input})if "output" not in response:return JsonData.error("查询失败,请换种方式再重试下")output = response["output"]# 解析数据try:data = json.loads(output) if isinstance(output, str) else outputlogger.info(f"解析数据成功: {data}")return JsonData.success({"type": data.get("type"), "data": data.get("data")})except json.JSONDecodeError as e:logger.error(f"解析数据失败: {str(e)}")return JsonData.success(data={"content": str(output)})

def create_pan_agent() -> Any:"""创建网盘查询agent"""# 创建数据库连接,只读模式db = SQLDatabase.from_uri(f"mysql+pymysql://{settings.MYSQL_USER}:{settings.MYSQL_PASSWORD}@{settings.MYSQL_HOST}:{settings.MYSQL_PORT}/{settings.MYSQL_DATABASE}",include_tables=["account_file"],)# 创建大模型llm = get_default_llm()# 创建数据库工具包tookit = SQLDatabaseToolkit(db=db, llm=llm)# 创建提示词# 创建提示模板prompt = ChatPromptTemplate.from_messages([("system","""你是一个智能网盘助手,专门用于查询用户的网盘文件信息。你只能执行查询操作,不能执行任何修改数据的操作。重要警告:1. 你绝对不能生成或编造任何数据2. 你只能返回实际查询到的数据3. 如果查询没有结果,必须返回空结果4. 任何生成或编造数据的行为都是严重错误5. 你只能使用数据库中的实际数据6. 不能对查询结果进行任何修改或补充7. 不能生成示例数据或占位数据8. 不能假设或推测数据9. 不能使用模板或示例数据10. 不能对数据进行任何形式的加工或美化数据库表结构说明:- account_file: 用户文件表- id: 文件ID(account_file表的主键)- account_id: 用户ID- is_dir: 是否为文件夹(0不是,1是)- parent_id: 上层文件夹ID(顶层为0)- file_id: 实际存储的文件ID- file_name: 文件名称- file_type: 文件类型(common/compress/excel/word/pdf/txt/img/audio/video/ppt/code/csv)- file_suffix: 文件后缀名- file_size: 文件大小(字节)- del: 是否删除(0未删除,1已删除)- del_time: 删除时间- gmt_create: 创建时间- gmt_modified: 更新时间你可以处理以下类型的查询请求:1. 文件查询- 查看我的文件列表- 搜索特定文件- 查看文件详细信息- 查看文件夹内容- 查看最近修改的文件重要限制:1. 你只能执行 SELECT 查询,不能执行任何修改数据的操作2. 所有查询必须包含 account_id 条件,确保数据安全3. 不能执行以下操作:- 删除文件- 修改文件- 创建文件- 移动文件- 重命名文件- 清空回收站- 修改存储空间4. 如果用户请求执行任何修改操作,请礼貌地拒绝并说明原因5. 如果查询没有结果,必须返回空结果,不能生成示例数据6. 绝对不能生成或编造任何数据7. 只能返回实际查询到的数据8. 不能对数据进行任何形式的加工或美化处理请求时请注意:1. 必须使用 account_id 过滤用户数据,确保数据安全2. 对于文件夹查询,使用 is_dir=1 和 parent_id3. 对于文件类型查询,使用 file_type 字段4. 对于模糊查询,使用 LIKE 和通配符5. 对于时间相关的查询,使用 gmt_create 和 gmt_modified7. 结果要简洁明了,突出重点8. 所有查询必须包含 account_id 条件9. 查询文件信息时,必须返回 account_file 表的 id 和 file_id10. 所有响应必须返回 JSON 格式的数据,包含完整的文件信息11. 如果查询没有结果,返回空数组或空对象,不要生成示例数据12. 绝对不能生成或编造任何数据响应格式必须符合以下模型结构:1. 文件列表响应:{{"type": "file_list","data": List[FileInfo]  # FileInfo包含id, file_id, file_name, file_type, file_suffix, file_size, gmt_create, gmt_modified}}请根据用户的问题,使用 SQL 查询来获取信息,并返回符合上述格式的 JSON 数据。重要警告:你绝对不能生成或编造任何数据,只能返回实际查询到的数据。任何生成或编造数据的行为都是严重错误。""",),("human", "{input}"),MessagesPlaceholder(variable_name="agent_scratchpad"),])# 创建SQLAgentagent = create_sql_agent(llm=llm,toolkit=tookit,agent_type="openai-tools",verbose=True,return_intermediate_steps=True,max_iterations=15,handle_parsing_errors=True,prompt=prompt,)return agentdef get_default_llm():return ChatOpenAI(model = settings.LLM_MODEL_NAME,base_url = settings.LLM_BASE_URL,api_key = settings.LLM_API_KEY,temperature = settings.LLM_TEMPERATURE,streaming = settings.LLM_STREAMING)

最主要的就是上面的这些提示词,用来给大模型做各种限制,给大模型提供样例

三、本地启动服务 验证效果

这些是数据库中存在的数据:

使用ApiFox 请求api 

{"code": 0,"data": {"type": "file_list","data": [{"id": 2,"file_id": 101,"file_name": "Resume.pdf","file_type": "pdf"}]},"msg": "","type": "text"
}

成功返回~ 

四、怎么提高SQL Agent智能体的回复准确性?

 SQL Agent智能体的回复准确性,和大模型参数、温度、能力、提示词工程强相关,也包括用户的提问内容

比如更详细的表结构Schema说明,提问改写,提供FewShot样例等,都是可以提高准确度

增强 Schema 理解

 # 在提示词中添加增强元数据描述
prefix = """
你连接的数据库包含以下关键表:
[Customers] 客户表(重要字段:CustomerId, FirstName, LastName, Country)
[Invoices] 发票表(与 Customers 通过 CustomerId 关联)
优先使用 JOIN 代替子查询,注意 Country 字段存储的是国家全称
"""

Few-Shot Learning 通过示例引导生成模式

 examples = [
    {
        "input": "法国客户数量是多少?",
        "query": "SELECT COUNT(*) FROM Customers WHERE Country = 'France'"
    },
    {
        "input": "显示最新的5张发票", 
        "query": "SELECT * FROM Invoices ORDER BY InvoiceDate DESC LIMIT 5"
    }

总结:

本文围绕如何构建一个能够通过自然语言与MySQL数据库交互的SQL Agent智能体展开,涵盖了从环境搭建到本地验证的完整流程。首先介绍了使用create_sql_agentSQLDatabaseToolkit来实现自然语言转SQL的核心机制,并给出了代码示例,帮助开发者快速上手。接着,通过构建一个网盘文件查询服务,展示了如何将智能体集成到实际业务场景中,包括定义数据模型、设计API接口、编写异步处理逻辑等内容。特别强调了提示词工程在控制模型行为、保证数据真实性和避免编造信息方面的重要性。最后,文章分析了影响SQL Agent性能的关键因素,并提出了多种优化策略,如增强Schema理解、提供示例引导等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/89544.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/89544.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL(112)如何选择读写分离策略?

选择读写分离策略是实施读写分离的关键一步。常见的读写分离策略包括简单的读写分离和基于负载均衡的读写分离。为了实现这些策略,我们需要动态地选择数据源。下面详细介绍如何实现基于Spring Boot的读写分离,并结合代码示例展示不同策略的实现。 读写分…

日志-解决Linux因target is busy无法卸载硬盘/分区的问题 - PHP持续占用分区

效果图 写在前面 此次遇到的问题是,php-fpm持续占用设备/mnt/disk1,强制杀死php所有进程后,依然会自动产生新的进程再次霸占分区,导致设备无法卸载umount。思路是解决谁在不停的捣乱。 步骤 核心: 挂载文件系统到指定…

Linux系统权限维持篇

Openssh后门 重新安装自定义的openssh,达到记录账户密码,也可以采用万能密码连接的功能 1、登录方式 2、登录软件 3、登录机制 环境准备 yum -y install openssl openssl-devel pam-devel zlib zlib-devel yum -y install gcc gcc-c makewget http://c…

spring中maven缺少包如何重新加载,报错java: 程序包org.springframework.web.reactive.function不存在

错误原因分析 java: 程序包org.springframework.web.reactive.function不存在 这个错误是由于 项目中缺少 Spring WebFlux 相关依赖 导致的。org.springframework.web.reactive.function 包属于 Spring WebFlux 模块(用于响应式 Web 开发),如…

Linux--线程池

目录 Linux线程池 线程池的概念 线程池的优点 线程池的应用场景 线程池的实现 Linux线程池 线程池的概念 线程池是一种线程的使用模式。 其存在的主要原因就为:线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程&#…

mars3d (基于 Cesium 的轻量化三维地图库)

mars3d 是什么? Mars3D 作为基于 Cesium 的轻量化框架,正以其简洁的 API 和强大的功能重新定义开发体验。它不仅解决了原生 Cesium 学习曲线陡峭的问题,还通过封装和优化实现了性能与易用性的双重突破。无论是智慧城市、低空经济还是军事仿真,Mars3D 都能提供高效的三维可视…

uniapp 中使用路由导航守卫,进行登录鉴权

前言: 在uniapp 使用中,对于登录界面可能需要路由守卫进行方便判断跳转,以下有两种方案,可以判断用户跳转的时候是否是登录状态 方案一: 1. 可以使用插件 hh-router-guard 2. 使用 uni-simpe-route 方案二: 使用通过uni提供的拦截器实现, uni.addInterceptor 1.新建in…

Leetcode 262. 行程和用户

1.题目基本信息 1.1.题目描述 表:Trips ----------------------- | Column Name | Type | ----------------------- | id | int | | client_id | int | | driver_id | int | | city_id | int | | status | enum | | request_at | varchar | -----------…

P1102 A-B 数对

P1102 A-B 数对 题目背景 出题是一件痛苦的事情! 相同的题目看多了也会有审美疲劳,于是我舍弃了大家所熟悉的 A+B Problem,改用 A-B 了哈哈! 题目描述 给出一串正整数数列以及一个正整数 C C C,要求计算出所有满足 A − B = C A - B = C A−B=C 的数对的个数(不同…

devextreme-vue的DxDataGrid如何显示行号列

devextreme-vue我使用的是23.2版本,其DxDataGrid如何显示行号列,官方一直没有方案。 DataGrid - How to display a row number in data rows in Angular | DevExpress Support dxDataGrid - provide capability to display a column with row numbers …

【设计模式06】建造者模式

前言 没什么用,类似于builder.build UML类图 代码示例 package com.sw.learn.pattern.B_create.e_builder;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();for …

datax-web报错:连接数据库失败. 请检查您的 账号、密码、数据库名称、IP、Port或者向 DBA 寻求帮助(注意网络环境)

文章目录 一、报错内容二、解决方法 一、报错内容 背景描述: 在linux安装了datax202309版本及datax-web2.1.2版本,datax与datax-web默认都是mysql5.x版本的。我的数据库是mysql8.x版本的。 在datax中执行json脚本从一个mysql导入mysql没问题&#xff0…

C#调用C++导出的dll怎么调试进入C++ DLL源码

第一步:首先需要打开C源码,不需要任何设置,直接下断点,然后将生成DLL目录改成到C# exe生成目录里面 第二步:打开winform项目,然后在C#项目属性->启用本地代码调试勾选后即可 最后在C#下断点F10或者F11…

Skyeye 云智能制造办公系统 - Saas v3.16.10 发布

Skyeye 云智能制造,采用 Springboot (微服务) Layui UNI-APP Ant Design Vue 的低代码平台。包含 30 多个应用模块、50 多种电子流程,CRM、PM、ERP、MES、ADM、EHR、笔记、知识库、项目、门店、商城、财务、多班次考勤、薪资、招聘、云售后、论坛、公…

pdf 合并 python实现(已解决)

在Python中,可以使用多种库来合并PDF文件,其中最常用的是PyPDF2和PyMuPDF(又名fitz)。下面我将分别介绍如何使用这两个库来合并PDF文件。 使用PyPDF2 首先,你需要安装PyPDF2。可以使用pip来安装: 先按照库…

VCenter SSL过期,登录提示HTTP 500错误解决办法

报错图: 1. 开启 VCenter ssh远程连接 登录vmware esxi,双击打开VCenter 控制台黑窗口,根据提示按F2键 两次,打开系统设置(有fn键使用fnF2键) 输入root密码,按回车登录 选择“Troubleshooting …

Linux 下安装Oracle 11gR2 x64 netca启动不了

前言 Oracle Network Configuration Assistant (netca) 是 Oracle 提供的图形化网络配置工具,用于简化 Oracle 数据库网络组件的配置和管理。 核心功能 1、配置监听器 (LISTENER)创建、修改或删除数据库监听器(默认端口 1521)定义监听协议…

Pytorch1线性代数实现

Pytorch --线性代数实现 矩阵 正如向量将标量从零阶推广到一阶,矩阵将向量从一阶推广到二阶。 矩阵,我们通常用粗体、大写字母来表示 (例如,𝑋、𝑌和𝑍), 在代码中表示…

行业分享丨泛亚汽车数字化转型实践:虚拟仿真技术如何赋能汽车研发的创新实践?

随着汽车行业向智能化、电动化快速转型,虚拟仿真技术正成为推动产品研发变革的核心驱动力。作为行业技术先锋,泛亚汽车通过系统性布局,构建了完整的虚拟仿真技术体系,并总结出三个关键方向:打造数字化研发体系、探索精…

【硬核数学】4. AI的“寻路”艺术:优化理论如何找到模型的最优解《从零构建机器学习、深度学习到LLM的数学认知》

欢迎来到本系列的第四篇文章。我们已经知道,训练一个AI模型,本质上是在寻找一组参数,使得描述模型“有多差”的损失函数 L ( θ ) L(\theta) L(θ) 达到最小值。微积分给了我们强大的工具——梯度下降,告诉我们如何一步步地向着最…