基于SQL大型数据库的智能问答系统优化

一、食用指南

基于SQL数据库的智能问答系统设计与实现介绍了在数据库中创建表格数据问答系统的基本方法,我们可以向该系统提出关于数据库数据的问题,最终获得自然语言答案。

在这里插入图片描述

为了针对数据库编写有效的查询,我们需要向模型提供表名、表结构和特征值以供其查询。当存在许多表、列和/或高基数列时,我们不可能在每个提示中倾倒关于数据库的全部信息,相反,我们必须找到一种方法,仅将最相关的信息动态地插入到提示中。

本文介绍识别此类相关信息并将其输入到查询生成步骤中的方法,我们将涵盖:

  • 识别相关的表子集;
  • 识别相关的列值子集。

二、安装依赖

%pip install --upgrade --quiet  langchain langchain-community langchain-openai

三、示例数据

# 下载sql脚本
wget https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sql
sqlite3 Chinook.db
.read Chinook_Sqlite.sql
SELECT * FROM Artist LIMIT 10;
$ sqlite3 Chinook.db
SQLite version 3.45.3 2024-04-15 13:34:05
Enter ".help" for usage hints.
sqlite> .read Chinook_Sqlite.sql
sqlite> SELECT * FROM Artist LIMIT 10;
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
sqlite> .quit

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

