Model IO
我们可以把对模型的使用过程拆解成三块,分别是输入提示(对应图中的Format)、调用模型(对应图中的Predict)和输出解析(对应图中的Parse)。这三块形成了一个整体,因此在LangChain中这个过程被统称为 Model I/O(Input/Output)。
- 提示模板:使用模型的第一个环节是把提示信息输入到模型中,你可以创建LangChain模板,根据实际需求动态选择不同的输入,针对特定的任务和应用调整输入。
- 语言模型:LangChain允许你通过通用接口来调用语言模型。这意味着无论你要使用的是哪种语言模型,都可以通过同一种方式进行调用,这样就提高了灵活性和便利性。
- 输出解析:LangChain还提供了从模型输出中提取信息的功能。通过输出解析器,你可以精确地从模型的输出中获取需要的信息,而不需要处理冗余或不相关的数据,更重要的是还可以把大模型给回的非结构化文本,转换成程序可以处理的结构化数据。
提示模板
所谓提示模板 就是给模型正确的提示,可以提高回答的准确性,如何合理的提出问题就是我们思考的关键了
langchain有相应的提示模板,使用提示模板让我们提出的问题更加有针对性
快速上手
# 导入LangChain中的提示模板
import os
from langchain.prompts import PromptTemplate
# 创建原始模板
template = """您是一位专业的鲜花店文案撰写员。\n
对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?
"""
# 根据原始模板创建LangChain提示模板
prompt = PromptTemplate.from_template(template)
# 打印LangChain提示模板的内容
print(prompt)
# 设置OpenAI API Key
# os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key'
# 导入LangChain中的OpenAI模型接口
from langchain_openai import ChatOpenAI
# 创建模型实例
# model = OpenAI(model_name='gpt-3.5-turbo-instruct')
model = ChatOpenAI(model=os.environ.get("LLM_MODELEND"))
# 输入提示
input = prompt.format(flower_name=["玫瑰"], price="50")
# 得到模型的输出
output = model.invoke(input).content
# 打印输出内容
print(output)
运行结果如下:
不难看出,这是将一个模板中填入了flower_name和price两个参数,而且模板开头还给予了模型一个身份的提示,然后得到了相应的文案
模板复用
构建一次模板,使用多次
代码如下:
# 导入LangChain中的提示模板
from langchain.prompts 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"] = '你的OpenAI API Key'
# 导入LangChain中的OpenAI模型接口
from langchain_openai import OpenAI, ChatOpenAI
# 创建模型实例
# model = OpenAI(model_name='gpt-3.5-turbo-instruct')
model = ChatOpenAI(model=os.environ.get("LLM_MODELEND"))
# 多种花的列表
flowers = ["玫瑰", "百合", "康乃馨"]
prices = ["50", "30", "20"]
# 生成多种花的文案
for flower, price in zip(flowers, prices):
# 使用提示模板生成输入
input_prompt = prompt.format(flower_name=flower, price=price)
# 得到模型的输出
output = model.invoke(input_prompt).content
# 打印输出内容
print(output)
结果如下:
使用模板实现了复用,但是在我看来,好像没有多大的作用,可能是我不懂。
OpenAI的模板
除了langchain带的模板之外,openai也有相应的模板功能
代码如下:
from httpx import Response
from openai import OpenAI # 导入OpenAI
import os
# openai.api_key = '你的OpenAI API Key' # API Key
prompt_text = "您是一位专业的鲜花店文案撰写员。对于售价为{}元的{},您能提供一个吸引人的简短描述吗?" # 设置提示
flowers = ["玫瑰", "百合", "康乃馨"]
prices = ["50", "30", "20"]
# 循环调用Text模型的Completion方法,生成文案
for flower, price in zip(flowers, prices):
prompt = prompt_text.format(price, flower)
# response = openai.completions.create(
# model="gpt-3.5-turbo-instruct",
# prompt=prompt,
# max_tokens=100
# )
client = OpenAI()
response = client.chat.completions.create(
model=os.environ.get("LLM_MODELEND"),
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt},
],
max_tokens=100,
)
# print(response.choices[0].text.strip()) # 输出文案
print(response.choices[0].message.content)
结果如下:
感觉和lagnchain模板复用类似,没啥感觉
huggingface的模板
huggingface的模板,因为外网的原因,我在我本地使用魔法跑的是可以的
代码如下:
# 导入LangChain中的提示模板
from langchain.prompts import PromptTemplate
# 创建原始模板
template = """You are a flower shop assitiant。\n
For {price} of {flower_name} ,can you write something for me?
"""
# 根据原始模板创建LangChain提示模板
prompt = PromptTemplate.from_template(template)
# 打印LangChain提示模板的内容
print(prompt)
# 设置HuggingFace API Token
import os
os.environ['HUGGINGFACEHUB_API_TOKEN'] = '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'
from langchain_community.llms import HuggingFaceHub
# 创建模型实例
model = HuggingFaceHub(repo_id="Qwen/Qwen2.5-Coder-32B-Instruct")
# 输入提示
input = prompt.format(flower_name=["玫瑰"], price="50")
# 得到模型的输出
output = model.invoke(input)
# 打印输出内容
print(output)
结果如下:
输出解析
相对于提示模板来说,输出解析更加的让我心动,因为传统的str 对应 str的模式可能使用对对话,如果想使用到更多的方面,就要结构化处理输出,让我们处理起来更加的方便,可以应用到更多的方面。
代码如下:
# 导入OpenAI Key
import os
# os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key'
# 导入LangChain中的提示模板
from langchain.prompts import PromptTemplate
# 创建提示模板
prompt_template = """您是一位专业的鲜花店文案撰写员。
对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?
{format_instructions}"""
# 通过LangChain调用模型
from langchain_openai import OpenAI, ChatOpenAI
# 创建模型实例
# model = OpenAI(model_name='gpt-3.5-turbo-instruct')
model = ChatOpenAI(model=os.environ.get("LLM_MODELEND"))
# 导入结构化输出解析器和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.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)
最核心的就是:
# 定义我们想要接收的响应模式
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}
)
不难看出,定义了各个部分的描述,得到一个结构化的结果:以逗号为分割 flower,price,description,reason
总结
在本篇文章中,我们探讨了模型的输入输出(IO)过程,具体分为三个主要模块:提示模板、调用模型和输出解析。表面上看,文章似乎并没有明确提到“调用模型”的部分,但如果仔细观察,你会发现“提示模板”和“输出解析”两个环节已经隐含了对模型的调用。因为,最终的输出结果正是通过模型的推理和计算得出的。
首先,提示模板(Prompt Template)为模型提供了输入的格式和语境,它通过结构化的文本将问题或任务传递给模型。在这个阶段,模型虽然没有直接被调用,但已经通过模板设置了对模型输入的要求,因此这一环节本身就是在为后续的模型调用做准备。
接着是调用模型的过程。虽然在提示模板部分没有明确指出调用模型,但当我们通过编程接口(例如 OpenAI API)或者类似的框架向模型发送请求时,模型的计算过程便开始了。模型根据接收到的提示信息进行处理,进行推理和计算,最终产生一个输出结果。所以,从这个角度来看,调用模型的步骤已经在提示模板和模型输入的构建过程中隐含进行了。
最后,输出解析是将模型返回的结果进行理解和转换的过程。此时,模型的计算已经完成,输出结果可能需要进一步的解释或格式化,才能为用户提供最终的答案。因此,尽管调用模型的步骤看似没有单独列出,但它的核心功能已经在整个过程的背后发挥了作用。
在后续的文章中,我们将更加详细地讲解模型的提示模板、调用模型和解析输出这三个环节,以及它们如何协同工作,帮助用户有效地与大语言模型进行交互。