构建基于大模型的Autonomous Agents案例(一)

news2024/9/17 8:38:24

构建基于大模型的Autonomous Agents案例
1.1 Autonomous Agents原理机制
在本节中,我们将聚焦于LangChain上的自治代理(Autonomous Agents on LangChain)。自治代理是当前业界最热门的话题之一,特别是在企业级应用中。当然,自治代理也是核心研究的焦点之一。
如图15-1所示,这是BabyAGI的一个基本流程图。
在这里插入图片描述

图15- 1 BabyAGI的一个基本流程图
在这个流程图中,我们可以看到它从具体的任务列表开始。
Gavin大咖微信:NLP_Matrix_Space
第一步:是获取第一个未完成的任务(pull the first Incomplete task)。显然,它是从任务列表中获取的。根据之前我们分享的内容,大家应该清楚任务列表是由我们的大型语言模型生成的,比如GPT-4,这是第一步,获取了未完成的任务后,接下来就是执行任务的过程(Execute task)。我们有一个具体的执行代理(Execution Agent),在这里可以进行各种操作,因为它是一个代理,可以与我们的模型进行交互。在这个执行过程中,核心是BabyAGI,最初的思想依赖于模型,但是作为一个代理,根据我们之前分享的内容,大家应该清楚它也可以与工具进行交互,会涉及模型、工具和数据访问,从而产生结果。在LangChain中,可以使用链式(chain)的方式,例如LLMChain,完成了许多工作。所产生的结果来源是语言模型提供的,提供的信息基于一些前提条件,比如任务的目标、过去的历史记录和系统设置等。当然,有时代理会调用第三方工具来生成结果,这些结果也会作为模型在生成结果之前的输入信息。这些内容对大家来说,不应该有任何理解上的难度,因为我们之前通过大量的案例和源码解析已经剖析了这些内容。例如,GPT-4基于这些因素生成了一个结果,把这个结果交给代理,转过来,作为下一步执行的前提或上下文。
第二步:丰富结果并存储在Vector DB中(Enrich result and store in Vector DB)。由于BabyAGI是一个面向任务的自动自治代理,因此它会有一些状态管理或保存。这里有一个非常有趣的词,叫做“Enrich”,这个词非常有意思。做大数据Flink开发的人员会明白,Flink在数据流动中的核心工作之一就是数据的丰富化操作。所谓数据丰富化操作,意思是基于某个事件,你可能在执行之前或之后都会产生一些新的信息,但是这些新的信息需要完成丰富化的过程,它会与其他信息进行关联,所以觉得在这里使用这个词非常恰当。“丰富结果并存储在Vector DB”,在这里,实际上它的核心是做什么呢?它的核心是将上下文、过去完成的任务、系统设置信息以及你的目标结合起来,完成整个丰富化的过程,并将结果存储在向量数据库中。在这一步中,涉及到上下文代理(Context Agent),其中,检索上下文(Retrieve context)与许多历史信息相关联。返回结果(Return result)是第一步中的结果,基于检索上下文以及返回结果,将结果存储在向量数据库中(Store result in Vector DB)中。
Gavin大咖微信:NLP_Matrix_Space
第三步:创建新任务并重新确定任务列表的优先级(Create new tasks and reprioritize task list)。在这一步中,我们可以创建新的任务,并重新确定任务列表的优先级。创建新任务和重新确定任务列表的优先级由谁来完成呢?当然是我们的语言模型,比如GPT-4。我们对大型语言模型应用程序开发特别感兴趣的原因之一是它的推理能力。创建新任务是一个动态的、不断发展的过程,这是使用语言模型的关键之一,在具体的实际场景中,这一点具有重要意义。例如,在教育领域,如果学习过程由大型语言模型驱动,教授或导师给学生分配任务,学生完成第一个任务后,语言模型会结合上下文信息和历史信息进行数据丰富(Data Enrich),“Enrich”这个词非常合适,“Enrich”的概念可以通过其他学术表现来进行丰富,不仅仅局限于本学期或本学年,还可以考虑过去1年甚至5年的表现。当将这些信息再次交给我们的语言模型进行处理时,它会动态生成新的任务。生成新任务后,语言模型还会进行另一个操作,即重新确定任务列表的优先级,以决定下一步最佳的执行顺序。因此,这个系统实现了自动化、个性化、更加高效和有针对性的教育场景。对于从事教育领域的人来说,这个过程应该是非常令人激动的,因为现在技术已经成为现实。
我们进行了优先级代理(Prioritization Agent)的操作,确定了下一步的执行操作,然后可能会再次重复(Loop)之前的过程,但是请注意,在这个重复的过程中,有一些东西是不变的,那就是用户的目标。以教育场景为例,你的导师可能要求你完成一个作业,这个作业的背景、条件和评估等信息,这些是不变的,这些信息会约束你的整个行为。但是,什么是在变化的呢?是你每次完成任务时的状态变化。在目标不变的情况下,你的状态不断变化,结合目标、状态和历史表现,语言模型会动态调整生成的学习任务,而且具有很强的针对性。例如,对于一般学生来说,完成一个任务可能需要执行30个步骤或者完成30个子任务。但对于那些非常优秀或对该领域特别感兴趣的学生来说,他们可能只需要一两个步骤就能完成。尤其是在数据丰富化(Data Enrichment)这一步骤中,没有必要一步一步进行。但如果你的基础不好,或者对该领域的兴趣不够强烈,那么给你提供更精细化的步骤就是必要的。
因此,BabyAGI在业界产生了相当大的影响,尤其是它的思想揭示了语言模型的潜力和能力,以及它对教育行业和其他相关行业的实际价值。这也是为什么我们专门花一节内容来讨论基于LangChain的自主代理(autonomous agent on langchain)的原因之一。我们也专门讨论了另一个自主代理,是AutoGPT,揭示其背后的原理以及案例的源代码。
如图15-2所示,是LangChain的自治代理的代码目录,在目录(autonomous_agents)下面有两个目录,一个是AutoGPT,另外一个是BabyAGI。
在这里插入图片描述