from langchain_community.utilities import SQLDatabasedb = SQLDatabase.from_uri("sqlite:///Chinook.db")
print(db.dialect)
print(db.get_usable_table_names())
print(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')]

四、LLM

%pip install langchain-openai
import osos.environ["OPENAI_BASE_URL"] = "https://api.siliconflow.cn/v1/"
os.environ["OPENAI_API_KEY"] = "sk-xxx"from langchain.chat_models import init_chat_modelllm = init_chat_model("Qwen/Qwen3-8B", model_provider="openai")
# llm = init_chat_model("THUDM/GLM-Z1-9B-0414", model_provider="openai")
# llm = init_chat_model("deepseek-ai/DeepSeek-R1-0528-Qwen3-8B", model_provider="openai")

这里使用硅基流动的免费模型服务,以上代码中使用 Qwen/Qwen3-8B 模型,当然也可以使用其他免费模型,直接复制官网上的模型名称即可,点击这里直达官网,注册完成后创建一个 API 密钥就能使用模型了。

在这里插入图片描述
在这里插入图片描述

五、相关表

我们需要在提示中包含的主要信息之一是相关表的结构,当我们有非常多的数据表时,无法将所有表都放入一个提示中。在这种情况下,我们可以先提取与用户输入最相关的表名,一种简单可靠的方法是使用工具调用,agent 通过工具获取符合查询所需格式的输出(在本例中为表名list),我们使用聊天模型的 .bind_tools 方法绑定一个 Pydantic 格式的工具,并将其输入到输出解析器中,以从模型的响应中重建对象。

from langchain_core.output_parsers.openai_tools import PydanticToolsParser
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Fieldclass Table(BaseModel):"""Table in SQL database."""name: str = Field(description="Name of table in SQL database.")table_names = "\n".join(db.get_usable_table_names())
system = f"""返回可能与用户问题相关的所有SQL表名称。表包括:{table_names}。请记住包含所有可能相关的表,即使不确定是否需要它们。"""prompt = ChatPromptTemplate.from_messages([("system", system),("human", "{input}"),]
)
llm_with_tools = llm.bind_tools([Table])
output_parser = PydanticToolsParser(tools=[Table])table_chain = prompt | llm_with_tools | output_parsertable_chain.invoke({"input": "Alanis Morissette 歌曲的所有流派是什么"})
[Table(name='Artist'), Table(name='Track'), Table(name='Genre')]

效果很好,返回的三个表名中,Genre 是真正所需要的。实际上,我们还需要一些其他表才能把信息链打通,但仅根据用户问题,模型很难知道这些。在这种情况下,我们可以考虑通过将表分组来简化模型的工作,只要求模型在“音乐”和“业务”类别之间进行选择所有相关表。

system = """返回与用户问题相关的SQL表名。可用的表有:
1. 音乐(Music)
2. 业务(Business)
"""prompt = ChatPromptTemplate.from_messages([("system", system),("human", "{input}"),]
)category_chain = prompt | llm_with_tools | output_parser
category_chain.invoke({"input": "Alanis Morissette 歌曲的所有流派是什么"})
[Table(name='Music')]

根据返回结果再做细分处理:

from typing import Listdef get_tables(categories: List[Table]) -> List[str]:tables = []for category in categories:if category.name == "Music":tables.extend(["Album","Artist","Genre","MediaType","Playlist","PlaylistTrack","Track",])elif category.name == "Business":tables.extend(["Customer", "Employee", "Invoice", "InvoiceLine"])return tablestable_chain = category_chain | get_tables
table_chain.invoke({"input": "Alanis Morissette 歌曲的所有流派是什么"})
['Album', 'Artist', 'Genre', 'MediaType', 'Playlist', 'PlaylistTrack', 'Track']

现在我们有了一个可以为任何查询输出相关表的 Chain,将其与 create_sql_query_chain 连接起来,该 Chain 可以接受一个 table_names_to_use 列表来确定提示中包含哪些表:

from operator import itemgetterfrom langchain.chains import create_sql_query_chain
from langchain_core.runnables import RunnablePassthroughquery_chain = create_sql_query_chain(llm, db)
# Convert "question" key to the "input" key expected by current table_chain.
table_chain = {"input": itemgetter("question")} | table_chain
# Set table_names_to_use using table_chain.
full_chain = RunnablePassthrough.assign(table_names_to_use=table_chain) | query_chain
query_chain
RunnableAssign(mapper={input: RunnableLambda(...),table_info: RunnableLambda(...)
})
| RunnableLambda(lambda x: {k: v for (k, v) in x.items() if k not in ('question', 'table_names_to_use')})
| PromptTemplate(input_variables=['input', 'table_info'], input_types={}, partial_variables={'top_k': '5'}, template='You are a SQLite expert. Given an input question, first create a syntactically correct SQLite query to run, then look at the results of the query and return the answer to the input question.\nUnless the user specifies in the question a specific number of examples to obtain, query for at most {top_k} results using the LIMIT clause as per SQLite. You can order the results to return the most informative data in the database.\nNever query for all columns from a table. You must query only the columns that are needed to answer the question. Wrap each column name in double quotes (") to denote them as delimited identifiers.\nPay attention to use only the column names you can see in the tables below. Be careful to not query for columns that do not exist. Also, pay attention to which column is in which table.\nPay attention to use date(\'now\') function to get the current date, if the question involves "today".\n\nUse the following format:\n\nQuestion: Question here\nSQLQuery: SQL Query to run\nSQLResult: Result of the SQLQuery\nAnswer: Final answer here\n\nOnly use the following tables:\n{table_info}\n\nQuestion: {input}')
| RunnableBinding(bound=ChatOpenAI(client=<openai.resources.chat.completions.completions.Completions object at 0x74101c7aacb0>, async_client=<openai.resources.chat.completions.completions.AsyncCompletions object at 0x74101c7a9de0>, root_client=<openai.OpenAI object at 0x74101e9b24a0>, root_async_client=<openai.AsyncOpenAI object at 0x74101c2af100>, model_name='Qwen/Qwen3-8B', model_kwargs={}, openai_api_key=SecretStr('**********')), kwargs={'stop': ['\nSQLResult:']}, config={}, config_factories=[])
| StrOutputParser()
| RunnableLambda(_strip)
full_chain
RunnableAssign(mapper={table_names_to_use: {input: RunnableLambda(itemgetter('question'))}| ChatPromptTemplate(input_variables=['input'], input_types={}, partial_variables={}, messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='返回与用户问题相关的SQL表名。可用的表有:\n1. 音乐(Music)\n2. 业务(Business)\n'), additional_kwargs={}), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], input_types={}, partial_variables={}, template='{input}'), additional_kwargs={})])| RunnableBinding(bound=ChatOpenAI(client=<openai.resources.chat.completions.completions.Completions object at 0x74101c7aacb0>, async_client=<openai.resources.chat.completions.completions.AsyncCompletions object at 0x74101c7a9de0>, root_client=<openai.OpenAI object at 0x74101e9b24a0>, root_async_client=<openai.AsyncOpenAI object at 0x74101c2af100>, model_name='Qwen/Qwen3-8B', model_kwargs={}, openai_api_key=SecretStr('**********')), kwargs={'tools': [{'type': 'function', 'function': {'name': 'Table', 'description': 'Table in SQL database.', 'parameters': {'properties': {'name': {'description': 'Name of table in SQL database.', 'type': 'string'}}, 'required': ['name'], 'type': 'object'}}}]}, config={}, config_factories=[])| PydanticToolsParser(tools=[<class '__main__.Table'>])| RunnableLambda(get_tables)
})
| RunnableAssign(mapper={input: RunnableLambda(...),table_info: RunnableLambda(...)})
| RunnableLambda(lambda x: {k: v for (k, v) in x.items() if k not in ('question', 'table_names_to_use')})
| PromptTemplate(input_variables=['input', 'table_info'], input_types={}, partial_variables={'top_k': '5'}, template='You are a SQLite expert. Given an input question, first create a syntactically correct SQLite query to run, then look at the results of the query and return the answer to the input question.\nUnless the user specifies in the question a specific number of examples to obtain, query for at most {top_k} results using the LIMIT clause as per SQLite. You can order the results to return the most informative data in the database.\nNever query for all columns from a table. You must query only the columns that are needed to answer the question. Wrap each column name in double quotes (") to denote them as delimited identifiers.\nPay attention to use only the column names you can see in the tables below. Be careful to not query for columns that do not exist. Also, pay attention to which column is in which table.\nPay attention to use date(\'now\') function to get the current date, if the question involves "today".\n\nUse the following format:\n\nQuestion: Question here\nSQLQuery: SQL Query to run\nSQLResult: Result of the SQLQuery\nAnswer: Final answer here\n\nOnly use the following tables:\n{table_info}\n\nQuestion: {input}')
| RunnableBinding(bound=ChatOpenAI(client=<openai.resources.chat.completions.completions.Completions object at 0x74101c7aacb0>, async_client=<openai.resources.chat.completions.completions.AsyncCompletions object at 0x74101c7a9de0>, root_client=<openai.OpenAI object at 0x74101e9b24a0>, root_async_client=<openai.AsyncOpenAI object at 0x74101c2af100>, model_name='Qwen/Qwen3-8B', model_kwargs={}, openai_api_key=SecretStr('**********')), kwargs={'stop': ['\nSQLResult:']}, config={}, config_factories=[])
| StrOutputParser()
| RunnableLambda(_strip)

