BabyAGI源码解读(1)-主体配置部分

news2025/1/11 22:53:17

1. BabyAGI概览

babyAGI是一个AI驱动的任务管理系统,其中babyagi.py脚本中定义了整个的流程,使用OpenAI的NLP能力根据目标创建新的任务,使用Chroma和Weaviate作为上下文存储和获取任务结果。

babyAGI实际上是一个死循环,它执行以下几步

  • 从任务列表中获取第一个任务
  • 将任务发送给agent,agent使用 OpenAI 的 API 根据上下文完成任务
  • 将生成的结果存在向量数据库chroma或weaviate中
  • 创建新任务,并根据上一个任务的目标和结果重新确定任务列表的优先级

babyAGI流程
execution_agent()使用了OpenAI提供的API,他有两个参数:

  • 目标
  • 任务

它通过OpenAI的API发送一个Prompt,Prompt包含了任务的描述、目标和任务本身,结果会以字符串形式的反馈。

task_creation_agent()函数使用OpenAI API创建基于目标和之前任务结果的新任务。这个函数有四个参数:

  • 目标
  • 之前任务的结果
  • 任务的描述
  • 当前任务列表

它返回一个新任务的列表,并将新任务处理成一个字典,每个字典包含任务名称

prioritization_agent()函数只有一个参数,当前任务的id,它向OpenAI API发送提示词,返回一个编号的重新确定优先级的任务列表。

最后,使用Chroma/Weaviate向量数据库来存储和检索上下文任务结果。脚本根据TABLE_NAME变量中指定的表名创建一个Chroma/Weaviate集合。然后使用Chroma/Weaviate将任务结果存储到集合中,同时包括任务名称和任何额外的元数据。

2. BabyAGI源码解读

babyagi的程序主体放在babyagi.py文件中,大概600行左右的程序。

主要用的依赖有

  • chromadb
  • tiktoken
  • openai
  • llama-cpp-python 主要用来运行llama模型

1. 参数获取

代码首先是一些从环境变量中获取的参数,需要配置的参数有

  • OPENAI_API_MODEL或LLM_MODEL 使用的openai的模型名称
  • OPENAI_API_KEY openai的api key,后续我们可以进行造,以支持其他模型接口
  • RESULTS_STORE_NAME 结果存放的名称
  • INSTANCE_NAME 实体名称,也就是你的角色名
  • OBJECTIVE 目标
  • INITIAL_TASK或FIRST_TASK 初始任务或第一个任务
  • OPENAI_TEMPERATURE openai的temperature
  • COOPERATIVE_MODE 协作方式,alone、local以及distribute
  • JOIN_EXISTING_OBJECTIVE 是否加入已经存在的目标
client = chromadb.Client(Settings(anonymized_telemetry=False))

# Engine configuration

# Model: GPT, LLAMA, HUMAN, etc.
LLM_MODEL = os.getenv("LLM_MODEL", os.getenv("OPENAI_API_MODEL", "gpt-3.5-turbo")).lower()

# API Keys
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY", "")
if not (LLM_MODEL.startswith("llama") or LLM_MODEL.startswith("human")):
    assert OPENAI_API_KEY, "\033[91m\033[1m" + "OPENAI_API_KEY environment variable is missing from .env" + "\033[0m\033[0m"

# Table config
RESULTS_STORE_NAME = os.getenv("RESULTS_STORE_NAME", os.getenv("TABLE_NAME", ""))
assert RESULTS_STORE_NAME, "\033[91m\033[1m" + "RESULTS_STORE_NAME environment variable is missing from .env" + "\033[0m\033[0m"

# Run configuration
INSTANCE_NAME = os.getenv("INSTANCE_NAME", os.getenv("BABY_NAME", "BabyAGI"))
COOPERATIVE_MODE = "none"
JOIN_EXISTING_OBJECTIVE = False

# Goal configuration
OBJECTIVE = os.getenv("OBJECTIVE", "")
INITIAL_TASK = os.getenv("INITIAL_TASK", os.getenv("FIRST_TASK", ""))

# Model configuration
OPENAI_TEMPERATURE = float(os.getenv("OPENAI_TEMPERATURE", 0.0))

dotenv现在使用的越来越多了,也可能和12-factor有关。

2. 扩展配置