图15- 2 LangChain的自治代理代码目录
AutoGPT和BabyAGI是两个典型的代理,但我们并不是直接使用它们,而是它们揭示了自然语言处理模型的巨大推理能力,并将其变成了现实。它们展示了这一点,并对各个领域产生了重大的理论影响。AutoGPT自动地将一个高层任务分解为具体步骤,并自动进行反思的自我调整。这在通用人工智能或自动化领域中提供了许多令人想象的空间。
我们初步讨论了这个基本流程。在代理的视角下,我们考虑了三个核心代理。第一个是执行代理(Execute Agent),它背后调用GPT-4或其他大型语言模型。第二个是任务创建代理(Task Creation Agent),它根据你的目标进行任务创建。在教育场景中,例如导师给出一个作业,这对所有学生来说是相同的,只是具体的学习过程不同。任务创建代理会考虑你之前的执行情况,并考虑你的背景、最近和长期的学习记录。这也涉及到上下文代理(Context Agent)的内容,将所有的状态数据存储在一个地方,并随时可以访问。当然,我们使用基于向量数据库的方式,例如,你可以使用Facebook的Faiss。第三个核心是优先级代理(Prioritization Agent),它涉及到确定下一步最重要的任务是什么。这是非常关键的,特别是在动态环境下。作为一个代理,设定优先级非常重要。回到之前提到的教育场景的例子,优先级代理可以确定哪些任务是重要且紧急的,这样可以让学生在最合适的时候学习最重要的内容或获得及时的帮助。然而,设置优先级时需要考虑许多因素,而这些因素的考虑是由模型驱动的。我们也强调了另一个非常重要的点,你可以使用专家模型来影响决策过程,包括影响优先级的排序或管理决策过程。无论是通过论文,还是源代码的角度,我们前面都非常清楚地向大家解释了,当你的大型语言模型考虑不同领域专家的观点,尤其是那些相对较小的模型时,可以显著提升性能。
Gavin大咖微信:NLP_Matrix_Space
回到我们的案例,具体看看它是如何实施的,以及案例的运行过程。在这个基础上,我们将深入探讨框架的内部实现。无论是案例,还是框架,我们都基于LangChain进行开发。LangChain已经成为开源界和工业界公认的标准大型模型应用开发框架,它提供了许多实用的工具,能够节省大量时间。我们具体看一下代码部分,这是基于官方文档中的“BabyAGI with Tools”实现的,这个名称本身就让人兴奋,因为它基于代理思想与工具进行交互,工具是LangChain提供的一个非常核心的功能。
第一步,我们需要安装一些库,例如LangChain、OpenAI、tiktoken等。我们使用的是faiss-cpu,这不仅是一个CPU版本,而且你不需要依赖其他工具,因为它可以在本地模式下运行。此外,我们还使用了google-search-results等库。

