BabyAGI源码解读(2)-核心agents部分

话不多说,我们直接进入babyAGI的核心部分,也就是task agent部分。

1. 创建任务agent

这一段代码的任务是创建一个任务,这个函数有四个参数

  • objective 目标
  • result 结果,dict类型
  • task_list 任务清单
  • task_descritption 任务描述

将结果存放到out这个dict中返回。

在prompt中,指定了

You are to use the result from an execution agent to create new tasks with the following objective: {objective}.

角色和目标,当然目标不论是人工智能还是人类,都是很重要的一点。值得注意的,角色和能力都在prompt最开始就以指定,作为一个背景的存在。

接着输入上一个完成的任务的结果和任务描述,然后拼接未完成的任务清单。

最后加入任务的一些规范,新任务不得与未完成任务重复和输出prompt的样式规范等。

整体来看,整个prompt的架构按顺序是

  1. 指定角色和任务
  2. 描述详细内容
  3. 指定输出格式和规则

这是一个优秀的prompt案例,大家可以学习一下。

def task_creation_agent(objective: str, result: Dict, task_description: str, task_list: List[str]
):prompt = f"""
You are to use the result from an execution agent to create new tasks with the following objective: {objective}.
The last completed task has the result: \n{result["data"]}
This result was based on this task description: {task_description}.\n"""if task_list:prompt += f"These are incomplete tasks: {', '.join(task_list)}\n"prompt += "Based on the result, return a list of tasks to be completed in order to meet the objective. "if task_list:prompt += "These new tasks must not overlap with incomplete tasks. "prompt += """
Return one task per line in your response. The result must be a numbered list in the format:#. First task
#. Second taskThe number of each entry must be followed by a period. If your list is empty, write "There are no tasks to add at this time."
Unless your list is empty, do not include any headers before your numbered list or follow your numbered list with any other output."""print(f'\n*****TASK CREATION AGENT PROMPT****\n{prompt}\n')response = openai_call(prompt, max_tokens=2000)print(f'\n****TASK CREATION AGENT RESPONSE****\n{response}\n')new_tasks = response.split('\n')new_tasks_list = []for task_string in new_tasks:task_parts = task_string.strip().split(".", 1)if len(task_parts) == 2:task_id = ''.join(s for s in task_parts[0] if s.isnumeric())task_name = re.sub(r'[^\w\s_]+', '', task_parts[1]).strip()if task_name.strip() and task_id.isnumeric():new_tasks_list.append(task_name)# print('New task created: ' + task_name)out = [{"task_name": task_name} for task_name in new_tasks_list]return out

2. 任务优先级排序agent

这段代码主要是调用openAI对已存储的任务清单进行优先级排序,返回一个新的任务列表。

这段代码可以看一下,prompt的编写,整体和上面的差异不大。

def prioritization_agent():task_names = tasks_storage.get_task_names()bullet_string = '\n'prompt = f"""
You are tasked with prioritizing the following tasks: {bullet_string + bullet_string.join(task_names)}
Consider the ultimate objective of your team: {OBJECTIVE}.
Tasks should be sorted from highest to lowest priority, where higher-priority tasks are those that act as pre-requisites or are more essential for meeting the objective.
Do not remove any tasks. Return the ranked tasks as a numbered list in the format:#. First task
#. Second taskThe entries must be consecutively numbered, starting with 1. The number of each entry must be followed by a period.
Do not include any headers before your ranked list or follow your list with any other output."""print(f'\n****TASK PRIORITIZATION AGENT PROMPT****\n{prompt}\n')response = openai_call(prompt, max_tokens=2000)print(f'\n****TASK PRIORITIZATION AGENT RESPONSE****\n{response}\n')if not response:print('Received empty response from priotritization agent. Keeping task list unchanged.')returnnew_tasks = response.split("\n") if "\n" in response else [response]new_tasks_list = []for task_string in new_tasks:task_parts = task_string.strip().split(".", 1)if len(task_parts) == 2:task_id = ''.join(s for s in task_parts[0] if s.isnumeric())task_name = re.sub(r'[^\w\s_]+', '', task_parts[1]).strip()if task_name.strip():new_tasks_list.append({"task_id": task_id, "task_name": task_name})return new_tasks_list

