使用GPT的自主代理的综合实践指南
每当我认为 GPT 的进步速度很快时,它就会变得更快。在过去的一个月里,GPT / LLM支持的自治代理的概念变得越来越疯狂 - 该领域最著名的项目AutoGPT在发布后不到一个月的时间内在GitHub上获得了超过117K的星星,并获得了前所未有的社交媒体报道。许多其他项目,如BabyAGI,AgentGPT和斯坦福版本的“西部世界”也经常出现在新闻中。这些智能体非常聪明,他们可以用自己的思维和推理完成复杂的任务。
所有这些项目都建立在生成自主代理的理念之上。您是否对像 AutoGPT 这样的自主代理如何在引擎盖下工作感到好奇?您来对地方了 — 在本文中,我将全面概述自治代理,包括它们是什么、它们如何工作、它们可以做什么、它们对企业和员工的影响,甚至是有关如何构建简单自治代理的实践教程。阅读本文后,您将更好地了解它们以及它们如何改变您周围的世界。
如果您不是技术人员并且不知道如何编写代码,请不要担心,我将用简单的语言解释这些概念。如果您准备好了,让我们潜入!
什么是自治代理?
自主代理的一些例子包括AutoGPT,BabyAGI和斯坦福大学的Interactive Simulacra。AutoGPT 使用 GPT-4 作为底层思维引擎,自主实现用户设定的一组目标。一旦设定了目标,它将分解任务,计划行动,在线收集信息或使用外部工具,并迭代地重新评估和调整行动,直到实现目标[11]。BabyAGI是一个类似但规模小得多的项目,它试图完成类似的过程来帮助用户实现他们的目标[12]。
斯坦福大学的互动模拟是一个类似“西部世界”的模拟游戏,所有NPC都由GPT控制,并有自己的日常程序,任务,记忆等[13]。尽管这些是自主代理的早期尝试并且有许多局限性,但它们显示了自主代理可以做的巨大潜力。
那么它们实际上是如何工作的呢?让我们退后一小步,看看 GPT,生成预训练变压器,它们是这些代理中的动力引擎。GPT 是一种大型语言模型 (LLM),它从大量文本中学习,并可以根据输入序列(即提示)生成文本 [1]。它是 ChatGPT 和自主代理的基础 AI 模型。
(要了解有关ChatGPT和GPT的更多信息,您可以阅读:https://medium.com/design-bootcamp/how-chatgpt-really-works-explained-for-non-technical-people-71efb078a5c9)
在 ChatGPT 中,您可以向模型提供指令,它将按照您的指示进行操作。这种遵循指令的行为已经很神奇了,可以提高人们的工作效率。人们用它来进行研究、编写内容、编写代码等。但是有一个问题 — 模型不会自行作用,它会为您的一个输入提示给出一个响应。您必须不断提供更多上下文和输入来指导它完成更复杂的任务。
但研究人员发现,这些模型实际上可以做的不仅仅是文本生成——大型语言模型可以具有推理能力。这在早期的快速工程研究中很明显。例如,Kojima等人发现,在提示的末尾添加“让我们一步一步地思考”可以显着提高GPT的性能[2],Wei等人发现思维提示链可以“在大型语言模型中引发推理”[3]。
(还有许多其他提示工程技术试图在LLM中引起更好的性能,您可以在此处阅读更多信息)
这种紧急能力是自主代理的关键。如果大型语言模型能够推理和思考,它们就有可能计划任务并使用工具完成更复杂的任务。研究人员和工程师开始研究我们是否可以创建自主代理 - 人工智能驱动的智能系统,能够根据用户输入和访问一套工具来完成复杂任务做出决策。
仅仅拥有推理技能不足以完成复杂的任务,这些任务需要比大型语言模型所知道的更多的信息。研究人员开发了像LangChain[4]和Semantic Kernel [5]这样的框架,使LLM能够更容易地使用外部工具,编排其他AI模型,调用API并将信息存储在矢量数据库中。许多项目,包括Toolformer [6],JARVIS(HuggingGPT)[7],VisualChatGPT(TaskMatrix)[8]等,成功地允许LLM使用各种外部工具。
他们还试图教语言模型如何更好地使用外部工具并从错误中学习。Yao等人的ReAct(推理-行动)框架引入了提示LLM以交错方式为任务生成推理和操作的想法,以提高与外部API交互的性能[9]。Shinn等人提出了反射,它使用动态记忆和自我反思来增强其推理和行动以完成任务的能力[10]。
通过这些不同的研究和开源项目,自主代理现在可以通过思考子任务、计划要采取的行动、在外部工具的帮助下执行行动以及反思结果来尝试实现长期目标。
自主代理如何工作?
从上一节中,我们已经知道自主代理可以自己实现长期目标,这要归功于以下技能:理解和创建信息的基本语言技能、短期和长期记忆、计划和确定行动优先级的推理技能,以及使用外部工具来收集相关上下文和执行任务。
在本节中,我们将分解整个过程并解释每个主要组件的工作原理。自主代理工作的典型结构和过程是:
- 设置目标:用户将设置代理将完成的高级目标。例如,“构建心理健康日记应用”。
- 分解任务:代理将使用LLM(如GPT-4)将目标分解为要执行的潜在任务列表。这些任务可以是信息收集,如“在谷歌上搜索心理健康日记应用程序的竞争对手”,也可以是执行,如“为网络应用程序页面编写JavaScript代码以记录用户的情绪”。此任务列表存储在长期内存中,该内存通常是矢量数据库。
- Prioritization. Once there is a list of tasks, the agent will use LLMs’ reasoning skills to evaluate and prioritize the tasks to decide which task it should do next.
- 执行。代理将执行任务,如果它不需要外部信息或工具,则可以自行执行,或者使用外部工具收集上下文的相关信息并完成任务。执行结果和收集的信息也将保存在长期内存中。
- 评估和创建新任务。当代理完成任务时,它将评估手头的剩余任务和先前执行的结果,仍然使用 LLM 的推理功能。然后,它将提出为实现最终目标而需要完成的新任务。
- 重复。重复步骤 2-5,直到代理认为原始目标已实现或用户干预。
不同实施项目的确切过程可能不同,但总体过程是相似的。您可以注意到,以下组件对于简化自治代理的过程是必需的。
LLM是连接流程每个步骤的推理引擎。他们将较大的目标分解为较小的任务(步骤 2),确定任务的优先级(步骤 3),决定是否需要更多信息或使用工具(步骤 4),并将评估执行结果以获取更新的任务列表(步骤 5)。为了确保这些推理步骤得到有效和正确的完成,我们可以使用提示工程来复杂地提示。在下一节中,我们将提供可以执行所有这些任务的提示示例。
数据库保留LLM的上下文和内存。由于对LLM(或GPT API)的每次调用都仅限于该单个会话,因此要向LLM提供它不知道的信息,我们需要从外部动态存储和检索信息。这些自主代理中的许多使用Pinecone [14],Weaviate [15]或Chroma等矢量数据库,以实现其高效的文本搜索功能。代理可以将他们的目标、任务列表和从 Web 搜索中收集的信息或先前步骤的执行结果保存到这些矢量数据库中。
外部工具允许LLM与外界互动。虽然LLM在文本生成方面很强大,但它们本身无法与文本框以外的外部世界进行交互。因此,我们需要他们可以用来收集信息并与外界互动的工具。这些工具包括浏览、代码解释器和其他 AI 模型,用于以文本以外的方式处理信息等。
动手构建简单的自治代理
在前面的部分中,我们已经介绍了什么是自治代理、它们如何获得其功能以及自治代理中的典型过程。但是纯理论对某些人来说可能看起来很抽象,所以让我们构建一个简单的自治代理,其中包含我们所描述的内容。
在本节中,我们将逐步构建一个最低限度的自治代理。该自主代理可以在Arxiv中搜索相关论文,并根据用户的研究问题总结论文的核心思想。我们将构建它两次:在第一个例子中,我们将使用 LangChain 来构建代理,它抽象掉了许多较低级别的细节,但更容易实现;在第二个示例中,我们将从头开始构建一个裸最小代理。
本部分的 Colab 笔记本位于: https://github.com/Troyanovsky/autonomous_agent_tutorial
使用 LangChain 构建自治代理
第一个示例是使用 LangChain 的高级示例。LangChain是一个Python框架,它将LLM的许多功能包装成易于使用的函数和方法。我们可以使用代理模块和 arxiv 实用程序来快速构建自治代理。
安装包,设置环境,然后导入必要的包。
!pip install langchain
!pip install arxiv
!pip install openai
# import necessary packages
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.agents import Tool
from langchain.chat_models import ChatOpenAI
from langchain.utilities import ArxivAPIWrapper
我们首先定义语言模型可以使用的工具:arxiv api,包括工具的名称和描述,以便LLM知道它可以在需要时使用该工具。
llm = ChatOpenAI(temperature=0) # Initialize the LLM to be used
arxiv = ArxivAPIWrapper()
arxiv_tool = Tool(
name="arxiv_search",
description="Search on arxiv. The tool can search a keyword on arxiv for the top papers. It will return publishing date, title, authors, and summary of the papers.",
func=arxiv.run
)
tools = [arxiv_tool]
然后,我们可以通过将定义的工具和LLM传递给代理来初始化代理。此代理将从其名称和描述中识别该工具,并决定是否需要使用该工具。
agent_chain = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
)
然后,我们可以运行代理,并提出一个问题:
agent_chain.run("What is ReAct reasoning and acting in language models?")
我们可以看到,代理首先考虑了任务,发现它没有所有必要的信息,因此它创建了一个使用 arxiv API 搜索相关论文的动作。然后,它执行此操作并返回三篇论文,然后可以使用这些论文来响应用户的请求。
从头开始构建自治代理
如果你想深入了解自治代理的工作原理,我将向您展示一个自治代理的最小实现,它与第一个示例执行相同的操作,但这次我们将从头开始实现它,而不使用 LangChain。
安装包,设置环境,然后导入必要的包。
!pip install openai
!pip install arxiv
import openai
import arxiv
# Set up the OpenAI API
openai.api_key = "sk-......" # Replace the string content with your OpenAI API key
将 OpenAI API 调用包装在一个函数中,使其更易于使用
def getResponse(prompt):
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
temperature = 0, # We want consistent behavior, so we set a very low temperature
messages=[
{"role": "system", "content": "You're a helpful assistant. Carefully follow the user's instructions."},
{"role": "user", "content": prompt}
]
)
response = str(response['choices'][0]['message']['content'])
return response
将 Arxiv API 包装在一个函数中,以便我们可以将其提供给 GPT 代理,以便在需要时使用
def searchArxiv(keyword):
# Perform a search with the given query
search = arxiv.Search(query=keyword, max_results=3)
# Get the metadata for each result and extract relevant information
results = []
for result in search.results():
title = result.title
published_date = result.published.strftime("%Y-%m-%d")
authors = ", ".join(author.name for author in result.authors)
summary = result.summary
# Store the extracted information as a dictionary
results.append((
"title: " + title,
"published_date: " + published_date,
"authors: " + authors,
"summary: " + summary
))
# Return the list of tuples containing the result information
return results
使用 GPT 通过为其提供目标、内存和工具来确定要执行的操作。如果它认为它已经完成了目标,只需给出答案。如果需要更多信息,它将根据工具说明选择工具以获取相关信息。(这是上一节中自主代理工作流程中步骤 2 和 3 的简化版本。
def determineAction(objective, memory, tools):
formattedPrompt = f"""Determine if the following memory is enough to answer
the user's objective. Your past actions are stored in the memory for reference
If it is enough, answer the question in the format: 'FINAL ANSWER: <your answer>'.
If the memory is not enough, you can use a tool in the available tools section
to get more information. When using a tool you should use this format:
'USE <tool name>:<parameter>'. If no tool can help you achieve the user's
objective, then answer 'FINAL: CANNOT ANSWER'.
```Objective
Answer: {objective}
```
```Memory
{memory}
```
```Available Tools
{tools}
```
"""
response = getResponse(formattedPrompt)
(finished, result, memory) = parseResponse(response, memory,tools)
return (finished, result, memory)
解析来自 GPT 的响应以确定目标是否已完成。如果完成,只需给出最终答案。如果目标无法通过上下文和工具完成,它将通过说它无法回答请求来完成工作。如果 GPT 选取工具,请执行该工具并将工具的结果保存在内存中。
def parseResponse(response, memory,tools):
finished = False
if response.startswith('FINAL ANSWER:'):
finished = True
memory.append(response)
return (finished, response, memory)
elif response == 'FINAL: CANNOT ANSWER':
finished = True
memory.append(response)
return (finished, response, memory)
elif response.startswith('USE '):
# split the string using ':' as the delimiter
parsed_str = response.split(':')
# get the tool name and parameter
tool_name = parsed_str[0].split()[1]
parameter = parsed_str[1]
print("THOUGHT: " + response)
memory.append("THOUGHT: " + response)
result = executeTool(tool_name, parameter,tools)
new_memory = "OBSERVATION: " + str(result)
print(new_memory)
memory.append(new_memory)
return (finished, result, memory)
如果 GPT 选取工具,则使用其提供的参数执行 GPT 选取的工具。此函数返回执行结果,以便 GPT 可以获取相关信息。
def executeTool(tool_name, parameter,tools):
# Find the tool with the given name
tool = None
for t in tools:
if t['tool_name'] == tool_name:
tool = t
break
# If the tool is found, execute its function with the given parameter
if tool:
return tool['function_name'](parameter)
else:
return "Tool not found"
使用内存和可用工具初始化自治 GPT 代理。它将请求用户目标并自主运行,直到实现目标。(作为安全措施,它也会在 5 次迭代后停止,以防万一出现问题。
def startAgent():
objective = input("What is your research question? ")
# For simplicity, we will just use a list to store every thing.
# For production, you will probably use vector databases.
memory = []
tools = [{'tool_name': 'searchArxiv',
'description': """You can use this tool to search for scientific papers on Arxiv. The response will have title, author, published date, and summary.""",
'function_name' : searchArxiv,
'parameter': 'search key word'}]
n = 0
while True:
(finished, result, memory) = determineAction(objective, memory, tools)
n += 1
if finished:
print(result)
return
if n > 5:
print("Ended for reaching limit.")
return
startAgent()
为什么自主代理很重要
这些项目之所以获得如此多的公众关注和媒体曝光,不仅是因为它们看起来很酷,而且它们展示了改变我们日常生活和工作生活的潜力。它们对企业和工人来说可能是一个巨大的机会,也可以成为我们个人生活中的有力助手。
对于企业来说,这些自主代理可以节省成本,并使公司能够以更少的人提高生产力。在未来,企业家可能会开始一项有利可图的业务,只有少数几个关键决策者,而这些人工智能自主代理完成的大部分重复性工作。如果较小的团队知道如何利用这些代理,他们将拥有更大的影响力。可能还有另一种商业模式,即公司为他人提供量身定制的代理商。如果一家公司具有深厚的行业知识,它可以更好地设计代理,以便比一般的自主代理更有效地完成任务。他们还可以设计和销售这些代理可以使用的工具。将来,可能会有以代理为中心的产品(或者 ChatGPT 插件已经是以代理为中心的产品的早期形式?
对于工人来说,这些自主代理可以将大部分时间解放在平凡、单调的任务上,让他们专注于更重要的任务,这些任务需要人性化的一面——比如情感同情、创造性解决问题和批判性思维。根据我自己的经验,即使使用现在不那么智能的自主代理,我也可以在产品管理工作流程中腾出一些时间。(只是不要太依赖代理,因为他们有时也会犯错误。
在我们的个人生活中,这些代理也可以成为比Siri等旧语音助手更有用的助手。想象一下,在未来,你只需要在你的待办事项列表中添加一些家务,它们将由你的自主代理完成——订购杂货、预订餐厅,甚至安排家庭维修。它们还可以通过分析可穿戴设备的健康数据来帮助您监控和计划您的运动、营养和心理健康。
结语
我希望本文为您提供使用LLM的自治代理的全面且易于理解的概述。作为快速回顾,以下是本文涵盖的一些要点:
- 自主代理是由 GPT 等 LLM 驱动的智能系统,可以在最少的人类指导下自行实现长期目标。
- 他们的能力包括基本语言能力,紧急推理能力,使用外部工具的能力,以及访问矢量数据库等长期记忆的能力。
- 自治代理的典型过程是:从用户那里获取目标、分解任务、确定任务优先级、执行任务(使用外部工具)、评估结果和创建新任务。
- 自主代理可以通过降低企业成本和提高员工的生产力来潜在地改变业务格局。
由于这项技术仍处于起步阶段,因此还有很多东西需要探索和跟上。我相信会有一段时间,先行者,无论是制造这些代理还是使用它们,都会比那些拒绝更多地了解它们的人更有优势。
引用
[1] Brown, Tom B., et al. 语言模型是少数镜头的学习者。arXiv,22年2020月10日。arXiv.org,https://doi.org/48550.2005/arXiv.14165.<>。
[2] 小岛,Takeshi等。 大型语言模型是零镜头推理者。 arXiv,29 年 2023 月 10 日。arXiv.org,https://doi.org/48550.2205/arXiv.11916.<>。
[3] Wei, Jason, et al. Think-of-Prompt Eleadits Reasoning in Large Language Models. arXiv,10 年 2023 月 10 日。arXiv.org,https://doi.org/48550.2201/arXiv.11903.<>。
[4] 欢迎来到 LangChain — ?? LangChain 0.0.152。https://python.langchain.com/en/latest/。28 年 2023 月 <> 日访问。
[5] 语义内核。 https://github.com/microsoft/semantic-kernel。28 年 2023 月 <> 日访问。
[6] Schick, Timo, et al. Toolformer: Language Model Can Teach Yourself Use Tools. arXiv,9 年 2023 月 10 日。arXiv.org,https://doi.org/48550.2302/arXiv.04761.<>。
[7] Shen, Yongliang, et al. HuggingGPT: Solve AI Tasks with ChatGPT and its Friends in HuggingFace. arXiv,2 年 2023 月 10 日。arXiv.org,https://doi.org/48550.2303/arXiv.17580.<>。
[8] 任务矩阵。https://github.com/microsoft/TaskMatrix。28 年 2023 月 <> 日访问。
[9] Yao, Shunyu, et al. React: Synergizing Reasoning and Act in Language Models. arXiv,9 年 2023 月 10 日。arXiv.org,https://doi.org/48550.2210/arXiv.03629.<>。
[10] Shinn, Noah, et al. Reflexion: An Autonomous Agent with Dynamic Memory and Self-Reflection.arXiv,20 年 2023 月 10 日。arXiv.org,https://doi.org/48550.2303/arXiv.11366.<>。
[11] 自动GPT。https://github.com/Significant-Gravitas/Auto-GPT。1年2023月<>日访问
[12] 宝贝AGI.https://github.com/yoheinakajima/babyagi。1年2023月<>日访问
[13] Park, Joon Sung, et al. 生成代理:人类行为的交互式模拟。 arXiv,6 年 2023 月 10 日。arXiv.org,https://doi.org/48550.2304/arXiv.03442.<>。
[14] “用于矢量搜索的矢量数据库”。松果,https://www.pinecone.io/。1年2023月<>日访问。
[15] 欢迎 |Weaviate — 矢量数据库。https://weaviate.io/。1年2023月<>日访问。
[16] AI 原生开源嵌入数据库。 https://www.trychroma.com。1年2023月<>日访问。