langchain实现基于sql的问答

1. 数据准备

import requests

url = "https://storage.googleapis.com/benchmarks-artifacts/chinook/Chinook.db"

response = requests.get(url)

if response.status_code == 200:
    # Open a local file in binary write mode
    with open("Chinook.db", "wb") as file:
        # Write the content of the response (the file) to the local file
        file.write(response.content)
    print("File downloaded and saved as Chinook.db")
else:
    print(f"Failed to download the file. Status code: {response.status_code}")
File downloaded and saved as Chinook.db

2. 数据库链接

from langchain_community.utilities import SQLDatabase

db = SQLDatabase.from_uri("sqlite:///Chinook.db")
# 数据库结构展示
print(db.dialect)
print(db.get_usable_table_names())
db.run("SELECT * FROM Artist LIMIT 10;")

输出:

sqlite
['Album', 'Artist', 'Customer', 'Employee', 'Genre', 'Invoice', 'InvoiceLine', 'MediaType', 'Playlist', 'PlaylistTrack', 'Track']
"[(1, 'AC/DC'), (2, 'Accept'), (3, 'Aerosmith'), (4, 'Alanis Morissette'), (5, 'Alice In Chains'), (6, 'Antônio Carlos Jobim'), (7, 'Apocalyptica'), (8, 'Audioslave'), (9, 'BackBeat'), (10, 'Billy Cobham')]"

3. 提示词模板

from langchain import hub
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
from langchain_community.agent_toolkits import SQLDatabaseToolkit
# Pull prompt (or define your own)
prompt_template = hub.pull("langchain-ai/sql-agent-system-prompt")

system_message = prompt_template.format(dialect="SQLite", top_k=5)

print(prompt_template)
print(system_message)

输出:

d:\soft\anaconda\envs\langchain\Lib\site-packages\langsmith\client.py:354: LangSmithMissingAPIKeyWarning: API key must be provided when using hosted LangSmith API
  warnings.warn(


input_variables=['dialect', 'top_k'] input_types={} partial_variables={} metadata={'lc_hub_owner': 'langchain-ai', 'lc_hub_repo': 'sql-agent-system-prompt', 'lc_hub_commit_hash': '31156d5fe3945188ee172151b086712d22b8c70f8f1c0505f5457594424ed352'} messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['dialect', 'top_k'], input_types={}, partial_variables={}, template='You are an agent designed to interact with a SQL database.\nGiven an input question, create a syntactically correct {dialect} query to run, then look at the results of the query and return the answer.\nUnless the user specifies a specific number of examples they wish to obtain, always limit your query to at most {top_k} results.\nYou can order the results by a relevant column to return the most interesting examples in the database.\nNever query for all the columns from a specific table, only ask for the relevant columns given the question.\nYou have access to tools for interacting with the database.\nOnly use the below tools. Only use the information returned by the below tools to construct your final answer.\nYou MUST double check your query before executing it. If you get an error while executing a query, rewrite the query and try again.\n\nDO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database.\n\nTo start you should ALWAYS look at the tables in the database to see what you can query.\nDo NOT skip this step.\nThen you should query the schema of the most relevant tables.'), additional_kwargs={})]
System: You are an agent designed to interact with a SQL database.
Given an input question, create a syntactically correct SQLite query to run, then look at the results of the query and return the answer.
Unless the user specifies a specific number of examples they wish to obtain, always limit your query to at most 5 results.
You can order the results by a relevant column to return the most interesting examples in the database.
Never query for all the columns from a specific table, only ask for the relevant columns given the question.
You have access to tools for interacting with the database.
Only use the below tools. Only use the information returned by the below tools to construct your final answer.
You MUST double check your query before executing it. If you get an error while executing a query, rewrite the query and try again.

DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database.

To start you should ALWAYS look at the tables in the database to see what you can query.
Do NOT skip this step.
Then you should query the schema of the most relevant tables.

4. 数据库工具箱

toolkit = SQLDatabaseToolkit(db=db, llm=llm)
tools = toolkit.get_tools()
tools

输出:

[QuerySQLDataBaseTool(description="Input to this tool is a detailed and correct SQL query, output is a result from the database. If the query is not correct, an error message will be returned. If an error is returned, rewrite the query, check the query, and try again. If you encounter an issue with Unknown column 'xxxx' in 'field list', use sql_db_schema to query the correct table fields.", db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x00000182B25C3770>),
 InfoSQLDatabaseTool(description='Input to this tool is a comma-separated list of tables, output is the schema and sample rows for those tables. Be sure that the tables actually exist by calling sql_db_list_tables first! Example Input: table1, table2, table3', db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x00000182B25C3770>),
 ListSQLDatabaseTool(db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x00000182B25C3770>),
 QuerySQLCheckerTool(description='Use this tool to double check if your query is correct before executing it. Always use this tool before executing a query with sql_db_query!', db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x00000182B25C3770>, llm=ChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x00000182B778E750>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x00000182B77B0140>, root_client=<openai.OpenAI object at 0x00000182B778C620>, root_async_client=<openai.AsyncOpenAI object at 0x00000182B778E7B0>, model_name='GLM-4-Plus', temperature=0.0, model_kwargs={}, openai_api_key=SecretStr('**********'), openai_api_base='https://open.bigmodel.cn/api/paas/v4/'), llm_chain=LLMChain(verbose=False, prompt=PromptTemplate(input_variables=['dialect', 'query'], input_types={}, partial_variables={}, template='\n{query}\nDouble check the {dialect} query above for common mistakes, including:\n- Using NOT IN with NULL values\n- Using UNION when UNION ALL should have been used\n- Using BETWEEN for exclusive ranges\n- Data type mismatch in predicates\n- Properly quoting identifiers\n- Using the correct number of arguments for functions\n- Casting to the correct data type\n- Using the proper columns for joins\n\nIf there are any of the above mistakes, rewrite the query. If there are no mistakes, just reproduce the original query.\n\nOutput the final SQL query only.\n\nSQL Query: '), llm=ChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x00000182B778E750>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x00000182B77B0140>, root_client=<openai.OpenAI object at 0x00000182B778C620>, root_async_client=<openai.AsyncOpenAI object at 0x00000182B778E7B0>, model_name='GLM-4-Plus', temperature=0.0, model_kwargs={}, openai_api_key=SecretStr('**********'), openai_api_base='https://open.bigmodel.cn/api/paas/v4/'), output_parser=StrOutputParser(), llm_kwargs={}))]

6. 流程图

llm = ChatOpenAI(
    temperature=0,
    model="GLM-4-Plus",
    openai_api_key="your api key",
    openai_api_base="https://open.bigmodel.cn/api/paas/v4/"
)

# Create agent
agent_executor = create_react_agent(
    llm, tools , state_modifier=system_message
)

from IPython.display import Image, display

try:
    display(Image(agent_executor.get_graph(xray=True).draw_mermaid_png()))
except Exception:
    # This requires some extra dependencies and is optional
    pass

在这里插入图片描述

7. 示例

example_query = "Which sales agent made the most in sales in 2009?"

events = agent_executor.stream(
    {"messages": [("user", example_query)]},
    stream_mode="values",
)
for event in events:
    event["messages"][-1].pretty_print()

输出:

