利用LangChain实现BabyAGI

ops/2025/2/25 10:55:51/

文章目录

      • BabyAGI介绍
      • 环境与工具
      • 向量存储
      • 构建任务链

    本文将利用LangChain实现BabyAGI。通过本文内容,读者可以更加直观地看到每一步骤的运行情况,并且也可以在自己的环境中进行实验。

BabyAGI介绍

    BabyAGI是由Yohei Nakajima在2023年5月发布的一个自治的AI代理程序代码。这种自治的AI代理旨在根据给定的目标生成和执行任务。它利用OpenAI、Pinecone、LangChain和Chroma来自动化任务并实现代理特定目标。在Agent模块中,可以把AgentExecutor看作一个项目经理,其实BabyAGI也可以被看作一个项目经理管理项目。BabyAGI通过创建、优先处理和执行任务列表来实现代理特定的目标。它还适应变化,并进行必要的调整以确保达到目标。与项目经理一样,BabyAGI具有从以前的经验中学习并做出明智决策的能力。

    我们也可以认为BabyAGI是计算机中AI驱动的个人助手。通过解释给定的目标,它创建了一个所需任务的列表,然后执行它们。每完成一个任务后,BabyAGI都会评估结果并相应地调整其方法。BabyAGI的独特之处在于它能够从试验和错误反馈中学习,做出类似人类的认知决策。它还可以编写和运行代码来实现特定的目标。

    使用BabyAGI的好处是,可以让我们有更多的时间专注于更高价值的任务,如决策和创意项目。在原BabyAGI项目中,BabyAGI按照以下步骤来创建Agent,承担不同的任务,开展自动化任务并联合这些Aget以实现目标。下面依然遵照这样的步骤,使用LangChain内部的模块功能,创建Agent,实现与BabyAGI相同能力的Agent。下面先了解一下原来BabyAGI的实施步骤(如图所示是作者绘制的流程图)。

图片名称
  1. 设置明确的目标:首先,用户设置BabyAGI将完成的目标。
  2. 任务生成(Agent):接下来,BabyAGI将使用诸如GPT-4之类的大语言模型,将目标细分为一系列潜在任务。然后将任务列表存储在长期内存(向量数据库)中供将来参考。
  3. 任务优先级(Agent):有了任务列表后,BabyAGI将使用其推理能力评估任务并根据它们的重要性和依赖性对任务进行优先排序,以达到最终的结果。BabyAGI将决定首先执行哪个任务。
  4. 任务执行(Agent):然后,BabyAGI将执行并完成任务。执行的结果和收集到的信息也将被保存在长期记忆中供将来使用。
  5. 评估和创建新任务:执行任务后,BabyAGI将使用其推理能力评估剩余的任务和先前执行的结果。基于评估,它将创建要完成的新任务,以达到最终的目标。
  6. 重复:重复这些步骤,直到BabyAGI实现原始目标或用户干预为止。BabyAGI将不断评估目标的进展,并相应地调整任务列表和优先级,以有效地达到期望的结果。

环境与工具

    对于此次实验,需要两个主要工具:OpenAI及一个搜索引擎API。这两者将会协同完成BabyAGI的构建。

!pip -q install langchain huggingface_hub openai google-search-results
tiktoken cohere faiss-cpu
import os
os.environ["OPENAI API KEY"]="填人你的OPENAI密钥"
os,environ["SERPAPI API KEY"]="填人你的SERPAPI密钥"

    导入工具:

import os
from collections import deque
from typing import Dict,List,Optional,Any
from langchain import LLMChain,OpenAI,PromptTemplate
from langchain.embeddings import OpenAIEmbeddings
from langchain.11ms import BaseLLM
from langchain.vectorstores.base import VectorStore
from pydantic import BaseModel,Field
from langchain.chains.base import Chain

向量存储

    在此示例中使用了FAISS向量存储。这是一种内存存储技术,无须进行任何外部调用,例如向Pinecone请求。但如果你愿意,完全可以改变其中的一些设定,将其连接到Pinecone。向量存储是利用OpenAI的嵌人模型进行的。先导人FAISS向量库:

from langchain.vectorstores import FAISS
from langchain.docstore import InMemoryDocstore

    在构建一个特定的嵌人模型,生成向量索引并存储这些向量时,可以按照以下步骤来操作。首先,需要选择一个适当的嵌人模型。这种模型可以是词嵌人模型,如Word2Vec或GloVe,也可以是句子嵌人模型,如BERT或者Doc2Vec。这些模型通过将词或句子映射到高维度的向量空间,实现了对词或句子语义的捕捉。选择哪种嵌入模型主要取决于处理的任务特性和数据的特点。这里使用的是OpenAI的文本嵌人模型。OpenAI的文本嵌人模型可以精确地嵌入大段文本,输出1536维的向量列表。