这一段主要的功能是,为babyagi加载扩展功能,其使用importlib实现了热加载的行为

其配置项有

  • DOTENV_EXTENSIONS 配置要加载的额外项,多个使用逗号分隔
  • ENABLE_COMMAND_LINE_ARGS 启用命令行参数传入
# Extensions support begin

def can_import(module_name):
    try:
        importlib.import_module(module_name)
        return True
    except ImportError:
        return False


DOTENV_EXTENSIONS = os.getenv("DOTENV_EXTENSIONS", "").split(" ")

# Command line arguments extension
# Can override any of the above environment variables
ENABLE_COMMAND_LINE_ARGS = (
        os.getenv("ENABLE_COMMAND_LINE_ARGS", "false").lower() == "true"
)
if ENABLE_COMMAND_LINE_ARGS:
    if can_import("extensions.argparseext"):
        from extensions.argparseext import parse_arguments

        OBJECTIVE, INITIAL_TASK, LLM_MODEL, DOTENV_EXTENSIONS, INSTANCE_NAME, COOPERATIVE_MODE, JOIN_EXISTING_OBJECTIVE = parse_arguments()

# Human mode extension
# Gives human input to babyagi
if LLM_MODEL.startswith("human"):
    if can_import("extensions.human_mode"):
        from extensions.human_mode import user_input_await

# Load additional environment variables for enabled extensions
# TODO: This might override the following command line arguments as well:
#    OBJECTIVE, INITIAL_TASK, LLM_MODEL, INSTANCE_NAME, COOPERATIVE_MODE, JOIN_EXISTING_OBJECTIVE
if DOTENV_EXTENSIONS:
    if can_import("extensions.dotenvext"):
        from extensions.dotenvext import load_dotenv_extensions

        load_dotenv_extensions(DOTENV_EXTENSIONS)

# TODO: There's still work to be done here to enable people to get
# defaults from dotenv extensions, but also provide command line
# arguments to override them

# Extensions support end

3.打印配置

print("\033[95m\033[1m" + "\n*****CONFIGURATION*****\n" + "\033[0m\033[0m")
print(f"Name  : {INSTANCE_NAME}")
print(f"Mode  : {'alone' if COOPERATIVE_MODE in ['n', 'none'] else 'local' if COOPERATIVE_MODE in ['l', 'local'] else 'distributed' if COOPERATIVE_MODE in ['d', 'distributed'] else 'undefined'}")
print(f"LLM   : {LLM_MODEL}")

4. 检查配置项

  • 检查了目标OBJECTIVE和初始任务INITIAL_TASK是否填写。
  • 配置的llama_cpp的模型和embedding
    • LLAMA_MODEL_PATH设定llama模型名称、
    • LLAMA_THREADS_NUM 设定llama占用的CPU核心数
  • 配置openai模型的参数

这里值得注意的是,JOIN_EXISTING_OBJECTIVE参数,当设置了初始任务INITIAL_TASK时,改值必须为true。

# Check if we know what we are doing
assert OBJECTIVE, "\033[91m\033[1m" + "OBJECTIVE environment variable is missing from .env" + "\033[0m\033[0m"
assert INITIAL_TASK, "\033[91m\033[1m" + "INITIAL_TASK environment variable is missing from .env" + "\033[0m\033[0m"

LLAMA_MODEL_PATH = os.getenv("LLAMA_MODEL_PATH", "models/llama-13B/ggml-model.bin")
if LLM_MODEL.startswith("llama"):
    if can_import("llama_cpp"):
        from llama_cpp import Llama

        print(f"LLAMA : {LLAMA_MODEL_PATH}" + "\n")
        assert os.path.exists(LLAMA_MODEL_PATH), "\033[91m\033[1m" + f"Model can't be found." + "\033[0m\033[0m"

        CTX_MAX = 1024
        LLAMA_THREADS_NUM = int(os.getenv("LLAMA_THREADS_NUM", 8))

        print('Initialize model for evaluation')
        llm = Llama(
            model_path=LLAMA_MODEL_PATH,
            n_ctx=CTX_MAX,
            n_threads=LLAMA_THREADS_NUM,
            n_batch=512,
            use_mlock=False,
        )

        print('\nInitialize model for embedding')
        llm_embed = Llama(
            model_path=LLAMA_MODEL_PATH,
            n_ctx=CTX_MAX,
            n_threads=LLAMA_THREADS_NUM,
            n_batch=512,
            embedding=True,
            use_mlock=False,
        )

        print(
            "\033[91m\033[1m"
            + "\n*****USING LLAMA.CPP. POTENTIALLY SLOW.*****"
            + "\033[0m\033[0m"
        )
    else:
        print(
            "\033[91m\033[1m"
            + "\nLlama LLM requires package llama-cpp. Falling back to GPT-3.5-turbo."
            + "\033[0m\033[0m"
        )
        LLM_MODEL = "gpt-3.5-turbo"

