本文主要是介绍13|连接数据库:通过链和代理查询鲜花信息,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
新的数据库查询范式
- 提出问题:用户用自然语言提出一个问题,例如“去年的总销售额是多少?”。
- LLM 理解并转译:LLM 首先会解析这个问题,理解其背后的意图和所需的信息。接着,模
型会根据解析的内容,生成相应的 SQL 查询语句,例如 “SELECT SUM(sales) FROM
sales_data WHERE year = ‘last_year’;”。 - 执行 SQL 查询:生成的 SQL 查询语句会被发送到相应的数据库进行执行。数据库处理这个
查询,并返回所需的数据结果。 - LLM 接收并解释结果:当数据库返回查询结果后,LLM 会接收到这些数据。然后,LLM 会
开始解析这些数据,并将其转化为更容易被人类理解的答案格式。 - 提供答案:最后,LLM 将结果转化为自然语言答案,并返回给用户。例如“去年的总销售
额为 1,000,000 元”。
实战案例背景信息
这个应用可以被简单地用作一个查询工具,允许员工在存货或销售系统中快速查找价 格。员工不再需要记住复杂的查询语句或进行手动搜索,只需选择鲜花种类,告诉系统他所想 要的东西,系统就会为他们生成正确的查询。
其次,这个模板也可以被整合到一个聊天机器人或客服机器人中。顾客可以直接向机器人询 问:“红玫瑰的价格是多少?” 机器人会根据输入内容来调用 LangChain 和 LLM,生成适 当的查询,然后返回确切的价格给顾客。这样,不仅提高了服务效率,还增强了用户体验。
创建数据库表
我们使用 SQLite 作为我们的示例数据库。它提供了轻量级的磁盘文件数据库,并不需 要单独的服务器进程或系统,应用程序可以直接与数据库文件交互。 SQLite 支持 ACID(原子性、一致性、隔离性、持久性)
sqlite3 库,则是 Python 内置的轻量级 SQLite 数据库
# 导入sqlite3库
import sqlite3# 连接到数据库
conn = sqlite3.connect('FlowerShop.db')
cursor = conn.cursor()# 执行SQL命令来创建Flowers表
cursor.execute('''CREATE TABLE Flowers (ID INTEGER PRIMARY KEY,Name TEXT NOT NULL,Type TEXT NOT NULL,Source TEXT NOT NULL,PurchasePrice REAL,SalePrice REAL,StockQuantity INTEGER,SoldQuantity INTEGER,ExpiryDate DATE,Description TEXT,EntryDate DATE DEFAULT CURRENT_DATE);''')# 插入5种鲜花的数据
flowers = [('Rose', 'Flower', 'France', 1.2, 2.5, 100, 10, '2023-12-31', 'A beautiful red rose'),('Tulip', 'Flower', 'Netherlands', 0.8, 2.0, 150, 25, '2023-12-31', 'A colorful tulip'),('Lily', 'Flower', 'China', 1.5, 3.0, 80, 5, '2023-12-31', 'An elegant white lily'),('Daisy', 'Flower', 'USA', 0.7, 1.8, 120, 15, '2023-12-31', 'A cheerful daisy flower'),('Orchid', 'Flower', 'Brazil', 2.0, 4.0, 50, 2, '2023-12-31', 'A delicate purple orchid')
]for flower in flowers:cursor.execute('''INSERT INTO Flowers (Name, Type, Source, PurchasePrice, SalePrice, StockQuantity, SoldQuantity, ExpiryDate, Description)VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);''', flower)# 提交更改
conn.commit()# 关闭数据库连接
conn.close()
用 Chain 查询数据库
pip install langchain-experimental
# 导入langchain的实用工具和相关的模块
from langchain.utilities import SQLDatabase
from langchain.llms import OpenAI
from langchain_experimental.sql import SQLDatabaseChain# 连接到FlowerShop数据库(之前我们使用的是Chinook.db)
db = SQLDatabase.from_uri("sqlite:///FlowerShop.db")# 创建OpenAI的低级语言模型(LLM)实例,这里我们设置温度为0,意味着模型输出会更加确定性
llm = OpenAI(temperature=0, verbose=True)# 创建SQL数据库链实例,它允许我们使用LLM来查询SQL数据库
db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)# 运行与鲜花运营相关的问题
response = db_chain.run("有多少种不同的鲜花?")
print(response)response = db_chain.run("哪种鲜花的存货数量最少?")
print(response)response = db_chain.run("平均销售价格是多少?")
print(response)response = db_chain.run("从法国进口的鲜花有多少种?")
print(response)response = db_chain.run("哪种鲜花的销售量最高?")
print(response)
我们导入必要的 LangChain 模块,然后连接到 FlowerShop 数据库,初始化 OpenAI 的 LLM 实例。之后用 SQLDatabaseChain 来创建一个从 LLM 到数据库的链接。
用 db_chain.run() 方法来查询多个与鲜花运营相关的问题,Chain 的内部会把这些自 然语言转换为 SQL 语句,并查询数据库表,得到查询结果之后,又通过 LLM 把这个结果转换 成自然语言。
用 Agent 查询数据库
除了通过 Chain 完成数据库查询之外,LangChain 还可以通过 SQL Agent 来完成查询任 务。相比 SQLDatabaseChain,使用 SQL 代理有一些优点。
它可以根据数据库的架构以及数据库的内容回答问题(例如它会检索特定表的描述)。
它具有纠错能力,当执行生成的查询遇到错误时,它能够捕获该错误,然后正确地重新生成并执行新的查询
LangChain 使用 create_sql_agent 函数来初始化代理,通过这个函数创建的 SQL 代理包含 SQLDatabaseToolkit,这个工具箱中包含以下工具:
- 创建并执行查询
- 检查查询语法
- 检索数据表的描述
from langchain.utilities import SQLDatabase
from langchain.llms import OpenAI
from langchain.agents import create_sql_agent
from langchain.agents.agent_toolkits import SQLDatabaseToolkit
from langchain.agents.agent_types import AgentType# 连接到FlowerShop数据库
db = SQLDatabase.from_uri("sqlite:///FlowerShop.db")
llm = OpenAI(temperature=0, verbose=True)# 创建SQL Agent
agent_executor = create_sql_agent(llm=llm,toolkit=SQLDatabaseToolkit(db=db, llm=llm),verbose=True,agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
)# 使用Agent执行SQL查询questions = ["哪种鲜花的存货数量最少?","平均销售价格是多少?",
]for question in questions:response = agent_executor.run(question)print(response)
总结
“告诉计算机要做什么”的编程范式向“告诉计算机我们想要什么”的范式的转变。
- 更大的可达性:不再需要深入的技术知识或特定的编程背景。这意味着非技术人员,比如业 务分析师、项目经理甚至是终端用户,都可以直接与数据交互。
- 高效率与生产力:传统的编程方法需要大量的时间和努力,尤其是在复杂的数据操作中。自 然语言处理和理解能够显著减少这种负担,使得复杂的数据操作变得更加直观。
- 错误的减少:许多编程错误源于对特定语法或结构的误解,通过使用自然语言,这些源于误 解的错误将大大减少。
- 人与机器的紧密结合:在这种新范式下,机器更像是人类的合作伙伴,而不仅仅是一个工 具。它们可以理解我们的需求,并为我们提供解决方案,而无需我们明确指导每一步。
但这种转变也带来了挑战。
-
模糊性的问题:自然语言本身是模糊的,机器必须能够准确地解释这种模糊性,并在必要时 寻求澄清。
-
对现有系统的依赖:虽然自然语言查询看起来很有吸引力,但许多现有系统可能不支持或不 兼容这种新范式。
-
过度依赖:如果过于依赖机器为我们做决策,那么我们可能会失去对数据的深入了解和对结 果的质疑。
-
LangChain 中用 Chain 和 Agent 来查询数据库,这两种方式有什么异同?
-
你能否深入上面这两种方法的代码,看一看它们的底层实现。尤其是要看 LangChain 是如 何做提示工程,指导模型生成 SQL 代码的。
如何对多数据库的多表进行查询?
- 使用多数据库查询工具。一些ORM框架如SQLAlchemy支持跨数据库查询。或者可以使用像Ditto这样的多数据库查询工具。
- 将不同数据库的数据同步到一个数据库,然后在一个数据库中进行查询。可以使用工具实现数据库之间的数据同步。
- 使用消息队列进行异步查询。将查询任务发布到消息队列,不同数据库各自监听并查询,最后聚合结果。
- 查询服务化。将每个数据库封装为查询服务,在应用中调用这些服务然后聚合结果。
1、Chain采用一轮对话得到结果,意味着如果表多时,会发送很多表的schema到llm,一个是 浪费token,一个是可能超长。
2、Agent采用ReAct方式逐步推理执行,多轮对话得到结果,一个是准确性高,一个是只需将 上轮对话推理出来的需要的表的schema发送到服务端,节省token的同时避免token超出。 这引起了另外一个极端场景的思考,如果需要3表甚至更多表联查,且这3表都有上百个字段 (在大型业务系统如ERP这并不夸张),可能还是会导致token超长。
这篇关于13|连接数据库:通过链和代理查询鲜花信息的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!