LangChain六大核心组件
- Model
- Prompts
- Chains
- Memory
- Agents
- Indexes
Model I/O
- 输入提示(Format):使用模型的第一个环节是把提示信息输入到模型中。我们可以创建LangChain的提示模板,根据实际需求动态选择不同的输入。
- 调用模型(Parse):LangChain允许我们通过通用接口来调用语言模型。
- 输出解析(Input/Output):LangChain还提供了从模型输出中提取信息的功能。通过输出解析器,我们可以精确地从模型的输出中获取需要的信息,而不需要处理冗余或不相关的数据,更重要的是还可以把大模型给回的非结构化文本,转换成程序可以处理的结构化数据。
1 提示模板
1.1 提示模板的生成方式
导入langchain中的提示模板
import os
from langchain.prompts import PromptTemplate
PromptTemplate 是 LangChain 库中的一个类,用于创建和管理提示模板。通过使用 PromptTemplate,可以定义一个模板,其中包含固定的文本和可变的占位符,这些占位符可以在运行时被具体的值替换。
在导入 PromptTemplate 之后,通常会创建一个提示模板的实例,并使用它来格式化输入,然后将格式化后的提示传递给语言模型进行处理。
根据原始模板创建LangChain提示模板
template = """您是一位专业的鲜花店文案撰写员。\n 对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗? """
prompt = PromptTemplate.from_template(template)
print(prompt)
from_template是PromptTemplate 类的一个方法,它允许我们直接从一个字符串模板中创建一个PromptTemplate对象,这个对象就是LangChain中的提示模板。
1.2 PromptTemplate对象的具体内容
input_variables=['flower_name', 'price']
output_parser=None partial_variables={}
template='/\n您是一位专业的鲜花店文案撰写员。\n对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?\n'
template_format='f-string'
validate_template=True
input_variables表示输入变量是flower_name和priceoutput_parser=None表示没有指定输出解析器partial_variables参数表示一个字典,用于提供模板中占位符的部分变量值,格式为{模板中的占位符内容:替换后的内容}。partial_variables={}表示没有提供任何部分变量值,因此模板中的所有占位符都将等待在实例化时被填充。template_format='f-string'表示模版格式为‘f-string’格式。f-string是 Python 3.6 及以后版本引入的一种字符串格式化方式,它允许在字符串字面量中插入表达式,并在运行时计算这些表达式的值。f-string的格式通常是在字符串的前面加上字母f或F,然后在字符串内部使用花括号{}来包含要插入的表达式。validate_template参数表示是否验证模版有效性。当设置为True时,LangChain 会检查模板字符串是否符合特定的格式要求,例如是否包含正确的占位符和语法。如果模板字符串格式不正确,验证将失败,并可能抛出一个异常。如果验证通过,from_template方法将继续创建建PromptTemplate对象。
2 语言模型
2.1 LangChain支持的语言模型
- 大语言模型(LLM):也叫Text Model,这些模型将文本字符串作为输入,并返回文本字符串作为输出。Open AI的text-davinci-003、Facebook的LLaMA、ANTHROPIC的Claude,都是典型的LLM。
- 聊天模型(Chat Model):主要代表Open AI的ChatGPT系列模型。这些模型通常由语言模型支持,但它们的 API 更加结构化。具体来说,这些模型将聊天消息列表作为输入,并返回聊天消息。
- 文本嵌入模型(Embeding Model):这些模型将文本作为输入并返回浮点数列表,也就是Embedding。文本嵌入模型负责把文档存入向量数据库,典型的文本嵌入模型如我们之前见的OpenAI的text-embedding-ada-002。
2.2 调用语言模型
调用OpenAI类创建模型
os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key'
from langchain_openai import OpenAI
model = OpenAI(model_name='gpt-3.5-turbo-instruct')
- 首先在系统的环境变量处设置OpenAI API Key
- 从
langchain_openai模块中导入OpenAI类,该类通常用于与 OpenAI 的文本模型(如text-davinci-003)进行交互,它提供了一种简单的方法来调用 OpenAI 的 API 并获取文本生成的结果。 - 利用
OpenAI类的构造函数创建了一个OpenAI模型的实例model,使用的模型名称是gpt-3.5-turbo-instruct。OpenAI类的构造函数接受一个或多个参数,用于指定要使用的模型名称、API 密钥、temperature(控制输出的随机性)等。在本次示例中我们只指定了模型名称。 调用ChatOpenAI类创建模型
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model=os.environ.get("LLM_MODELEND"))
- 从
langchain_openai模块中导入ChatOpenAI类,该类用于与 OpenAI 的聊天模型(如gpt-3.5-turbo或gpt-4)进行交互,它允许我们构建一个对话历史,并以对话的形式与模型进行交流。 - 首先使用
os.environ.get()方法从环境变量中获取名为LLM_MODELEND的值,并将其赋值给变量model_name。这个环境变量通常包含了要使用的 OpenAI 模型的名称,例如gpt-3.5-turbo或gpt-4。然后使用获取到的模型名称model_name来初始化ChatOpenAI类的实例model。
输入提示
input = prompt.format(flower_name=["玫瑰"], price="50")
调用了 PromptTemplate类的 format 方法,传入了两个参数:flower_name 和 price。这两个参数将替换模板字符串中的占位符 {flower_name} 和 {price},生成一个具体的输入字符串。
得到模型的输出
output = model.invoke(input)
print(output)
调用了 model 实例的 invoke 方法,并将之前格式化好的输入字符串 input 作为参数传递给该方法。invoke 方法会将这个输入字符串发送给 OpenAI 的聊天模型,并返回模型生成的响应。
使用LangChain相较于直接使用Open AI API的优势:我们只需要定义一次模板,就可以用它来生成各种不同的提示。对比单纯使用
f-string来格式化文本,这种方法更加简洁,也更容易维护。而LangChain在提示模板中,还整合了output_parser、template_format以及是否需要validate_template等功能。
3 输出解析
创建输出解析器
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}
)
- 从
langchain.output_parsers模块导入StructuredOutputParser和ResponseSchema两个类。StructuredOutputParser是一个用于解析结构化输出的类。它可以帮助我们从模型的输出中提取特定的信息,并将其转换为结构化的数据格式,例如字典或列表。ResponseSchema是一个用于定义输出结构的类。可以用它来指定我们期望从模型输出中获取哪些信息,以及这些信息应该如何被组织。
- 接下来定义了一个名为
response_schemas的列表,该列表包含两个ResponseSchema对象。每个ResponseSchema对象都有一个名称和一个描述。 - 根据我们之前定义的
response_schemas列表创建一个StructuredOutputParser对象。调用了StructuredOutputParser类的from_response_schemas方法,传入了response_schemas列表作为参数。这个方法会根据列表中的ResponseSchema对象自动生成解析规则,以便后续能够将模型的输出解析成指定的结构化格式。 - 然后调用
StructuredOutputParser类的get_format_instructions方法获取格式指示。这个方法返回一个字符串,该字符串包含了如何格式化模型输出的说明。这些说明通常是一个 JSON 结构的模板,模型的输出应该遵循这个模板,以便output_parser能够正确地解析它。 - 最后我们在提示模板中加入输出解析器的说明。
将解析好的数据存入csv文档
# 数据准备
flowers = ["玫瑰", "百合", "康乃馨"]
prices = ["50", "30", "20"]
# 创建一个空的DataFrame用于存储结果
import pandas as pd
df = pd.DataFrame(columns=["flower", "price", "description", "reason"]) # 先声明列名
for flower, price in zip(flowers, prices):
# 根据提示准备模型的输入
input = prompt.format(flower_name=flower, price=price)
# 获取模型的输出
output = model.invoke(input)
# 解析模型的输出(这是一个字典结构)
parsed_output = output_parser.parse(output.content)
# 在解析后的输出中添加“flower”和“price”
parsed_output["flower"] = flower
parsed_output["price"] = price
# 将解析后的输出添加到DataFrame中
df.loc[len(df)] = parsed_output
# 打印字典
print(df.to_dict(orient="records"))
# 保存DataFrame到CSV文件
df.to_csv("flowers_with_descriptions.csv", index=False)
parse方法会根据output_parser中定义的解析规则,从模型输出的文本中提取出相应的信息,并将其转换为字典格式。df.loc[len(df)]:使用loc索引器来选择 DataFrame 的下一行。len(df)返回 DataFrame 的当前长度,因此df.loc[len(df)]指向的是 DataFrame 的最后一行之后的新行。df.loc[len(df)] = parsed_output这行代码的作用是将解析后的输出数据作为新的一行添加到 DataFrame 中。orient="records"参数在pandas.DataFrame.to_dict()方法中指定了将 DataFrame 转换为字典的格式。具体来说,它指定了将 DataFrame 的每一行转换为一个字典,其中字典的键是 DataFrame 的列名,值是对应行的数据。