最近,开源 AI 项目 AutoGPT 在开发者圈中掀起了不小的热潮,“无需人类插手,自主完成任务”的特点吸引来了很多人的关注,为此本文作者将就 AutoGPT 的工作原理进行深入解析。
原文链接:https://sudoApps.substack.com/p/technical-dive-into-autogpt
作者 | SAMIR KHOJA
译者 | 弯月 责编 | 郑丽媛
出品 | CSDN(ID:CSDNnews)
你是否曾听说过开源项目 Auto-GPT?该项目使用各种技巧打造的 GPT 可以围绕某个特定的目标自主完成任务,还为 GPT 提供了一个可执行命令列表,帮助它朝着总体目标持续迈进。
我尝试使用 Auto-GPT 获得了一些有趣的结果,我还深入查看了项目的整体架构,Github 上 10 万+的 Star 数表明了其巨大的发展潜力。
为了更好地理解 Auto-GPT 的概念及其工作原理,我们将深入探讨以下核心领域:
▶ 该项目使用了哪些模型?
▶ 如何让 GPT 具备记忆力?
▶ 如何提高 GPT 的响应可靠性?
▶ 如何解析 GPT 的响应?
▶ 如何指定 GPT 可以执行 的命令?
模型
在撰写本文之际,Auto-GPT 仅支持 OpenAI 的 GPT 模型。如果你不熟悉 OpenAI,请参考官方文档(参考链接:https://platform.openai.com/docs/guides/chat/introduction),了解 API 与模型的互动。
在使用 GPT-3.5-turbo 和 GPT-4 测试了 Auto-GPT 之后,我发现仍有改进的空间,但是通过 GPT-4 获得的输出远胜于 GPT-3.5-turbo。包括 token 限制在内的所有设置,都可以直接在 .env 文件中配置,例如可以利用 token 限制控制输入 (上下文)和输出(响应)的长度,从而控制成本。
我看到了一些与 LangChain 集成的拉取请求,这意味着Auto-GPT可以访问其他开源模型了,但也许项目本身也有集成其他模型的计划。我不打算在此深入研究 OpenAI API 或其他开源模型,但在接下来几个主题的讨论中,了解一些大型语言模型的背景会有所帮助。
如何让 GPT 具备记忆力?
GPT 模型的设计并没有考虑记忆力,然而 Auto-GPT 使用外部记忆模块消除了这个限制。在深入了解如何让 GPT 具备记忆力之前,我们先来介绍几个概念:
▶ 嵌入
▶ 向量存储与搜索
▶ OpenAI 的聊天补全 API
嵌入是文本的向量表示,可以更轻松地用于各种机器学习的模型或算法。Auto-GPT 使用了 OpenAI 的嵌入 API 根据 GPT 文本输出创建嵌入。
我们可以使用的向量存储服务有很多。Auto-GPT 使用的是:本地存储、Pinecone(第三方服务)、redis 和 Milvus(开源服务)。Pinecone 和 Milvus 优化了向量搜索算法,可以根据相关上下文搜索文本嵌入。
Auto-GPT 将嵌入存储到这些向量存储服务之一,然后通过搜索当前任务会话的相关向量将上下文注入到 GPT。下面是这段代码的核心部分:
图片源自:https://github.com/Significant-Gravitas/Auto-GPT/blob/master/autogpt/chat.py
OpenAI 的聊天补全 API 拥有“系统”角色的概念,用于为 GPT 提供初始身份、约束和上下文。你可以看到在上述代码片段中,relevant_memory 被注入到对话中,作为 GPT 过去事件的引用。此外,Auto-GPT 还将相应角色完整的聊天对话传递给了聊天补全 API(最大长度为 token 的上限)。
给出提示以获得可靠的响应
在对话刚开始的时候,Auto-GPT 使用“系统”角色来配置约束,并进行自我绩效评估。Auto-GPT 有一个提示生成器,其中一些约束是硬编码的:
图片源自:https://github.com/Significant-Gravitas/Auto-GPT/blob/master/autogpt/prompts/prompt.py
我们看到在这些提示的引导下,GPT 的自主性和自力更生能力都得到了提高,还能看到很多通过持续反馈循环来帮助 GPT 自我改进输出的案例。我不确定下面的自我绩效评估提示是否能达到同样的效果,但至少这段代码奠定了基础:
图片源自:https://github.com/Significant-Gravitas/Auto-GPT/blob/master/autogpt/prompts/prompt.py
初始角色还有一些额外的提示。不过,需要指出的是:“每个命令都有成本,所以一定要确保智能且高效。我们的目标是以最少的步骤完成任务。”由于我们稍后会查看命令以及 GPT 执行每个命令的过程,因此这一行代码很重要,可以确保响应尽可能高效,避免不必要的步骤(使用更多 token),保证 最低成本。
解读响应
这可能是理解 Auto-GPT 内部工作原理最重要的方面。如果不能有效地解释响应,就不应该让 GPT 执行命令(即允许它访问外部世界)。Auto-GPT 使用了一种非常简单但很强大的提示技术来确保 GPT 以固定的 JSON 格式响应,然后通过代码进行解析:
图片源自:https://github.com/Significant-Gravitas/Auto-GPT/blob/master/autogpt/prompts/generator.py
在测试中,我使用了固定格式的响应,从结果看来 GPT-3.5-turbo 非常高效,尽管偶尔也有一些幻觉(相比之下 GPT-4 更可靠)。我们通过这种方法指示 GPT 执行命令,还需要检查结果。在 GPT 执行命令时,响应的信息包含在 command 对象中。
与现实世界互动
自主代理要想真正发挥作用就必须能够完成实际的工作,并与现实世界交互,比如文件系统或互联网等。Auto-GPT 必须编写能授权 GPT 执行的每个命令,在生成约束和自我评估的初始提示时,还可以提供可执行命令及其参数的列表。下面是将命令添加到提示符的类函数:
图片来源:https://github.com/Significant-Gravitas/Auto-GPT/blob/master/autogpt/prompts/generator.py
基本的提示生成器中有一个预定义的命令列表:
图片来源:https://github.com/Significant-Gravitas/Auto-GPT/blob/stable/autogpt/prompt.py
这是 GPT 引用命令的格式,可以使用参数执行命令。以下代码可以将最终提示格式化为 GPT 的字符串:
图片来源:https://github.com/Significant-Gravitas/Auto-GPT/blob/master/autogpt/prompts/generator.py
如你所见,这段代码集合了上述所有功能。这个提示可以为 GPT 提供约束条件、自我评估的方向、资源、命令以及响应格式。接下来,在解析 GPT 返回的响应时,我们就很清楚它所执行的命令和参数了。最后一步是执行命令:
图片来源:https://github.com/Significant-Gravitas/Auto-GPT/blob/stable/autogpt/app.py
在这段代码中,在解析 GPT 的响应后,每个命令都获得了自己的参数,然后执行。GPT 的命令之一是 task_completed,如果在连续模式下运行,程序将在 GPT 实现目标后关闭或退出:
图片来源:https://github.com/Significant-Gravitas/Auto-GPT/blob/master/autogpt/app.py
BabyAGI
BabyAGI 也使用了类似的概念,但大大简化了实现(整体功能较少)。它支持 LLaMA 和 OpenAI 作为模型输入,在提供目标和初始任务后,创建三个代理来执行目标:任务执行代理、任务创建代理和任务优先级代理。每个代理都有自己的提示和约束,包括来自每个相关任务执行的上下文。这个过程将循环执行,直到没有剩余的任务并且目标完成。
Auto-GPT 和 BabyAGI 都获得了大量关注,并且正在不断改进。
总结
毋庸置疑,很多人为这些项目做出了努力,并在不断改进它们。这些项目是 AI 领域向前迈出的激动人心的一步,我们距离 AI 自主完成任务并在生活方方面面协助我们的未来更近了一步。我要强调的不仅仅是一些核心概念,这些概念可以帮助我们了解其内部运作方式,并为自主代理的新世界做出贡献。