使用大语言模型从零构建知识图谱(上)

从零到一:大语言模型在知识图谱构建中的实操指南

©作者|Ninja Geek

来源|神州问学

将你的 Pandas data frame 利用大语言模型转换为知识图谱。从零开始构建自己的基于大语言模型的图谱构建器,实际使用 Langchain 的 LLMGraphTransformer ,并对知识图谱进行问答。

在当前 RAG 相关技术领域,知识图谱变得越来越重要,因为该检索结构支持许多大语言模型背后的知识检索系统。许多公司、科研院所、高校都在大力投资检索增强生成技术的实际落地,因为这是提高语言模型输出准确性,并防止产生幻觉的一种高效手段。

这不仅仅是技术上的进步(相对于较为早期的 RAG 实现而言),从我个人的角度来看,Graph RAG 正在人工智能领域普及化。这是因为在过去,如果我们想将模型定制化以适应不同的场景(无论是处于娱乐场景还是商业场景),通常有以下三种选择:预训练模型以提供更好的行业适应性,或者针对特定数据集对模型进行微调,又或者是基于给定的上下文让模型进行总结性回复。

对于预训练,这种方式的成本极高并且技术实现上也相对复杂,对于大多数开发者来说并不现实。

模型微调比预训练模型相对容易些,尽管微调的成本取决于模型和训练的语料库,但通常来说是一种更经济的选择。这曾是大多数人工智能开发者的首选策略。然而,模型每隔一段时间就会发布新的版本,因此开发者需要不断的在新模型上进行微调。

第三种选择是直接在基于提示词的上下文中提供知识。然而,这仅在所需知识量较小时有效。尽管模型的上下文容量越来越大,但召回特定元素的准确性通常与提供的上下文大小成反比。

这三种技术路径似乎都不是理想的解决方案。是否存在另外一种方法,让模型能够学习完成某个特定任务或主题所需的所有知识?答案是:没有。

但模型不需要一次性学习所有知识。当我们向大语言模型提问时,通常只需要获取一部分或几条信息。在这里,Graph-RAG 提供了帮助。通过基于查询进行的信息检索,Graph-RAG 能够提取所需的信息,而无需进一步训练模型。

让我们来看一下 Graph-RAG 的构成:

图构建:在这一步中,我们从数据源创建节点(有些语境下也叫实体)和边(有些语境下也叫关系),并将它们加载到知识图谱(Knowledge Graph)中。这通常是一个更加需要人工介入的步骤,常用的查询语言(如 OpenCypher)上传实体并通过“边”将它们相互连接。

节点索引:此步骤涉及创建一种数据结构以高效检索数据。在知识图谱中,这通常包括创建一个向量搜索索引,其中每个索引都与一个向量嵌入相关联。

图检索器:在这里,我们构建一个检索函数,用于计算相似度分数并检索最相关的节点,作为大语言模型提供答案的上下文。在最简单的情况下,我们将查询转换为一个向量嵌入,并对其与向量索引中的所有嵌入进行余弦相似度计算。

RAG 评估:最后一步是用于衡量大语言模型的准确性和性能。这对于试验阶段非常有用,可以比较不同的大语言模型和 RAG 框架在特定用例上的表现。

现在我们对 RAG 管道有了总体了解,你可能会急于尝试复杂的数学函数来优化图图检索,确保信息检索的最佳准确性。不过请先等等。到目前为止,还没有知识图谱。这一步可能看起来像数据科学中的经典数据清洗和预处理过程。但如果告诉你还有更好的选择呢?一种引入更多科学性和自动化的方法。

确实,最近的研究集中在如何自动构建知识图谱,因为这一步对于良好的信息检索至关重要。想一想,如果知识图谱中的数据质量不好,就不可能让你的 Graph-RAG 达到最好的性能。

在我的这篇文章中,我们将深入探讨第一步:如何在不真正构建知识图谱的情况下构建知识图谱。

从 CSV 到知识图谱

