Langchain文档 安装

700 阅读9分钟

要安装LangChain,请运行:

pip install langchain

环境设置

使用LangChain通常需要与一个或多个模型提供者、数据存储、API等进行集成。在此示例中,我们将使用OpenAI的模型API。

首先,我们需要安装他们的Python包:

pip install openai

访问API需要一个API密钥,您可以通过创建账户并前往此处获取。获取密钥后,我们将通过运行以下命令将其设置为环境变量:

export OPENAI_API_KEY="您的API密钥"

如果您不想设置环境变量,您可以在初始化OpenAI LLM类时通过openai_api_key命名参数直接传递密钥:

from langchain.llms import OpenAI
llm = OpenAI(openai_api_key="您的API密钥")

构建应用程序

现在我们可以开始构建语言模型应用程序。LangChain提供了许多模块,可用于构建语言模型应用程序。模块可以作为简单应用程序中的独立模块使用,也可以组合在一起以实现更复杂的用例。

LLMs

从语言模型中获取预测

LangChain的基本构建块是LLM,它接收文本并生成更多文本。

举个例子,假设我们正在构建一个根据公司描述生成公司名称的应用程序。为了做到这一点,我们需要初始化一个OpenAI模型包装器。在这种情况下,由于我们希望输出更加随机,我们将使用较高的温度初始化模型。

from langchain.llms import OpenAI
llm = OpenAI(temperature=0.9)

现在我们可以传入文本并获取预测!

llm.predict("一个生产多彩袜子的公司的好公司名称是什么?")

输出结果为:

'欢乐之脚'

Chat模型

Chat模型是语言模型的一种变体。虽然Chat模型在内部使用语言模型,但它们提供的接口有点不同:它们不是提供一个“文本输入,文本输出”的API,而是提供一个接口,其中“聊天消息”是输入和输出。

您可以通过将一个或多个消息传递给Chat模型来获得聊天完成。响应将是一条消息。LangChain中支持的消息类型有AIMessage、HumanMessage、SystemMessage和ChatMessage,ChatMessage使用一个任意的角色参数。大多数情况下,您只需要处理HumanMessage、AIMessage和SystemMessage。

from langchain.chat_models import ChatOpenAI
from langchain.schema import (
    AIMessage,
    HumanMessage,
    SystemMessage
)
chat = ChatOpenAI(temperature=0)
chat.predict_messages([HumanMessage(content="将这句话从英文翻译成法文。我喜欢编程。")])

输出结果为:

AIMessage(content="J'aime programmer.", additional_kwargs={})

了解Chat模型与普通LLM的区别很有用,但有时仅仅将它们视为相同的模型进行交互可能更方便。LangChain通过也提供了一个接口,通过该接口您可以像处理普通LLM一样与Chat模型进行交互。您可以通过predict接口来实现:

chat.predict("将这句话从英文翻译成法文。我喜欢编程。")

输出结果为:

"J'aime programmer."

Prompt模板

大多数LLM应用程序不会直接将用户输入传递给LLM。通常,它们将用户输入添加到一个更大的文本片段中,称为prompt模板,以提供关于特定任务背景的额外上下文信息。

在前面的例子中,我们传递给模型的文本包含了生成公司名称的指示。对于我们的应用程序来说,如果用户只需要提供公司/产品的描述,而无需担心给模型提供指示,那将非常方便。

使用PromptTemplates可以很容易实现这一点!在这种情况下,我们的模板会非常简单:

from langchain.prompts import PromptTemplate
prompt = PromptTemplate.from_template("一个生产{product}的公司的好公司名称是什么?")
prompt.format(product="多彩袜子")

输出结果为:

'一个生产多彩袜子的公司的好公司名称是什么?'

现在我们已经有了一个模型和一个prompt模板,我们希望将两者结合起来。链为我们提供了一种将多个基本模块(如模型、prompt和其他链)链接(或串联)在一起的方式。

最简单且最常见的链类型是LLMChain,它首先将输入传递给PromptTemplate,然后再传递给LLM。我们可以从现有的模型和prompt模板构建一个LLM链。

from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
chain.run("多彩袜子")

输出结果为:

'欢乐之脚'

理解这个简单的链是学习如何处理更复杂链的好基础。

Agents

我们的第一个链运行了一个预先确定的步骤序列。为了处理复杂的工作流,我们需要能够根据输入动态选择操作。

代理正是做到这一点的:它们使用语言模型来确定应采取的操作及其顺序。代理可以访问工具,并重复选择工具、运行工具和观察输出,直到得出最终答案。

