LangChain的发展
LangChain的目标
LangChain的价值
组件化:LangChain 对与 LLMs 交互的流程进行了统一的抽象,同时也提供了不同 LLMs 的实现。这极大的提升了我们使用 LLMs 的效率。
序列化:LangChain 提供的序列化的能力,可以将
提示词
、chain
等以文件的形式而不是以代码的形式进行存储,这样可以极大的方便我们共享提示词
,并对提示词
进行版本管理。[4]丰富的 chains 套件:LangChain 提供了丰富、用于完成特定目的、开箱即用的 chains 套件,例如用于总结文档的
StuffDocumentsChain
和MapReduceDocumentsChain
,这些套件将会降低我们使用 LLMs 的门槛。
更具体的, LangChain 可以在如下的 6 大方向上给我们提供非常大的便利:
LLMs & Prompt:LangChain 提供了目前市面上几乎所有 LLM 的通用接口,同时还提供了
提示词
的管理和优化能力,同时也提供了非常多的相关适用工具,以方便开发人员利用 LangChain 与 LLMs 进行交互。Chains:LangChain 把
提示词
、大语言模型
、结果解析
封装成Chain
,并提供标准的接口,以便允许不同的Chain
形成交互序列,为 AI 原生应用提供了端到端的Chain
。Data Augemented Generation[5]:
数据增强生成式
是一种解决预训练语料数据无法及时更新而带来的回答内容陈旧的方式。LangChain 提供了支持数据增强生成式
的Chain
,在使用时,这些Chain
会首先与外部数据源进行交互以获得对应数据,然后再利用获得的数据与LLMs
进行交互。典型的应用场景如:基于特定数据源的问答机器人。Agent:对于一个任务,
代理
主要涉及让LLMs
来对任务进行拆分、执行该行动、并观察执行结果,代理
会重复执行这个过程,直到该任务完成为止。LangChain 为代理
提供了标准接口,可供选择的代理,以及一些端到端的代理
的示例。Memory:
内存
指的是 chain 或 agent 调用之间的状态持久化。LangChain 为内存
提供了标准接口,并提供了一系列的内存
实现。Evaluation:LangChain 还提供了非常多的评估能力以允许我们可以更方便的对
LLMs
进行评估。
基本概念
prompt templates
提示词模版为不同的提示词提供预定义格式。就好像目前超市售卖的洗净切好、配好相关配菜源材料的预制菜一样,提示词模版可以简化我们和 LLMs 交互的效率。
模版会包含:指令,少量的样本示例,相关的上下文信息。LLMs 会分为 大语言模型
和 聊天模型
两种类型,因此,LangChain 提供了两种类型的提示词模版:prompt template
、chat prompt template
。
prompt template
:提供字符串格式的提示词。chat prompt template
:提示聊天消息格式的提示词。
from langchain import PromptTemplate
prompt_template = PromptTemplate.from_template(
"请以轻松欢快的语气写一篇描写 {topic} 的文章,字数不超过 {count} 字。"
)
res = prompt_template.format(topic="北京的秋天", count="100")
print(res)
# 请以轻松欢快的语气写一篇描写 北京的秋天 的文章,字数不超过 100 字。
from langchain.prompts import ChatPromptTemplate
template = ChatPromptTemplate.from_messages([
("system", "你是一个能力非凡的人工智能机器人,你的名字是 {name}。"),
("human", "你好!"),
("ai", "你好~"),
("human", "{user_input}"),
])
messages = template.format_messages(
name="小明",
user_input="你是谁?"
)
print(messages)
# [SystemMessage(content='你是一个能力非凡的人工智能机器人,你的名字是 小明。',
# additional_kwargs={}),
# HumanMessage(content='你好!', additional_kwargs={}, example=False),
# AIMessage(content='你好~', additional_kwargs={}, example=False),
# HumanMessage(content='你是谁?', additional_kwargs={}, example=False)]
LLMs
LangChain 提供了两种模型的通用接口:
LLMs
:模型以字符串格式的提示词作为输入,并返回字符串格式的结果。Chat models
:其背后也是由某种 LLM 来支撑,但是以聊天消息列表格式的提示词作为输入,并返回聊天消息格式的结果。
LLM 和 聊天模式的区别
LLM 和 聊天模式 之间的区别虽然很微妙,但是却完全不同。
LangChain 中的 LLM 指的是纯文本 I/O 的模型,其包装的 API 将字符串提示作为输入,并输出字符串。OpenAI 的 GPT-3 就是 LLM。
聊天模型通常由 LLM 支持,但专门针对对话进行了调整,其 API 采用聊天消息列表作为输入,而不是单个字符串。通常,这些消息都标有角色(例如,“System”,“AI”,“Human”)。聊天模型会返回一条 AI 聊天消息作为输出。OpenAI 的 GPT-4,Anthropic 的 Claude,百度的 Ernie 都是聊天模型。
在 LangChain 中,LLM 和 聊天模式两者都实现了 BaseLanguageModel
接口,因此一般情况下,这两种模型可以混用。例如,两种模型都实现了常见的方法 predict()
和 predict_messages()
。predict()
接受字符串并返回字符串,predict_messages()
接受消息并返回消息。
在 LangChain 中,LLM 和 聊天模式两者都实现了 BaseLanguageModel
接口,因此一般情况下,这两种模型可以混用。例如,两种模型都实现了常见的方法 predict()
和 predict_messages()
。predict()
接受字符串并返回字符串,predict_messages()
接受消息并返回消息
class OpenAI(BaseOpenAI):
# ...
class BaseOpenAI(BaseLLM):
# ...
class BaseLLM(BaseLanguageModel[str], ABC):
# ...
class ErnieBotChat(BaseChatModel):
# ...
class BaseChatModel(BaseLanguageModel[BaseMessageChunk], ABC):
# ...
将 Prompt
和 LLM
整合起来,实现和大语言模型交互
from langchain import PromptTemplate
from langchain.llms import OpenAI
prompt_template = PromptTemplate.from_template(
"请以轻松欢快的语气写一篇描写 {topic} 的文章,字数不超过 {count} 字。"
)
llm = OpenAI()
prompt = prompt_template.format(topic="北京的秋天", count="100")
res = llm.predict(prompt)
print(res)
# 秋天来到了北京,一片金黄色的枫叶,漫山遍野。
# 湖面上的微风,吹起柔和的秋意,空气中弥漫着淡淡的枫香。
# 这时,每一个角落都洋溢着秋日的温馨,令人心旷神怡。
# 古老的长城上披着红叶,熙熙攘攘的人群中,也多了几分热闹与欢畅,这就是北京的秋天
from langchain.chat_models import ErnieBotChat
from langchain.prompts import ChatPromptTemplate
template = ChatPromptTemplate.from_messages([
("user", "你是一个能力非凡的人工智能机器人,你的名字是 {name}。"),
("assistant", "你好~"),
("user", "{user_input}"),
])
chat = ErnieBotChat()
messages = template.format_messages(
name="小明",
user_input="你是谁?"
)
res = chat.predict_messages(messages)
print(res)
# content='我是你的新朋友小明,一个拥有先进人工智能技术的人工智能机器人。'
# additional_kwargs={} example=False
output parsers
大语言模型一般会输出文本内容作为响应,当然更高级的大语言模型(例如文心大模型)还可以输出图片、视频作为响应。但是,很多时候,我们希望可以获得更结构化的信息,而不仅仅是回复一串字符串文本
from langchain.chat_models import ErnieBotChat
from langchain.prompts import ChatPromptTemplate
from langchain.output_parsers import CommaSeparatedListOutputParser
template = ChatPromptTemplate.from_messages([
("user", "你是一个能力非凡的人工智能机器人,你的名字是 {name}。"),
("assistant", "你好~"),
("user", "{user_input}"),
])
chat = ErnieBotChat()
messages = template.format_messages(
name="小明",
user_input="请仅给5个表示快乐的成语并以 , 分隔,除了成语外不要输出任何其他内容"
)
res = chat.predict_messages(messages)
print(res)
# content='欢呼雀跃,手舞足蹈,笑逐颜开,心花怒放,喜笑颜开' additional_kwargs={} example=False
output_parser = CommaSeparatedListOutputParser()
res = output_parser.parse(res.content.replace(',', ', '))
print(res)
# ['欢呼雀跃', '手舞足蹈', '笑逐颜开', '心花怒放', '喜笑颜开']
LLMChain
在 LangChain 中,提示词
、LLM
、输出解析
这三者构成了 Chain
,而不同的 Chain
则可以通过一定的方式链接起来,以实现强大的功能
单独使用 LLMs 已经可以实现强大的功能,但是如果可以将更多次的交互有效的链接起来,则能发挥 LLMs 更大的能量
from langchain.chat_models import ErnieBotChat
from langchain.prompts import ChatPromptTemplate
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.chains import LLMChain
template = ChatPromptTemplate.from_messages([
("user", "你是一个能力非凡的人工智能机器人,你的名字是 {name}。"),
("assistant", "你好~"),
("user", "{user_input}"),
])
chat = ErnieBotChat()
chain = LLMChain(llm=chat, prompt=template, output_parser=CommaSeparatedListOutputParser())
res = chain.run(name="小明", user_input="请仅给5个表示快乐的成语并以 , 分隔,除了成语外不要输出任何其他内容")
print(res)
# ['以下是五个表示快乐的成语:\n\n1. 喜出望外\n2. 乐不可支\n3. 心花怒放\n4. 满心欢喜\n5. 手舞足蹈']
评论区