测试:

query = full_chain.invoke({"question": "Alanis Morissette 歌曲的所有流派是什么"}
)
print(query)
SQLQuery: SELECT DISTINCT "Genre"."Name" FROM "Track" JOIN "Album" ON "Track"."AlbumId" = "Album"."AlbumId" JOIN "Artist" ON "Album"."ArtistId" = "Artist"."ArtistId" JOIN "Genre" ON "Track"."GenreId" = "Genre"."GenreId" WHERE "Artist"."Name" = 'Alanis Morissette' LIMIT 5;

执行 SQL:

db.run(query.replace("SQLQuery: ",""))
"[('Rock',)]"

至此,我们实现了在 Chain 中动态地在提示词中提供相关表。

解决此问题的另一种可能方法是让 Agent 通过调用工具来决定何时查找表,这个过程可能会需要多次调用查询工具,具体细节可参考:基于SQL数据库的智能问答系统设计与实现中的 Agent 部分。

六、高基数列

为了过滤包含专有名词(如地址、歌曲名称或艺术家)的列,我们首先需要仔细检查拼写,以正确过滤数据。我们可以通过创建一个包含数据库中所有不同专有名词的向量存储来实现这一点,然后,每当用户在问题中包含专有名词时,让 agent 查询该向量存储,以找到该词的正确拼写。通过这种方式,agent 可以确保在构建目标查询之前,它理解用户指的是哪个实体。

首先,将结果解析为元素列表:

import ast
import redef query_as_list(db, query):res = db.run(query)res = [el for sub in ast.literal_eval(res) for el in sub if el]res = [re.sub(r"\b\d+\b", "", string).strip() for string in res]return resproper_nouns = query_as_list(db, "SELECT Name FROM Artist")
proper_nouns += query_as_list(db, "SELECT Title FROM Album")
proper_nouns += query_as_list(db, "SELECT Name FROM Genre")
len(proper_nouns)
proper_nouns[:5]
['AC/DC', 'Accept', 'Aerosmith', 'Alanis Morissette', 'Alice In Chains']

现在我们可以将所有值嵌入并存储在向量数据库中:

# %pip install faiss-gpu
%pip install faiss-cpu
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddingsvector_db = FAISS.from_texts(proper_nouns, OpenAIEmbeddings(model="BAAI/bge-m3",base_url="http://localhost:8000/v1", api_key="EMPTY"))
retriever = vector_db.as_retriever(search_kwargs={"k": 15})

向量查询:

retriever.invoke("elanis Morisset")
[Document(id='0a7ad312-dbba-4a56-883a-7cf90edfbdf5', metadata={}, page_content='Alanis Morissette'),Document(id='9176353f-7047-4c9a-8780-b24174fb1f3d', metadata={}, page_content='Elis Regina'),Document(id='9a876473-aaea-4b86-8467-132008632795', metadata={}, page_content='Volume Dois'),Document(id='17298f91-b479-4447-9480-9712ef722412', metadata={}, page_content='Xis'),Document(id='0f7d044d-290d-4b43-b436-ab8e82b86688', metadata={}, page_content='Handel: Music for the Royal Fireworks (Original Version )'),Document(id='ef588f64-b5bf-40f0-9b06-f55ef7927435', metadata={}, page_content='LOST, Season'),Document(id='5bd80286-6b27-44af-b8a5-d5f52de2e125', metadata={}, page_content='Garage Inc. (Disc )'),Document(id='405229d7-a098-4425-ad97-7afb4d3a459a', metadata={}, page_content='Garage Inc. (Disc )'),Document(id='a108b0fc-e7ab-4095-9f6f-9a1a359717e1', metadata={}, page_content='Surfing with the Alien (Remastered)'),Document(id='36f7c22d-a4a1-4644-a026-a283f78dd761', metadata={}, page_content="Christopher O'Riley"),Document(id='71563ff6-ee38-439b-b743-c7e187bf34d5', metadata={}, page_content='Speak of the Devil'),Document(id='d254a91f-9745-4a69-ac07-39ae4b1655c1', metadata={}, page_content='The Police'),Document(id='5b74ec24-428a-42b8-99fb-9c1442ca47c0', metadata={}, page_content='Vs.'),Document(id='1a1ce9a3-3b28-4c73-a1ba-443e11051672', metadata={}, page_content='Elis Regina-Minha História'),Document(id='4679d89e-e1a8-46fb-884d-0ddf7b4e9953', metadata={}, page_content='Blue Moods')]

组合一个查询 Chain,该 Chain 首先从数据库中检索值并将其插入到提示词中:

from operator import itemgetterfrom langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthroughsystem = """您是SQLite专家。根据输入问题生成语法正确的SQLite查询,除非另有说明,返回不超过{top_k}行结果。仅返回SQL查询语句,不要包含任何标记或解释。相关表信息:{table_info}以下是可能特征值的非穷举列表。若需按特征值筛选,请先核对拼写:{proper_nouns}
"""prompt = ChatPromptTemplate.from_messages([("system", system), ("human", "{input}")])query_chain = create_sql_query_chain(llm, db, prompt=prompt)
retriever_chain = (itemgetter("question")| retriever| (lambda docs: "\n".join(doc.page_content for doc in docs))
)
chain = RunnablePassthrough.assign(proper_nouns=retriever_chain) | query_chain
query_chain
RunnableAssign(mapper={input: RunnableLambda(...),table_info: RunnableLambda(...)
})
| RunnableLambda(lambda x: {k: v for (k, v) in x.items() if k not in ('question', 'table_names_to_use')})
| ChatPromptTemplate(input_variables=['input', 'proper_nouns', 'table_info'], input_types={}, partial_variables={'top_k': '5'}, messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['proper_nouns', 'table_info', 'top_k'], input_types={}, partial_variables={}, template='您是SQLite专家。根据输入问题生成语法正确的SQLite查询,除非另有说明,返回不超过{top_k}行结果。\n\n仅返回SQL查询语句,不要包含任何标记或解释。\n\n相关表信息:{table_info}\n\n以下是可能特征值的非穷举列表。若需按特征值筛选,请先核对拼写:\n\n{proper_nouns}\n'), additional_kwargs={}), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], input_types={}, partial_variables={}, template='{input}'), additional_kwargs={})])
| RunnableBinding(bound=ChatOpenAI(client=<openai.resources.chat.completions.completions.Completions object at 0x74101c7aacb0>, async_client=<openai.resources.chat.completions.completions.AsyncCompletions object at 0x74101c7a9de0>, root_client=<openai.OpenAI object at 0x74101e9b24a0>, root_async_client=<openai.AsyncOpenAI object at 0x74101c2af100>, model_name='Qwen/Qwen3-8B', model_kwargs={}, openai_api_key=SecretStr('**********')), kwargs={'stop': ['\nSQLResult:']}, config={}, config_factories=[])
| StrOutputParser()
| RunnableLambda(_strip)
chain
RunnableAssign(mapper={proper_nouns: RunnableLambda(itemgetter('question'))| VectorStoreRetriever(tags=['FAISS', 'OpenAIEmbeddings'], vectorstore=<langchain_community.vectorstores.faiss.FAISS object at 0x7410111f3b80>, search_kwargs={'k': 15})| RunnableLambda(...)
})
| RunnableAssign(mapper={input: RunnableLambda(...),table_info: RunnableLambda(...)})
| RunnableLambda(lambda x: {k: v for (k, v) in x.items() if k not in ('question', 'table_names_to_use')})
| ChatPromptTemplate(input_variables=['input', 'proper_nouns', 'table_info'], input_types={}, partial_variables={'top_k': '5'}, messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=['proper_nouns', 'table_info', 'top_k'], input_types={}, partial_variables={}, template='您是SQLite专家。根据输入问题生成语法正确的SQLite查询,除非另有说明,返回不超过{top_k}行结果。\n\n仅返回SQL查询语句,不要包含任何标记或解释。\n\n相关表信息:{table_info}\n\n以下是可能特征值的非穷举列表。若需按特征值筛选,请先核对拼写:\n\n{proper_nouns}\n'), additional_kwargs={}), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], input_types={}, partial_variables={}, template='{input}'), additional_kwargs={})])
| RunnableBinding(bound=ChatOpenAI(client=<openai.resources.chat.completions.completions.Completions object at 0x74101c7aacb0>, async_client=<openai.resources.chat.completions.completions.AsyncCompletions object at 0x74101c7a9de0>, root_client=<openai.OpenAI object at 0x74101e9b24a0>, root_async_client=<openai.AsyncOpenAI object at 0x74101c2af100>, model_name='Qwen/Qwen3-8B', model_kwargs={}, openai_api_key=SecretStr('**********')), kwargs={'stop': ['\nSQLResult:']}, config={}, config_factories=[])
| StrOutputParser()
| RunnableLambda(_strip)

现在可以测试效果,看看在不使用检索和使用检索的情况下,尝试在歌手名字拼写错误提问时会返回什么。

# Without retrieval
query = query_chain.invoke({"question": "elanis Morissette歌曲的所有流派是什么", "proper_nouns": ""}
)
print(query)
db.run(query)
SELECT Genre.Name
FROM Track
JOIN Genre ON Track.GenreId = Genre.GenreId
WHERE Track.Composer LIKE '%Elanis Morissette%';
''
# With retrieval
query = chain.invoke({"question": "Alanis Morissett歌曲的所有流派是什么"})
print(query)
db.run(query)
SELECT DISTINCT g.Name
FROM Track t
JOIN Genre g ON t.GenreId = g.GenreId
WHERE t.Composer LIKE '%Alanis Morissette%' OR t.Name LIKE '%Alanis Morissette%';
"[('Rock',)]"

我们可以看到,通过检索能够将错误的拼写纠正并获得有效结果。

参考资料

  • https://python.langchain.ac.cn/docs/how_to/sql_large_db/

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

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

相关文章

