1. 代码功能简要说明
该代码基于LangChain+LangGraph框架构建具备自主决策能力的SQL智能代理(Agent),整合gpt-4-turbo模型与MySQL数据库,核心能力如下:
- 全流程自动化:代理可自主完成“分析用户自然语言问题→查看数据库表结构→生成语法正确的SQL→执行SQL→处理执行错误(如有)→整合结果生成自然语言回答”;
- 安全与规范:限制SQL查询结果最多10条、禁止执行DML操作(插入/更新/删除等)、执行前校验SQL语法;
- 支持复杂问答:能处理需多步推理的数据库问题(如“哪个部门员工人数最多?”),无需手动编写/执行SQL,全程由代理自主决策完成。
2. 带逐行详细注释的完整代码
# 导入os库:1.配置网络代理(解决国内访问OpenAI API的网络限制) 2.配置LangChain环境变量
import os
# 导入itemgetter:(本代码未使用)从字典提取指定key的值,预留参数提取能力
from operator import itemgetter
# 导入bs4(BeautifulSoup):(本代码未使用)预留网页数据加载能力
import bs4
# 导入create_stuff_documents_chain:(未使用)基础RAG问答链,预留检索增强能力
from langchain.chains.combine_documents import create_stuff_documents_chain
# 导入create_history_aware_retriever:(未使用)历史感知检索器,预留上下文关联能力
from langchain.chains.history_aware_retriever import create_history_aware_retriever
# 导入create_retrieval_chain:(未使用)顶层RAG链,预留检索+问答整合能力
from langchain.chains.retrieval import create_retrieval_chain
# 导入create_sql_query_chain:(未使用)基础SQL生成链,Agent内部已封装该能力
from langchain.chains.sql_database.query import create_sql_query_chain
# 导入Chroma:(未使用)向量数据库,预留RAG能力
from langchain_chroma import Chroma
# 导入SQLDatabaseToolkit:SQL工具包,封装数据库相关的所有工具(查表、查结构、执行SQL等)
from langchain_community.agent_toolkits import SQLDatabaseToolkit
# 导入WebBaseLoader:(未使用)网页加载器,预留外部数据加载能力
from langchain_community.document_loaders import WebBaseLoader
# 导入QuerySQLDataBaseTool:(未使用)独立SQL执行工具,Toolkit已包含该能力
from langchain_community.tools import QuerySQLDataBaseTool
# 导入SQLDatabase:LangChain封装的数据库交互类,支持MySQL/PostgreSQL等
from langchain_community.utilities import SQLDatabase
# 导入消息类型:
# - SystemMessage:系统指令,定义Agent的行为规则
# - HumanMessage:用户消息,封装用户的自然语言问题
from langchain_core.messages import SystemMessage, HumanMessage
# 导入StrOutputParser:(未使用)输出解析器,预留结果格式化能力
from langchain_core.output_parsers import StrOutputParser
# 导入提示模板相关:(未使用)预留提示模板定制能力
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder, PromptTemplate
# 导入Runnable相关:(未使用)预留链串联能力
from langchain_core.runnables import RunnableWithMessageHistory, RunnablePassthrough
# 导入RecursiveCharacterTextSplitter:(未使用)文本切割器,预留RAG能力
from langchain_text_splitters import RecursiveCharacterTextSplitter
# 导入ChatMessageHistory:(未使用)会话历史存储,预留上下文能力
from langchain_community.chat_message_histories import ChatMessageHistory
# 导入OpenAI相关组件:
# - ChatOpenAI:gpt-4-turbo聊天模型,作为Agent的核心推理引擎
# - OpenAIEmbeddings:(未使用)文本嵌入模型,预留RAG能力
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
# 导入chat_agent_executor:LangGraph预构建的工具调用Agent执行器,封装“推理→调用工具→整合结果”流程
from langgraph.prebuilt import chat_agent_executor
# 配置HTTP代理:127.0.0.1:7890是代理工具的本地端口,确保访问OpenAI API
os.environ['http_proxy'] = '127.0.0.1:7890'
# 配置HTTPS代理:OpenAI API基于HTTPS,需配置该代理确保请求正常
os.environ['https_proxy'] = '127.0.0.1:7890'
# 开启LangChain Tracing V2:追踪Agent的执行过程(查表、生成SQL、执行等),便于调试
os.environ["LANGCHAIN_TRACING_V2"] = "true"
# 配置LangChain项目名称:追踪数据归类到该项目,便于管理不同应用
os.environ["LANGCHAIN_PROJECT"] = "LangchainDemo"
# 配置LangChain API Key:认证LangChain Smith服务(追踪功能必需),替换为自己的密钥
os.environ["LANGCHAIN_API_KEY"] = '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'
# os.environ["TAVILY_API_KEY"] = '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' # 未使用Tavily,注释掉
# ===================== 核心步骤1:初始化OpenAI聊天模型 =====================
# 聊天机器人案例
# 创建ChatOpenAI模型实例:指定gpt-4-turbo(推理能力更强,适合Agent复杂决策)
model = ChatOpenAI(model='gpt-4-turbo')
# ===================== 核心步骤2:配置并连接MySQL数据库 =====================
# sqlalchemy 初始化MySQL数据库的连接(SQLAlchemy标准URL格式)
# 数据库连接参数:
HOSTNAME = '127.0.0.1' # 数据库服务器地址(本地)
PORT = '3306' # MySQL默认端口
DATABASE = 'test_db8' # 要连接的数据库名
USERNAME = 'root' # 数据库用户名
PASSWORD = '123123' # 数据库密码
# 构建MySQL连接URL(mysqlclient驱动):
# 格式:mysql+mysqldb://用户名:密码@地址:端口/数据库名?字符集
MYSQL_URI = 'mysql+mysqldb://{}:{}@{}:{}/{}?charset=utf8mb4'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
# 初始化数据库交互对象:通过URL连接MySQL,封装数据库操作(查表、执行SQL等)
db = SQLDatabase.from_uri(MYSQL_URI)
# ===================== 核心步骤3:创建SQL工具包 =====================
# 创建工具:SQLDatabaseToolkit封装了数据库相关的所有工具(查表名、查表结构、执行SQL等)
# - db=db:关联已连接的数据库对象
# - llm=model:关联gpt-4-turbo模型,工具内部需模型辅助生成SQL
toolkit = SQLDatabaseToolkit(db=db, llm=model)
# 提取工具包中的所有工具:返回列表(如ListSQLDatabaseTool、QuerySQLDataBaseTool等)
tools = toolkit.get_tools()
# ===================== 核心步骤4:定义Agent的系统指令 =====================
# 使用agent完成整个数据库的整合
# 系统提示词:定义Agent的行为规则、能力边界、执行流程
system_prompt = """
您是一个被设计用来与SQL数据库交互的代理。
给定一个输入问题,创建一个语法正确的SQL语句并执行,然后查看查询结果并返回答案。
除非用户指定了他们想要获得的示例的具体数量,否则始终将SQL查询限制为最多10个结果。
你可以按相关列对结果进行排序,以返回MySQL数据库中最匹配的数据。
您可以使用与数据库交互的工具。在执行查询之前,你必须仔细检查。如果在执行查询时出现错误,请重写查询SQL并重试。
不要对数据库做任何DML语句(插入,更新,删除,删除等)。
首先,你应该查看数据库中的表,看看可以查询什么。
不要跳过这一步。
然后查询最相关的表的模式。
"""
# 将系统提示词封装为SystemMessage对象:Agent执行器会优先读取该指令,约束Agent行为
system_message = SystemMessage(content=system_prompt)
# ===================== 核心步骤5:创建SQL智能Agent执行器 =====================
# 创建代理:chat_agent_executor是LangGraph预构建的工具调用执行器
# - model:gpt-4-turbo推理引擎
# - tools:SQL工具包中的工具列表(Agent可自主选择调用)
# - system_message:Agent的行为规则指令
agent_executor = chat_agent_executor.create_tool_calling_executor(model, tools, system_message)
# ===================== 核心步骤6:调用Agent并获取结果 =====================
# 测试不同问题(注释):
# resp = agent_executor.invoke({'messages': [HumanMessage(content='请问:员工表中有多少条数据?')]})
# resp = agent_executor.invoke({'messages': [HumanMessage(content='那种性别的员工人数最多?')]})
# 调用Agent处理复杂问题:“哪个部门下面的员工人数最多?”
resp = agent_executor.invoke({'messages': [HumanMessage(content='哪个部门下面的员工人数最多?')]})
# 提取Agent执行结果(消息列表):包含用户消息、Agent工具调用记录、最终回答
result = resp['messages']
# 优化print:分步展示结果,解释每一步的含义(小白易懂)
print('=== SQL智能Agent执行结果 ===')
print(f'1. Agent执行产生的完整消息列表:\n{result}\n')
print(f'2. 消息列表长度(包含用户消息/工具调用/最终回答):{len(result)}\n')
# 提取并打印最终回答(消息列表最后一条是Agent的自然语言回答)
final_answer = result[-1] # 等价于result[len(result)-1],更简洁
print(f'3. Agent最终回答(消息列表最后一条):\n{final_answer.content}')
3. 无任何注释的代码版本
import os
from operator import itemgetter
import bs4
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains.history_aware_retriever import create_history_aware_retriever
from langchain.chains.retrieval import create_retrieval_chain
from langchain.chains.sql_database.query import create_sql_query_chain
from langchain_chroma import Chroma
from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.tools import QuerySQLDataBaseTool
from langchain_community.utilities import SQLDatabase
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder, PromptTemplate
from langchain_core.runnables import RunnableWithMessageHistory, RunnablePassthrough
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langgraph.prebuilt import chat_agent_executor
os.environ['http_proxy'] = '127.0.0.1:7890'
os.environ['https_proxy'] = '127.0.0.1:7890'
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "LangchainDemo"
os.environ["LANGCHAIN_API_KEY"] = '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'
model = ChatOpenAI(model='gpt-4-turbo')
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'test_db8'
USERNAME = 'root'
PASSWORD = '123123'
MYSQL_URI = 'mysql+mysqldb://{}:{}@{}:{}/{}?charset=utf8mb4'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
db = SQLDatabase.from_uri(MYSQL_URI)
toolkit = SQLDatabaseToolkit(db=db, llm=model)
tools = toolkit.get_tools()
system_prompt = """
您是一个被设计用来与SQL数据库交互的代理。
给定一个输入问题,创建一个语法正确的SQL语句并执行,然后查看查询结果并返回答案。
除非用户指定了他们想要获得的示例的具体数量,否则始终将SQL查询限制为最多10个结果。
你可以按相关列对结果进行排序,以返回MySQL数据库中最匹配的数据。
您可以使用与数据库交互的工具。在执行查询之前,你必须仔细检查。如果在执行查询时出现错误,请重写查询SQL并重试。
不要对数据库做任何DML语句(插入,更新,删除,删除等)。
首先,你应该查看数据库中的表,看看可以查询什么。
不要跳过这一步。
然后查询最相关的表的模式。
"""
system_message = SystemMessage(content=system_prompt)
agent_executor = chat_agent_executor.create_tool_calling_executor(model, tools, system_message)
resp = agent_executor.invoke({'messages': [HumanMessage(content='哪个部门下面的员工人数最多?')]})
result = resp['messages']
print('=== SQL智能Agent执行结果 ===')
print(f'1. Agent执行产生的完整消息列表:\n{result}\n')
print(f'2. 消息列表长度(包含用户消息/工具调用/最终回答):{len(result)}\n')
final_answer = result[-1]
print(f'3. Agent最终回答(消息列表最后一条):\n{final_answer.content}')
4. 核心知识点详解(系统梳理+表格)
4.1 核心组件/概念对照表
| 核心组件/概念 | 导入路径 | 通俗解释 | 核心用法 | 本案例作用 |
|---|---|---|---|---|
| SQLDatabaseToolkit | langchain_community.agent_toolkits.SQLDatabaseToolkit | SQL专属工具包,封装数据库相关的所有工具(查表名、查结构、执行SQL等) | SQLDatabaseToolkit(db=数据库对象, llm=模型) | 为Agent提供全套数据库操作工具,无需手动封装工具 |
| chat_agent_executor | langgraph.prebuilt.chat_agent_executor | LangGraph预构建的工具调用Agent执行器,封装“推理→选工具→执行→整合结果”全流程 | create_tool_calling_executor(模型, 工具列表, 系统消息) | 构建SQL智能Agent,实现自主决策和工具调用 |
| SystemMessage | langchain_core.messages.SystemMessage | 系统指令消息,定义Agent的行为规则、能力边界 | SystemMessage(content=系统提示词) | 约束Agent:限制SQL结果数、禁止DML操作、强制先查表结构 |
| HumanMessage | langchain_core.messages.HumanMessage | 用户消息封装类,传递用户的自然语言问题 | HumanMessage(content=用户问题) | 传递“哪个部门员工最多?”给Agent |
| Agent消息列表 | resp[‘messages’] | Agent执行过程的完整记录,包含: 1. HumanMessage(用户问题) 2. ToolCallMessage(工具调用记录) 3. AIMessage(最终回答) | result = resp['messages']; final_answer = result[-1] | 完整追溯Agent执行过程,最后一条是最终回答 |
4.2 关键知识点深度解释
(1)SQLDatabaseToolkit包含的核心工具(Agent可自主调用)
| 工具名称 | 功能 | 本案例调用场景 |
|---|---|---|
| ListSQLDatabaseTool | 列出数据库中所有表名 | Agent第一步调用,确认有哪些表(如t_emp、t_dept) |
| DescribeSQLDatabaseTool | 查询指定表的结构(字段名、类型、主键等) | Agent第二步调用,查询t_emp/t_dept的结构,确保SQL字段正确 |
| QuerySQLDataBaseTool | 执行SQL语句并返回结果 | Agent第三步调用,执行生成的“统计各部门人数”SQL |
(2)Agent处理“哪个部门员工最多?”的完整决策流程
flowchart TD
A[用户问题:哪个部门员工最多?] --> B[Agent接收消息]
B --> C1[调用ListSQLDatabaseTool,获取表名:t_emp、t_dept]
C1 --> C2[调用DescribeSQLDatabaseTool,查询t_emp(含dept_id字段)、t_dept结构]
C2 --> C3[推理生成SQL:SELECT dept.name, COUNT(emp.id) AS num FROM t_emp emp JOIN t_dept dept ON emp.dept_id=dept.id GROUP BY dept.name ORDER BY num DESC LIMIT 10;]
C3 --> C4[调用QuerySQLDataBaseTool执行SQL,获取结果:研发部 30人]
C4 --> C5[整合结果生成自然语言回答]
C5 --> D[返回最终回答:研发部门的员工人数最多,共有30人。]
(3)SystemMessage的核心约束作用
- 安全约束:禁止执行DML语句(INSERT/UPDATE/DELETE),避免误操作修改数据库;
- 规范约束:SQL结果最多返回10条,避免大数据量查询卡顿;
- 流程约束:强制先查表名→再查表结构→最后生成SQL,避免因表/字段名错误导致SQL执行失败。
5. print函数修改说明
5.1 优化对比与原因
| 原代码print | 优化后print | 核心改进 |
|---|---|---|
print(result)print(len(result))print(result[len(result)-1]) | print('=== SQL智能Agent执行结果 ===')print(f'1. 完整消息列表:{result}')print(f'2. 列表长度:{len(result)}')print(f'3. 最终回答:{final_answer.content}') | 1. 增加模块标题,清晰区分结果维度; 2. 标注每一步内容的含义(如“列表长度包含用户消息/工具调用/最终回答”); 3. 简化最终回答提取方式( result[-1]替代result[len(result)-1]);4. 仅打印最终回答的 content字段,避免输出AIMessage对象的冗余信息 |
5.2 输出示例(参考)
=== SQL智能Agent执行结果 ===
1. Agent执行产生的完整消息列表:
[HumanMessage(content='哪个部门下面的员工人数最多?'), ToolCallMessage(...), ToolCallMessage(...), AIMessage(content='研发部门的员工人数最多,共有30人。')]
2. 消息列表长度(包含用户消息/工具调用/最终回答):4
3. Agent最终回答(消息列表最后一条):
研发部门的员工人数最多,共有30人。
5.3 环境依赖说明
运行代码前需安装以下库(终端执行):
pip install langchain langchain-openai langchain-community langgraph chromadb beautifulsoup4 mysqlclient sqlalchemy
mysqlclient:MySQL连接驱动(若安装失败,可换pymysql,并修改URL为mysql+pymysql://...);langgraph:LangChain官方的Agent/工作流框架,核心依赖。
总结(关键点回顾)
- 核心能力:SQL智能Agent实现“自然语言→自主查表/查结构→生成SQL→执行→自然语言回答”的全流程自动化,支持复杂数据库问答;
- 核心组件:
SQLDatabaseToolkit封装全套SQL工具,无需手动构建;chat_agent_executor是Agent执行的核心,封装决策和工具调用逻辑;SystemMessage定义Agent的行为规则,保障安全和规范;
- 关键流程:Agent处理问题时会先查表名→再查表结构→最后生成/执行SQL,避免语法错误;
- 实用技巧:
- 优先使用gpt-4-turbo作为Agent推理引擎,复杂SQL生成/决策能力更强;
- 通过LangChain Tracing查看Agent的工具调用记录,便于调试SQL生成错误;
- 系统提示词中明确约束(如禁止DML),避免数据库安全风险。
1038

被折叠的 条评论
为什么被折叠?



