我正在参加「豆包MarsCode AI练中学体验活动」详情请看:掘金小册上线 AI练中学功能 | 你的 AI 编程助教喊你免费领小册啦!
前言
模型(Model),位于LangChain框架的最底层,它是基于语言模型构建的应用的 核心元素,因为所谓LangChain应用开发,就是以LangChain作为框架,通过API调用大模型来解决具体问题的过程。
可以说,整个LangChain框架的逻辑都是由LLM这个发动机来驱动的。没有模型,LangChain这个框架也就失去了它存在的意义。
Model I/O 概览
模型的使用过程可以分成三部分,在LangChain中这个过程被统称为 Model I/O(Input/Output)
- 输入提示(对应图中的Format)
- 调用模型(对应图中的Predict)
- 输出解析(对应图中的Parse)
在整个I/O流程中,LangChain为用户提供了多种模板和工具,使得调用各类语言模型的接口变得更加便捷。
- 提示模板:在利用模型的过程中,首要步骤是将提示信息导入模型。借助LangChain提供的模板,用户可以根据具体的应用场景灵活选择输入内容,针对不同任务定制化调整输入信息。
- 语言模型:LangChain设计了一个统一的接口来访问语言模型。这使得即便是在不同类型的模型间切换,也能保持调用方式的一致性,大大增强了系统的灵活性和易用性。
- 输出解析:此外,LangChain还具备从模型输出结果中筛选有用信息的能力。利用其内置的输出解析功能,可以高效地从模型返回的数据中精准提取所需部分,避免了不必要的信息干扰,更重要的是能够将模型输出的非结构化文本转换为易于程序处理的结构化格式。
接下来,我们将通过具体的例子深入探讨上述三个关键环节。
提示模板
Prompt Engineering,就是专门研究对大语言模型的提示构建
例如:为每一种鲜花生成一段简介文案,这样每当你的员工或顾客想要了解某种鲜花时,调用该模板就会生成适合的文字。
提示模板的生成方式如下:
python
# 导入LangChain中的提示模板
from langchain import PromptTemplate
# 创建原始模板
template = """您是一位专业的鲜花店文案撰写员。\n
对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?
"""
# 根据原始模板创建LangChain提示模板
prompt = PromptTemplate.from_template(template)
# 打印LangChain提示模板的内容
print(prompt)
print(prompt) 打印的提示模板的具体消息如下:
python
input_variables=['flower_name', 'price']
output_parser=None partial_variables={}
template='/\n您是一位专业的鲜花店文案撰写员。
\n对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?\n'
template_format='f-string'
validate_template=True
在这里,所谓"模板"就是一段描述某种鲜花的文本格式,它是一个 f-string,其中有两个变量 {flower_name} 和 {price} 表示花的名称和价格,这两个值是模板里面的占位符,在实际使用模板生成提示时会被具体的值替换。
代码中的from_template是一个类方法,它允许我们直接从一个字符串模板中创建一个PromptTemplate对象 。打印出这个PromptTemplate对象,你可以看到这个对象中的信息包括输入的变量(在这个例子中就是 flower_name
和 price
)、输出解析器(这个例子中没有指定)、模板的格式(这个例子中为 'f-string'
)、是否验证模板(这个例子中设置为 True
)。
因此PromptTemplate的from_template方法就是将一个原始的模板字符串转化为一个更丰富、更方便操作的PromptTemplate对象,这个对象就是LangChain中的提示模板。LangChain 提供了多个类和函数,也 为各种应用场景设计了很多内置模板,使构建和使用提示变得容易。
语言模型
LangChain中支持的模型分为三大类。
- 大语言模型(LLM),也称为Text Model,这些模型将文本字符串作为输入,并返回文本字符串作为输出。Open AI的text-davinci-003、Facebook的LLaMA、ANTHROPIC的Claude,都是典型的LLM。
- 聊天模型(Chat Model),主要代表Open AI的ChatGPT系列模型。这些模型通常由语言模型支持,但它们的 API 更加结构化。具体来说,这些模型将聊天消息列表作为输入,并返回聊天消息。
- 文本嵌入模型(Embedding Model),这些模型将文本作为输入并返回浮点数列表,也就是Embedding。而文本嵌入模型如OpenAI的text-embedding-ada-002,我们之前已经见过了。文本嵌入模型负责把文档存入向量数据库,和我们这里探讨的提示工程关系不大。
接下来,我们将调用语言模型,让模型帮我们写文案,并且返回文案的结果。
python
# 设置OpenAI API Key
import os
os.environ["OPENAI_API_KEY"] = '你的Open AI API Key'
# 导入LangChain中的OpenAI模型接口
from langchain import OpenAI
# 创建模型实例
model = OpenAI(model_name='text-davinci-003')
# 输入提示,模板实例化并传入变量值
input = prompt.format(flower_name=["玫瑰"], price='50')
# 得到模型的输出
output = model(input)
# 打印输出内容
print(output)
# 让你心动!50元就可以拥有这支充满浪漫气息的玫瑰花束,让TA感受你的真心爱意。
复用提示模板,我们可以同时生成多个鲜花的文案。
python
# 导入LangChain中的提示模板
from langchain import PromptTemplate
# 创建原始模板
template = """您是一位专业的鲜花店文案撰写员。\n
对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?
"""
# 根据原始模板创建LangChain提示模板
prompt = PromptTemplate.from_template(template)
# 打印LangChain提示模板的内容
print(prompt)
# 设置OpenAI API Key
import os
os.environ["OPENAI_API_KEY"] = '你的Open AI API Key'
# 导入LangChain中的OpenAI模型接口
from langchain import OpenAI
# 创建模型实例
model = OpenAI(model_name='text-davinci-003')
# 多种花的列表
flowers = ["玫瑰", "百合", "康乃馨"]
prices = ["50", "30", "20"]
# 生成多种花的文案
for flower, price in zip(flowers, prices):
# 使用提示模板生成输入
input_prompt = prompt.format(flower_name=flower, price=price)
# 得到模型的输出
output = model(input_prompt)
# 打印输出内容
print(output)
使用LangChain和提示模板的好处包括:
- 代码的可读性:使用模板使得提示文本更易于阅读和理解,特别是对于复杂的提示或多变量的情况。
- 可复用性:模板可以在多个地方被复用,使你的代码更简洁,无需在每个需要生成提示的地方重新构造提示字符串。
- 维护:如果你在后续需要修改提示,使用模板的话,只需修改模板即可,而不需要在代码中查找所有使用到该提示的地方进行修改。
- 变量处理:如果你的提示中涉及到多个变量,模板可以自动处理变量的插入,无需手动拼接字符串。
- 参数化:模板可以根据不同的参数生成不同的提示,这对于个性化生成文本非常有用。
输出解析
LangChain提供的解析模型输出的功能,使你能够更容易地从模型输出中获取结构化的信息,这将大大加快基于语言模型进行应用开发的效率。
python
# 通过LangChain调用模型
from langchain import PromptTemplate, OpenAI
# 导入OpenAI Key
import os
os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key'
# 创建原始提示模板
prompt_template = """您是一位专业的鲜花店文案撰写员。
对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?
{format_instructions}"""
# 创建模型实例
model = OpenAI(model_name='text-davinci-003')
# 导入结构化输出解析器和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})
# 数据准备
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(input)
# 解析模型的输出(这是一个字典结构)
parsed_output = output_parser.parse(output)
# 在解析后的输出中添加"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)
输出
python
[{'flower': '玫瑰', 'price': '50', 'description': 'Luxuriate in the beauty of this 50 yuan rose, with its deep red petals and delicate aroma.', 'reason': 'This description emphasizes the elegance and beauty of the rose, which will be sure to draw attention.'},
{'flower': '百合', 'price': '30', 'description': '30元的百合,象征着坚定的爱情,带给你的是温暖而持久的情感!', 'reason': '百合是象征爱情的花,写出这样的描述能让顾客更容易感受到百合所带来的爱意。'},
{'flower': '康乃馨', 'price': '20', 'description': 'This beautiful carnation is the perfect way to show your love and appreciation. Its vibrant pink color is sure to brighten up any room!', 'reason': 'The description is short, clear and appealing, emphasizing the beauty and color of the carnation while also invoking a sense of love and appreciation.'}]