当前位置: 首页 > news >正文

使用大语言模型(Deepseek)构建一个基于 SQL 数据的问答系统

GitHub代码仓库

架构

从高层次来看,这些系统的步骤如下:

  1. 将问题转换为SQL查询:模型将用户输入转换为SQL查询。

  2. 执行SQL查询:执行查询。

  3. 回答问题:模型根据查询结果响应用户输入。

image.png

样本数据

下载样本数据:

curl -s https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sql | sqlite3 Chinook.db

现在,Chinook.db 位于我们的目录中,我们可以使用 SQLAlchemy 驱动的 SQLDatabase 类与它进行交互:

from langchain_community.utilities import SQLDatabasedb = SQLDatabase.from_uri("sqlite:Documents/learn-langchain/example-data/Chinook.db")
print(db.dialect)
print(db.get_usable_table_names())
db.run("SELECT * FROM Artist LIMIT 10;")

链条是可预测步骤的组合。在 LangGraph 中,我们可以通过简单的节点序列来表示链条。让我们创建一个步骤序列,给定一个问题,执行以下操作:

  1. 将问题转换为 SQL 查询;

  2. 执行查询;

  3. 使用结果回答原始问题。

这个安排并不支持所有场景。例如,系统会对任何用户输入执行 SQL 查询——即使是“你好”。值得注意的是,正如我们下面将看到的,有些问题需要多次查询才能回答。我们将在“代理”部分解决这些场景。

应用状态

我们应用的 LangGraph 状态控制着输入到应用程序的数据、在步骤之间传递的数据以及应用程序输出的数据。它通常是一个 TypedDict,也可以是一个 Pydantic BaseModel。

对于这个应用,我们可以只跟踪输入的问题、生成的查询、查询结果和生成的答案:

from typing_extensions import TypedDictclass State(TypedDict):question: strquery: strresult: stranswer: str

现在我们只需要一些函数来操作这个状态并填充其内容。

将问题转换为 SQL 查询

第一步是将用户输入转换为 SQL 查询。为了可靠地获取 SQL 查询(不包括 Markdown 格式的说明或解释),我们将利用 LangChain 的结构化输出抽象。

from config import *
from langchain_openai import ChatOpenAIllm = ChatOpenAI(model='deepseek-v3')

我们将从 Prompt Hub 中获取一个提示,来指导模型。

