LangChain开发【NL2SQL】应用

前言

关于LangGraph的简单介绍,请参考这篇博客:

LangGraph开发Agent智能体应用【基础聊天机器人】-CSDN博客

对比LangChain实现NL2SQL

关于用LangChain开发NL2SQL的Agent应用,在这篇博客提供了完整的代码实现:

LangChain开发LLM应用【入门指南】_langchain 开发社区-CSDN博客

我在这里赘述一下:

from sqlalchemy import create_engine
from langchain_community.utilities import SQLDatabase# 数据库连接信息
username = 'root'
password = 'MyNewPass1!'
host = 'desk04v.mlprod.bjpdc.qihoo.net'
port = '3306'
database = 'test'engine = create_engine(f'mysql+mysqlconnector://{username}:{password}@{host}:{port}/{database}')
db = SQLDatabase(engine)
result = db.run("select * FROM courses LIMIT 5;")
print(result)from langchain_community.agent_toolkits import create_sql_agent
from langchain_openai import ChatOpenAIllm = ChatOpenAI(model="gpt-4o", temperature=0)
agent_executor = create_sql_agent(llm, db=db, agent_type="openai-tools", verbose=True)agent_executor.invoke("找到学分最高的课程"
)

效果如下:

我并没有在代码中定义执行链,只是给LLM提供了一个工具集,让Agent自行决定如何使用。

可以看到,Agent,先查了一下数据库中有哪些表,找到看上去有用的表后,再查了一下表结构以及预览数据,再生成sql执行(先校验一遍再执行),最后整合结果告诉我结论。

可以说已经是非常智能了。

LangGraph实现实现NL2SQL

LangGraph的方式,就和LangChain不一样了,它的开发方式就是不断给图添加“节点”和“线”,组成一个工作流。

注意:这里的工作流,并不是简单理解的操作流,LangGraph的工作流和LangChain的工作流不是是一个层面的东西,相信你看完这个例子就能感受到了。

还是先上代码!!!

第一步:定义工具集合

LangChain 和 LangGraph是打通的(准确的说,LangGraph是LangChain生态的高级框架)

所以我们可以直接使用LangChain的工具集 SQLDatabaseToolkit

如果你愿意深入看看源码,就知道这个工具集里有四个工具:
执行sql:QuerySQLDataBaseTool 
查看表详情:InfoSQLDatabaseTool
sql语法检查:QuerySQLCheckerTool
查看所有表:ListSQLDatabaseTool

from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain_openai import ChatOpenAI
from sqlalchemy import create_engine
from langchain_community.utilities import SQLDatabase# 数据库连接信息
username = 'root'
password = 'MyNewPass1!'
host = 'desk04v.mlprod.bjpdc.qihoo.net'
port = '3306'
database = 'test'engine = create_engine(f'mysql+mysqlconnector://{username}:{password}@{host}:{port}/{database}')
db = SQLDatabase(engine)
toolkit = SQLDatabaseToolkit(db=db, llm=ChatOpenAI(temperature=0))
context = toolkit.get_context()
tools = toolkit.get_tools()

第二步:定义LLM节点,并加入到图中

让LLM绑定工具,一定要绑定,就像你需要告诉LLM,可以使用哪些工具,LLM才会生成调用计划

from typing import Annotatedfrom langchain_openai import ChatOpenAI
from typing_extensions import TypedDictfrom langgraph.graph import StateGraph
from langgraph.graph.message import add_messagesclass State(TypedDict):messages: Annotated[list, add_messages]graph_builder = StateGraph(State)# expt_llm = "gpt-4-1106-preview"
expt_llm = "gpt-4o"
llm = ChatOpenAI(temperature=0, model=expt_llm)
# Modification: tell the LLM which tools it can call
llm_with_tools = llm.bind_tools(tools)def chatbot(state: State):return {"messages": [llm_with_tools.invoke(state["messages"])]}graph_builder.add_node("chatbot", chatbot)

第三步:定义工具节点,并加入到图中