!pip install langchain openai tiktoken faiss-cpu google-search-results -q

我们在本地使用的是faiss的cpu版本,因为有faiss的本地模式。在当前进行大模型应用开发时,实际上进行向量操作的时候,并不需要太多的计算资源。这是一个经常被读者问到的问题,是否需要一台专门的GPU服务器,从开发或学习的角度来看,实际上是不需要的。即使在某些情况下确实需要GPU,最简单且最高效的方法是使用Google Colab,它是最简单且最广泛使用的方式,因为全世界有那么多人在使用Google Colab,它已经经过了充分的测试和优化,经历了千锤百炼,而且它不仅提供GPU,还提供TPU,所以你根本不用担心硬件的许多问题。对于开发大型模型应用程序,对机器的特殊要求并不是必须的,并没有对机器提出特别的要求。
导入必要的库,并设置环境变量,导入LLMChain、OpenAI等。代码中还包括了一些向量存储的导入,以及一些基本的配置。在导入库和设置环境变量后,代码使用了dotenv库加载环境变量文件,并将SERPAPI_API_KEY和OPENAI_API_KEY设置为相应的值。

1.	import os
2.	from collections import deque
3.	from typing import Dict, List, Optional, Any
4.	
5.	from langchain import LLMChain, OpenAI, PromptTemplate
6.	from langchain.embeddings import OpenAIEmbeddings
7.	from langchain.llms import BaseLLM
8.	from langchain.vectorstores.base import VectorStore
9.	from pydantic import BaseModel, Field
10.	from langchain.chains.base import Chain 
11.	 
12.	import os
13.	
14.	from dotenv import load_dotenv, find_dotenv
15.	_ = load_dotenv(find_dotenv())
16.	
17.	os.environ['SERPAPI_API_KEY'] = os.getenv('SERPAPI_API_KEY')
18.	os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY')

以上代码中,我们使用了collections库中的一个重要数据结构deque,它作为一种数据结构,deque可以从左侧或右侧进行操作,也可以从前端或后端进行操作,而且非常高效。作者之前给一家跨国公司讲解高级Python开发时,其中有五个核心的高级数据结构,而deque是其中一个非常重要的结构,之所以重要,是因为它提供了许多有用的数据结构操作,值得大家花时间去学习。
接下来我们导入了LLMChain,在之前的源码和运行过程中,我们一直使用LLMChain。导入PromptTemplate和OpenAIEmbeddings,因为它们对于管理提示(Prompt)和将文本转换为向量非常有效。尤其是OpenAIEmbeddings的表现还不错,它可以将输入的信息或文本转换为向量表示。BaseLLM作为类似于包装器(wrapper)的方式,可以将它视为类似于一个接口。VectorStore用于数据存储,BaseModel、Field和Chain是一些基本的对象。
我们回到官方文档,LangChain为我们提供了一些模块,包括模型输入输出(Model I/O)、数据连接(Data connection)、链(Chains)、内存(Memory)、代理(Agent)、回调(Callbacks)等。LangChain提供了这些模块,使得开发变得更容易。它提供了许多LangChain本身没有实现的功能,特别是当你想复现最新的研究论文,或展示一个在网络上找不到参考的产品演示时,LangChain的模块可以极大地方便你的开发,提高开发质量并节省时间。
由于我们需要进行网络操作,使用了Python封装的Google服务,并且有对应的SERPAPI_API_KEY。此外,我们还需要OPENAI_API_KEY。
以下代码中,首先,导入InMemoryDocstore和FAISS模块。InMemoryDocstore用于在内存中存储文档数据,而FAISS是一个用于向量存储和相似性搜索的模块。接下来,定义了一个嵌入式向量模型embeddings_model,使用的是OpenAIEmbeddings,一般是1536维,每个维度代表一个特征,这个嵌入式向量模型可以将文本转换为向量表示。这里使用了FAISS模块,检索模型是IndexFlatL2,Faiss会有很多其他的检索算法,将嵌入查询函数embeddings_model.embed_query、索引和文档存储对象传递给FAISS的构造函数。InMemoryDocstore({})表示使用内存中的文档存储。