【计算机网络】前端基础知识Cookie、localStorage、sessionStorage 以及 Token

一、先搞懂&#xff1a;为什么需要这些“存储工具”&#xff1f; 网页是“无状态”的——比如你登录一个网站&#xff0c;浏览器和服务器每次通信都是独立的&#xff0c;服务器默认记不住你是谁。为了让服务器“记住”用户状态&#xff08;比如登录状态、购物车内容&#xff09…

【语法】【C+V】【mermaid】本身常用图表类型用法快查【CSDN不支持,VSCODE可用】

文章目录 Mermaid 简介Mermaid 由三部分组成Mermaid 的使用方法复杂图表结构的技巧饼图简介饼图语法饼图示例雷达图简介雷达图语法雷达图语法细节标题轴曲线选项 雷达图示例时间线简介时间线语法时间线示例树形图简介树形图语法树形图示例数据包图简介数据包图语法1&#xff1a…

不止效率工具:AI 在文化创作中如何重构 “灵感逻辑”?

一、引言1.1 AI 创作的崛起在当今时代&#xff0c;AI 技术在文化创作领域的迅猛发展已成为不可忽视的现象。从文字创作领域中&#xff0c;AI 能够快速生成小说、诗歌&#xff0c;一些新闻媒体也开始运用 AI 撰写新闻稿件&#xff1b;到视觉艺术方面&#xff0c;AI 绘画软件能依…

软考-系统架构设计师 专家系统(ES)详细讲解

个人博客&#xff1a;blogs.wurp.top 一、ES的核心概念与价值 1. 什么是专家系统&#xff08;ES&#xff09;&#xff1f; 专家系统是一种模拟人类专家解决特定领域问题的智能计算机程序系统。它运用特定领域内大量专家水平的知识和经验&#xff0c;进行推理和判断&#xff…

Vue3+TS+Element-Plus+el-tree创建树节点

1、一级树应用效果&#xff1a;代码&#xff1a;MaterialCategory.vue<script setup lang"ts" name"MaterialCategory"> ...... // 创建树&#xff08;一级树&#xff09; const createTree (dataList: IMaterialCategory[]) > {// 将原始数据转…

C++基础(④链表反转(链表 + 迭代 / 递归))

链表反转&#xff08;链表 迭代 / 递归&#xff09; 题目描述&#xff1a;给你单链表的头节点 head&#xff0c;请你反转链表&#xff0c;并返回反转后的链表头节点。 示例&#xff1a;输入链表 1→2→3→4→5 → 输出 5→4→3→2→1。 思路提示&#xff1a;迭代法&#xff1a…

面向企业级产品开发的自动化脚本实战

引言&#xff1a; 在产品开发团队中&#xff0c;设计师、产品经理和工程师之间的协作常常伴随着大量重复性工作&#xff1a;手动整理设计稿链接、更新产品需求文档、同步项目状态...这些工作不仅耗时&#xff0c;还容易出错。本文将带你编写一个Python脚本&#xff0c;自动化这…

科技赋能生态,智慧守护农林,汇岭生态开启农林产业现代化新篇章

在我国&#xff0c;农林业作为国民经济的基础产业&#xff0c;不仅关乎国家粮食安全与生态平衡&#xff0c;更是乡村振兴战略实施的核心领域。近年来&#xff0c;国家高度重视“三农”问题&#xff0c;大力推进乡村振兴战略&#xff0c;强调要实现农业农村现代化&#xff0c;促…

贪心算法面试常见问题分类解析