if LLM_MODEL.startswith("gpt-4"):
    print(
        "\033[91m\033[1m"
        + "\n*****USING GPT-4. POTENTIALLY EXPENSIVE. MONITOR YOUR COSTS*****"
        + "\033[0m\033[0m"
    )

if LLM_MODEL.startswith("human"):
    print(
        "\033[91m\033[1m"
        + "\n*****USING HUMAN INPUT*****"
        + "\033[0m\033[0m"
    )

print("\033[94m\033[1m" + "\n*****OBJECTIVE*****\n" + "\033[0m\033[0m")
print(f"{OBJECTIVE}")

if not JOIN_EXISTING_OBJECTIVE:
    print("\033[93m\033[1m" + "\nInitial task:" + "\033[0m\033[0m" + f" {INITIAL_TASK}")
else:
    print("\033[93m\033[1m" + f"\nJoining to help the objective" + "\033[0m\033[0m")

# Configure OpenAI
openai.api_key = OPENAI_API_KEY


# Llama embedding function
class LlamaEmbeddingFunction(EmbeddingFunction):
    def __init__(self):
        return


    def __call__(self, texts: Documents) -> Embeddings:
        embeddings = []
        for t in texts:
            e = llm_embed.embed(t)
            embeddings.append(e)
        return embeddings

5.向量存储初始化代码

向量数据库这里除了使用chromadb外,还使用了weaviate和pinecone,也都是通过环境变量进行配置的,并且可以通过插件的形式进行加载。

这里值得注意的是,chroma用到的metadata,不管是在collection中添加任务名称等信息,而且在创建collection时,使用的metadata。

创建collection时,使用的hnsw:space数据,来自定义嵌入空间的距离方法。

目前可用的参数有:

  • l2(Squared L2) d = ∑ ( A i − B i ) 2 d = \sum\left(A_i-B_i\right)^2 d=(AiBi)2
  • ip(Inner product) d = 1.0 − ∑ ( A i × B i ) d = 1.0 - \sum\left(A_i \times B_i\right) d=1.0(Ai×Bi)
  • cosine(Cosine similarity) d = 1.0 − ∑ ( A i × B i ) ∑ ( A i 2 ) ⋅ ∑ ( B i 2 ) d = 1.0 - \frac{\sum\left(A_i \times B_i\right)}{\sqrt{\sum\left(A_i^2\right)} \cdot \sqrt{\sum\left(B_i^2\right)}} d=1.0(Ai2) (Bi2) (Ai×Bi)

babyAGI使用的cosine参数,即余弦相似度,它衡量的是两个向量在方向上的相似程度,而与它们的长度无关,优点是对向量的长度不敏感,因此可以有效地处理不同规模的数据集。同时,它对异常值的影响较小,且可以很好地处理高维空间中的数据。

Squared L2的优点是它的计算简单,而且当数据点分布在高维空间时,它可以有效地避免计算平方根的运算,从而提高计算效率。缺点是它对异常值比较敏感,并且随着维度的增加,不同维度的尺度可能会对结果产生较大影响。

Inner product(内积)内积常用于计算向量之间的相似度,内积的值越大,表示两个向量越相似。当内积为正时,表示两个向量的方向大致相同;当内积为负时,表示两个向量的方向大致相反。内积不直接提供距离信息,但可以通过其他方法(如相关系数)转换为相似度度量。