现在,让我们通过一个实际的例子来具体说明。我们来解决一个重要的日常问题:看什么电影?我相信在你打开优酷、爱奇艺、腾讯视频等视频平台 App 后会漫无目的的浏览可能感兴趣的电影,直到意识到时间已经过去半个小时了。

为了解决这个问题,我们可以使用来自 Kaggle 的关于维基百科中统计的电影数据集来创建一个知识图谱,并与知识图谱对话。首先,我们将使用大语言模型实现一个“从零开始”的解决方案。然后,我们会探讨通过 Langchain 这一流行且强大的大语言模型框架,以及另一个常用的解决方案 LlamaIndex 的最新实现。

让我们从 Kaggle 下载这个公开的数据集:

Wikipedia Movie Plots

先决条件

在开始之前,我们需要下载 Neo4j 桌面版和一个商业模型的 API 秘钥,或者你用本地模型也可以。如果这些都准备好了,可以跳过这部分直接进入实操环节。如果没有,也不用担心,我会带着你完成设置。

使用 Neo4j 有多种方式,但为了简化流程,我们将使用 Neo4j 桌面版,因此数据库将本地托管。由于数据集较小,运行该应用程序不会对你的电脑性能造成影响。

要安装 Neo4j,只需要访问 Neo4j 桌面版下载页面并点击“下载”。安装完成后打开 Neo4j Desktop,登录或创建一个 Neo4j 的账号(激活软件的时候需要用到)。

登录后,创建一个新项目:

1. 点击左上角的 ➕ 按钮。

2. 为项目命名(例如:Wiki-Movie-KG)

3. 在项目内,点击 Add Database,选择 Local DBMS,最后点击 Create a Local Graph。

配置数据库:

1. 名称:输入一个数据库名称(例如:neo4j)

2. 密码:设置一个密码(例如:mysecret)。请记住该密码,后面会用到。

3.点击 Create 初始化数据库。

接下来,让我们配置大语言模型。运行该 notebook 的推荐方式是使用 Ollama。Ollama 是一种本地托管的大语言模型解决方案,可以非常简单地在你的电脑上下载并设置大语言模型。它支持许多开源大语言模型,例如 Qwen2.5、GLM、Llama 和 Gemma。我认为 Ollama 是非常棒的本地模型解决方案,因为这样一来我可以在本地使用大语言模型而不用将个人数据暴露给服务提供商。

要下载 Ollama,请访问 Ollama 官网,下载适合你操作系统的安装程序。安装完成后,打开 Ollama 应用。

打开终端,使用以下命令列出可用模型:

解释

ollama list

安装并运行某个模型。这里,我们将使用 qwen2.5-coder:latest ,这是一款在编码任务上进行过微调的 7B 模型。

解释

ollama run qwen2.5-coder:latest

最后来验证安装:

解释

ollama show qwen2.5-coder:latest

您会看到如下的输出:

解释

Modelarchitecture        qwen2parameters          7.6Bcontext length      32768embedding length    3584quantization        Q4_K_MSystemYou are Qwen, created by Alibaba Cloud. You are a helpful assistant.LicenseApache LicenseVersion 2.0, January 2004

另一个免费的方案是使用 Google的大模型服务平台,要获取 api key,请访问这里(假设你已经拥有一个 Google 的账号并且已经登录到管理控制台),然后按照开发平台的引导创建 api key 并将生成的 key 复制并保存起来,后面会用到。

从零开始构建图谱工具

让我们先导入项目所需的一些库:

解释

# 提供类型提示
from typing import Any, Dict, List, Tuple# 标准库
import ast
import logging
import re
import warnings# 第三方包 - 数据操作
import pandas as pd
from tqdm import tqdm# 第三方包 - 环境配置和数据库
from dotenv import load_dotenv
from neo4j import GraphDatabase# 第三方包 - 错误处理与重试逻辑
from tenacity import retry, stop_after_attempt, wait_exponential# Langchain - 核心库
from langchain.chains import GraphCypherQAChain
from langchain.prompts import PromptTemplate
from langchain_core.documents import Document# Langchain - 模型和连接器
from langchain_google_genai import ChatGoogleGenerativeAI, GoogleGenerativeAI
from langchain_ollama.llms import OllamaLLM# Langchain - 图相关库与体验包
from langchain_community.graphs import Neo4jGraph
from langchain_experimental.graph_transformers import LLMGraphTransformer# 抑制警告
warnings.filterwarnings('ignore')# 加载环境变量
load_dotenv()

