贫瘠之地

华北无浪漫,死海扬起帆
多少个夜晚,独自望着天

0%

LangChain 文档学习 No.1 - 快速开始

介绍

LangChain 是一个基于语言模型开发应用程序的框架。它可以实现以下功能:

  • 数据感知:将语言模型与其他数据源连接起来
  • 主体性:允许语言模型与其环境进行交互

LangChain 的主要价值包括:

  1. 组件:用于处理语言模型的抽象,以及每个抽象的一系列实现。组件是模块化且易于使用的,无论您是否使用 LangChain 框架的其他部分,都可以轻松使用
  2. 现成的管道:用于完成特定高级任务的结构化组件组合

现成的管道使得入门变得容易。对于更复杂的应用程序和细致入微的用例,组件使得自定义现有管道或构建新管道变得容易


实践示例:

  • 聊天机器人
  • 使用数据源回答问题(知识库)
  • 分析结构化数据

模块

LangChain 为以下模块提供标准、可扩展的接口和外部集成(功能模块)

  • 模型 I/O:与语言模型进行接口
  • 检索:与特定于应用程序的数据进行接口
  • 管道:构建调用序列
  • 代理:让管道根据高级指令选择使用哪些工具
  • 内存:在管道运行期间保持应用程序状态
  • 回调:记录和流式传输任何管道的中间步骤

环境

LangChain

LangChain Python 版本的安装

1
pip install langchain 

OpenAI

使用 LangChain 通常需要与一个或多个模型提供者、数据存储、API等进行集成

我们可以使用 OpenAI 的模型 API

本示例使用微软 Azure 的模型 API

1
pip install openai

开始

构建模块

LangChain 提供了许多可以用来构建语言模型应用程序的模块

这些模块可以作为简单应用程序中的独立模块使用,也可以组合在一起用于更复杂的用例

LangChain 应用程序的核心构建模块是 LLMChain,它结合了三个方面:

  • LLM(大语言模型):语言模型是核心推理引擎;要使用 LangChain,您需要了解不同类型的语言模型以及如何使用它们
  • Prompt Templates(提示词模板):提供语言模型的指令;这控制了语言模型的输出,因此了解如何构建提示和不同的提示策略至关重要
  • Output Parsers(输出解析器):将 LLM 的原始响应转换为更易处理的格式,使得在下游使用输出变得容易

LLMs

LangChain 中有两种类型的语言模型,称为:

  • LLMs:这是一个以字符串作为输入并返回字符串的语言模型
  • ChatModels:这是一个以消息列表作为输入并返回消息的语言模型

LLMs 的输入/输出简单易懂,是字符串

但是 ChatModels 输入是一个 ChatMessage 列表,输出是一个单独的 ChatMessage,一个 ChatMessage 具有两个必需的组件:

  • content:这是消息的内容
  • role:这是 ChatMessage 来自的实体的角色

LangChain 提供了几个对象,用于方便地区分不同的角色:

  • HumanMessage:来自人类/用户的 ChatMessage
  • AIMessage:来自AI/助手的 ChatMessage
  • SystemMessage:来自系统的 ChatMessage
  • FunctionMessage:来自函数调用的 ChatMessage

如果这些角色都不合适,还可以使用 ChatMessage 类手动指定角色,有关如何最有效地使用这些不同的消息的更多信息,请参阅我们的提示指南

LangChain 为两者提供了一个标准接口,但了解这种差异以便为给定的语言模型构建提示非常有用 LangChain 提供的标准接口有两种方法:

  • predict:接受一个字符串,返回一个字符串
  • predict_messages:接受一个消息列表,返回一个消息


两者的区别,首先,让我们导入 LLM 和 ChatModel

1
2
3
4
5
6
7
8
9
10
11
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI

llm = OpenAI()
chat_model = ChatOpenAI()

llm.predict("hi!")
>>> "Hi"

chat_model.predict("hi!")
>>> "Hi"

使用 predict 方法对字符串输入进行处理

1
2
3
4
5
6
7
text = "What would be a good company name for a company that makes colorful socks?"

llm.predict(text)
# >> Feetful of Fun

chat_model.predict(text)
# >> Socks O'Color

使用 predict_messages 方法对消息列表进行处理

1
2
3
4
5
6
7
8
9
10
from langchain.schema import HumanMessage

text = "制造多彩袜子的公司的好名字是什么?"
messages = [HumanMessage(content=text)]

llm.predict_messages(messages)
# >> Feetful of Fun

chat_model.predict_messages(messages)
# >> Socks O'Color

对于这两种方法,还可以将参数作为关键字参数传递,例如可以传入 temperature=0 来调整使用的温度,该温度将覆盖对象的配置

需要注意在运行时传入的任何值都将始终覆盖对象的配置

AzureOpenAI LLM

本示例使用微软 Azure 的模型 API