import jsonfrom langchain_core.messages import ToolMessageclass BasicToolNode:"""运行最后一个AIMessage中请求的工具"""def __init__(self, tools: list) -> None:self.tools_by_name = {tool.name: tool for tool in tools}def __call__(self, inputs: dict):if messages := inputs.get("messages", []):message = messages[-1]else:raise ValueError("No message found in input")outputs = []for tool_call in message.tool_calls:print(tool_call["name"])print(self.tools_by_name[tool_call["name"]])tool_result = self.tools_by_name[tool_call["name"]].invoke(tool_call["args"])outputs.append(ToolMessage(content=json.dumps(tool_result),name=tool_call["name"],tool_call_id=tool_call["id"],))return {"messages": outputs}tool_node = BasicToolNode(tools=tools)
graph_builder.add_node("tools", tool_node)

第四步:定义“边”

add_edge方法是直接定义“边”,在例子中表示tools -> chatbot

add_conditional_edges方法是增加条件路由“边”,在例子中表示chatbot根据情况 -> tools 或者 -> __end__

from typing import Literaldef route_tools(state: State,
) -> Literal["tools", "__end__"]:"""如果最后一条消息,在conditional_edge中使用路由到ToolNode,就调用工具。否则,路线到终点。"""if isinstance(state, list):ai_message = state[-1]elif messages := state.get("messages", []):ai_message = messages[-1]else:raise ValueError(f"在tool_edge的输入状态中没有找到消息: {state}")if hasattr(ai_message, "tool_calls") and len(ai_message.tool_calls) > 0:return "tools"return "__end__"# ' tools_condition '函数返回"tools",表示LLM要求使用工具,返回"__end__"直接结束。
graph_builder.add_conditional_edges("chatbot",route_tools,# The following dictionary lets you tell the graph to interpret the condition's outputs as a specific node# It defaults to the identity function, but if you# want to use a node named something else apart from "tools",# You can update the value of the dictionary to something else# e.g., "tools": "my_tools"{"tools": "tools", "__end__": "__end__"},
)
# 任何时候调用一个工具,我们都会流转到聊天机器人
graph_builder.add_edge("tools", "chatbot")
graph_builder.set_entry_point("chatbot")
graph = graph_builder.compile()

第五步:把图画出来(非必需)

from IPython.display import Image, displaytry:display(Image(graph.get_graph().draw_mermaid_png()))
except:# This requires some extra dependencies and is optionalpass

效果如下:

整个流程很简单,用大白话讲,就是:

把提问信息传给LLM,LLM决定用什么工具,然后graph就调用工具返回结果传给LLM,LLM拿到结果后有可能继续调用工具,也有可能直接输出答案,如此循环或者终止。

第六步:执行

通过流式调用,传入用户的提问

from langchain_core.messages import BaseMessagewhile True:user_input = input("User: ")if user_input.lower() in ["quit", "exit", "q"]:print("Goodbye!")breakfor event in graph.stream({"messages": [("user", user_input)]}):for value in event.values():if isinstance(value["messages"][-1], BaseMessage):print("Assistant:", value["messages"][-1].content)

效果如下:

User:  找到5月各地区的运费最贵的用户
Assistant: 
sql_db_list_tables
db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x7fd64efb1f90>
Assistant: "arbitraments, courses, orders, scores, sink_chunjun_1, source_chunjun_1, students, test_binlog_1"
Assistant: 
sql_db_schema
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 0x7fd64efb1f90>
Assistant: "\nCREATE TABLE orders (\n\torder_id INTEGER NOT NULL COMMENT '\u8ba2\u5355ID', \n\tcustomer_id VARCHAR(255) COMMENT '\u5ba2\u6237ID', \n\temployee_id INTEGER COMMENT '\u5458\u5de5ID', \n\torder_date DATE COMMENT '\u8ba2\u5355\u65e5\u671f', \n\trequired_date DATE COMMENT '\u8981\u6c42\u4ea4\u8d27\u65e5\u671f', \n\tshipped_date DATE COMMENT '\u53d1\u8d27\u65e5\u671f', \n\tshipper_id INTEGER COMMENT '\u53d1\u8d27\u65b9\u5f0f', \n\tfreight DECIMAL(10, 2) COMMENT '\u8fd0\u8d39', \n\tship_name VARCHAR(255) COMMENT '\u6536\u8d27\u4eba\u540d\u79f0', \n\tship_address VARCHAR(255) COMMENT '\u6536\u8d27\u5730\u5740', \n\tship_city VARCHAR(255) COMMENT '\u6536\u8d27\u57ce\u5e02', \n\tship_region VARCHAR(255) COMMENT '\u6536\u8d27\u5730\u533a', \n\tship_postal_code VARCHAR(255) COMMENT '\u6536\u8d27\u90ae\u7f16', \n\torder_status VARCHAR(50) COMMENT '\u8ba2\u5355\u72b6\u6001', \n\tsnapshot_timestamp TIMESTAMP NULL COMMENT '\u5feb\u7167\u65f6\u95f4\u6233' DEFAULT CURRENT_TIMESTAMP, \n\tPRIMARY KEY (order_id)\n)DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_0900_ai_ci ENGINE=InnoDB\n\n/*\n3 rows from orders table:\norder_id\tcustomer_id\temployee_id\torder_date\trequired_date\tshipped_date\tshipper_id\tfreight\tship_name\tship_address\tship_city\tship_region\tship_postal_code\torder_status\tsnapshot_timestamp\n1\tCUST001\t1\t2024-05-01\t2024-05-05\t2024-05-03\t1\t100.50\t\u5f20\u4e09\t\u5317\u4eac\u5e02\u671d\u9633\u533a\u5efa\u56fd\u8def100\u53f7\t\u5317\u4eac\t\u534e\u5317\t100022\t\u5df2\u53d1\u8d27\t2024-06-04 17:05:11\n2\tCUST002\t2\t2024-05-02\t2024-05-06\t2024-05-04\t2\t200.75\t\u674e\u56db\t\u4e0a\u6d77\u5e02\u6d66\u4e1c\u65b0\u533a\u4e16\u7eaa\u5927\u9053200\u53f7\t\u4e0a\u6d77\t\u534e\u4e1c\t200120\t\u5df2\u53d1\u8d27\t2024-06-04 17:05:11\n3\tCUST003\t3\t2024-05-03\t2024-05-07\t2024-05-05\t3\t150.00\t\u738b\u4e94\t\u5e7f\u5dde\u5e02\u5929\u6cb3\u533a\u4f53\u80b2\u897f\u8def300\u53f7\t\u5e7f\u5dde\t\u534e\u5357\t510620\t\u5df2\u53d1\u8d27\t2024-06-04 17:05:11\n*/"
Assistant: 
sql_db_query_checker
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 0x7fd64efb1f90> llm=ChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x7fd64e081310>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x7fd64e099350>, temperature=0.0, openai_api_key=SecretStr('**********'), openai_api_base='https://api.360.cn/v1', openai_proxy='') llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['dialect', 'query'], 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 0x7fd64e081310>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x7fd64e099350>, temperature=0.0, openai_api_key=SecretStr('**********'), openai_api_base='https://api.360.cn/v1', openai_proxy=''))
Assistant: "SELECT ship_region, customer_id, freight FROM orders \nWHERE MONTH(order_date) = 5 \nORDER BY freight DESC \nLIMIT 1;"
Assistant: 
sql_db_query
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 0x7fd64efb1f90>
Assistant: "[('\u534e\u4e1c', 'CUST008', Decimal('300.80'))]"
Assistant: 在5月份各地区中,运费最贵的用户信息如下:- 地区:华东
- 用户ID:CUST008
- 运费:300.80元
User:  统计5月的每个地区的运费最贵的用户
Assistant: 
sql_db_list_tables
db=<langchain_community.utilities.sql_database.SQLDatabase object at 0x7fd64efb1f90>
Assistant: "arbitraments, courses, orders, scores, sink_chunjun_1, source_chunjun_1, students, test_binlog_1"
Assistant: 
sql_db_schema
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 0x7fd64efb1f90>
Assistant: "\nCREATE TABLE orders (\n\torder_id INTEGER NOT NULL COMMENT '\u8ba2\u5355ID', \n\tcustomer_id VARCHAR(255) COMMENT '\u5ba2\u6237ID', \n\temployee_id INTEGER COMMENT '\u5458\u5de5ID', \n\torder_date DATE COMMENT '\u8ba2\u5355\u65e5\u671f', \n\trequired_date DATE COMMENT '\u8981\u6c42\u4ea4\u8d27\u65e5\u671f', \n\tshipped_date DATE COMMENT '\u53d1\u8d27\u65e5\u671f', \n\tshipper_id INTEGER COMMENT '\u53d1\u8d27\u65b9\u5f0f', \n\tfreight DECIMAL(10, 2) COMMENT '\u8fd0\u8d39', \n\tship_name VARCHAR(255) COMMENT '\u6536\u8d27\u4eba\u540d\u79f0', \n\tship_address VARCHAR(255) COMMENT '\u6536\u8d27\u5730\u5740', \n\tship_city VARCHAR(255) COMMENT '\u6536\u8d27\u57ce\u5e02', \n\tship_region VARCHAR(255) COMMENT '\u6536\u8d27\u5730\u533a', \n\tship_postal_code VARCHAR(255) COMMENT '\u6536\u8d27\u90ae\u7f16', \n\torder_status VARCHAR(50) COMMENT '\u8ba2\u5355\u72b6\u6001', \n\tsnapshot_timestamp TIMESTAMP NULL COMMENT '\u5feb\u7167\u65f6\u95f4\u6233' DEFAULT CURRENT_TIMESTAMP, \n\tPRIMARY KEY (order_id)\n)DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_0900_ai_ci ENGINE=InnoDB\n\n/*\n3 rows from orders table:\norder_id\tcustomer_id\temployee_id\torder_date\trequired_date\tshipped_date\tshipper_id\tfreight\tship_name\tship_address\tship_city\tship_region\tship_postal_code\torder_status\tsnapshot_timestamp\n1\tCUST001\t1\t2024-05-01\t2024-05-05\t2024-05-03\t1\t100.50\t\u5f20\u4e09\t\u5317\u4eac\u5e02\u671d\u9633\u533a\u5efa\u56fd\u8def100\u53f7\t\u5317\u4eac\t\u534e\u5317\t100022\t\u5df2\u53d1\u8d27\t2024-06-04 17:05:11\n2\tCUST002\t2\t2024-05-02\t2024-05-06\t2024-05-04\t2\t200.75\t\u674e\u56db\t\u4e0a\u6d77\u5e02\u6d66\u4e1c\u65b0\u533a\u4e16\u7eaa\u5927\u9053200\u53f7\t\u4e0a\u6d77\t\u534e\u4e1c\t200120\t\u5df2\u53d1\u8d27\t2024-06-04 17:05:11\n3\tCUST003\t3\t2024-05-03\t2024-05-07\t2024-05-05\t3\t150.00\t\u738b\u4e94\t\u5e7f\u5dde\u5e02\u5929\u6cb3\u533a\u4f53\u80b2\u897f\u8def300\u53f7\t\u5e7f\u5dde\t\u534e\u5357\t510620\t\u5df2\u53d1\u8d27\t2024-06-04 17:05:11\n*/"
Assistant: 
sql_db_query_checker
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 0x7fd64efb1f90> llm=ChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x7fd64e081310>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x7fd64e099350>, temperature=0.0, openai_api_key=SecretStr('**********'), openai_api_base='https://api.360.cn/v1', openai_proxy='') llm_chain=LLMChain(prompt=PromptTemplate(input_variables=['dialect', 'query'], 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 0x7fd64e081310>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x7fd64e099350>, temperature=0.0, openai_api_key=SecretStr('**********'), openai_api_base='https://api.360.cn/v1', openai_proxy=''))
Assistant: "SELECT ship_region, customer_id, MAX(freight) as max_freight\nFROM orders\nWHERE order_date BETWEEN '2024-05-01' AND '2024-05-31'\nGROUP BY ship_region, customer_id"
Assistant: 
sql_db_query
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 0x7fd64efb1f90>
Assistant: "[('\u534e\u5317', 'CUST001', Decimal('100.50')), ('\u534e\u4e1c', 'CUST002', Decimal('200.75')), ('\u534e\u5357', 'CUST003', Decimal('150.00')), ('\u534e\u5357', 'CUST004', Decimal('120.25')), ('\u897f\u5357', 'CUST005', Decimal('180.90')), ('\u897f\u5357', 'CUST006', Decimal('250.60')), ('\u534e\u4e1c', 'CUST007', Decimal('90.45')), ('\u534e\u4e1c', 'CUST008', Decimal('300.80')), ('\u534e\u4e2d', 'CUST009', Decimal('220.30')), ('\u897f\u5317', 'CUST010', Decimal('170.95'))]"
Assistant: 以下是5月每个地区运费最贵的用户:| 地区   | 客户ID  | 最大运费 (¥) |
|-------|--------|--------------|
| 华北   | CUST001 | 100.50       |
| 华东   | CUST008 | 300.80       |
| 华南   | CUST003 | 150.00       |
| 西南   | CUST006 | 250.60       |
| 华中   | CUST009 | 220.30       |
| 西北   | CUST010 | 170.95       |可以看到,每个地区的运费最高的用户及其对应的运费如上所示。
User:  q
Goodbye!

