用 Chain 查询数据库
1. 连接到数据库
首先,我们需要连接到数据库。这里我们使用的是SQLite数据库,并通过SQLDatabase.from_uri方法来建立连接。
from langchain.chains import SQLDatabaseChain
from langchain.llms import OpenAI
from langchain.tools import SQLDatabase
# 连接到数据库
database = SQLDatabase.from_uri("sqlite:///flowers.db")
SQLDatabase.from_uri:这是LangChain中提供的方法,用于从URI(统一资源标识符)连接到数据库。sqlite:///flowers.db是SQLite数据库的URI,表示数据库位于当前工作目录中的flowers.db文件。
2. 创建链(SQLDatabaseChain)
接下来,我们创建一个查询链SQLDatabaseChain。SQLDatabaseChain是LangChain提供的一个功能模块,专门用于执行SQL查询。它将OpenAI模型与数据库连接起来,实现自动化查询。
# 创建一个OpenAI模型
llm = OpenAI(temperature=0)
# 创建链
db_chain = SQLDatabaseChain(llm=llm, database=database)
OpenAI(temperature=0):我们创建一个OpenAI的语言模型。temperature=0表示模型的输出会更加确定和一致。这个模型用于生成查询数据库所需的SQL语句或处理查询结果。SQLDatabaseChain:这个类将数据库和LLM(语言模型)结合起来,形成一个完整的链式查询结构。我们将数据库对象和LLM模型传入SQLDatabaseChain,实现智能数据库查询。
3. 执行查询
此时,链已经准备好了,我们只需要执行查询并返回结果。我们定义了一个SQL查询语句,用来查询数据库中价格低于15的所有鲜花。
# 执行查询
query = "SELECT * FROM flowers WHERE category = 'Flower' AND price < 15;"
result = db_chain.run(query)
query = "SELECT * FROM flowers WHERE category = 'Flower' AND price < 15;":这是我们要执行的SQL查询语句,目标是从flowers表中筛选出类别为'Flower'且价格低于15的所有鲜花。db_chain.run(query):调用链对象的run方法执行查询。run方法会根据给定的SQL语句执行相应的数据库查询,并返回结果。
4. 输出查询结果
最后,我们将查询结果打印出来,展示符合条件的鲜花数据。
print(result)
print(result):输出查询结果。如果查询成功,result将包含所有符合条件的鲜花记录。
代码分步讲解:用 Agent 查询数据库
1. 连接到数据库并创建工具集合
与链式查询不同,代理查询(Agent)需要更多的动态决策。在代理查询中,我们定义了一个代理,它可以根据自然语言的查询指令自动选择工具并执行任务。
from langchain.agents import initialize_agent, AgentType
from langchain.llms import OpenAI
from langchain.tools import SQLDatabase
# 连接到数据库
database = SQLDatabase.from_uri("sqlite:///flowers.db")
# 创建一个OpenAI模型
llm = OpenAI(temperature=0)
# 创建一个工具集合,包含SQL数据库工具
tools = [
Tool(
name="FlowerDatabase",
func=database.run,
description="查询鲜花数据库,获取相关信息"
)
]
initialize_agent:这是LangChain提供的一个函数,用于初始化代理。代理可以自动决定使用哪个工具来处理任务。Tool:我们为代理定义了一个名为FlowerDatabase的工具,工具的功能是执行数据库查询。func=database.run表示代理使用数据库的run方法来执行查询。
2. 初始化代理并执行查询
在这个阶段,我们初始化代理,并用自然语言的查询指令来让代理决定如何执行数据库查询。
# 初始化代理
agent = initialize_agent(
tools, llm, agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)
# 查询:根据自然语言来决定查询
query = "找出价格低于15的鲜花"
response = agent.run(query)
initialize_agent:使用这个函数来初始化代理。我们传入了工具集合(tools)、模型(llm)和代理类型(AgentType.ZERO_SHOT_REACT_DESCRIPTION)。代理类型ZERO_SHOT_REACT_DESCRIPTION表示代理能够根据用户的自然语言输入动态选择工具并执行查询。agent.run(query):代理根据输入的自然语言查询指令(例如“找出价格低于15的鲜花”)决定使用哪个工具,并执行相应的操作。代理会自动执行数据库查询并返回结果。
3. 输出查询结果
和链查询一样,查询结果也会输出:
print(response)
print(response):显示代理返回的查询结果。由于代理能够根据查询指令自动选择工具,这种查询方式更加灵活且适应性强。
总结
在这个案例中,我们展示了如何通过LangChain的链式查询和代理查询两种方式来查询数据库。两者的区别在于:
- 链式查询(Chain) :链式查询适合那些结构化的查询任务。通过将不同的功能(如SQL查询、数据处理等)链式组合,可以高效地处理数据库查询。链式查询通常是固定的流程,执行时较为直接。
- 代理查询(Agent) :代理查询则更加智能,可以根据用户的自然语言查询指令动态选择合适的工具。代理查询适合更复杂、需要决策的任务,能够灵活应对各种查询场景。
通过这两种方式,我们能够简化数据库查询过程,同时提升查询的灵活性和智能化水平。这些技术使得数据库查询能够通过自然语言进行,降低了使用门槛,提升了用户体验。
感悟
通过这次实践,我深刻认识到将传统的数据库查询与现代的自然语言处理技术结合,能够大大简化数据查询的复杂度。对于普通用户来说,编写SQL语句可能是一个不小的门槛,但通过链和代理的方式,用户只需通过自然语言表达需求,就能获得数据库查询的结果。
特别是代理查询的使用,给我带来了更多的灵感。代理不仅能根据用户输入自动选择工具,执行查询操作,还能够处理复杂的查询任务。这种方式更加灵活,适应性强,非常适合于多变和不确定的查询任务。链式查询则更多地用于结构化且较为固定的查询,适合用来处理简单明了的查询任务。
总之,这次的实践让我更加深刻地体会到自动化与智能化的查询方式的重要性。它不仅让数据库查询变得更加高效,也为应用开发提供了更广阔的思路和更高效的工作方式。