1.	from langchain.docstore import InMemoryDocstore
2.	from langchain.vectorstores.faiss import FAISS
3.	
4.	# 定义嵌入模型
5.	embeddings_model = OpenAIEmbeddings()
6.	# 将vectorstore初始化为空
7.	import faiss
8.	embedding_size = 1536
9.	index = faiss.IndexFlatL2(embedding_size)
10.	vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) 

接下来,定义一些链(Chains),BabyAGI依赖于三个LLM链:
 任务创建链:以选择要添加到列表中的新任务
 任务优先级链:以重新确定任务的优先级
 执行链:执行任务
TaskCreationChain类是LLMChain的子类,关键在于TaskCreationChain类,它在创建任务时提供了帮助。TaskCreationChain类提供了一个from_llm的类方法,用于从基本LLM(Language Model)对象创建LLMChain对象。这个方法接受一个llm参数和一个verbose参数,并返回一个LLMChain对象。在from_llm方法中,定义了一个task_creation_template的任务创建模板。该模板描述了任务创建AI的功能和使用的输入变量,包括目标(objective)、结果(result)、任务描述(task_description)和未完成任务(incomplete_tasks)等。
任务创建模板的内容为:

你是一个任务创建AI,它使用执行代理的结果来创建具有以下目标的新任务:{objective},最后完成的任务具有结果:{result}。此结果基于任务描述:{task_description}。这些是未完成的任务:{incomplete_tasks}。根据结果,创建AI系统需要完成的新任务,且不与未完成的任务重叠。以数组形式返回任务。
通过使用PromptTemplate,将任务创建模板和输入变量传递给LLMChain的构造函数,创建了一个具有任务创建功能的LLMChain对象,并将其作为结果返回。

1.	class TaskCreationChain(LLMChain):
2.	    """生成任务的链."""
3.	
4.	    @classmethod
5.	    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
6.	        """获取响应解析器."""
7.	        task_creation_template = (
8.	            "You are an task creation AI that uses the result of an execution agent"
9.	            " to create new tasks with the following objective: {objective},"
10.	            " The last completed task has the result: {result}."
11.	            " This result was based on this task description: {task_description}."
12.	            " These are incomplete tasks: {incomplete_tasks}."
13.	            " Based on the result, create new tasks to be completed"
14.	            " by the AI system that do not overlap with incomplete tasks."
15.	            " Return the tasks as an array."
16.	        )
17.	        prompt = PromptTemplate(
18.	            template=task_creation_template,
19.	            input_variables=["result", "task_description", "incomplete_tasks", "objective"],
20.	        )
21.	        return cls(prompt=prompt, llm=llm, verbose=verbose) 

这里使用的from_llm方法是基于大语言模型的,我们在这里明确指出,任务的创建是由任务创建代理(Task Creation Agent)使用大语言模型,根据提示(Prompts)来创建的。我们来看一下模板(templates),在这里使用的是 PromptTemplate。在这个模板中,我们描述了一个任务创建的AI,它利用执行代理(Execution Agent)的结果来创建任务。那么我们的执行代理在哪里呢?如图15-3所示,虚框标识的是执行代理。第一步是获取要执行的任务,并由执行代理完成任务。执行代理的结果经过丰富化的过程,结合上下文,然后传递给我们的任务创建代理。
在这里插入图片描述