总结

不知道你有没有发现一个神奇的现象:

对于问题:找到5月各地区的运费最贵的用户

assistant生成的sql其实是错的

SELECT ship_region, customer_id, MAX(freight) as max_freight
FROM orders
WHERE order_date BETWEEN '2024-05-01' AND '2024-05-31'
GROUP BY ship_region, customer_id

这是我在Leetcode上找的一个中等难度的sql题

assistant生成的这个sql,执行的结果,应该会出现同一个地区有多个用户的情况,但是最后给我的输出答案确实对的。。。

原因是:chatgpt4o 耍诈,它没有能力生成这么复杂sql,但是可以写一个中间结果的sql,然后自己把结果处理一下再返回给我

这只是测试数据集,数据量比较小,如果在生产环境上,那就有问题了。

如何解决?

可以使用few-shot的方式优化

关于few-shot的调优,我单独写了一个博客,请移步:LangGraph开发Agent智能体应用【NL2SQL】(few-shot优化)-CSDN博客

参考

🦜🕸️LangGraph - LangGraph

LangChain开发LLM应用【入门指南】_langchain 开发社区-CSDN博客

LangGraph开发Agent智能体应用【基础聊天机器人】-CSDN博客

Introduction | 🦜️🔗 LangChain

代码已上传,按需下载,谢谢大家

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图Transformer 推荐系统

