大型语言模型(LLMs)非常强大,但它们缺乏一些“最笨”的计算机程序可以轻松处理的特定能力。逻辑、计算和搜索是计算机通常擅长的领域,但LLMs则表现不佳。
计算机可以解决非常复杂的数学问题,然而,如果我们要求GPT-4告诉我们4.1 * 7.9的答案,它会失败:
根据一个简单的计算器,答案是19.357,四舍五入到三位小数。令人着迷的是,一个简单的计算器程序可以做到这一点,但一个极其复杂的AI引擎失败了。
这还不是全部。如果我问GPT-4,“How do I use the LLMChain in LangChain?”它再次遇到困难:
LangChain确实是一个区块链项目[1] [2]。然而,似乎没有任何“LLMChain”组件或“LANG代币”——这两者都是幻觉。
GPT-4无法告诉我们有关LangChain的原因是它与外部世界没有联系。它唯一的知识来自于它从训练数据中捕获的内容,而这些数据截止到2021年末。
由于今天的LLMs存在重大弱点,我们必须找到解决这些问题的方法。一组潜在的解决方案以“代理人”的形式出现。
这些代理人不仅解决了我们上面看到的问题,还解决了许多其他问题。事实上,添加代理人在提升LLM能力方面具有几乎无限的潜力。
在本章中,我们将讨论代理人。我们将了解它们是什么,它们如何工作,以及如何在LangChain库中使用它们来赋予我们的LLMs超能力。
什么是代理?
我们可以将代理人看作是LLMs的“工具”。就像人类会使用计算器进行数学运算或进行谷歌搜索获取信息一样,代理人允许LLMs执行类似的操作。
使用代理,LLM可以编写和执行Python代码。它可以搜索信息,甚至查询SQL数据库。
让我们看一个简单的示例。我们将从一个“零-shot”代理开始(稍后详细介绍),允许我们的LLM使用计算器。
代理和工具
要使用代理,我们需要三样东西:
- 基础LLM,
- 我们将要进行交互的工具,
- 用于控制交互的代理。
让我们开始安装langchain并初始化我们的基础LLM。
ini复制代码from langchain import OpenAI
llm = OpenAI(
openai_api_key="OPENAI_API_KEY",
temperature=0,
model_name="text-davinci-003"
)
现在初始化计算器工具。在初始化工具时,我们可以创建自定义工具或加载预构建工具。无论哪种情况,“工具”都是一个具有工具名称和描述的实用程序链。
例如,我们可以从现有的llm_math链创建一个新的计算器工具:
In[3]:
ini复制代码from langchain.chains import LLMMathChain
from langchain.agents import Tool
llm_math = LLMMathChain(llm=llm)
# initialize the math tool
math_tool = Tool(
name='Calculator',
func=llm_math.run,
description='Useful for when you need to answer questions about math.'
)
# when giving tools to LLM, we must pass as list of tools
tools = [math_tool]
In[4]:
css复制代码tools[0].name, tools[0].description
Out[4]:
rust复制代码('Calculator', 'Useful for when you need to answer questions about math.')
在使用自定义工具时,我们必须遵循这个过程。然而,预构建的llm_math工具执行相同的操作。因此,我们可以像上面那样做相同的操作,如下所示:
In[5]:
ini复制代码from langchain.agents import load_tools
tools = load_tools(
['llm-math'],
llm=llm
)
In[6]:
css复制代码tools[0].name, tools[0].description
Out[6]:
rust复制代码('Calculator', 'Useful for when you need to answer questions about math.')
当然,只有在我们的用例中存在预构建的工具时,我们才能采用第二种方法。
现在,我们有了LLM和工具,但还没有代理。要初始化一个简单的代理,我们可以执行以下步骤:
ini复制代码from langchain.agents import initialize_agent
zero_shot_agent = initialize_agent(
agent="zero-shot-react-description",
tools=tools,
llm=llm,
verbose=True,
max_iterations=3
)
这里使用的代理是一个“零次反应描述”代理。零次反应意味着代理仅在当前操作上执行功能 – 它没有记忆。它使用ReAct框架来决定使用哪个工具,仅基于工具的描述。
在本章中,我们不会讨论ReAct框架,但你可以将其看作是LLM可以在推理和行动步骤之间循环的方式,以便识别答案的多步过程。
初始化了我们的代理后,我们可以开始使用它。让我们尝试一些提示,看看代理如何响应。
In[8]:
scss复制代码zero_shot_agent("what is (4.5*2.1)^2.2?")
Out[8]:
vbnet复制代码