# Results storage using local ChromaDB
class DefaultResultsStorage:
    def __init__(self):
        logging.getLogger('chromadb').setLevel(logging.ERROR)
        # Create Chroma collection
        chroma_persist_dir = "chroma"
        chroma_client = chromadb.PersistentClient(
            settings=chromadb.config.Settings(
                persist_directory=chroma_persist_dir,
            )
        )

        metric = "cosine"
        if LLM_MODEL.startswith("llama"):
            embedding_function = LlamaEmbeddingFunction()
        else:
            embedding_function = OpenAIEmbeddingFunction(api_key=OPENAI_API_KEY)
        self.collection = chroma_client.get_or_create_collection(
            name=RESULTS_STORE_NAME,
            metadata={"hnsw:space": metric},
            embedding_function=embedding_function,
        )

    def add(self, task: Dict, result: str, result_id: str):

        # Break the function if LLM_MODEL starts with "human" (case-insensitive)
        if LLM_MODEL.startswith("human"):
            return
        # Continue with the rest of the function

        embeddings = llm_embed.embed(result) if LLM_MODEL.startswith("llama") else None
        if (
                len(self.collection.get(ids=[result_id], include=[])["ids"]) > 0
        ):  # Check if the result already exists
            self.collection.update(
                ids=result_id,
                embeddings=embeddings,
                documents=result,
                metadatas={"task": task["task_name"], "result": result},
            )
        else:
            self.collection.add(
                ids=result_id,
                embeddings=embeddings,
                documents=result,
                metadatas={"task": task["task_name"], "result": result},
            )

    def query(self, query: str, top_results_num: int) -> List[dict]:
        count: int = self.collection.count()
        if count == 0:
            return []
        results = self.collection.query(
            query_texts=query,
            n_results=min(top_results_num, count),
            include=["metadatas"]
        )
        return [item["task"] for item in results["metadatas"][0]]


# Initialize results storage
def try_weaviate():
    WEAVIATE_URL = os.getenv("WEAVIATE_URL", "")
    WEAVIATE_USE_EMBEDDED = os.getenv("WEAVIATE_USE_EMBEDDED", "False").lower() == "true"
    if (WEAVIATE_URL or WEAVIATE_USE_EMBEDDED) and can_import("extensions.weaviate_storage"):
        WEAVIATE_API_KEY = os.getenv("WEAVIATE_API_KEY", "")
        from extensions.weaviate_storage import WeaviateResultsStorage
        print("\nUsing results storage: " + "\033[93m\033[1m" + "Weaviate" + "\033[0m\033[0m")
        return WeaviateResultsStorage(OPENAI_API_KEY, WEAVIATE_URL, WEAVIATE_API_KEY, WEAVIATE_USE_EMBEDDED, LLM_MODEL, LLAMA_MODEL_PATH, RESULTS_STORE_NAME, OBJECTIVE)
    return None

def try_pinecone():
    PINECONE_API_KEY = os.getenv("PINECONE_API_KEY", "")
    if PINECONE_API_KEY and can_import("extensions.pinecone_storage"):
        PINECONE_ENVIRONMENT = os.getenv("PINECONE_ENVIRONMENT", "")
        assert (
            PINECONE_ENVIRONMENT
        ), "\033[91m\033[1m" + "PINECONE_ENVIRONMENT environment variable is missing from .env" + "\033[0m\033[0m"
        from extensions.pinecone_storage import PineconeResultsStorage
        print("\nUsing results storage: " + "\033[93m\033[1m" + "Pinecone" + "\033[0m\033[0m")
        return PineconeResultsStorage(OPENAI_API_KEY, PINECONE_API_KEY, PINECONE_ENVIRONMENT, LLM_MODEL, LLAMA_MODEL_PATH, RESULTS_STORE_NAME, OBJECTIVE)
    return None

def use_chroma():
    print("\nUsing results storage: " + "\033[93m\033[1m" + "Chroma (Default)" + "\033[0m\033[0m")
    return DefaultResultsStorage()

results_storage = try_weaviate() or try_pinecone() or use_chroma()

这里我们还是使用chromadb,其余的两个数据库均为线上服务,需要花钱。

6. 任务列表创建

这段代码主要是建立了任务清单的模型类,判断是否为local或distributed任务,这里主要是使用了python ray分布式多进程框架来处里。
这个后续会在babyAGI的扩展部分讲解。