正如你所看到的,Langchain 在代码组织方面表现不佳,导致导入了相当多的库。让我们逐一解析这些库的用途:

●os 和 dotenv:帮助我们管理环境变量(例如数据库凭证)。

● pandas:用于处理电影数据集。

● neo4j:这个库将 Python 连接到 Neo4j 图数据库。

●langchain:提供工具,用于处理语言模型和图谱。

● tqdm:为打印语句添加一个友好的用户界面。我们会用它在循环中显示进度条,以便知道剩余的处理量。

● warnings:抑制不必要的警告信息,使输出的内容更干净。

我们将加载电影数据集,该数据集包含来自世界各地的大约 34000 多部电影的信息。此数据集可在 Kaggle 上公开获取。

解释

movies = pd.read_csv('data/wiki_movies.csv') # 按照你自己实际保存该数据集的路径进行修改
movies.head()

这里我们可以看到以下特征:

● Release Year(上映年份):电影的上映年份

● Title(标题):电影的标题

●Origin/Ethnicity(起源/民族性):电影的起源(例如:中国、美国、好莱坞、宝莱坞)

●Director(导演):导演(一部电影可能由多名导演共同执导)

●Plot(剧情):主要演员

●Genre(类型):电影的类型

●Wiki Page(电影在维基百科上的页面):提供剧情描述的维基百科页面的 URL 地址

● Plot(剧情描述):电影剧情的长篇描述

●通过观察这些特征,我们可以快速设计一些希望在知识图谱中看到的标签和关系。由于这是一个电影数据集,“电影”会是一个显而易见的标签。此外,我们可能对查询特定的演员和导演会感兴趣。因此,我们最终为节点确定了三个标签:Movie(电影)、Actor(演员)和 Director(导演)。当然,我们还可以添加更多标签,但为了简单起见,先到此为止。

● 同样的,为了简化操作,我们对数据集稍作清理,仅提取前 1000 行:

解释

def clean_data(df: pd.DataFrame) -> pd.DataFrame:"""清理并预处理 DataFrame.参数:data: 输入 DataFrame返回值:清理后的 DataFrame"""df.drop(["Wiki Page"], axis=1, inplace=True)# 删除重复项df = df.drop_duplicates(subset='Title', keep='first')# 获取对象类型的列col_obj = df.select_dtypes(include=["object"]).columns# 清理字符串列for col in col_obj:# Strip whitespacedf[col] = df[col].str.strip()# 替换未知/空值df[col] = df[col].apply(lambda x: None if pd.isna(x) or x.lower() in ["", "unknown"] else x.capitalize())# 删除包含任何空值的行df = df.dropna(how="any", axis=0)return dfmovies = clean_data(movies).head(1000)
movies.head()

在这里,我们删除了包含维基百科页面链接的 Wiki Page 列。不过,如果你愿意,也可以保留这一列,因为它可以作为 Movie(电影)节点的一个属性。接下来,我们根据标题删除所有重复项,并清理所有字符串(对象)列。最后,仅保留前 1000 部电影。

由于我们的知识图谱将托管在 Neo4j 上,接下来设置一个辅助类来建立连接并提供一些实用的方法:

解释

class Neo4jConnection:def __init__(self, uri, user, password):self.driver = GraphDatabase.driver(uri, auth=(user, password))def close(self):self.driver.close()print("连接已关闭。")def reset_database(self):with self.driver.session() as session:session.run("MATCH (n) DETACH DELETE n")print("数据库重置成功!")def execute_query(self, query, parameters=None):with self.driver.session() as session:result = session.run(query, parameters or {})return [record for record in result]