3. 执行任务agent

这两段段代码执行五个基于目标的优先级比较高的任务。

这段代码是从结果存储中,根据查询内容获取top_results_nums个任务。

# Get the top n completed tasks for the objective
def context_agent(query: str, top_results_num: int):"""Retrieves context for a given query from an index of tasks.Args:query (str): The query or objective for retrieving context.top_results_num (int): The number of top results to retrieve.Returns:list: A list of tasks as context for the given query, sorted by relevance."""results = results_storage.query(query=query, top_results_num=top_results_num)# print("****RESULTS****")# print(results)return results

这段代码是通过OpenAI API执行agent,整个prompt的结构同样是

  1. 先说明目标
  2. 拼接已完成的上下文,详细内容
  3. 再表明你的任务
# Execute a task based on the objective and five previous tasks
def execution_agent(objective: str, task: str) -> str:"""Executes a task based on the given objective and previous context.Args:objective (str): The objective or goal for the AI to perform the task.task (str): The task to be executed by the AI.Returns:str: The response generated by the AI for the given task."""context = context_agent(query=objective, top_results_num=5)# print("\n****RELEVANT CONTEXT****\n")# print(context)# print('')prompt = f'Perform one task based on the following objective: {objective}.\n'if context:prompt += 'Take into account these previously completed tasks:' + '\n'.join(context)prompt += f'\nYour task: {task}\nResponse:'return openai_call(prompt, max_tokens=2000)

这两段代码不知道为什么带上注释了,可能是作者买了coplit了吧😂

4. 任务主体

下面就是整体代码的最终部分了,主程序部分

主程序是一个大的死循环,主要分为三步

  • 获取task_storage中第一个未完成的任务,执行execution_agent,传入目标和未完成的任务,获取result
  • 重新包装resultresult_id,并将结果存放到result_storage中,而这个result_storage正式之前配置的向量数据库
  • 创建新任务,并重新排列任务优先级,这里只有设置了cooperative mode才会执行这个,这里我们也可以理解,当有多个线程同时参与时,需要进行优先级排序,防止重复执行任务

整体项目来看的话,就是一个执行任务-分解任务-执行任务的循环,当列表为空时,任务执行完成。

# Add the initial task if starting new objective
if not JOIN_EXISTING_OBJECTIVE:initial_task = {"task_id": tasks_storage.next_task_id(),"task_name": INITIAL_TASK}tasks_storage.append(initial_task)def main():loop = Truewhile loop:# As long as there are tasks in the storage...if not tasks_storage.is_empty():# Print the task listprint("\033[95m\033[1m" + "\n*****TASK LIST*****\n" + "\033[0m\033[0m")for t in tasks_storage.get_task_names():print(" • " + str(t))# Step 1: Pull the first incomplete tasktask = tasks_storage.popleft()print("\033[92m\033[1m" + "\n*****NEXT TASK*****\n" + "\033[0m\033[0m")print(str(task["task_name"]))# Send to execution function to complete the task based on the contextresult = execution_agent(OBJECTIVE, str(task["task_name"]))print("\033[93m\033[1m" + "\n*****TASK RESULT*****\n" + "\033[0m\033[0m")print(result)# Step 2: Enrich result and store in the results storage# This is where you should enrich the result if neededenriched_result = {"data": result}# extract the actual result from the dictionary# since we don't do enrichment currently# vector = enriched_result["data"]result_id = f"result_{task['task_id']}"results_storage.add(task, result, result_id)# Step 3: Create new tasks and re-prioritize task list# only the main instance in cooperative mode does thatnew_tasks = task_creation_agent(OBJECTIVE,enriched_result,task["task_name"],tasks_storage.get_task_names(),)print('Adding new tasks to task_storage')for new_task in new_tasks:new_task.update({"task_id": tasks_storage.next_task_id()})print(str(new_task))tasks_storage.append(new_task)if not JOIN_EXISTING_OBJECTIVE:prioritized_tasks = prioritization_agent()if prioritized_tasks:tasks_storage.replace(prioritized_tasks)# Sleep a bit before checking the task list againtime.sleep(5)else:print('Done.')loop = Falseif __name__ == "__main__":main()