# Task storage supporting only a single instance of BabyAGI
class SingleTaskListStorage:
    def __init__(self):
        self.tasks = deque([])
        self.task_id_counter = 0

    def append(self, task: Dict):
        self.tasks.append(task)

    def replace(self, tasks: List[Dict]):
        self.tasks = deque(tasks)

    def popleft(self):
        return self.tasks.popleft()

    def is_empty(self):
        return False if self.tasks else True

    def next_task_id(self):
        self.task_id_counter += 1
        return self.task_id_counter

    def get_task_names(self):
        return [t["task_name"] for t in self.tasks]


# Initialize tasks storage
tasks_storage = SingleTaskListStorage()
if COOPERATIVE_MODE in ['l', 'local']:
    if can_import("extensions.ray_tasks"):
        import sys
        from pathlib import Path

        sys.path.append(str(Path(__file__).resolve().parent))
        from extensions.ray_tasks import CooperativeTaskListStorage

        tasks_storage = CooperativeTaskListStorage(OBJECTIVE)
        print("\nReplacing tasks storage: " + "\033[93m\033[1m" + "Ray" + "\033[0m\033[0m")
elif COOPERATIVE_MODE in ['d', 'distributed']:
    pass

7.计算token以及封装OpenAI API

这一段是封装的openai的请求,这里面需要注意的是,与OpenAI交互时使用的System角色

这里有关于角色的几点说明

  • system 指定模型回答问题的方式。经典例子:“你是一个程序员“
  • user 等同于用户进行提问
  • assistant 模型的响应(基于用户消息)

def limit_tokens_from_string(string: str, model: str, limit: int) -> str:
    """Limits the string to a number of tokens (estimated)."""

    try:
        encoding = tiktoken.encoding_for_model(model)
    except:
        encoding = tiktoken.encoding_for_model('gpt2')  # Fallback for others.

    encoded = encoding.encode(string)

    return encoding.decode(encoded[:limit])

def openai_call(
    prompt: str,
    model: str = LLM_MODEL,
    temperature: float = OPENAI_TEMPERATURE,
    max_tokens: int = 100,
):
    while True:
        try:
            if model.lower().startswith("llama"):
                result = llm(prompt[:CTX_MAX],
                             stop=["### Human"],
                             echo=False,
                             temperature=0.2,
                             top_k=40,
                             top_p=0.95,
                             repeat_penalty=1.05,
                             max_tokens=200)
                # print('\n*****RESULT JSON DUMP*****\n')
                # print(json.dumps(result))
                # print('\n')
                return result['choices'][0]['text'].strip()
            elif model.lower().startswith("human"):
                return user_input_await(prompt)
            elif not model.lower().startswith("gpt-"):
                # Use completion API
                response = openai.Completion.create(
                    engine=model,
                    prompt=prompt,
                    temperature=temperature,
                    max_tokens=max_tokens,
                    top_p=1,
                    frequency_penalty=0,
                    presence_penalty=0,
                )
                return response.choices[0].text.strip()
            else:
                # Use 4000 instead of the real limit (4097) to give a bit of wiggle room for the encoding of roles.
                # TODO: different limits for different models.

                trimmed_prompt = limit_tokens_from_string(prompt, model, 4000 - max_tokens)

                # Use chat completion API
                messages = [{"role": "system", "content": trimmed_prompt}]
                response = openai.ChatCompletion.create(
                    model=model,
                    messages=messages,
                    temperature=temperature,
                    max_tokens=max_tokens,
                    n=1,
                    stop=None,
                )
                return response.choices[0].message.content.strip()
        except openai.error.RateLimitError:
            print(
                "   *** The OpenAI API rate limit has been exceeded. Waiting 10 seconds and trying again. ***"
            )
            time.sleep(10)  # Wait 10 seconds and try again
        except openai.error.Timeout:
            print(
                "   *** OpenAI API timeout occurred. Waiting 10 seconds and trying again. ***"
            )
            time.sleep(10)  # Wait 10 seconds and try again
        except openai.error.APIError:
            print(
                "   *** OpenAI API error occurred. Waiting 10 seconds and trying again. ***"
            )
            time.sleep(10)  # Wait 10 seconds and try again
        except openai.error.APIConnectionError:
            print(
                "   *** OpenAI API connection error occurred. Check your network settings, proxy configuration, SSL certificates, or firewall rules. Waiting 10 seconds and trying again. ***"
            )
            time.sleep(10)  # Wait 10 seconds and try again
        except openai.error.InvalidRequestError:
            print(
                "   *** OpenAI API invalid request. Check the documentation for the specific API method you are calling and make sure you are sending valid and complete parameters. Waiting 10 seconds and trying again. ***"
            )
            time.sleep(10)  # Wait 10 seconds and try again
        except openai.error.ServiceUnavailableError:
            print(
                "   *** OpenAI API service unavailable. Waiting 10 seconds and trying again. ***"
            )
            time.sleep(10)  # Wait 10 seconds and try again
        else:
            break