在初始化方法(__init__)中,我们使用数据库的 URL(uri)、用户名和密码来设置与 Neo4j 数据库的连接。在初始化类时会传递这些变量。

close 方法:终止与数据库的连接。

reset_database 方法:通过 Cypher 命令 MATCH (n) DETACH DELETE n 删除数据库中的所有节点和关系。

execute_query 方法:运行给定的查询(如添加电影或获取关系)并返回结果。

接下来,我们使用这个辅助类连接到数据库:

解释

uri = "bolt://localhost:7687"
user = "neo4j"
password = "mysecret"
conn = Neo4jConnection(uri, user, password)
conn.reset_database()

默认情况下,uri 和 user 将与上面提供的内容一致。至于 password ,它将是你在创建数据库时定义的密码。此外,我们使用 reset_database 来确保从干净的数据库开始,移除任何现有数据。

如果你遇到与数据库中未安装 APOC 相关的错误,请按照以下步骤操作:

1.打开 Neo4j

2.点击数据库

3.转到 Plugins(插件)

4.安装 APOC 插件

现在我们需要将数据集中的每部电影转换成图中的一个节点。在本节中,我们将手动完成此操作,而在接下来的章节中,我们将利用大语言模型来为我们完成这一任务。

解释

def parse_number(value: Any, target_type: type) -> Optional[float]:"""将字符串解析为数字,并进行适当的错误处理。"""if pd.isna(value):return Nonetry:cleaned = str(value).strip().replace(',', '')return target_type(cleaned)except (ValueError, TypeError):return Nonedef clean_text(text: str) -> str:"""清理并规范化文本字段。"""if pd.isna(text):return ""return str(text).strip().title()

让我们创建两个简短的函数 —— parse_number 和 clean_text ,分别用于将数值列的数据转换为数字,并正确格式化文本列。如果转换失败(比如值为空),对于数值列,这些函数返回 None ,对于对象列,返回一个空字符串。

接下来,让我们创建一个方法,用于将数据迭代加载到我们的知识图谱中:

解释

def load_movies_to_neo4j(movies_df: pd.DataFrame, connection: GraphDatabase) -> None:"""将电影数据加载到 Neo4j 中,并进行进度跟踪和错误处理。"""logger = logging.getLogger(__name__)logger.setLevel(logging.INFO)# 查询模板MOVIE_QUERY = """MERGE (movie:Movie {title: $title})SET movie.year = $year,movie.origin = $origin,movie.genre = $genre,movie.plot = $plot"""DIRECTOR_QUERY = """MATCH (movie:Movie {title: $title})MERGE (director:Director {name: $name})MERGE (director)-[:DIRECTED]->(movie)"""ACTOR_QUERY = """MATCH (movie:Movie {title: $title})MERGE (actor:Actor {name: $name})MERGE (actor)-[:ACTED_IN]->(movie)"""# 处理每部电影for _, row in tqdm(movies_df.iterrows(), total=len(movies_df), desc="正在加载电影数据"):try:# 准备电影相关实体的参数movie_params = {"title": clean_text(row["Title"]),"year": parse_number(row["Release Year"], int),"origin": clean_text(row["Origin/Ethnicity"]),"genre": clean_text(row["Genre"]),"plot": str(row["Plot"]).strip()}# 创建电影节点connection.execute_query(MOVIE_QUERY, parameters=movie_params)# Process directorsfor director in str(row["Director"]).split(" and "):director_params = {"name": clean_text(director),"title": movie_params["title"]}connection.execute_query(DIRECTOR_QUERY, parameters=director_params)# 处理演员相关数据if pd.notna(row["Cast"]):for actor in row["Cast"].split(","):actor_params = {"name": clean_text(actor),"title": movie_params["title"]}connection.execute_query(ACTOR_QUERY, parameters=actor_params)except Exception as e:logger.error(f"加载 {row['Title']} 错误: {str(e)}")continuelogger.info("加载电影数据到 Neo4j 已完成。")