这就是整体的项目代码,下一篇,我们整体来看看AGI的原理,做个总结。

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

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

相关文章

【MySql】利用DataX同步mysql数据,多数据源数据同步方案

你说你知道他们的世界 悲歌三首买一切 买昆仑落脚 蓬莱放思想 买人们的争执酿酒汤 买公主坟的乌鸦 事发之木和东窗之麻 买胭脂河里船行渔歌 黄金世界中万物法则 你我都一样 将被遗忘 郭源潮 你的病也和我的一样 风月难扯 离合不骚 层楼终究误少年 自由早晚乱余生 你我山前没相见…

iOS开发进阶之列表加载图片

iOS开发进阶之列表加载图片 列表加载图片通常使用UITableView或UICollectionView,由于列表中内容数量不确定并且对于图片质量要求也不确定,所以对于图片加载的优化是很有必要的。 首先借鉴前文,我们逐步进行操作,以下是加载1000…

基于springboot实现数据库的加解密

项目地址 https://github.com/Chenchicheng/spring-ibatis-encryption 功能说明 支持使用注解的方式目标类进行加解密支持同一个类多个字段分别使用不同的加密方式支持自定义加密方法 本地调试 pull代码到本地,更换application.yml中的数据库用户名和密码&…

nginx用法以及核心知识详解-可以当作使用nginx的操作手册

前言 nginx的使用真的是非常简单,下载下来解压运行就可以,配置都是再conf文件夹的里的nginx.conf文件里配置,所以对于nginx的上手使用,nginx.conf文件里字段的含义是需要掌握的,然后就是一些nginx的常见问题 nginx核心…

.NET CORE 分布式事务(三) DTM实现Saga及高并发下的解决方案

目录(结尾附加项目代码资源地址) 引言: 1. SAGA事务模式 2. 拆分为子事务 3. 失败回滚 4. 如何做补偿 4.1 失败的分支是否需要补偿 5. 异常 6. 异常与子事务屏障 6.1 NPC的挑战 6.2 现有方案的问题 6.3 子事务屏障 6.4 原理 7. 更多高级场景 7.1 部分…

永磁同步电机初始转子位置检测

/// https://zhuanlan.zhihu.com/p/409887456 ///

vue3+threejs新手从零开发卡牌游戏(二十二):添加己方游戏流程(先后手、抽牌、主要阶段、战斗阶段、结束阶段)