这就是babyagi的配置和前期准备的代码,第二篇文章我会给大家继续展示核心部分-agents编写,这里将展示如何使用prompt完成任务的创建、优先级排序以及执行任务,包括项目的运行部分。

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

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

相关文章

每日一题(力扣136):只出现一次的数字

利用哈希&#xff1a;时间复杂度O(n)&#xff0c;空间复杂度O(n) class Solution { public:int singleNumber(vector<int>& nums) {if (nums.size() 1){return nums[0];}unordered_map<int, int> map;int len nums.size();for (int i 0; i < len; i){if…

计算机视觉的技术领域

计算机视觉是一门研究如何使计算机能够“看”和理解图像和视频的科学。它结合了图像处理、模式识别、机器学习、人工智能等多个领域的技术。以下是计算机视觉中的一些关键技术领域。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. …

梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码

源码简介 最新梨花带雨网页音乐播放器二开优化修复美化版全开源版本源码下载 梨花带雨播放器基于thinkphp6开发的XPlayerHTML5网页播放器前台控制面板,支持多音乐平台音乐解析。二开内容&#xff1a;修复播放器接口问题&#xff0c;把接口本地化&#xff0c;但是集成外链播放器…

【C++】 vector <string> 的超详细解析!!!

目录 一、前言 二、 vector <string> 的个人理解和总结 三、vector <string> 的初始化 四、vector <string> 的输入 \ 输出 五、vector <string> 中的注意事项 六、常考面试题 七、共勉 一、前言 在【C】中&#xff0c;vector 是一个动态数组…

加域报错:无法完成此功能

在尝试将计算机加入Windows域时&#xff0c;如果收到“无法完成此功能”的提示&#xff0c;这可能由多种原因引起&#xff0c;以下是一些常见的问题及其解决方法&#xff1a; 网络连接问题&#xff1a;确保当前计算机与域控制器之间的网络连接是正常的。可以尝试使用ping命令测…

Linux 环境下 Redis基础配置及开机自启

Linux 环境下 Redis基础配置及开机自启 linux环境安装redis<redis-6.0.5.tar.gz> 1-redis基本安装配置 解压 获取到tar包后&#xff0c;解压到相关目录&#xff0c;一般是将redis目录放在usr/local/redis目录下&#xff0c;可以使用-C指定到解压下目录 tar -zvxf re…

介绍一下Java的数据类型

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…

【JavaEE初阶系列】——synchronized原理及优化(偏向锁,轻量级锁,自旋锁,锁消除,锁粗化)

目录 &#x1f6a9;synchronized锁特性详细解说 &#x1f6a9;加锁工作过程(锁升级) &#x1f388;偏向锁 &#x1f388;轻量级锁(自适应的自旋锁) &#x1f388; 重量级锁 &#x1f6a9;其他的优化操作 &#x1f388;锁消除 &#x1f388;锁粗化 &#x1f388;相关面…

【AcWing】蓝桥杯集训每日一题Day10|递归|暴力|数学归纳法|1360.有序分数(C++)

1360.有序分数 1360. 有序分数 - AcWing题库难度&#xff1a;简单时/空限制&#xff1a;1s / 64MB总通过数&#xff1a;4128总尝试数&#xff1a;6630来源&#xff1a;usaco training 2.1算法标签枚举排序最大公约数递归Stern-Brocot Tree 题目内容 给定一个整数 N&#xff0…

Linux利用Jenkins部署SpringBoot项目保姆级教程

在当今快速发展的软件开发领域&#xff0c;持续集成和持续部署&#xff08;CI/CD&#xff09;已经成为提升开发效率、缩短产品上市时间的关键实践。Linux系统以其稳定性和开源友好性&#xff0c;成为众多开发者和企业的首选平台。而Spring Boot&#xff0c;作为一个轻量级的Jav…