图15- 3 执行代理
创建具有以下目标的新任务:{objective}。显然,这个目标是你输入的一个目标,用户告诉你要做什么。最后完成的任务的结果是:{result},这是你的输出结果。如果目标是用户的输入,那么结果就是输出。这样说也不完全准确,因为我们讨论的是最后一个任务的输出结果。从大语言模型的角度来看,当它生成一个类似于报告的最终结果时,最后一个任务肯定是一个核心内容,但它还包含历史信息和其他的一些信息。这个结果是基于以下任务描述{task_description}的内容,接下来是未完成的任务:{incomplete_tasks}。根据这个结果,创建新的将要去完成的任务。这是它的指令,要求你创建新的任务,AI系统根据指令创建的任务不应与未完成的任务重叠。这是一个非常高质量的提示,因为它清晰地说明了在创建新任务时,不应与已存在的未完成任务有重叠,否则会有太多的重复信息。然后,将任务作为一个数组返回,我们将在其中将提示(Prompt)放入我们的 PromptTemplate,并设置 input_variables为[“result”,“task_description”,“incomplete_tasks”,“objective”]。这个目标(objective)显然是最终的目标。有时候我们开玩笑地说,开放式的目标是什么?目标就像一个婴儿,而这个婴儿是个老板。婴儿看起来好像发出了一个指令或者需求,就像一个婴儿有各种各样的需求一样。无论是人,还是物,我们都围绕着这个婴儿转,这就是你所处的环境。因此,当我们谈到目标时,我们经常说“婴儿是老板”。一方面,这是为了强调目标的重要性,另一方面,在团队协作和交流时,大家都明白这句话的含义,即一切都应与目标保持一致。 确实,在整个自主(Autonomous)模型的运行过程中,它会在每一步考虑你的目标,只有这样它才能以自主的方式执行任务。因此,这种自主方式实际上是有具体目标的,而这个目标是由用户输入的,只是用户输入了目标后,自动帮助他去完成。实际上,它是由用户控制的,因为用户给出了任务,它是面向任务的自主代理(Autonomous Agent)。
以上代码第21行,这里是创建LLMChain类的实例,我们返回的是一个LLMChain对象。该对象包含了我们的模型、提示(prompts)以及verbose状态。通常,大家会将verbose设置为True,因为这样可以看到更多的内部状态。这个对象是我们的任务创建代理(Task Creation Agent)。
接下来,另外一个代理是优先级排序代理(Prioritization Agent),它以一个链(Chain)的方式帮我们进行封装,这是确定任务优先级的链。
task_prioritization.py的代码实现:

1.	class TaskPrioritizationChain(LLMChain):
2.	    """确定任务优先级的链."""
3.	
4.	    @classmethod
5.	    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
6.	        """获取响应解析器."""
7.	        task_prioritization_template = (
8.	            "You are an task prioritization AI tasked with cleaning the formatting of and reprioritizing"
9.	            " the following tasks: {task_names}."
10.	            " Consider the ultimate objective of your team: {objective}."
11.	            " Do not remove any tasks. Return the result as a numbered list, like:"
12.	            " #. First task"
13.	            " #. Second task"
14.	            " Start the task list with number {next_task_id}."
15.	        )
16.	        prompt = PromptTemplate(
17.	            template=task_prioritization_template,
18.	            input_variables=["task_names", "next_task_id", "objective"],
19.	        )
20.	        return cls(prompt=prompt, llm=llm, verbose=verbose) 

TaskPrioritizationChain类继承至LLMChain类,是一个确定任务优先级的链。实现了一个from_llm类方法,接收llm和verbose两个参数,返回一个LLMChain对象。该方法的作用是获取响应解析器。其中,定义一个task_prioritization_template的字符串变量,包含任务名称和目标信息,并使用一些占位符,如{task_names}、{objective}和{next_task_id},用于在代码中进行动态替换。
任务优先级模板的内容为:

你是一个任务优先级AI,负责清理以下任务的格式,并重新排定优先级:{task_names}。考虑你团队的最终目标:{objective},不要删除任何任务,以编号列表的形式返回结果,如:#.第一个任务 #.第二个任务 启动编号为{next_task_id}的任务列表