理解上述 Cypher 查询的两个重要关键词是 MERGE 和 SET。

MERGE 确保节点或关系的存在,如果不存在,则创建它。因此,它结合了 MATCH 和 CREATE 子句的功能,其中 MATCH 用于在图中搜索特定结构,CREATE 用于创建节点和关系。因此,MERGE 会首先检查我们要创建的节点/边是否已存在,如果不存在,则创建它。

在上述函数中,我们使用 MERGE 为每部电影(Movie)、导演(Director)和演员(Actor)创建节点。特别地,由于我们有关于演员的特性(Star1、Star2、Star3 和 Star4),我们为每一列创建一个演员节点。

接下来,我们创建两个关系:

1.从导演到电影的关系(DIRECTED)。

2.从演员到电影的关系(ACTED_IN)。

SET 用于更新节点或边的属性。在这里,我们为电影节点提供了 Year(年份)、Rating(评分)、Genre(电影风格)、Runtime(电影时长)和 Overview(电影概述)属性。为导演和演员节点添加了 Name(姓名)属性。

另外,需要注意的是,我们使用了特殊符号 $ 来定义参数。

接下来,让我们调用该函数并加载所有电影数据:

解释

load_movies_to_neo4j(movies, conn)

加载所有 1000 部电影大约需要一分钟。(当然,这个视你的电脑配置而定)

执行完成后,我们运行一个 Cypher 查询来检查电影是否已正确上传:

解释

query = """
MATCH (m:Movie)-[:ACTED_IN]-(a:Actor)
RETURN m.title, a.name
LIMIT 10;
"""
results = conn.execute_query(query)
for record in results:print(record)

该查询现在应该看起来很熟悉了。我们使用 MATCH 来查找图中的模式。

●(m:Movie): 匹配标签为 “Movie” (电影)的节点。

● (a:Actor): 匹配标签为 “Actor” (演员)的节点。

此外,我们使用 RETURN 指定要显示的内容 —— 在这个例子中是电影标题和演员姓名,并使用 LIMIT 限制结果为前 10 个匹配项。

你应该会得到类似以下的输出:

解释

[<Record m.title='Daniel Boone' a.name='William Craven'>,<Record m.title='Daniel Boone' a.name='Florence Lawrence'>,<Record m.title='Laughing Gas' a.name='Bertha Regustus'>,<Record m.title='Laughing Gas' a.name='Edward Boulden'>,<Record m.title="A Drunkard'S Reformation" a.name='Arthur V. Johnson'>,<Record m.title='The Adventures Of Dollie' a.name='Arthur V. Johnson'>,<Record m.title='A Calamitous Elopement' a.name='Linda Arvidson'>,<Record m.title='The Adventures Of Dollie' a.name='Linda Arvidson'>,<Record m.title='The Black Viper' a.name='D. W. Griffith'>,<Record m.title='A Calamitous Elopement' a.name='Harry Solter'>]

这个包含 10 条记录(代表电影和演员)的列表确认了电影已经上传到知识图谱中了。

接下来,让我们看看实际的图谱。切换到 Neo4j Desktop 应用,选择为本次练习创建的电影数据库(Movie Database),并点击 Open with Neo4j Browser。这将打开一个新标签页,你可以在其中运行 Cypher 查询。然后,运行以下查询:

解释

MATCH p=(m:Movie)-[r]-(n)
RETURN p
LIMIT 100;

你现在应该会看到类似这样的内容:

是不是看起来很厉害!

然而,这确实还需要一些时间来探索数据集、进行数据清理,并手动编写 Cypher 查询。不过,现在大家不都在使用人工智能了嘛,当然我们不再需要通过人工方式这样做了,除非你想这么做。现在已经有多种方法可以自动化此过程。在该教程的下半部分中,我们将利用 LLM 创建一个基本的自动化解决方案。敬请期待!

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

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

相关文章

18.自动化生成知识图谱的多维度质量评估方法论