文章目录 Graph Transformer for Recommendation摘要引言相关工作方法3.1 Graph Invariant Rationale Learning3.1.1 Graph Collaborative Rationale Discovery3.1.2 Global Topology Information Injection3.1.3 Rationale Discovery with Graph Transformer.3.1.4 Task-Adapt…

怎样快速获取Vmware VCP 证书,线上考试,voucher报名优惠

之前考一个VCP证书&#xff0c;要花大一万的费用&#xff0c;可贵了&#xff0c;考试费不贵&#xff0c;贵就贵在培训费&#xff0c;要拿到证书&#xff0c;必须交培训费&#xff0c;即使vmware你玩的很溜&#xff0c;不需要再培训了&#xff0c;但是一笔贵到肉疼的培训费你得拿…

Android MediaMetadataRetriever获取视频宽高,Java

Android MediaMetadataRetriever获取视频宽高&#xff0c;Java public static int[] getVideoSize(Context ctx, Uri uri) {MediaMetadataRetriever retriever new MediaMetadataRetriever();int[] size {-1, -1}; //宽&#xff0c;高try {retriever.setDataSource(ctx, uri)…

PowerDesigner 16.5安装教程

&#x1f4d6;PowerDesigner 16.5安装教程 ✅1. 下载✅2. 安装 ✅1. 下载 官网地址&#xff1a;https://www.powerdesigner.biz/EN/powerdesigner/powerdesigner-licensing-history.php 云盘下载&#xff1a;https://www.123pan.com/s/4brbVv-aUoWA.html ✅2. 安装 1.运行P…

开发uniapp 小程序时遇到的问题

1、【微信开发者工具报错】routeDone with a webviewId XXX that is not the current page 解决方案: 在app.json 中添加 “lazyCodeLoading”: “requiredComponents” uniapp的话加到manifest.json下的mp-weixin 外部链接文章&#xff1a;解决方案文章1 解决方案文章2 &qu…

