LangChain 系列 - 快速上手 LangChain
LangChain 是一个用于开发基于大语言模型的应用的基础框架。本文介绍了 LangChain 的最基本概念和如何开始使用。
自从 ChatGPT 大受欢迎之后,大语言模型(LLM)成为了一个新的热点。大家都在思考如何将大语言模型集成到自己的应用场景中。最简单的集成方案是直接调用 OpenAI 的 API 来构建自己的系统。大语言模型不仅仅是 OpenAI 的,还有 LLaMA、Chatglm2、Falcon 等可选。同时,我们也希望将大语言模型和我们的业务数据结合起来使用。
LangChain 的诞生旨在解决 LLM 的工程化问题。LangChain 通过抽象 LLM 模型层、引入数据交互模块、记忆模块和回调模块等极大地简化了构建 LLM 工程的流程,统一了各种语言模型接口,构建好的应用可以很方便地切换不同的语言模型进行调试。
PS: 这个思路和我 2020 年开源的 Kashgari 框架的思路一样嘿嘿。
安装
1 | pip install langchain |
我们需要申请一个 OpenAI API key 来使用,申请网址,需要科学上网。
LangChain 三大模块
现在我们可以尝试构建自己的第一个应用。LangChain 提供了许多模块,可用于构建语言模型应用程序。这些模块可以作为独立模块在简单的应用程序中使用,也可以结合在一起用于更复杂的用例。
LangChain 中最核心的模块 LLMChain。LLMChain 由以下几个模块组成。
- LLM: 语言模型是这里的核心推理引擎。为了使用 LangChain,需要了解不同类型的语言模型以及如何与它们一起工作。
- Prompt Template:Prompt Templates 提供了对语言模型的指令。它控制语言模型的输出,因此了解如何构建提示和不同的提示策略至关重要。
- Output Parser:这些将 LLM 的原始响应转换为更易处理的格式,使得在下游使用输出变得更加容易。
在这个入门指南中,我们将单独介绍这三个组件,然后介绍将它们结合起来的 LLMChain。理解这些概念将为能够使用和自定义 LangChain 应用程序奠定良好的基础。大多数 LangChain 应用程序允许配置 LLM 和/或使用的提示,因此了解如何利用这一点将成为构建 LLM 应用的核心。
LLM
LangChain 中有两类语言模型,分别是
- LLMs: 这是一个以字符串作为输入并返回字符串的语言模型。
- ChatModel:这是一个以 ChatMessage 数组作为输入并返回 ChatMessage 的语言模型。
ChatMessage 实际上是包含以下两个元素的对象。
content
: 消息的内容,字符串形式。role
: 消息的来源角色。
下面几个 ChatMessage 子类是内置 role 角色信息的 Message 对象,方便我们快速使用。
HumanMessage
: 一个来自用户的ChatMessage
对象。AIMessage
: 一个来自 AI 的ChatMessage
对象。SystemMessage
: 一个来自系统的ChatMessage
对象。FunctionMessage
: 一个来自会函数调用的ChatMessage
对象。
如果上面的四个预定义角色不符合任务需求,可以使用 ChatMessage 自定义角色。
LangChain 中的语言模型都有统一的推理接口。标准的推理接口都包含以下俩方法:
predict
: 输入一个字符串,返回一个字符串。predict_messages
: 输入一个 ChatMessage 数组,返回一个 ChatMessage 对象。
首先我们实例化两个语言模型
1 | from langchain.llms import OpenAI |
注意其中 OpenAI 和 ChatOpenAI 还能传入很多基础参数,比如 model_name
, temperature
和 max_tokens
等。更多参数可以查阅 API 文档.
实例化语言模型后,我们先尝试 predict
接口,代码如下。可以看到返回均为字符串对象。
1 | result1 = llm.predict("hi!") |
现在我们尝试使用 predict_messages
接口,代码如下:
1 | from langchain.schema import HumanMessage |
上面两个推理接口还能传入 temperature
等参数来调整本次的输出。调用函数时候传入参数将会覆盖初始化语言模型使用的参数。
Prompt Template
大多数 LLM 应用程序不会直接将用户输入传递给 LLM。通常,它们会将用户输入添加到一个更大的文本片段中,称为提示模板,该模板提供了有关当前具体任务的附加上下文。
在先前的示例中,我们传递给模型的文本包含了生成游戏的指令。对于我们的应用程序来说,如果用户只需要提供游戏的描述,而不必担心给模型提供指令,那会极大方便用户的使用。
PromptTemplates 正好可以解决这个问题!它们将从用户输入到完全格式化的提示的所有逻辑打包在一起。这可以非常简单地开始 - 例如,为了生成上述字符串,一个提示只需是:
1 | from langchain.prompts import PromptTemplate |
这时候你估计就要说,那我为什么不直接用字符串拼接来完成这一步骤。当然,字符串拼接完全可以做到这个 Prompt 构建过程,但是 PromptTemplate 提供了一些便利的方法,比如我可以一次只填写部分的变量。可以把多个 PromptTemplate 组合在一起构成一个 prompt 等。
下面就是用多个 PromptTemplate 组合出一个 prompt 的例子。
1 | from langchain.prompts.chat import ( |
运行结果为
1 | [ |
Output Parser
OutputParser 用于将 LLM 的原始输出转换为可在下游应用使用的格式。常见的 OutputParser 用途有:
- 将 LLM 的文本转换为结构化信息(例如 JSON)
- 将 ChatMessage 转换为字符串
- 将调用返回的消息以外的额外信息(例如 OpenAI 函数调用)转换为字符串。
我们定义一个最小自定义 OutputParser,代码如下:
1 | from langchain.schema import BaseOutputParser |
LLMChain 组合
现在我们把前面的三大模块组合起来构造我们的 LLMChain。这个 chain 将会接受变量输入,将输入转换为 prompt,再把 prompt 传入 LLM 得到结果,并用 Parser 把结果解析成程序输出。
1 | from langchain.chat_models import ChatOpenAI |
常见问题解决
charset_normalizer has no attribute md__mypyc
1 | AttributeError: partially initialized module 'charset_normalizer' has no attribute 'md__mypyc' (most likely due to a circular import) |
如果遇到上面的报错,可以通过重新安装 charset-normalizer
特定版本,然后重启 Jupyter 来解决。
1 | pip install --force-reinstall charset-normalizer==3.1.0 |