接下来,使用PromptTemplate创建了一个prompt的实例,该实例的作用是将上述占位符替换为实际的信息。然后,返回一个TaskPrioritizationChain的实例对象,该对象包含了prompt、llm和verbose等属性。
TaskPrioritizationChain类的from_llm方法返回的是一个LLMChain对象,这一点是显而易见的。在这个方法中,我们可以看到一些重要的指令。注意,我们之前已经明确说明了,这个模型是GPT-4的服务,用于管理任务的优先级。因此,在指令中,你需要明确地告诉GPT-4要做什么,“你是一个任务优先级AI,负责清理格式,并重新排定以下任务的优先级:{task_names}。”这句话,告诉了模型它需要清理和重新排序任务。这里面的一些符号,如“cleaning the formatting”、 “reprioritizing”都是动名词的形式,语言模型会根据符号之间的关系,去获取相应的信息。这种观点在我们之前的论文中已经非常清楚地被阐述过,即模型本身并不会思考,它只是将文本基于符号构建的模式隐式提取出来。由于有这些模式,它会涉及到一些步骤。其中,{task_names}是具体任务的列表。同时,你需要明确告诉模型,你的团队的终极目标{objective}是什么。注意,一定不要删除任何任务,因为它们都是核心信息。如果模型将它们删除了,将会产生非常大的影响。但如果从应用的角度来看,你可能希望它移除一些任务,以更好地适应特定个体的需求。返回结果是一个编号列表,例如:“#. 第一个任务,#.第二个任务”,并从数字{next_task_id}开始计任务列表,这里的列表可以看作是计算机中的堆栈,模板的输入变量是[“task_names”, “next_task_id”, “objective”],返回一个LLMChain实例。

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

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

相关文章

关于综合能源智慧管理系统的架构及模式规划的研究

安科瑞 华楠 摘 要:探讨了国内外能源互联网的研究发展,分析了有关综合智慧能源管理系统的定位,以及系统的主要特点,研究了综合智慧能源管理系统的构架以及模式规划。 关键词:综合能源;智慧管理系统&#…

MySql操作进阶

目录 1.多表联查 1.1内连接 1.2左连接和右连接 1.3自连接 2.子查询 3.合并查询 1.多表联查 多表联查实际上就是对多张表中的数据合并在一起进行查询,具体合并多张表中的数据方式为:取笛卡尔积的方式进行合并。 但仅是以笛卡尔积的方式合并表较为…

网络安全进阶学习第九课——SQL注入介绍

文章目录 一、什么是注入二、什么是SQL注入三、SQL注入产生的原因四、SQL注入的危害五、SQL注入在渗透中的利用1、绕过登录验证:使用万能密码登录网站后台等。2、获取敏感数据3、文件系统操作4、注册表操作5、执行系统命令 六、如何挖掘SQL注入1、SQL注入漏洞分类按…

无涯教程-Lua - Arrays(数组)

数组是对象的有序排列,可以是包含行集合的一维数组,也可以是包含多行和多列的多维数组。 在Lua中,数组是使用带有整数的索引表实现的。数组的大小不是固定的,并且可以根据无涯教程的要求(取决于内存限制)来增长。 一维数组 一维…

WEB应用程序数据库防守篇之预防SQL漏洞注入

前言: 国内目前几乎市面上所有的web应用程序都使用关系型数据库来存储用户的数据信息,可以这么说,数据库是一个项目,一个互联网公司乃至国家最重要的数据中心。如果数据库被入侵成功,所引发的后果将是灾难性,无法想象…

JavaSE 【类和对象】(3)(重点:代码块、对象的打印)

目录 一、代码块 1.静态代码块 2.构造代码块/实例代码块 3.总结 代码块执行的顺序: 1.静态代码块 2.构造代码块(实例代码块) 3.执行对应的构造方法 其中:静态的只执行一次 二、 对象的打印 有一个快速打印的方法&#x…

scrapy框架简单实现豆瓣评分爬取案例

豆瓣网址:https://movie.douban.com/top250 1.创建scrapy框架 scrapy startproject 项目名(scrapy_test_one)创建好以后的目录是这样的 2.创建spider文件 在spiders目录下创建一个spider_one.py文件,可以随意命名,该文件主要是让我们进行数…

MaxPatrol SIEM 增加了一套检测供应链攻击的专业技术

我们为 MaxPatrol SIEM 信息安全事件监控系统增加了一套新的专业技术。 该产品可帮助企业防范与供应链攻击相关的威胁。 此类攻击正成为攻击者的首要目标:它们以软件开发商和供应商为目标,网络犯罪分子通过他们的产品进入最终目标的基础设施。 因此&a…

【数据结构】——线性表的相关习题

目录 题型一(顺序表的存储结构)题型二(链表的判空)题型三(单链表的建立)题型四(顺序表、单链表的插入删除) 题型一(顺序表的存储结构) 1、线性表的顺序存储结…