文章目录 一、结构维度评估1.1 拓扑结构评估1.1.1 基础图论指标1.1.2 层级结构指标 1.2 逻辑一致性评估1.2.1 形式逻辑验证1.2.2 约束满足度 二、语义维度评估2.1 语义一致性评估2.1.1 标签语义分析2.1.2 关系语义评估 2.2 语义表示质量2.2.1 嵌入质量2.2.2 上下文语义评估 三、…

go 集成base64Captcha 支持多种验证码

base64Captcha 是一个基于 Go 语言开发的验证码生成库&#xff0c;主要用于在 Web 应用中集成验证码功能&#xff0c;以增强系统的安全性。以下是其主要特点和简介&#xff1a; base64Captcha主要功能 验证码类型丰富&#xff1a;支持生成多种类型的验证码&#xff0c;包括纯…

制作大风车动画

这个案例的风车旋转应用了图形变换来实现&#xff0c;速度和缩放比例应用slider来实现&#xff0c;其中图片的速度&#xff0c;图片大小的信息通过State来定义变量管理&#xff0c;速度和和缩放比例的即时的值通过Prop来管理。 1. 案例效果截图 2. 案例运用到的知识点 2.1. 核…

代码随想录算法训练营第四十二四十三天

LeetCode/卡码网题目: 42. 接雨水84. 柱状图中最大的矩形98. 所有可达路径 其他: 今日总结 往期打卡 42. 接雨水 跳转: 42. 接雨水 学习: 代码随想录公开讲解 问题: 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能…

SEO 优化实战:ZKmall模板商城的 B2C商城的 URL 重构与结构化数据

在搜索引擎算法日益复杂的今天&#xff0c;B2C商城想要在海量信息中脱颖而出&#xff0c;仅靠优质商品和营销活动远远不够。ZKmall模板商城以实战为导向&#xff0c;通过URL 重构与结构化数据优化两大核心策略&#xff0c;帮助 B2C 商城实现从底层架构到搜索展示的全面升级&…

Linux自有服务

自有服务概述 概述 自有服务&#xff0c;即不需要用户独立去安装的软件的服务&#xff0c;而是当系统安装好之后就可以直接使用的服务&#xff08;内置&#xff09; 显示服务 显示服务 命令&#xff1a;systemctl \[选项] 选项参数 list-units --type service --all&#x…

ZYNQ Overlay硬件库使用指南:用Python玩转FPGA加速

在传统的FPGA开发中,硬件设计需要掌握Verilog/VHDL等硬件描述语言,这对软件开发者而言门槛较高。Xilinx的PYNQ框架通过Overlay硬件库彻底改变了这一现状——开发者只需调用Python API即可控制FPGA的硬件模块,实现硬件加速与灵活配置。本文将深入探讨ZYNQ Overlay的核心概念、…

JavaScript入门【1】概述

1.JavaScript是什么? <font style"color:rgb(38,38,38);">Javascript &#xff08;简称“JS”&#xff09;是⼀种直译式脚本语⾔&#xff0c;⼀段脚本其实就是⼀系列指令&#xff0c;计算机通过这些指令来达成⽬标。它⼜是⼀种动态类型的编程语⾔。JS⽤来在⽹…

c++从入门到精通(五)--异常处理,命名空间,多继承与虚继承

异常处理 栈展开过程&#xff1a; 栈展开过程沿着嵌套函数的调用链不断查找&#xff0c;直到找到了与异常匹配的catch子句为止&#xff1b;也可能一直没找到匹配的catch&#xff0c;则退出主函数后查找过程终止。栈展开过程中的对象被自动销毁。 在栈展开的过程中&#xff0c…

自适应稀疏核卷积网络:一种高效灵活的图像处理方案

自适应稀疏核卷积网络&#xff1a;一种高效灵活的图像处理方案 引言 在深度学习的大潮中&#xff0c;计算机视觉技术取得了长足的进步。其中&#xff0c;卷积神经网络&#xff08;CNN&#xff09;作为图像处理的核心工具&#xff0c;极大地推动了各类图像识别任务的效果提升。…

Nginx:利用 FreeSSL 申请(Https)免费证书的技术指南