一、贪心算法问题 1. 跳跃游戏系列 能否到达终点: def canJump(nums):max_reach = 0for i in range(len(nums)):if i > max_reach:return Falsemax_reach = max(max_reach, i + nums[i])return True 最少步数: def jump(nums):jumps = end = max_pos = 0for i in range(l…

【3D入门-指标篇上】3D 网格重建评估指标详解与通俗比喻

一、指标对比表格指标名称核心定义计算关键步骤通俗比喻典型应用场景Chamfer距离双向平均几何距离采样点→计算最近邻距离→取平均沙滩沙粒的平均距离差评估服装轮廓、褶皱的细微差异法向量一致性表面法向量方向匹配度计算法向量点积→取绝对值→平均刺猬刺的朝向一致程度评估布…

补题报告08

题目背景某天&#xff0c;奇异博士在纽约圣所研究维山帝之书时&#xff0c;发现了连接不同多元宇宙的传送门网络......题目描述经研究&#xff0c;奇异博士发现每个传送门都有固定的 “时间代价”—— 正数表示双向通行&#xff08;往返时间代价相同均为正值&#xff09;&#…

马斯克杀入AI编程!xAI新模型Grok Code Fast 1发布,深度评测:速度、价格与API上手指南

AI 编程的赛道&#xff0c;又迎来一位重量级玩家——马斯克的 xAI。 就在最近&#xff0c;xAI 悄然发布了一款专为编码而生的新模型&#xff1a;Grok Code Fast 1。这款模型最初以代号“Sonic”在内部流传&#xff0c;如今正式亮相&#xff0c;便凭借其 256K 超长上下文、惊人的…

GaussDB 数据库架构师修炼(十八) SQL引擎-计划管理-SPM

1 背景由于业务数据的变化或者数据库版本的升级&#xff0c;可能导致SQL的执行计划发生变化&#xff0c;这种变化不一定是正收益&#xff0c;这时需 要一个防止计划劣化的机制。该机制需适用于版本升级时固化计划防止计划跳变等场景。2 SPM 的功能SPM(SQL Plan Manager)功能&a…

数字IC前端设计——前仿篇(VCS,DVE,Verdi)

文章目录引言一、软件介绍1. VCS2. DVE3. Verdi二、VCS的使用1. VCS的编译流程2. 常用的编译选项1&#xff09;基础编译选项2&#xff09;调试相关选项3&#xff09;性能优化选项4&#xff09;文件和路径选项3. 常用仿真选项1&#xff09;基础仿真选项2&#xff09;运行控制选项…

20250826--inter

一、非对称加密的应用 非对称加密应用-CSDN博客 2、怎么避免跨站脚本攻击&#xff0c;包括还有其他的一些web安全&#xff0c;怎么做的 网页安全XSS攻击和CSRF攻击_csrf共计-CSDN博客 3、前端异常监控&#xff0c;性能监控&#xff0c;埋点&#xff0c;怎么做的 &#xff1f…

MongoDB Shell

MongoDB官方提供的单独命令行工具 MongoDB Shell Download | MongoDB 下载MongoDB Shell windows系统打开&#xff0c;直接在解压后的目录里面找到bin目录 然后双击打开mongosh.exe这个文件 看到这个命令行就表示Mongo Shell已经启动成功了 test代表 当前正在使用的数据库的…

Docker03-知识点整理

Docker03-知识点整理 文章目录Docker03-知识点整理1-参考网址2-知识整理2-思考题1-Docker image和Docker Native image有什么区别1. Docker Image&#xff08;Docker 镜像&#xff09;定义特点构建和使用示例2. Docker Native Image&#xff08;通常指 GraalVM Native Image 结…

华为 eNSP 从入门到精通:企业级网络仿真全攻略

一、eNSP 简介华为 eNSP&#xff08;Enterprise Network Simulation Platform &#xff09;是面向企业网络的虚拟化仿真平台&#xff0c;其核心架构基于分布式虚拟化引擎和真实设备镜像&#xff0c;具备以下技术亮点&#xff1a;高度仿真&#xff1a;可模拟华为 AR 路由器、x7 …

docker compose设置命令别名的方法

docker compose名字比较长&#xff0c;输入比较费事&#xff0c;可以为它设置别名来简化输入。1、Linux编辑~/.bash_aliasesalias dcdocker-compse编辑~/.bashrc&#xff0c;确认其包含以下内容&#xff1a;if [ -f ~/.bash_aliases ]; then. ~/.bash_aliasesfi重新加载 ~/.bas…

【RAGFlow代码详解-10】文本处理和查询处理

概述 文本处理和查询处理系统将自然语言查询转换为与 RAGFlow 的文档存储后端配合使用的优化搜索表达式。该系统支持中英文文本处理&#xff0c;具有专门的标记化、术语加权和查询增强技术。核心组件 FulltextQueryer 类 FulltextQueryer 类是查询处理和文本分析的主要接口。它…