首先在utils/common.ts里定义一些流程相关的变量: const flow ref([ // 游戏流程{name: "抽卡阶段"},{name: "主要阶段"},{name: "战斗阶段"},{name: "结束阶段"}])const flowIndex ref(0) // 当前流程const currentPla…

[C++初阶] 爱上C++ : 与C++的第一次约会

🔥个人主页:guoguoqiang 🔥专栏:我与C的爱恋 本篇内容带大家浅浅的了解一下C中的命名空间。 在c中,名称(name)可以是符号常量、变量、函数、结构、枚举、类和对象等等。工程越大,名称…

什么是gif? 如何把视频格式转成gif动图格式?展现动图的魅力

一,什么是gif格式 gif是一种位图图形文件格式,主要用于显示索引彩色图像。gif格式在1987年由CompuServe公司开发,它采用LZW(Lempel-Ziv-Welch)无损压缩算法,这种算法可以有效地减少图像文件在网络上传…

在.Net6中用gdal实现第一个功能

目录 一、创建.NET6的控制台应用程序 二、加载Gdal插件 三、编写程序 一、创建.NET6的控制台应用程序 二、加载Gdal插件 Gdal的资源可以经过NuGet包引入。右键单击项目名称,然后选择 "Manage NuGet Packages"(管理 NuGet 包)。N…

【C++】 vector 数组/向量

文章目录 【 1. vector 的声明与初始化 】1.1 vector 的声明1.2 vector 的初始化1.2.1 构造一个空的 vector1.2.2 指定数量初值的方式初始化 vector1.2.3 迭代器的方式初始化1.2.4 构造一个相同的 vector 【 2. vector 的相关操作 】2.1 插入元素2.1.1 在vector的末尾插入新元素…

蚂蚁新村3.30答案:“秀女拈针锦线长,纤纤玉指领馨香”说的是哪一项非遗技艺

蚂蚁新村是一个虚拟社区。在这个虚拟社区中,用户可以参与各种活动,比如生产能量豆、做慈善捐赠等。同时,蚂蚁新村也提供了一些知识问答环节,用户在参与的过程中可以增进知识。这些问答内容往往涉及广泛的主题,如文化、…

iOS - Runtime - Class-方法缓存(cache_t)

文章目录 iOS - Runtime - Class-方法缓存(cache_t)1. 散列表的存取值 iOS - Runtime - Class-方法缓存(cache_t) Class内部结构中有个方法缓存(cache_t),用散列表(哈希表)来缓存曾经调用过的方法,可以提高…

tornado上传文件

简介 在 Tornado web 框架中,上传图片通常涉及创建一个表单,让用户选择文件并上传。Tornado 通过其 RequestHandler 类来处理这些请求,你可以重写 post 方法来接收上传的文件。 后端 import os import tornado.ioloop import tornado.web …

Python3:ModuleNotFoundError: No module named ‘elftools‘

问题背景 问题 ModuleNotFoundError: No module named ‘elftools’ 解决方法 pip3 install pyelftools 成功!!!

YPay源支付V7开源版

YPay_V7版本即将停止维护更新,同时我们将开放最新版开源代码供学习和参考。虽然首批阶段的【function_8.1.php文件是加密的】,但授权已经除去,该代码将在新版YPay上线时开放给大家。我们也会定期进行迭代更新,随后将创建对应仓库&…

达梦数据库集成mybatis-plus

先总结 库名,表名和字段名尽量大写。小写必须要使用双引号,不然会报各种问题,包括【语法解析错误】,【无效的列名】如果列名必须小写,那么要自己写mapper.xml。mybatis-plus在操作insert的时候会报【dm.jdbc.driver.D…

【QT学习】1.qt初识,创建qt工程,使用按钮,第一个交互按钮

1.初识qt--》qt是个框架,不是语言 1.学习路径 一 QT简介 ,QTCreator ,QT工程 ,QT的第一个程序,类,组件 二 信号与槽 三 对话框 四 QT Desiner 控件 布局 样式 五 事件 六 GUI绘图 七 文件 八 …

解决 linux 服务器 java 命令不生效问题

在Linux系统中,当你安装Java并设置了JAVA_HOME环境变量后,你可能需要使用source /etc/profile命令来使Java命令生效。这是因为/etc/profile是一个系统级的配置文件,它包含了系统的全局环境变量设置。 但是需要注意的是,source /e…

使用C语言实现Linux下的并发Http服务器

使用C语言实现Linux下的并发Http服务器 文章目录 使用C语言实现Linux下的并发Http服务器先备知识Http协议请求格式:客户端请求服务端响应 Demo 实现Mini的Http服务器流程接收Http请求实现按行读取请求头部请求头部的结束 解析请求响应请求读取文件(http需…