求助:基于Langchain结合SQLDatabaseToolkit等工具的数据分析可行方案
问题描述
我想通过LangChain结合SQLDatabaseToolkit、create_pandas_dataframe_agent和PythonREPL实现数据分析,需求是让大语言模型(LLM)从数据库提取数据并转换为DataFrame进行分析,同时利用PythonREPL生成数据图表。但当前代码无法正常运行,求可行的解决思路。
现有代码
# 确保SQLite数据库文件可访问 database_path = 'sensor.db' if not os.path.isfile(database_path): raise Exception(f"Database file not found: {database_path}") # 建立SQLite数据库连接 conn = sqlite3.connect(database_path) # 执行SQL查询并将结果读取到DataFrame df = pd.read_sql_query('SELECT * FROM mytable', conn) pandas_tool = create_pandas_dataframe_agent(OpenAI(temperature=0), df, verbose=True) #db = SQLDatabase.from_uri(f'sqlite:///{database_path}') #toolkit = SQLDatabaseToolkit(db=db, llm=OpenAI(temperature=0)) python_repl = PythonREPL() tools = [Tool(name="python repl", func=python_repl.run, description="useful for when you need to use python to write code to create charts from data")] tools.append(pandas_tool) agent_kwargs = { "extra_prompt_messages": [MessagesPlaceholder(variable_name="memory")], } memory = ConversationBufferMemory(memory_key="memory", return_messages=True) # 创建SQL agent llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613") zero_shot_agent = initialize_agent( agent="zero-shot-react-description", tools=tools, llm=llm, verbose=True, agent_kwargs=agent_kwargs, memory=memory )
核心问题分析
- Agent嵌套错误:
create_pandas_dataframe_agent本身是完整的Agent实例,不能直接作为Tool添加到另一个Agent的tools列表中,这会导致工具调用逻辑混乱,是代码无法运行的主要原因。 - LLM模型不一致:同时使用
OpenAI(文本模型)和ChatOpenAI(聊天模型),可能引发兼容性问题。 - 手动查询限制灵活性:提前执行
SELECT * FROM mytable加载全量数据,失去了LLM根据需求动态生成SQL的能力。
可行解决思路与代码修正
方案架构调整
采用「SQL查询→DataFrame转换→PythonREPL绘图」的链式逻辑,将每个步骤封装为独立Tool,避免Agent嵌套,让LLM自主选择工具完成流程。
修正后的代码
import os import sqlite3 import pandas as pd from langchain.chat_models import ChatOpenAI from langchain.tools import Tool, PythonREPL from langchain.sql_database import SQLDatabase from langchain.agents import initialize_agent, AgentType from langchain.memory import ConversationBufferMemory from langchain.schema import MessagesPlaceholder from langchain.agents.agent_toolkits import SQLDatabaseToolkit # 确保SQLite数据库文件可访问 database_path = 'sensor.db' if not os.path.isfile(database_path): raise Exception(f"未找到数据库文件: {database_path}") # 初始化数据库连接与统一LLM db = SQLDatabase.from_uri(f'sqlite:///{database_path}') llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-0613") # 初始化SQL工具包:提供表结构查询、SQL执行等基础工具 toolkit = SQLDatabaseToolkit(db=db, llm=llm) sql_tools = toolkit.get_tools() # 自定义Tool:执行SQL并返回DataFrame的JSON格式数据 def sql_to_dataframe(sql_query): conn = sqlite3.connect(database_path) df = pd.read_sql_query(sql_query, conn) conn.close() # 返回JSON格式方便LLM理解和后续处理 return df.to_json(orient='records') dataframe_tool = Tool( name="sql_to_dataframe", func=sql_to_dataframe, description="执行输入的SQL查询,将结果转换为DataFrame并返回JSON格式数据,用于后续数据分析或绘图" ) # 初始化PythonREPL工具:用于执行Python代码生成图表 python_repl = PythonREPL() repl_tool = Tool( name="python_repl", func=python_repl.run, description="执行Python代码处理数据、生成图表,需传入完整可运行代码,记得导入必要库(如matplotlib.pyplot、seaborn)" ) # 组合所有工具 tools = sql_tools + [dataframe_tool, repl_tool] # 配置对话记忆与Agent参数 memory = ConversationBufferMemory(memory_key="memory", return_messages=True) agent_kwargs = { "extra_prompt_messages": [MessagesPlaceholder(variable_name="memory")], } # 初始化最终Agent zero_shot_agent = initialize_agent( agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, tools=tools, llm=llm, verbose=True, agent_kwargs=agent_kwargs, memory=memory )
关键修正说明
- 移除Agent嵌套:将原有的
create_pandas_dataframe_agent替换为自定义的sql_to_dataframe工具,确保所有工具都是标准Tool类型。 - 统一LLM模型:全程使用
ChatOpenAI,避免混合模型导致的指令格式不兼容问题。 - 恢复SQL工具包:启用
SQLDatabaseToolkit,让LLM可以自主查询表结构、生成针对性SQL,而非提前加载全量数据。 - 明确工具描述:为每个工具编写清晰的功能说明,帮助LLM正确判断何时使用哪个工具。
内容的提问来源于stack exchange,提问作者Karsten
相关产品推荐
相关产品推荐