# Define your embedding model
embeddings_model = OpenAIEmbeddings (

    其次,对文本数据进行处理,生成相应的嵌人向量。在生成向量后,需要构建一个索引,以便能够高效地查询和比较向量。

# Initialize the vectorstore as empty
import faiss
embedding_size = 1536
index_faiss.IndexFlatL2 (embedding_size)

    最后,需要将生成的向量和构建的索引进行存储。

vectorstore = FAISS (embeddings_model.embed_query,index,InMemoryDocstore(()),())

构建任务链

    LangChain的好处在于,可以让我们清楚地看到链组件在执行哪些操作,以及它们的提示是什么。其中有3个主要链组件:创建任务链、任务优先级链和执行链。这些链组件都在为达成整体目标而工作,它们会生成一系列任务。通过定义TaskCreationChain类实现创建任务链的功能,这个类定义了一个名为TaskCreationChain的类,它的主要职责是基于已有的任务结果和目标,自动生成新的任务。这个类是LLMChain的子类,专门用于生成任务。

    该类有一个类方法from llm,这个方法接受一个BaseLLM类型的对象和一个可选的布尔参数verbose.from_llm方法中定义了一个模板字符串task_creation_template,这个模板用于描述如何从已有任务的结果和描述,以及未完成任务的列表中,生成新的任务。

class TaskCreationChain (LLMChain):"""Chain to generates tasks."""@classmethoddef from_llm(cls,llm:BaseLLM,verbose:bool True)->LLMChain:"""Get the response parser.""task_creation_template =("You are an task creation AI that uses the result of an execution agent""to create new tasks with the following objective:(objective),"The last completed task has the result:(result)."This result was based on this task description:(task description)."These are incomplete tasks:(incomplete tasks).""Based on the result,create new tasks to be completed""by the AI system that do not overlap with incomplete tasks.""Return the tasks as an array."prompt PromptTemplatetemplate=task creation_template,input_variables=["result","task description","incomplete tasks","objective"],return cls (prompt=prompt,llm=llm,verbose=verbose)

    这些步骤看起来很简单,但这里就是你可以进行修改,从而使AI更符合你需求的地方。这个链组件的主要职责是将传人的任务进行清理,重新设置它们的优先级,以便按照你的最终目标进行排序。任务优先级链组件不会删除任何任务,而是将任务以编号列表的形式返回。

class TaskPrioritizationChain (LLMChain):"""Chain to prioritize tasks."""@classmethoddef from 11m(cls,11m:BaseLLM,verbose:bool True)->LLMChain:"""Get the response parser."""task_prioritization template ="You are an task prioritization AI tasked with cleaning theformatting of and reprioritizing""the following tasks:(task_names)."Consider the ultimate objective of your team:(objective)."Do not remove any tasks.Return the result as a numbered list, like:""#First task""#Second task"Start the task list with number (next_task_id)."prompt = PromptTemplate(template=task prioritization template,input_variables=["task_names","next task_id","objective"],)return cls(prompt=prompt,llm=llm,verbose=verbose)

    在这个过程中,定义了一个执行代理,并传递了一些工具给它。这个执行代理是一个计划者,能够为给定的目标制定一个待办事项清单。传递搜索和待办事项这两种工具给它,是为了让它能够在需要的时候进行搜索或者制定待办事项清单。

from langchain.agents import ZeroShotAgent,Tool,AgentExecutor
from langchain import OpenAI,SerpAPIWrapper,LLMChain
todo prompt PromptTemplate.from template("You are a planner
who is an expert at coming up with a todo list for a given objective.
Come up with a todo list for this objective:(objective)")
todo_chain LLMChain(llm=OpenAI(temperature=0),prompt=todo_prompt)
search SerpAPIWrapper()
tools=Tool(name "Search",func=search.run,description="useful for when you need to answer questions aboutcurrent events"),Tool(name "TODO",func=todo chain.run,description="useful for when you need to come up with todo lists.Input:an objective to create a todo list for.Output:a todo listfor that objective.Please be very clear what the objective is!")]
prefix = """You are an AI who performs one task based on the following
objective:(objective}.Take into account these previously completed tasks:(context}.
"""
suffix="""Question:(task)(agent scratchpad)
"""
prompt = ZeroShotAgent.create_prompt(
tools,
prefix=prefix,
suffix=suffix,
input variables=["objective","task","context","agent scratchpad"]
)

    可以看到,这个执行器使用ZeroShotAgent将提示词、前缀/后缀及输人变量一并输人。通过这种方式,可以让我们更清楚地看到在程序执行过程中,这些部分是如何组合在一起工作的。下面定义一组函数,主要负责任务的创建(get next task)、优先级排序(prioritize tasks和get top tasks)和执行(execute task)。它使用了LLMChain对象来运行不同的任务管理逻辑,并使用vectorstore来进行相似度搜索。这一系列功能合在一起为任务管理提供了一套完整的解决方案。

def get_next_task(task_creation_chain:LLMChain,result:Dict,task description:str, task list:List(str],objective:str)->List[Dict]:"""Get the next task."""incomplete tasks "".join(task_list)response task_creation_chain.run(result=result,task_description=task description,incomplete_tasks=incomplete_tasks,objective=objectivenew_tasks response.split ('\n')return [("task name":task name)for task name in new tasks if task name.strip()]
def prioritize_tasks(task prioritization chain:LLMChain,this task id:int,task list:List [Dict],objective:str)->List[Dict]:"""Prioritize tasks."""task_names = [t["task name"]for t in task list]next_task_id = int(this_task_id)+1response_task_prioritization chain.run(task_names=task_names,next_task_id=next_task_id,objective=objective)new_tasks = response.split ('\n')prioritized_task_list [for task_string in new_tasks:if not task_string.strip():continuetask_parts = task_string.strip().split(".",1)if len(task_parts)==2:task_id = task_parts[0].strip()task_name = task_parts[1].strip()prioritized_task_list.append ("task_id":task_id,"task_name":task_name))return prioritized_task_list
def get top tasks(vectorstore,query:str,k:int)->List[str]:"""Get the top k tasks based on the query.""results = vectorstore.similarity_search_with_score(query,k=k)if not results:return [sorted_results,_=zip(*sorted(results,key=lambda x:x[1],reverse=True))return [str(item.metadata['task'])for item in sorted results]
def execute_task(vectorstore,execution chain:LLMChain,objective:str,task:str,k:int 5)->str:"""Execute a task."context =_get_top_tasks(vectorstore,query=objective,k=k)return execution_chain.run(objective=objective,context=context,task=task)

http://www.ppmy.cn/ops/161180.html

相关文章

视频大小怎么计算?视频码率是什么,构成视频清晰度的核心要素!

前言: 最近对高清视频比较感兴趣,码率是一个提及很多的词语,所以也就来了解一下码率。 1:含义 视频码率(Bitrate)是衡量视频数据在单位时间内传输或处理的数据量,通常以 比特每秒(…

kafka基本知识

什么是 Kafka? Apache Kafka 是一个开源的分布式流处理平台,最初由 LinkedIn 开发,后来成为 Apache 软件基金会的一部分。Kafka 主要用于构建实时数据管道和流处理应用程序。它能够高效地处理大量的数据流,广泛应用于日志收集、数…

详解 @符号在 PyTorch 中的矩阵乘法规则

详解 符号在 PyTorch 中的矩阵乘法规则 在 PyTorch 和 NumPy 中, 符号被用作矩阵乘法运算符,它本质上等价于 torch.matmul() 或 numpy.matmul(),用于执行张量之间的矩阵乘法。 在本篇博客中,我们将深入探讨: 运算符…

Linux系统中常见的词GNU是什么意思?

GNU 是 “GNU’s Not Unix” 的递归缩写,它是一个自由软件项目,旨在创建一个完全自由的操作系统。这个名字反映了GNU项目的核心理念:它试图创建一个类Unix的系统,但不是Unix本身。 GNU 项目由 理查德斯托曼(Richard S…

使用Windbg调试目标进程排查C++软件异常的一般步骤与要点分享

目录 1、概述 2、将Windbg附加到已经启动起来的目标进程上,或者用Windbg启动目标程序 2.1、将Windbg附加到已经启动起来的目标进程上 2.2、用Windbg启动目标程序 2.3、Windbg关联到目标进程上会中断下来,输入g命令将该中断跳过去 3、分析实例说明 …

Python 高级数据结构操作全解析:从理论到实践

Python 高级数据结构操作全解析:从理论到实践 本文深入剖析 Python 高级数据结构,通过丰富的代码示例、形象的配图,详细讲解集合、字典、堆、队列等数据结构的操作,同时拓展相关知识,帮助读者深入掌握 Python 编程核心…

jsherp importItemExcel接口存在SQL注入

一、漏洞简介 很多人说管伊佳ERP(原名:华夏ERP,英文名:jshERP)是目前人气领先的国产ERP系统虽然目前只有进销存财务生产的功能,但后面将会推出ERP的全部功能,有兴趣请帮点一下 二、漏洞影响 …

Java基础常见的面试题(易错!!)

面试题一:为什么 Java 不支持多继承 Java 不支持多继承主要是为避免 “菱形继承问题”(又称 “钻石问题”),即一个子类从多个父类继承到同名方法或属性时,编译器无法确定该调用哪个父类的成员。同时,多继承…