LangChain中的六大核心组件:Models、Chains、Agents、Prompts、Memory、Indexes
本文先对models进行学习,它相当于整条链路的发动机
- 目标:自动生成鲜花文案的应用程序
- 任务:以LangChain作为框架,通过API调用大模型来解决具体问题
Model I/O
对模型的使用可以分为输入提示、调用模型和输出解析三个部分。对应下图的各个部分,LangChain提供了模板和工具,能形成调用各种语言模型的接口。
- 提示模板: 根据提示模板输入信息,这个模板可以根据实际需求选择不同的输入,针对特定的任务和应用调整输入
- 语言模型: 调用接口使用任何一种语言模型,而不改变调用方式
- 输出解析: 从输出中提取信息,不需要处理冗余或不相关的数据。也就是把大模型给回的非结构化文本,转换成程序可以处理的结构化数据。
提示模板
PromptTemplate的from_template方法将一个原始的模板字符串转化为一个更易操作的PromptTemplate对象,这个对象就是LangChain中的提示模板。LangChain 提供了多个类和函数,也为各种应用场景设计了很多内置模板,使构建和使用提示变得容易。
参数:
- f-string 模板的格式,用{}替换参数
- output_parser输出解析器,负责解析从大语言模型返回的文本输出,并将其转换成结构化的数据形式
- validate_template是否验证模板 这是什么意思
语言模型
LangChain中支持的模型有三大类。
- 大语言模型(LLM) ,也叫Text Model,这些模型将文本字符串作为输入,并返回文本字符串作为输出。
- 聊天模型(Chat Model),主要代表Open AI的ChatGPT系列模型。这些模型通常由语言模型支持,但它们的 API 更加结构化。具体来说,这些模型将聊天消息列表作为输入,并返回聊天消息。
- 文本嵌入模型(Embedding Model),这些模型将文本作为输入并返回Embedding。文本嵌入模型负责把文档存入向量数据库。上篇有提到
# 设置OpenAI API Key
import os
os.environ["OPENAI_API_KEY"] = '你的Open AI API Key'
# 导入LangChain中的OpenAI模型接口
from langchain_openai import OpenAI
# 创建模型实例
model = OpenAI(model_name='gpt-3.5-turbo-instruct')
# 输入提示
input = prompt.format(flower_name=["玫瑰"], price='50')
# 得到模型的输出
output = model.invoke(input)
# 打印输出内容
print(output)
使用LangChain的好处有什么?
我们只需要定义一次模板,就可以用它来生成各种不同的提示。对比单纯使用 f-string 来格式化文本,这种方法更加简洁,也更容易维护。而LangChain在提示模板中,还整合了output_parser、template_format 以及是否需要validate_template等功能。
更重要的是,使用LangChain提示模板,我们还可以很方便地把程序切换到不同的模型,而不需要修改任何提示相关的代码。
输出解析
出发点:在开发具体应用的过程中,很明显我们不仅仅需要文字,更多情况下我们需要的是程序能够直接处理的、结构化的数据。
通过LangChain的输出解析器来重构程序,让模型有能力生成结构化的回应,同时对其进行解析,直接将解析好的数据存入CSV文档。
# 导入结构化输出解析器和ResponseSchema
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
# 定义我们想要接收的响应模式
response_schemas = [
ResponseSchema(name="description", description="鲜花的描述文案"),
ResponseSchema(name="reason", description="问什么要这样写这个文案")
]
# 创建输出解析器
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
# 获取格式指示
format_instructions = output_parser.get_format_instructions()
# 根据原始模板创建提示,同时在提示中加入输出解析器的说明
prompt = PromptTemplate.from_template(prompt_template,
partial_variables={"format_instructions": format_instructions})
完成了链路中的每个部分,现在运行可以看到如下结果,同时他还可以生成csv文件,以便或许其他任务的使用。
思考题
-
请你用自己的理解,简述LangChain调用大语言模型来做应用开发的优势。 1.
简化集成:LangChain提供了一套工具和API,使得开发者可以更容易地将大型语言模型集成到他们的应用程序中。这减少了开发者需要自己处理的复杂性,让他们可以更快地实现功能。
模块化设计:LangChain支持模块化开发,可以根据自己的需求选择不同的组件来构建应用。这种灵活性允许开发者优化其应用程序以满足特定的业务需求。
易于扩展:随着应用程序需求增长,LangChain的设计使其能够轻松地添加新的功能或调整现有的设置,以适应更大的用户基数或更复杂的任务。
-
在上面的示例中,format_instructions,也就是输出格式是怎样用output_parser构建出来的,又是怎样传递到提示模板中的?
定义
OutputParser类:在这个类中,主要实现parse方法,该方法接收模型的原始输出,并返回一个结构化的对象。 - 可选地,你可以实现get_format_instructions方法,这个方法返回一个字符串,描述了模型输出应遵循的格式。这个字符串将被用作提示的一部分,帮助指导模型生成正确的格式。创建
OutputParser实例:定义好OutputParser类后,创建其实例。这个实例将在构建提示时使用。将
format_instructions传递给提示模板: - 在构建提示时,你可以通过output_parser.get_format_instructions()的结果作为变量插入到提示模板中。这样,当模型接收到提示时,它会看到关于期望输出格式的指示,从而有助于生成符合要求的输出。 -
加入了partial_variables,也就是输出解析器指定的format_instructions之后的提示,为什么能够让模型生成结构化的输出?你可以打印出这个提示,一探究竟。
通过在提示中明确指定了输出格式,模型在生成输出时会尽量遵循这些指示。
-
使用输出解析器后,调用模型时有没有可能仍然得不到所希望的输出?也就是说,模型有没有可能仍然返回格式不够完美的输出?
即使使用了输出解析器(
output_parser),模型仍然有可能返回格式不够完美的输出。虽然输出解析器可以帮助模型更好地理解期望的输出格式,但模型的生成行为仍然是基于其训练数据和内部算法的,因此不能完全保证每次都能生成完全符合预期的输出。