C++ | Leetcode C++题解之第144题二叉树的前序遍历

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> preorderTraversal(TreeNode *root) {vector<int> res;if (root nullptr) {return res;}TreeNode *p1 root, *p2 nullptr;while (p1 ! nullptr) {p2 p1->left;if (p2 ! nullptr) {…

STM32 | 独立看门狗 | RTC(实时时钟)

01、独立看门狗概述 在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,由单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以出于对单片机运行状…

【学习心得】算法刷题心得分享

一、为什么要刷题&#xff1f; 提升编程能力&#xff0c;强化对数据结构的理解&#xff0c;熟练掌握常用的算法等为竞赛、考试做准备找实习、找工作需要&#xff08;上机考试面试手撕代码&#xff09;提升自信心&#xff0c;放松一下 二、刷题前应该有哪些知识储备&#xff1f;…

lua对接GPT4实现对话

演示效果&#xff1a; 准备材料&#xff1a; 1、FastWeb网站开发服务&#xff1a;fwlua.com 2、一台服务器 该示例使用开源项目&#xff1a;fastweb 实现。 代码比较简单&#xff0c;主要是两部分&#xff0c;一个lua代码和一个html页面&#xff0c;用来用户发起请求和后台…

5.1 实体完整性

一个表只能有一个主键约束&#xff0c;且主键约束不能取空值。 通过unique约束定义唯一性&#xff0c;为了保证一个表非主键列不输入重复值&#xff0c;可在该列定义unique约束。 primary key约束与unique约束主要区别如下。 (1)一个表只能创建一个primary key约束&#xff0…

计算机组成原理之指令格式

1、指令的定义 零地址指令&#xff1a; 1、不需要操作数&#xff0c;如空操作、停机、关中断等指令。 2、堆栈计算机&#xff0c;两个操作数隐藏在栈顶和此栈顶&#xff0c;取两个操作数&#xff0c;并运算的结果后重新压回栈顶。 一地址指令&#xff1a; 二、三地址指令 四…

Flutter 实现dispose探测控件

文章目录 前言一、什么是dispose探测控件&#xff1f;1、通常情况2、使用dispose探测控件 二、如何实现1、继承StatefulWidget2、定义dipose回调3、定义child4、重载Dispose方法5、build child 三、完整代码四、使用示例1、基本用法2、设置定义数据 总结 前言 开发flutter一般…

《TCP/IP网络编程》(第十四章)多播与广播

当需要向多个用户发送多媒体信息时&#xff0c;如果使用TCP套接字&#xff0c;则需要维护与用户数量相等的套接字&#xff1b;如果使用之前学习的UDP&#xff0c;传输次数也需要和用户数量相同。 所以为了解决这些问题&#xff0c;可以采用多播和广播技术&#xff0c;这样只需要…

数据挖掘丨轻松应用RapidMiner机器学习内置数据分析案例模板详解(上篇)

RapidMiner 案例模板 RapidMiner 机器学习平台提供了一个可视化的操作界面&#xff0c;允许用户通过拖放的方式构建数据分析流程。 RapidMiner目前内置了 13 种案例模板&#xff0c;这些模板是预定义的数据分析流程&#xff0c;可以帮助用户快速启动和执行常见的数据分析任务。…

gdb 【Linux】

程序发布方式&#xff1a;  1、debug版本&#xff1a;程序会被加入调试信息&#xff0c;以便于进行调试。  2、release版本&#xff1a;不添加任何调试信息&#xff0c;是不可调试   确定一个可执行程序是debug&#xff0c;还是release [cxqiZ7xviiy0goapxtblgih6oZ test_g…

LabVIEW图像采集处理项目中相机选择与应用

在LabVIEW图像采集处理项目中&#xff0c;选择合适的相机是确保项目成功的关键。本文将详细探讨相机选择时需要关注的参数、黑白相机与彩色相机的区别及其适用场合&#xff0c;帮助工程师和开发者做出明智的选择。 相机选择时需要关注的参数 1. 分辨率 定义&#xff1a;分辨率…

Deepin安装PostGresql

最近要把开发环境完全从Windows移到Deepin上&#xff0c;本次介绍在Deepin借助apt-get安装和配置数据库。同时可以用Dbever提供图形化管理工具。 安装PostGreSQL数据库和创建数据库 #安装postgresql zhanglianzhuzhanglianzhu-PC:/$ sudo apt-get install postgresql-16 正在…

876. 链表的中间结点-链表

876. 链表的中间结点 - 力扣&#xff08;LeetCode&#xff09; 快慢指针 class Solution { public:ListNode* middleNode(ListNode* head) {ListNode* slow head;ListNode* fast head;while(fast ! nullptr && fast->next ! nullptr){slow slow->next;fast …

论文阅读:Indoor Scene Layout Estimation from a Single Image

项目地址&#xff1a;https://github.com/leVirve/lsun-room/tree/master 发表时间&#xff1a;2018 icpr 场景理解&#xff0c;在现实交互的众多方面中&#xff0c;因其在增强现实&#xff08;AR&#xff09;等应用中的相关性而得到广泛关注。场景理解可以分为几个子任务&…

【Web世界探险家】3. CSS美学(二)文本样式

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更…