Framework开发的热度从未下降~

近几日,统计局也发布了就业相关数据,全国失业青年达600多万,面对此数据,我们能想到的是实际的失业人数肯定会比公布的数据要多很多,尤其是表示 “一周工作一小时以上” 也纳入了就业范围。 反观有一批Android开发在如此…

JavaWeb之HTML基础篇(一)

系列文章目录 HTML基础篇(一) 文章目录 系列文章目录HTML基础篇(一)[TOC](文章目录) 前言一、HTML简介1.1介绍1.2HTML文件的书写规范1.3 HTML标签介绍1.4 HTML常见的标签 二、CSS的简介2.1css技术介绍2.2 CSS与HTML结合的三种方式…

org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter-若依二开报错(已解决)

阿丹-问题描述: 今天在复制已经拆解过后的若依system模块删除掉中间的一些东西之后,出现了一个问题。已启动就报错。报错截图如下。 问题解析: 身边不少二开若依的小伙伴都遇到了这个问题。 这个异常是因为在启动应用程序时,Sprin…

杜教筛的小结

总所周知,杜教筛是一个可以快速求积性函数前缀和的工具,为了快速理解杜教筛,自己给自己写了一个文章快速理解。 它可以在O(n2/3)的复杂度快速求出某个积性函数的前缀和。 例如,我们想要知道 f f f函数的前缀和,我们可…

selenium官网文档阅读总结(day 2)

1.selenium元素定位方法 1.1selenium命令 当我们使用chormdriver打开网页后,接下来就要用python操作元素,模拟用户会作出的操作,这些操作元素的方法就是命令。比如 (1) click:点击(按钮,单选框&#xff…

STM32(HAL)多串口进行重定向(printf函数发送数据)

目录 1、简介 2.1 基础配置 2.1.1 SYS配置 2.1.2 RCC配置 2.2 串口外设配置 2.3 项目生成 3、KEIL端程序整合 4、效果测试 1、简介 在HAL库中,常用的printf函数是无法使用的。本文通过重映射实现在HAL库多个串口可进行类似printf函数的操作。 2.1 基础配置 2.…

《向量数据库指南》——腾讯云向量数据库Tencent Cloud Vector DB正式上线公测!提供10亿级向量检索能力

8月1日,腾讯云向量数据库(Tencent Cloud Vector DB)已正式上线公测。在腾讯云官网上搜索“向量数据库”,就可以正式体验该产品。 腾讯云向量数据库不仅能为大模型提供外部知识库,提高大模型回答的准确性,还可广泛应用于推荐系统、文本图像检索、自然语言处理等 AI 领域。…

【ARM Coresight 系列文章 2.3 - Coresight 寄存器】

文章目录 Coresight 寄存器介绍1.1 ITCTRL,integration mode control register1.2 CLAIM寄存器1.3 DEVAFF(Device Affinity Registers)1.4 LSR and LAR1.5 AUTHSTATUS(Authentication Status Register) Coresight 寄存器介绍 Coresight 对于每个 coresight 组件&am…

Python 进阶(七):高级文件操作(shutil 模块)

❤️ 博客主页:水滴技术 🌸 订阅专栏:Python 入门核心技术 🚀 支持水滴:点赞👍 收藏⭐ 留言💬 文章目录 1. 简介2. 常用函数2.1 复制文件2.2 复制目录2.3 移动文件或目录2.4 删除文件或目录2.…

【C++】STL——list的模拟实现、构造函数、迭代器类的实现、运算符重载、增删查改

文章目录 1.模拟实现list1.1构造函数1.2迭代器类的实现1.3运算符重载1.4增删查改 1.模拟实现list list使用文章 1.1构造函数 析构函数 在定义了一个类模板list时。我们让该类模板包含了一个内部结构体_list_node,用于表示链表的节点。该结构体包含了指向前一个节点…

构建容错软件系统的艺术

现在,我们生活在由软件系统推动的世界中。这些系统深入到我们日常生活的各个方面,其连续、可靠的性能不再是奢侈,而是必需。现在,企业比以往任何时候都更需要保证他们的系统可用、可靠,并具有弹性。这种需求由满足客户…