可以参考官方文档 在提示流中与 LangChain 集成 - Azure Machine Learning | Microsoft Learn 或者 LangChain 的 LLM Integrations 文档 Azure OpenAI | 🦜️🔗 Langchain | Azure | 🦜️🔗 Langchain

创建 LLM 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import os

from langchain.llms.openai import AzureOpenAI

os.environ["OPENAI_API_TYPE"] = "azure"
os.environ["OPENAI_API_VERSION"] = "2023-03-15-preview"
os.environ["OPENAI_API_KEY"] = ""

llm = AzureOpenAI(
deployment_name="",
azure_endpoint="",
model_name="gpt-35-turbo-16k",
)

result = llm.predict("Hello World")
print(result)

这里可能会接收到错误的返回

1
{'error': {'code': 'OperationNotSupported', 'message': 'The completion operation does not work with the specified model, gpt-35-turbo-16k. Please choose different model and try again. You can learn more about which models can be used with each operation here: https://go.microsoft.com/fwlink/?linkid=2197993.'}}

原因是 gpt-35-turbo-16k 模型不能用于 AzureOpenAI 对象,应该使用 AzureChatOpenAI;我理解 Azure 的 AI 服务对文本处理(LangChain 中的 LLMs)和问答、聊天(LangChain 中的 ChatModels)做了区分

1
2
3
4
5
6
# 使用 AzureChatOpenAI
llm = AzureChatOpenAI(
deployment_name="",
azure_endpoint="",
model_name="gpt-35-turbo-16k",
)

提示模板

提示模板可以将用户输入转化为完全格式化的提示的所有逻辑绑定在一起,下面是一个简单应用

1
2
3
4
5
prompt = PromptTemplate.from_template("please tell me in which country is {city_name} located?")
text = prompt.format(city_name="BeiJing")
# text = please tell me in which country is BeiJing located?
result = llm.predict(text)
# >> Beijing is located in China.

提示模板不仅是用于将字符串进行格式化,主要的优势:

  • 多提示中抽出共同变量,只格式化一次
  • 生成消息列表,系统消息、角色消息等
1
2
3
4
5
6
7
8
template = "You are a helpful assistant that translates {input_language} to {output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
messages = chat_prompt.format_messages(input_language="English", output_language="French", text="I love programming.")
print(messages)
# >> [SystemMessage(content='You are a helpful assistant that translates English to French.'), HumanMessage(content='I love programming.')]

更多详见后续提示词相关内容

输出解析器

OutputParsers 将 LLM 的原始输出转换为可以在下游使用的格式 输出解析器有几种主要类型:

  • 将 LLM 的文本转换为结构化信息(例如 JSON)
  • 将 ChatMessage 转换为字符串
  • 将除消息之外的其他信息(如 OpenAI 函数调用)转换为字符串

官方例子中实现了一个将逗号分隔的列表转换为列表的解析器

1
2
3
4
5
6
7
8
9
10
11
from langchain.schema import BaseOutputParser

class CommaSeparatedListOutputParser(BaseOutputParser):
"""Parse the output of an LLM call to a comma-separated list."""

def parse(self, text: str):
"""Parse the output of an LLM call."""
return text.strip().split(", ")

CommaSeparatedListOutputParser().parse("hi, bye")
# >> ['hi', 'bye']

LLMChain

现在可以将所有这些组合成一个链组件

这个链组件将接收输入变量,将其传递给提示模板以创建提示,将提示传递给 LLM,然后通过一个(可选的)输出解析器将输出解析后输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from langchain.chains import LLMChain
from langchain.chat_models import AzureChatOpenAI
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import BaseOutputParser
import os


class CommaSeparatedListOutputParser(BaseOutputParser):
"""Parse the output of an LLM call to a comma-separated list."""

def parse(self, text: str):
"""Parse the output of an LLM call."""
return text.strip().split(", ")


os.environ["OPENAI_API_TYPE"] = "azure"
os.environ["OPENAI_API_VERSION"] = "2023-03-15-preview"
os.environ["OPENAI_API_KEY"] = ""

chat_model = AzureChatOpenAI(
deployment_name="",
azure_endpoint="",
model_name="gpt-35-turbo-16k",
)

template = """You are a helpful assistant who generates comma separated lists.
A user will pass in a category, and you should generate 5 objects in that category in a comma separated list.
ONLY return a comma separated list, and nothing more."""
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)

chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
chain = LLMChain(
llm=chat_model,
prompt=chat_prompt,
output_parser=CommaSeparatedListOutputParser()
)
result = chain.run("DC super hero")
print(result)

# >> ['Superman', 'Batman', 'Wonder Woman', 'The Flash', 'Aquaman']

上面的例子让 AI 成为一个输出 5 个指定分类下对象,并且使用逗号分隔的助手

后续

本文介绍了如何创建 LangChain 应用程序的核心构建块 - LLMChains

在所有这些组件(LLMs、prompts、输出解析器)中还有很多微妙之处,会在后面持续学习

参考

快速入门 | 🦜️🔗 Langchain