要加载代理,您需要选择:

  • LLM/Chat模型:驱动代理的语言模型。
  • 工具:执行特定任务的函数。可以是谷歌搜索、数据库查询、Python REPL、其他链等。有关预定义工具及其规范的列表,请参阅工具文档。
  • 代理名称:引用支持的代理类的字符串。代理类在很大程度上由语言模型用于确定采取哪个动作来参数化。因为这篇文章侧重于最简单的、最高级别的API,所以只涵盖了使用标准支持的代理。如果您想实现自定义代理,请参阅此处。有关支持的代理及其规范的列表,请参阅此处。

对于这个示例,我们将使用SerpAPI来查询搜索引擎。

您需要安装SerpAPI Python包:

pip install google-search-results

并设置SERPAPI_API_KEY环境变量。

from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.llms import OpenAI

# 驱动代理的语言模型
llm = OpenAI(temperature=0)

# 给Agent访问的工具,注意'llm-math'工具使用LLM,因此需要将其传递给load_tools函数
tools = load_tools(["serpapi", "llm-math"], llm=llm)

# 初始化一个代理,包括工具、语言模型和要使用的代理类型
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

# 测试代理
agent.run("昨天旧金山的最高气温是多少华氏度?将该数字提高到0.023次方是多少?")

输出结果为:

> 进入新的AgentExecutor链...
思考:首先我需要找到温度,然后使用计算器将其提高到0.023次方。
动作:搜索
输入:"昨天旧金山的最高气温"
观察:旧金山昨天的温度。最高温度:57°F(下午1:56) 最低温度:49°F(上午1:56) 平均温度...
思考:现在我有了温度,所以我可以使用计算器将其提高到0.023次方。
动作:计算器
输入:57^0.023
观察:答案:1.0974509573251117
思考:现在我知道最终答案
最终答案:昨天旧金山的最高气温的0.023次方是1.0974509573251117。
> 完成链。

昨天旧金山的最高气温的0.023次方是1.0974509573251117。

Memory

到目前为止,我们看到的链和代理都是无状态的,但对于许多应用程序来说,引用过去的交互是必要的。聊天机器人就是一个明显的例子,您希望它能在过去的消息上下文中理解新的消息。

Memory模块提供了一种维护应用程序状态的方式。基本Memory接口很简单:它允许您根据最新的运行输入和输出更新状态,并且允许您使用存储的状态修改(或上下文化)下一个输入。

有许多内置的Memory系统。其中最简单的是一个缓冲区Memory,它只是将最近几个输入/输出添加到当前输入之前。我们将在下面的示例中使用它。

from langchain import OpenAI, ConversationChain

llm = OpenAI(temperature=0)
conversation = ConversationChain(llm=llm, verbose=True)
conversation.run("你好!")

下面是底层实现:

> 进入新的链...
格式化后的prompt:
以下是人类和AI之间友好对话的内容。AI会健谈,并提供其上下文的许多具体细节。如果AI不知道问题的答案,它会诚实地说不知道。
当前对话:
人类:你好!
AI:
> 完成链。
>> '你好!你今天好吗?'

现在,如果我们再次运行该链:

conversation.run("我很好!只是与AI聊天。")

我们会看到传递给模型的完整prompt包含我们第一个交互的输入和输出,以及我们最新的输入:

> 进入新的链...
格式化后的prompt:
以下是人类和AI之间友好对话的内容。AI会健谈,并提供其上下文的许多具体细节。如果AI不知道问题的答案,它会诚实地说不知道。
当前对话:
人类:你好!
AI:你好!你今天好吗?
人类:我很好!只是与AI聊天。
AI:
> 完成链。
>> '太好了!你想聊什么?'

内存

到目前为止,我们看到的链和代理都是无状态的,但对于许多应用程序来说,引用过去的交互是必要的。聊天机器人就是一个明显的例子,您希望它能在过去的消息上下文中理解新的消息。

Memory模块提供了一种维护应用程序状态的方式。基本Memory接口很简单:它允许您根据最新的运行输入和输出更新状态,并且允许您使用存储的状态修改(或上下文化)下一个输入。

有许多内置的Memory系统。其中最简单的是一个缓冲区Memory,它只是将最近几个输入/输出添加到当前输入之前。我们将在下面的示例中使用它。

from langchain.memory import BufferMemory

memory = BufferMemory(buffer_size=2)
memory.update_state("您好!")
memory.update_state("我很好!只是与AI聊天。")
memory.modify_next_input("这是一条新消息。")

输出结果为:

'这是一条新消息。您好!我很好!只是与AI聊天。'

在上面的示例中,我们首先更新了状态,然后修改了下一个输入,以便在最新的输入之前包含先前的输入和输出。

这只是Memory模块的一个简单示例。根据您的应用程序需求,可以使用不同的内置Memory系统或实现自定义的Memory系统。