【Linux入门】Linux简史

Linux 是什么&#xff1f;Linux 是一款叫做操作系统的软件。 操作系统这款软件有什么样的意义呢&#xff1f;简单来说&#xff0c;比如有顾客买了一台笔记本电脑&#xff0c;这台笔记本电脑由电脑硬件组成&#xff0c;在这堆硬件上一定搭载了一款操作系统。正因为操作系统存在&…

QT-自定义参数设计框架软件

QT-自定义参数设计框架软件 前言一、演示效果二、使用步骤1.应用进行参数注册2.数据库操作单例对象3.参数操作单例对象 三、下载链接 前言 常用本地数据参数通常使用的是xml等文本的格式&#xff0c;进行本地的数据参数的存储。这种参数的保存方式有个致命的一点&#xff0c;就…

linux监控命令全

1.1 top 1.1.1 命令说明 Top 命令能够实时监控系统的运行状态&#xff0c;并且可以按照cpu、内存和执行时间进行排序 1.1.2 用法 top -hv | -bcisSHM -d delay -n iterations [-u user | -U user] -p pid [,pid ...] 1.1.3 参数说明 命令行启动参数&#xff1a; -b : 批次…

从入门到实战:vue3路由知识点

本人在B站上关于vue3的尚硅谷的课程&#xff0c;以下是整理一些笔记。 1.两个知识点 1.路由组件通常存放在pages 或 views文件夹&#xff0c;一般组件通常存放在components文件夹。 组件可以分为&#xff1a; 1. 一般组件&#xff1a;亲手写标签出来的 2. 路由组件&#…

【检索增强】Retrieval-Augmented Generation for Large Language Models:A Survey

本文简介 1、对最先进水平RAG进行了全面和系统的回顾&#xff0c;通过包括朴素RAG、高级RAG和模块化RAG在内的范式描述了它的演变。这篇综述的背景下&#xff0c;更广泛的范围内的法学硕士研究RAG的景观。 2、确定并讨论了RAG过程中不可或缺的核心技术&#xff0c;特别关注“…

成都直播基地 天府新区产业园能获得哪些政府支持

为了推动成都直播产业的快速发展&#xff0c;政府出台了一系列政策措施&#xff0c;为成都直播基地提供了全方位的支持。本篇文章将为您具体解析入驻成都直播基地 天府新区产业园 天府锋巢直播产业基地都能获得哪些政府支持。 首先&#xff0c;天府新区作为成都市的重要发展区…

【亚马逊云科技】使用 Vscode Amazon-Q 完成 GUI 界面粉笔脚本开发

前言 亚马逊云科技- Q &#xff0c;可以快速获得紧迫问题的相关答案&#xff0c;解决问题&#xff0c;生成内容。当与 Q 聊天时&#xff0c;它会提供即时的相关信息和建议&#xff0c;以帮助简化任务、加快决策速度&#xff0c;并帮助激发工作中的创造力和创新。本次我们通过完…

捷途山海T2正式开启预售,新能源方盒子SUV仅售18.49万起

4月2日&#xff0c;捷途汽车宣布&#xff0c;定位为“旅行越野超混SUV”的山海T2正式开启预售。新车共计将推出3款不同配置车型&#xff0c;预售价格区间为18.49万-21.69万元。同时&#xff0c;预售期间捷途官方还将为用户推出7重预售礼。 山海T2是捷途山海系列第二款产品&…

idea使用docker将Java项目生成镜像并使用

1&#xff1a;开启docker 远程访问 使用 vim 编辑docker服务配置文件 vim /lib/systemd/system/docker.service [Service] Typenotify # the default is not to use systemd for cgroups because the delegate issues still # exists and systemd currently does not suppor…

【Python从入门到进阶】52、CrawlSpider链接提取器的使用

接上篇《51、电影天堂网站多页面下载实战》 上一篇我们采用Scrapy框架多页面下载的模式来实现电影天堂网站的电影标题及图片抓取。本篇我们来学习基于规则进行跟踪和自动爬取网页数据的“特殊爬虫”CrawlSpider。 一、什么是CrawlSpider&#xff1f; 1、CrawlSpider的概念 Cr…