1、简述 在现代互联网应用中,使用 HTTPS 连接是确保数据传输安全的基本需求。SSL/TLS 证书能够加密客户端与服务器之间的通信,防止中间人攻击等安全隐患。而许多开发者和小型企业可能会担心 SSL 证书的费用问题。幸运的是,FreeSSL 提供了一个简单易用的平台,允许我们申请免…

自定义库模块增加自定义许可操作详细方法

自定义库模块增加自定义许可操作详细方法 用到的工具: 后面程序用到的所有代码均是该工具生成的秘密&#xff01;&#xff01;&#xff01;&#xff01; 【切记切记&#xff01;&#xff01;&#xff01; 一定要记住密码&#xff0c;不然如果你想将库的许可认证移除&#xf…

python的漫画网站管理系统

目录 技术栈介绍具体实现截图![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0ed2084038144499a162b3fb731a5f37.png)![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/a76a091066f74a80bf7ac1be489ae8a8.png)系统设计研究方法&#xff1a;设计步骤设计流程核…

Python循环性脚本实践要点:打造稳定高效的定时任务

在Python开发中&#xff0c;循环性脚本&#xff08;长时间运行并定期执行任务的脚本&#xff09;非常常见&#xff0c;比如监控系统、数据采集程序、定时清理任务等。这类脚本虽然看似简单&#xff0c;但实际开发中容易遇到各种陷阱。本文将分享六大核心实践要点&#xff0c;帮…

编程基础:什么是变量

文章目录 变量&#xff1a;双要素变量必须代表一个意义&#xff1a;编程不需要无意义的变量。只要是变量&#xff0c;都需要有一个意义。变量必须要有不同的值&#xff1a;编程不需要只有一个值的变量。只要是变量&#xff0c;都需要有不同的值。 双要素少一个都不是变量即看见…

利用SenseGlove触觉手套开发XR手术训练体验

VirtualiSurg和VR触觉 作为领先的培训平台&#xff0c;VirtualiSurg自2017年以来一直利用扩展现实 (XR) 和触觉技术&#xff0c;为全球医疗保健行业提供个性化、数据驱动的学习解决方案。该平台赋能医疗专业人员进行协作式学习和培训&#xff0c;提升他们的技能&#xff0c;使…

【记录】Windows|竖屏怎么调整分辨率使横竖双屏互动鼠标丝滑

本文版本&#xff1a;Windows11&#xff0c;记录一下&#xff0c;我最后调整的比较舒适的分辨率是800*1280。 文章目录 第一步 回到桌面第二步 右键桌面第三步 设置横屏为主显示器第四步 调整分辨率使之符合你的需求第五步 勾选轻松在显示器之间移动光标第六步 拖动屏幕符合物理…

手机打电话时如何将通话对方的声音在手机上识别成文字

手机打电话时如何将通话对方的声音在手机上识别成文字 --本地AI电话机器人 上一篇&#xff1a;手机打电话时由对方DTMF响应切换多级IVR语音应答&#xff08;一&#xff09; 下一篇&#xff1a;手机打电话时由对方DTMF响应切换多级IVR语音应答&#xff08;二&#xff09; 一、…

uniapp-商城-61-后台 新增商品(添加商品到数据库)

完成商品的布局&#xff0c;完成商品的属性添加&#xff0c;最后的目的还是要完成数据添加&#xff0c;将我们前台的数据添加后台的数据库。 1、界面 2、点击提交完成商品添加 点击下方的提交按钮&#xff0c;将数据添加到数据库。 onSubmit 使用该函数---见3 <view cla…

A级、B级弱电机房数据中心建设运营汇报方案

该方案围绕A 级、B 级弱电机房数据中心建设与运营展开,依据《数据中心设计规范》等标准,施工范围涵盖 10 类机房及配套设施,采用专业化施工团队与物资调配体系,强调标签规范、线缆隐藏等细节管理。运营阶段建立三方协同运维模式,针对三级故障制定30 分钟至 1 小时响应机制…