from langchain import hubquery_prompt_template = hub.pull("langchain-ai/sql-query-system-prompt")assert len(query_prompt_template.messages) == 1
query_prompt_template.messages[0].pretty_print()
===============================[1m System Message [0m================================Given an input question, create a syntactically correct [33;1m[1;3m{dialect}[0m query to run to help find the answer. Unless the user specifies in his question a specific number of examples they wish to obtain, always limit your query to at most [33;1m[1;3m{top_k}[0m 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 a the few relevant columns given the question.Pay attention to use only the column names that you can see in the schema description. Be careful to not query for columns that do not exist. Also, pay attention to which column is in which table.Only use the following tables:
[33;1m[1;3m{table_info}[0mQuestion: [33;1m[1;3m{input}[0m

这个提示包含了我们需要填充的几个参数,例如 SQL 方言和表模式。LangChain 的 SQLDatabase 对象包含了一些方法来帮助我们处理这些。我们的 write_query 步骤将只填充这些参数并提示模型生成 SQL 查询:

from pydantic import BaseModel
from typing_extensions import Annotatedfrom langchain_core.messages import SystemMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import PydanticOutputParserclass QueryOutput(BaseModel):"""Generated SQL query."""query: Annotated[str, ..., "Syntactically valid SQL query."]parser = PydanticOutputParser(pydantic_object=QueryOutput)query_prompt = ChatPromptTemplate.from_messages([('system', '{format_instructions}'),query_prompt_template]
).partial(format_instructions=parser.get_format_instructions())def write_query(state: State):"""Generate SQL query to fetch information."""prompt = query_prompt.invoke({"dialect": db.dialect,"top_k": 10,"table_info": db.get_table_info(),"input": state["question"],})chain = llm | parserresult = chain.invoke(prompt)return {"query": result.query}

看一下query_prompt的内容:

for message in query_prompt.messages:message.pretty_print()
================================[1m System Message [0m================================[33;1m[1;3m{format_instructions}[0m
================================[1m System Message [0m================================Given an input question, create a syntactically correct [33;1m[1;3m{dialect}[0m query to run to help find the answer. Unless the user specifies in his question a specific number of examples they wish to obtain, always limit your query to at most [33;1m[1;3m{top_k}[0m 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 a the few relevant columns given the question.Pay attention to use only the column names that you can see in the schema description. Be careful to not query for columns that do not exist. Also, pay attention to which column is in which table.Only use the following tables:
[33;1m[1;3m{table_info}[0mQuestion: [33;1m[1;3m{input}[0m

让我们测试一下:

write_query({"question": "How many Employees are there?"})
{'query': 'SELECT COUNT(*) AS EmployeeCount FROM Employee;'}

执行查询

这是创建 SQL 链条中最危险的部分。在自动执行查询之前,请仔细考虑是否可以对数据运行自动化查询。尽可能减少数据库连接权限。考虑在查询执行之前在链条中添加人工批准步骤(见下文)。

为了执行查询,我们将从 langchain-community 加载一个工具。我们的 execute_query 节点只是封装这个工具:

from langchain_community.tools.sql_database.tool import QuerySQLDatabaseTooldef execute_query(state: State):"""Execute SQL query."""execute_query_tool = QuerySQLDatabaseTool(db=db)return {"result": execute_query_tool.invoke(state["query"])}

测试一下:

execute_query({'query': 'SELECT COUNT(*) AS EmployeeCount FROM Employee;'})
{'result': '[(8,)]'}

生成答案

最后,我们的最后一步是根据从数据库中提取的信息生成问题的答案:

def generate_answer(state: State):"""Answer question using retrieved information as context."""prompt = ("Given the following user question, corresponding SQL query, ""and SQL result, answer the user question.\n\n"f'Question: {state["question"]}\n'f'SQL Query: {state["query"]}\n'f'SQL Result: {state["result"]}')response = llm.invoke(prompt)return {"answer": response.content}

使用 LangGraph 进行协调

最后,我们将应用程序编译成一个单一的图形对象。在这种情况下,我们只是将这三步连接成一个单一的序列。

from langgraph.graph import START, StateGraphgraph_builder = StateGraph(State).add_sequence([write_query, execute_query, generate_answer]
)
graph_builder.add_edge(START, "write_query")
graph = graph_builder.compile()
from IPython.display import Image, displaydisplay(Image(graph.get_graph().draw_mermaid_png()))

请添加图片描述

测试一下应用!

for step in graph.stream({"question": "How many employees are there?"}, stream_mode="updates"
):print(step)
{'write_query': {'query': 'SELECT COUNT(*) AS NumberOfEmployees FROM Employee;'}}
{'execute_query': {'result': '[(8,)]'}}
{'generate_answer': {'answer': 'There are **8 employees** in total.'}}

人工参与

LangGraph 支持许多对这个工作流有用的功能,其中之一就是人工参与:我们可以在敏感步骤(如执行 SQL 查询)之前中断应用程序,以便进行人工审核。这是通过 LangGraph 的持久化层实现的,该层将运行进度保存到您选择的存储中。下面,我们指定了内存存储:

from langgraph.checkpoint.memory import MemorySavermemory = MemorySaver()
graph = graph_builder.compile(checkpointer=memory, interrupt_before=["execute_query"])# Now that we're using persistence, we need to specify a thread ID
# so that we can continue the run after review.
config = {"configurable": {"thread_id": "1"}}display(Image(graph.get_graph().draw_mermaid_png()))

请添加图片描述

让我们重复相同的运行,并添加一个简单的 yes/no 审批步骤:

for step in graph.stream({"question": "How many employees are there?"},config,stream_mode="updates",
):print(step)try:user_approval = input("Do you want to go to execute query? (yes/no): ")
except Exception:user_approval = "no"if user_approval.lower() == "yes":# If approved, continue the graph executionfor step in graph.stream(None, config, stream_mode="updates"):print(step)
else:print("Operation cancelled by user.")
{'write_query': {'query': 'SELECT COUNT(*) AS EmployeeCount FROM Employee;'}}
{'__interrupt__': ()}
{'execute_query': {'result': '[(8,)]'}}
{'generate_answer': {'answer': 'There are **8 employees** in total.'}}

代理

代理利用大型语言模型(LLM)的推理能力在执行过程中做出决策。使用代理可以将更多的判断权转移到查询生成和执行过程中。尽管它们的行为比上述“链条”更不可预测,但它们也有一些优势:

• 它们可以根据需要多次查询数据库以回答用户问题。

• 它们可以通过运行生成的查询,捕获回溯并正确地重新生成查询,从而从错误中恢复。

• 它们不仅可以根据数据库的内容回答问题,还可以基于数据库的模式回答问题(比如描述特定的表)。

下面我们组装一个最小的 SQL 代理。

from langchain_community.agent_toolkits import SQLDatabaseToolkittoolkit = 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 0x11919bee0>),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 0x11919bee0>),ListSQLDatabaseTool(db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x11919bee0>),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 0x11919bee0>, llm=ChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x11d442b80>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x11d4841f0>, root_client=<openai.OpenAI object at 0x11d3e05b0>, root_async_client=<openai.AsyncOpenAI object at 0x11d442bb0>, model_name='deepseek-v3', model_kwargs={}, openai_api_key=SecretStr('**********'), openai_api_base='https://dashscope.aliyuncs.com/compatible-mode/v1'), 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 0x11d442b80>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x11d4841f0>, root_client=<openai.OpenAI object at 0x11d3e05b0>, root_async_client=<openai.AsyncOpenAI object at 0x11d442bb0>, model_name='deepseek-v3', model_kwargs={}, openai_api_key=SecretStr('**********'), openai_api_base='https://dashscope.aliyuncs.com/compatible-mode/v1'), output_parser=StrOutputParser(), llm_kwargs={}))]

系统提示

我们还需要为我们的代理加载一个系统提示。这将包括行为指令。

from langchain import hubprompt_template = hub.pull("langchain-ai/sql-agent-system-prompt")assert len(prompt_template.messages) == 1

让我们填充提示中的参数:

system_message = prompt_template.format(dialect="SQLite", top_k=5)
print(system_message)
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.

初始化代理

我们将使用一个预构建的 LangGraph 代理来构建我们的代理。

from langchain_core.messages import HumanMessage
from langgraph.prebuilt import create_react_agentllm = ChatOpenAI(model="qwen-max")
agent_executor = create_react_agent(llm, tools, prompt=system_message)display(Image(agent_executor.get_graph().draw_mermaid_png()))

请添加图片描述

question = "Which country's customers spent the most?"result = agent_executor.invoke({"messages": [{"role": "user", "content": question}]})
for m in result['messages']:m.pretty_print()
================================[1m Human Message [0m=================================Which country's customers spent the most?
==================================[1m Ai Message [0m==================================
Tool Calls:sql_db_list_tables (call_11959469bb4c42ab8faaee)Call ID: call_11959469bb4c42ab8faaeeArgs:tool_input:
=================================[1m Tool Message [0m=================================
Name: sql_db_list_tablesAlbum, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track
==================================[1m Ai Message [0m==================================
Tool Calls:sql_db_schema (call_6f549cbdefa94a5e80152e)Call ID: call_6f549cbdefa94a5e80152eArgs:table_names: Customer,Invoice
=================================[1m Tool Message [0m=================================
Name: sql_db_schemaCREATE TABLE "Customer" ("CustomerId" INTEGER NOT NULL, "FirstName" NVARCHAR(40) NOT NULL, "LastName" NVARCHAR(20) NOT NULL, "Company" NVARCHAR(80), "Address" NVARCHAR(70), "City" NVARCHAR(40), "State" NVARCHAR(40), "Country" NVARCHAR(40), "PostalCode" NVARCHAR(10), "Phone" NVARCHAR(24), "Fax" NVARCHAR(24), "Email" NVARCHAR(60) NOT NULL, "SupportRepId" INTEGER, PRIMARY KEY ("CustomerId"), FOREIGN KEY("SupportRepId") REFERENCES "Employee" ("EmployeeId")
)/*
3 rows from Customer table:
CustomerId	FirstName	LastName	Company	Address	City	State	Country	PostalCode	Phone	Fax	Email	SupportRepId
1	Luís	Gonçalves	Embraer - Empresa Brasileira de Aeronáutica S.A.	Av. Brigadeiro Faria Lima, 2170	São José dos Campos	SP	Brazil	12227-000	+55 (12) 3923-5555	+55 (12) 3923-5566	luisg@embraer.com.br	3
2	Leonie	Köhler	None	Theodor-Heuss-Straße 34	Stuttgart	None	Germany	70174	+49 0711 2842222	None	leonekohler@surfeu.de	5
3	François	Tremblay	None	1498 rue Bélanger	Montréal	QC	Canada	H2G 1A7	+1 (514) 721-4711	None	ftremblay@gmail.com	3
*/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	2021-01-01 00:00:00	Theodor-Heuss-Straße 34	Stuttgart	None	Germany	70174	1.98
2	4	2021-01-02 00:00:00	Ullevålsveien 14	Oslo	None	Norway	0171	3.96
3	8	2021-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_a859a5ed305e42d2b9048f)Call ID: call_a859a5ed305e42d2b9048fArgs:query: SELECT Customer.Country, SUM(Invoice.Total) AS TotalSpent FROM Invoice JOIN Customer ON Invoice.CustomerId = Customer.CustomerId GROUP BY Customer.Country ORDER BY TotalSpent DESC LIMIT 5;
=================================[1m Tool Message [0m=================================
Name: sql_db_query_checker```sql
SELECT Customer.Country, SUM(Invoice.Total) AS TotalSpent 
FROM Invoice 
JOIN Customer ON Invoice.CustomerId = Customer.CustomerId 
GROUP BY Customer.Country 
ORDER BY TotalSpent DESC 
LIMIT 5;
```
==================================[1m Ai Message [0m==================================
Tool Calls:sql_db_query (call_5b569709098b49dd9336e5)Call ID: call_5b569709098b49dd9336e5Args:query: SELECT Customer.Country, SUM(Invoice.Total) AS TotalSpent FROM Invoice JOIN Customer ON Invoice.CustomerId = Customer.CustomerId GROUP BY Customer.Country ORDER BY TotalSpent DESC LIMIT 5;
=================================[1m Tool Message [0m=================================
Name: sql_db_query[('USA', 523.06), ('Canada', 303.96), ('France', 195.1), ('Brazil', 190.1), ('Germany', 156.48)]
==================================[1m Ai Message [0m==================================The countries whose customers spent the most, in descending order, are as follows:1. USA - $523.06
2. Canada - $303.96
3. France - $195.10
4. Brazil - $190.10
5. Germany - $156.48These are the top 5 countries with the highest spending customers.

代理会执行多个查询,直到获取所需的信息:
1. 列出可用的表;
2. 获取三个表的模式;
3. 通过联接操作查询多个表。

然后,代理能够使用最终查询的结果来生成原始问题的答案。

代理同样可以处理定性问题:

question = "Describe the playlisttrack table"result = agent_executor.invoke({"messages": [{"role": "user", "content": question}]})
for m in result['messages']:m.pretty_print()
================================[1m Human Message [0m=================================Describe the playlisttrack table
==================================[1m Ai Message [0m==================================
Tool Calls:sql_db_schema (call_b9ead21107664c6a851c85)Call ID: call_b9ead21107664c6a851c85Args:table_names: playlisttrack
=================================[1m Tool Message [0m=================================
Name: sql_db_schemaError: table_names {'playlisttrack'} not found in database
==================================[1m Ai Message [0m==================================It seems that there was an error because the table 'playlisttrack' could not be found in the database. Let me first retrieve a list of the available tables to check if the correct table name is being used.
Tool Calls:sql_db_list_tables (call_fc6f21ca229c4a84adb266)Call ID: call_fc6f21ca229c4a84adb266Args:tool_input:
=================================[1m Tool Message [0m=================================
Name: sql_db_list_tablesAlbum, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track
==================================[1m Ai Message [0m==================================The correct table name is indeed 'PlaylistTrack', and it is available in the database. Let me now retrieve the schema for the 'PlaylistTrack' table.
Tool Calls:sql_db_schema (call_ee9bcfe4dfae45edb01325)Call ID: call_ee9bcfe4dfae45edb01325Args:table_names: PlaylistTrack
=================================[1m Tool Message [0m=================================
Name: sql_db_schemaCREATE TABLE "PlaylistTrack" ("PlaylistId" INTEGER NOT NULL, "TrackId" INTEGER NOT NULL, PRIMARY KEY ("PlaylistId", "TrackId"), FOREIGN KEY("TrackId") REFERENCES "Track" ("TrackId"), FOREIGN KEY("PlaylistId") REFERENCES "Playlist" ("PlaylistId")
)/*
3 rows from PlaylistTrack table:
PlaylistId	TrackId
1	3402
1	3389
1	3390
*/
==================================[1m Ai Message [0m==================================The `PlaylistTrack` table has the following schema:- `PlaylistId` (INTEGER, NOT NULL): This is a foreign key that references the `Playlist` table and is part of the composite primary key.
- `TrackId` (INTEGER, NOT NULL): This is a foreign key that references the `Track` table and is also part of the composite primary key.The primary key for this table is a combination of `PlaylistId` and `TrackId`, which means that each track can only appear once in a given playlist. Here are a few sample rows from the `PlaylistTrack` table to illustrate:| PlaylistId | TrackId |
|------------|---------|
| 1          | 3402    |
| 1          | 3389    |
| 1          | 3390    |If you need more specific information or a query based on this table, please let me know!

相关文章:

使用大语言模型(Deepseek)构建一个基于 SQL 数据的问答系统

GitHub代码仓库 架构 从高层次来看&#xff0c;这些系统的步骤如下&#xff1a; 将问题转换为SQL查询&#xff1a;模型将用户输入转换为SQL查询。 执行SQL查询&#xff1a;执行查询。 回答问题&#xff1a;模型根据查询结果响应用户输入。 样本数据 下载样本数据&#xf…...

时间转换(acwing)c/c++/java/python

读取一个整数值&#xff0c;它是工厂中某个事件的持续时间&#xff08;以秒为单位&#xff09;&#xff0c;请你将其转换为小时&#xff1a;分钟&#xff1a;秒来表示。 输入格式 输入一个整数 NN。 输出格式 输出转换后的时间表示&#xff0c;格式为 hours:minutes:second…...

连接Sql Server时报错无法通过使用安全套接字层加密与 SQL Server 建立安全连接

文章目录 一. 前言二. 解决方案 方案1方案2 三. 总结 一. 前言 在《数据库原理》这门课的实验上&#xff0c;需要使用SQL Server&#xff0c;然后使用jdbc连接sql server突然报错为&#xff1a;SQLServerException: “Encrypt”属性设置为“true”且 “trustServerCertific…...

基于CNN的FashionMNIST数据集识别3——模型验证

源码 import torch import torch.utils.data as Data from torchvision import transforms from torchvision.datasets import FashionMNIST from model import LeNetdef test_data_process():test_data FashionMNIST(root./data,trainFalse,transformtransforms.Compose([tr…...

go channel 的用法和核心原理、使用场景

一、Channel 的核心用法 1. 基本操作 // 创建无缓冲 Channel&#xff08;同步通信&#xff09; ch : make(chan int) // 创建有缓冲 Channel&#xff08;容量为5&#xff0c;异步通信&#xff09; bufferedCh : make(chan int, 5) // 发送数据到 Channel ch <- 42 // 从…...

pyside6学习专栏(七):自定义QTableWidget的扩展子类QTableWidgetEx

PySide6界面编程中较常用的控件还有QTableWidget表格控件&#xff0c;用来将加载的数据在表格中显示出来&#xff0c;下面继承QTableWidget编写其扩展子类QTableWidgetEx,来实现用单元格来显示除数据文字外&#xff0c;还可以对表格的单元格的文字颜色、背景底色进行设置&#…...

Mybatis常用动态 SQL 相关标签

1. <if> 用于条件判断&#xff0c;当满足条件时执行对应的 SQL 片段。 示例: <select id"findUser" resultType"User">SELECT * FROM usersWHERE 11<if test"name ! null and name ! ">AND name #{name}</if><if…...

AWQ和GPTQ量化的区别

一、前言 本地化部署deepseek时发现&#xff0c;如果是量化版的deepseek&#xff0c;会节约很多的内容&#xff0c;然后一般有两种量化技术&#xff0c;那么这两种量化技术有什么区别呢&#xff1f; 二、量化技术对比 在模型量化领域&#xff0c;AWQ 和 GPTQ 是两种不同的量…...

ESP32S3:解决RWDT无法触发中断问题,二次开发者怎么才能使用内部RTC看门狗中断RWDT呢?

目录 基于ESP32S3:解决RWDT无法触发中断问题引言解决方案1. 查看报错日志2. 分析报错及一步一步找到解决方法3.小结我的源码基于ESP32S3:解决RWDT无法触发中断问题 引言 在嵌入式系统中,RWDT(看门狗定时器)是确保系统稳定性的重要组件。然而,在某些情况下,RWDT可能无法…...

基于SpringBoot的民宿管理系统的设计与实现(源码+SQL脚本+LW+部署讲解等)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…...

go 日志框架

内置log import ("log""os" )func main() {// 设置loglog.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)// 自定义日志前缀log.SetPrefix("[pprof]")log.Println("main ..")// 如果用format就用PrintF&#xff0c;而不是…...

如何在 PDF 文件中嵌入自定义数据

由于 PDF 文件格式功能强大且灵活&#xff0c;它经常被用于内部工作流程。有时候&#xff0c;将自定义数据嵌入 PDF 文件本身会非常有用。通常&#xff0c;这些信息会被大多数工具忽略&#xff0c;因此 PDF 仍然可以作为普通 PDF 文件正常使用。 以下是一些实现方法&#xff1…...

计算机毕业设计SpringBoot+Vue.js服装商城 服装购物系统(源码+LW文档+PPT+讲解+开题报告)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

22.回溯算法4

递增子序列 这里不能排序&#xff0c;因为数组的顺序是对结果有影响的&#xff0c;所以只能通过used数组来去重 class Solution { public:vector<int> path;vector<vector<int>> res;void backtracking(vector<int>& nums,int start){if(path.si…...

linux -对文件描述符的操作dup、fcntl有五种

dup #include<unistd.h> int dup(int oldfd);作用&#xff1a;复制一个新的文件描述符fd 3, int fd1 dup(fd);f指向的是a.txt,fd1指向的也是a.txt从空闲的文件描述符表中找一个最小的作为新的拷贝的文件描述符返回&#xff1a;成功返回新的文件描述符&#xff0c;失败…...

技术解析 | 适用于TeamCity的Unreal Engine支持插件,提升游戏构建效率

龙智是JetBrains授权合作伙伴、Perforce授权合作伙伴&#xff0c;为您提供TeamCity、Perforce Helix Core等热门的游戏开发工具及一站式服务 TeamCity 是游戏开发的热门选择&#xff0c;大家选择它的原因包括支持 Perforce、可以进行本地安装&#xff0c;并提供了多种配置选项。…...

Ubuntu22.04 - brpc的安装和使用

目录 介绍安装使用 介绍 brpc 是用 c语言编写的工业级 RPC 框架&#xff0c;常用于搜索、存储、机器学习、广告、推荐等高性能系统 安装 先安装依赖 apt-get install -y git g make libssl-dev libprotobuf-dev libprotoc-dev protobuf-compiler libleveldb-dev libgflags-d…...

网络运维学习笔记 018 HCIA-Datacom综合实验02

文章目录 综合实验2sw3&#xff1a;sw4&#xff1a;gw&#xff1a;core1&#xff08;sw1&#xff09;&#xff1a;core2&#xff08;sw2&#xff09;&#xff1a;ISP 综合实验2 sw3&#xff1a; vlan 2 stp mode stp int e0/0/1 port link-type trunk port trunk allow-pass v…...

Vulhub靶机 Apache Druid(CVE-2021-25646)(渗透测试详解)

一、开启vulhub环境 docker-compose up -d 启动 docker ps 查看开放的端口 1、漏洞范围 在Druid0.20.0及更低版本中 二、访问靶机IP 8888端口 1、点击Load data进入新界面后&#xff0c;再点击local disk按钮。 2、进入新界面后&#xff0c;在标红框的Base directory栏写上…...

VSCode配置自动生成头文件

一、配置步骤&#xff1a; 1.打开命令面板&#xff08;CtrlShiftp&#xff09;&#xff1a; 2.输入snippets 选择配置代码片段 3. 选择新建全局代码片段 输入文件名,比如header_cpp(随便定义)&#xff0c;然后点击键盘回车按钮&#xff0c;得到下面这个文件。 增加配置文…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...