================================[1m Human Message [0m=================================

Which sales agent made the most in sales in 2009?
==================================[1m Ai Message [0m==================================
Tool Calls:
  sql_db_list_tables (call_-9197044058595346666)
 Call ID: call_-9197044058595346666
  Args:
=================================[1m Tool Message [0m=================================
Name: sql_db_list_tables

Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track
==================================[1m Ai Message [0m==================================
Tool Calls:
  sql_db_schema (call_-9197044092955150896)
 Call ID: call_-9197044092955150896
  Args:
    table_names: Employee,Invoice
=================================[1m Tool Message [0m=================================
Name: sql_db_schema


CREATE TABLE "Employee" (
	"EmployeeId" INTEGER NOT NULL, 
	"LastName" NVARCHAR(20) NOT NULL, 
	"FirstName" NVARCHAR(20) NOT NULL, 
	"Title" NVARCHAR(30), 
	"ReportsTo" INTEGER, 
	"BirthDate" DATETIME, 
	"HireDate" DATETIME, 
	"Address" NVARCHAR(70), 
	"City" NVARCHAR(40), 
	"State" NVARCHAR(40), 
	"Country" NVARCHAR(40), 
	"PostalCode" NVARCHAR(10), 
	"Phone" NVARCHAR(24), 
	"Fax" NVARCHAR(24), 
	"Email" NVARCHAR(60), 
	PRIMARY KEY ("EmployeeId"), 
	FOREIGN KEY("ReportsTo") REFERENCES "Employee" ("EmployeeId")
)

/*
3 rows from Employee table:
EmployeeId	LastName	FirstName	Title	ReportsTo	BirthDate	HireDate	Address	City	State	Country	PostalCode	Phone	Fax	Email
1	Adams	Andrew	General Manager	None	1962-02-18 00:00:00	2002-08-14 00:00:00	11120 Jasper Ave NW	Edmonton	AB	Canada	T5K 2N1	+1 (780) 428-9482	+1 (780) 428-3457	andrew@chinookcorp.com
2	Edwards	Nancy	Sales Manager	1	1958-12-08 00:00:00	2002-05-01 00:00:00	825 8 Ave SW	Calgary	AB	Canada	T2P 2T3	+1 (403) 262-3443	+1 (403) 262-3322	nancy@chinookcorp.com
3	Peacock	Jane	Sales Support Agent	2	1973-08-29 00:00:00	2002-04-01 00:00:00	1111 6 Ave SW	Calgary	AB	Canada	T2P 5M5	+1 (403) 262-3443	+1 (403) 262-6712	jane@chinookcorp.com
*/


CREATE TABLE "Invoice" (
	"InvoiceId" INTEGER NOT NULL, 
	"CustomerId" INTEGER NOT NULL, 
	"InvoiceDate" DATETIME NOT NULL, 
	"BillingAddress" NVARCHAR(70), 
	"BillingCity" NVARCHAR(40), 
	"BillingState" NVARCHAR(40), 
	"BillingCountry" NVARCHAR(40), 
	"BillingPostalCode" NVARCHAR(10), 
	"Total" NUMERIC(10, 2) NOT NULL, 
	PRIMARY KEY ("InvoiceId"), 
	FOREIGN KEY("CustomerId") REFERENCES "Customer" ("CustomerId")
)

/*
3 rows from Invoice table:
InvoiceId	CustomerId	InvoiceDate	BillingAddress	BillingCity	BillingState	BillingCountry	BillingPostalCode	Total
1	2	2009-01-01 00:00:00	Theodor-Heuss-Straße 34	Stuttgart	None	Germany	70174	1.98
2	4	2009-01-02 00:00:00	Ullevålsveien 14	Oslo	None	Norway	0171	3.96
3	8	2009-01-03 00:00:00	Grétrystraat 63	Brussels	None	Belgium	1000	5.94
*/
==================================[1m Ai Message [0m==================================
Tool Calls:
  sql_db_query_checker (call_-9197047906887043597)
 Call ID: call_-9197047906887043597
  Args:
    query: SELECT e.FirstName, e.LastName, SUM(i.Total) as TotalSales FROM Employee e JOIN Invoice i ON e.EmployeeId = i.CustomerId WHERE strftime('%Y', i.InvoiceDate) = '2009' GROUP BY e.EmployeeId ORDER BY TotalSales DESC LIMIT 1
=================================[1m Tool Message [0m=================================
Name: sql_db_query_checker

```sql
SELECT e.FirstName, e.LastName, SUM(i.Total) as TotalSales 
FROM Employee e 
JOIN Invoice i ON e.EmployeeId = i.CustomerId 
WHERE strftime('%Y', i.InvoiceDate) = '2009' 
GROUP BY e.EmployeeId 
ORDER BY TotalSales DESC 
LIMIT 1
```
==================================[1m Ai Message [0m==================================
Tool Calls:
  sql_db_query (call_-9197041344174917718)
 Call ID: call_-9197041344174917718
  Args:
    query: SELECT e.FirstName, e.LastName, SUM(i.Total) as TotalSales FROM Employee e JOIN Invoice i ON e.EmployeeId = i.CustomerId WHERE strftime('%Y', i.InvoiceDate) = '2009' GROUP BY e.EmployeeId ORDER BY TotalSales DESC LIMIT 1
=================================[1m Tool Message [0m=================================
Name: sql_db_query

[('Nancy', 'Edwards', 24.75)]
==================================[1m Ai Message [0m==================================

The sales agent who made the most in sales in 2009 is Nancy Edwards, with a total of $24.75 in sales.

参考链接:https://langchain-ai.github.io/langgraph/tutorials/sql-agent/
如果有任何问题,欢迎在评论区提问。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

flink学习(14)—— 双流join

概述 Join:内连接 CoGroup&#xff1a;内连接&#xff0c;左连接&#xff0c;右连接 Interval Join&#xff1a;点对面 Join 1、Join 将有相同 Key 并且位于同一窗口中的两条流的元素进行关联。 2、Join 可以支持处理时间&#xff08;processing time&#xff09;和事件时…

深入学习指针(5)!!!!!!!!!!!!!!!

文章目录 1.回调函数是什么&#xff1f;2.qsort使用举例2.1使用qsort函数排序整形数据2.2使用sqort排序结构数据 3.qsort函数的模拟实现 1.回调函数是什么&#xff1f; 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数传递…

CEF127 编译指南 Linux篇 - 构建CEF Client(七)

1. 引言 在完成 CEF127 的编译工作后&#xff0c;我们需要了解如何正确运行编译后的程序。本文将详细介绍如何使用 CMake 构建示例程序&#xff0c;并成功运行 CEF 客户端。通过本文的指导&#xff0c;您将能够在 Linux 环境下顺利运行 CEF 应用程序。 2. 准备工作 2.1 确认…

位图的学习

一&#xff0c;位图介绍 位图&#xff08;Bitmap&#xff09;是一种用于存储图像的方式&#xff0c;它通过二维矩阵&#xff08;由像素组成&#xff09;来表示图像的每一个细节。每个像素通常对应一个特定的颜色值&#xff0c;位图的每个“位”就代表了图像的一个像素。 位图…

电脑与优傲协作机器人(实体)的TCP通讯(操作记录)

目录 一、UR通信端口 二、电脑&#xff08;客户端&#xff09;连接协作机器人&#xff08;服务端&#xff09; 1.设置网络方法 2.检查设置 3.示教器切换远程控制&#xff08;注&#xff09; 4.客户端与协作机器人建立连接 5.连接测试 三、电脑&#xff08;服务端&#…

后端 Java发送邮件 JavaMail 模版 20241128测试可用

配置授权码 依赖 <dependency><groupId>javax.mail</groupId><artifactId>javax.mail-api</artifactId><version>1.5.5</version> </dependency> <dependency><groupId>com.sun.mail</groupId><artifa…

12.2 正则表达式

object test04 {def main(args: Array[String]): Unit {//1.定义规则。写正则表达式val reg "\\d".r // \\d表示找数字//2.在目标字符串中&#xff0c;去按照这个规则去找符合的子字符串val result reg.findFirstIn("我是who&#xff0c;我的电话是&#xff…

MySQL:DDL数据定义语言

DDL(Data Definition Language)&#xff0c;数据定义语言 对数据库的常用操作 查看所有数据库 语法&#xff1a;show databases; 创建数据库 dbname&#xff1a;用户自己定义的数据库名称。 语法&#xff1a;create database [if not exists] dbname [charsetutf8]; 切换…

2024信创数据库TOP30之华为Gauss DB

近日&#xff0c;由DBC联合CIW/CIS共同发布的“2024信创数据库TOP30”榜单正式揭晓&#xff0c;汇聚了国内顶尖的数据库企业及其产品&#xff0c;成为展示中国信创领域技术实力与发展潜力的重要平台。在这份榜单中&#xff0c;华为的GaussDB凭借其卓越的技术实力、广泛的行业应…

HTML+CSS+JS制作圣诞祝福网页教程(附源码)

简介 在这个教程中&#xff0c;我们将学习如何使用HTML、CSS和JavaScript来创建一个充满节日气氛的圣诞祝福网页。这个网页将包括一个动态的圣诞树、飘落的雪花和闪烁的装饰物&#xff0c;以及一个显示“圣诞快乐&#xff01;”的消息。 准备工作 在开始之前&#xff0c;请确…

华为仓颉编程环境搭建

1、仓颉介绍 摘自华为官方&#xff1a;仓颉编程语言作为一款面向全场景应用开发的现代编程语言&#xff0c;通过现代语言特性的集成、全方位的编译优化和运行时实现、以及开箱即用的 IDE 工具链支持&#xff0c;为开发者打造友好开发体验和卓越程序性能。 其具体特性表现为&am…

朗迪锋亮相2024人因工程与智能系统交互国际会议

2024年11月28日至30日&#xff0c;2024人因工程与智能系统交互国际会议在深圳隆重举办。此次大会以推动我国人因工程学科发展为目标&#xff0c;致力于加强国际学术交流&#xff0c;深入探讨人工智能时代的智能系统交互&#xff0c;旨在培育新质生产力&#xff0c;助力经济社会…

【小白学机器学习39】如何用numpy生成总体,生成样本samples

目录 1 目的&#xff1a;研究 样本和总体之间的关系 2 先生成1个理论总体 2.0 下面是关于这一步的完整代码 2.1 一般情况下&#xff0c;我们先生成一个符合正态分布的总体 2.1.1 设置总体 &#xff0c;或者说生成一个总体 2.2 为什么一定要是一个符合正态分布的总体&…

什么是sfp,onu,​为什么PON(​俗称“光猫”​)模块使用SC光纤接口

在现代网络设备中&#xff0c;我们经常会看到SFP或SFP接口的身影&#xff0c;这些接口有时被简称为光口&#xff0c;但这个称呼并不严谨。有些厂商则称之为多功能口或多用途口&#xff0c;然而这对于不了解的人来说可能还是一头雾水。SFP&#xff0c;即Small Form-Factor Plugg…

Java个人博客系统项目文档

项目名称 Java个人博客系统 项目概述 该博客系统是一个多功能的Java应用程序。该系统支持用户发布新文章、浏览他人文章、管理个人文章收藏和删除不再需要的文章。通过该博客系统&#xff0c;用户可以享受一个安全、便捷的在线写作和阅读体验。 运行环境 编程语言&#xff1…

飞凌嵌入式受邀亮相OpenHarmony人才生态大会2024

2024年11月27日&#xff0c;OpenHarmony人才生态大会2024在武汉洲际酒店举行。在这场汇聚了行业精英、技术大咖及生态伙伴的年度盛会上&#xff0c;飞凌嵌入式作为OpenHarmony社区的重要成员受邀出席&#xff0c;并展示了其在OpenHarmony 4.1系统适配方面的最新成果。 在大会的…

SpringMVC:入门案例

从此开始&#xff0c;我们步入SpringMVC的学习。 SpringMVC是一种基于Java实现MVC模型的轻量级Web框架 先来看一下web程序是如何工作的&#xff1a; 因为是异步调用&#xff0c;所以后端不需要返回view视图&#xff0c;将其去除前端如果通过异步调用的方式进行交互&#xff0…

【Java基础】笔记

List和ArrayList区别 public class Arrays_BugDemo {public static void main(String[] args){/** List 是一个固定大小的列表&#xff0c;虽然可以进行查询操作&#xff0c;但不支持添加、删除或修改元素。* 如果需要一个可以动态修改的列表&#xff0c;可以使用 ArrayList 进…

思维导图+实现一个登录窗口界面

QQ2024122-205851 import sys from PyQt6.QtGui import QIcon, QPixmap, QMovie from PyQt6.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QLabel, QVBoxLayout# 封装我的窗口类 class LoginWidget(QWidget):# 构造函数def __init__(self):# 初始化父类su…

InterHub:为自动驾驶提供密集互动事件的自然驾驶轨迹数据集

InterHub 是一个为自动驾驶领域设计的自然驾驶轨迹数据集&#xff0c;它通过深入挖掘自然驾驶记录中的密集互动事件而构建。 InterHub 的特点在于其形式化的方法&#xff0c;这使得数据集能够精确描述和提取多智能体之间的互动事件&#xff0c;揭示了现有自动驾驶解决方案的局限…