模型 I/O | 豆包MarsCode AI刷题
什么是Model I/O
模型,位于LangChain框架的最底层,它是基于语言模型构建的应用的核心元素,是LangChain中的六大核心组件之一。
Model I/O
是语言模型的输入/输出处理的完整流程,由三部分组成:
- 输入提示(Format) :设计输入模板,确保结构清晰且动态适配实际内容。
- 调用模型(Predict) :通过 LLM 或 Chat 模型处理输入提示并生成输出。
- 输出解析(Parse) :将模型的自然语言输出转换为结构化数据。
输入提示
在输入提示(Format)部分,我们需要为LangChain设计一个模板提示语句,以固定输入信息的基本框架,同时将需要根据实际情况调整的内容通过参数化方式嵌入模板中。当我们向大模型提供输入信息时,只需为模板传入相应的参数,即可生成与模板结合的完整提示语句并传递给模型。这种方式能够有效简化输入信息的构建过程,确保结构清晰且高效。以下是一个利用模板生成输入提示的简单示例:
# 导入LangChain中的提示模板
import os
from langchain.prompts import PromptTemplate
# 创建原始模板
template = """您是一位专业的鲜花店文案撰写员。\n
对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?
"""
# 根据原始模板创建LangChain提示模板
prompt = PromptTemplate.from_template(template)
# 打印LangChain提示模板的内容
print(prompt)
# 导入LangChain中的OpenAI模型接口
from langchain_openai import OpenAI, ChatOpenAI
# 创建模型实例
model = ChatOpenAI(model=os.environ.get("LLM_MODELEND"))
# 输入提示
input = prompt.format(flower_name=["玫瑰"], price="50")
# 得到模型的输出
output = model.invoke(input)
# 打印输出内容
print(output)
调用模型
在这一部分,我们通过调用大语言模型(LLM)或聊天模型(Chat Model),对输入提示模块生成的内容进行处理,以获得相应的输出。在调用模型之前,首先需要了解LangChain支持的模型类型,包括大语言模型(LLM)、聊天模型(Chat Model)和文本嵌入模型(Embedding Model)。
- LLM:输入文本后返回文本字符串作为输出。
- Chat模型:以聊天消息的形式返回输出内容。
- 文本嵌入模型:对输入进行嵌入处理,返回浮点数表示的向量。
鉴于我们需要模型生成文本回复,这里重点使用LLM和Chat模型。
以下以Chat模型为例,简单介绍调用流程(LLM的使用方法类似,可自行尝试实践):
- 定义输入提示:通过模板构造需要传入模型的输入提示信息。
- 模型调用:将生成的提示输入传递给Chat模型,并获取响应结果。
- 结果处理:对模型返回的内容进行后续处理或直接使用。
这种方式为开发者提供了灵活且高效的调用手段,方便实现多样化的自然语言处理任务。
from httpx import Response
from openai import OpenAI # 导入OpenAI
import os
prompt_text = "您是一位专业的鲜花店文案撰写员。对于售价为{}元的{},您能提供一个吸引人的简短描述吗?" # 设置提示
flowers = ["玫瑰", "百合", "康乃馨"]
prices = ["50", "30", "20"]
# 循环调用Text模型的Completion方法,生成文案
for flower, price in zip(flowers, prices):
prompt = prompt_text.format(price, flower)
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].message.content)# 输出文案
输出解析
在LangChain中,输出解析器(Output Parser) 提供了强大的功能,使我们能够从大语言模型(LLM)生成的非结构化文本中提取出结构化数据。这种能力能够显著提升基于语言模型开发应用的效率,尤其在需要处理特定格式或清晰数据结构时。
例如,假设我们希望模型输出两个字段:
- description:鲜花的说明文本。
- reason:解释为何写上面的文案。
通常情况下,模型的输出可能是非结构化的,比如:
让你心动!50元就可以拥有这支充满浪漫气息的玫瑰花束,让TA感受你的真心爱意。为什么这样说呢?因为爱情是无价的,50元对应热恋中的情侣也会觉得值得。
而我们希望将其转换为结构化数据,如下所示:
{
"description": "让你心动!50元就可以拥有这支充满浪漫气息的玫瑰花束,让TA感受你的真心爱意。",
"reason": "因为爱情是无价的,50元对应热恋中的情侣也会觉得值得。"
}
为了实现这种从非结构化文本到结构化数据的转换,我们可以使用LangChain中的输出解析器。以下是一个基本流程:
- 定义输出格式 首先,明确模型输出的目标结构,例如JSON格式的字典。我们可以用一个模板来描述需要的字段及其格式。
- 设计解析逻辑 使用LangChain内置的解析器(如
OutputParser
类)或自定义解析器,根据输出内容提取目标数据。 - 集成到工作流中 在生成的非结构化文本基础上,通过解析器将其转换为可直接用于程序处理的结构化数据。
以下是一个完整的实现示例:
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
from langchain.chat_models import ChatOpenAI
# 定义输出格式
response_schemas = [
ResponseSchema(name="description", description="鲜花的说明文本"),
ResponseSchema(name="reason", description="解释为何写上面的文案"),
]
# 创建解析器
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
# 定义提示模板
template = """
你是一名专业文案写手。请根据以下描述生成文案,并按照JSON格式返回:
鲜花:玫瑰
价格:50元
格式:
{{
"description": "你的文案内容",
"reason": "文案背后的创意原因"
}}
"""
prompt = PromptTemplate(template=template, output_parser=output_parser)
# 调用模型
llm = ChatOpenAI(temperature=0) # 选择所需模型
chain = LLMChain(llm=llm, prompt=prompt)
# 获取结果
result = chain.run()
print(result) # 输出为结构化JSON格式
运行上述代码后,模型将返回结构化数据,例如:
{
"description": "让你心动!50元就可以拥有这支充满浪漫气息的玫瑰花束,让TA感受你的真心爱意。",
"reason": "因为爱情是无价的,50元对应热恋中的情侣也会觉得值得。"
}
通过输出解析器,我们能够从模型生成的笼统回答中快速提取所需的核心信息,并将其转换为标准化的格式,为后续的数据处理和业务逻辑提供便利。
LangChain 的优势
-
模块化设计:
- PromptTemplate 模板定义和复用。
- 输出解析器(Output Parsers)将复杂的模型输出转化为开发者需求的格式。
-
灵活性和易用性:
- 对接多种语言模型(OpenAI、Hugging Face、Anthropic等)。
- 统一的接口降低了开发者学习和迁移成本。
-
结构化输出:
- 能够轻松定义和提取结构化数据,适合构建复杂的多步骤应用(如自动化报告生成)。
实现鲜花文案生成的流程
-
提示模板 (PromptTemplate):
- 提示模板被定义为格式化的字符串,动态插入变量
flower_name
和price
。 - 使用
PromptTemplate.from_template()
方法构建模板。
代码示例:
from langchain.prompts import PromptTemplate template = """您是一位专业的鲜花店文案撰写员。 对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗? """ prompt = PromptTemplate.from_template(template)
- 提示模板被定义为格式化的字符串,动态插入变量
-
调用模型:
- 使用 OpenAI 的 GPT-3.5 模型生成文案。
- 通过提示模板动态生成输入提示,并调用模型。
代码示例:
from langchain_openai import OpenAI model = OpenAI(model_name='gpt-3.5-turbo-instruct') input_prompt = prompt.format(flower_name="玫瑰", price="50") output = model.invoke(input_prompt) print(output)
-
输出解析:
- 使用
StructuredOutputParser
定义解析规则。 - 将模型的自由文本输出解析为预定义的字段结构。
代码示例:
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( template, partial_variables={"format_instructions": format_instructions} ) parsed_output = output_parser.parse(model.invoke(prompt.format(flower_name="玫瑰", price="50"))) print(parsed_output)
- 使用
LangChain 对比直接使用 OpenAI API
特性 | 直接使用 OpenAI API | 使用 LangChain |
---|---|---|
提示生成 | 手动拼接字符串,格式容易出错 | 使用模板动态插值,减少出错 |
输出处理 | 自行解析自然语言输出,较为繁琐 | 内置解析器,直接返回结构化数据 |
代码复用 | 模板需多次手动定义 | 模板可复用,支持统一管理 |
模型兼容性 | 针对每个模型单独编写调用逻辑 | 框架层统一封装,便于模型切换 |
总结
LangChain 的 Model I/O 模块通过输入提示、模型调用和输出解析三部分,为开发者提供了一个系统化、模 块化的开发框架。在输入提示阶段,LangChain 通过模板化的提示语句设计,让开发者能够以灵活的方式动态构造提示内容,从而减少手动拼接字符串的繁琐步骤,同时保证输入信息的规范性和复用性。在模型调用阶段,LangChain 支持多种模型类型,包括大语言模型(LLM)、聊天模型(Chat Model)和嵌入模型(Embedding Model),并以统一的接口封装调用逻辑,降低了不同模型之间切换的成本。在输出解析阶段,LangChain 提供了功能强大的输出解析器,能够将非结构化的模型输出转换为程序可直接处理的结构化数据,如 JSON 格式,为复杂应用开发提供了便利。
相较于直接使用语言模型 API,LangChain 提供了更加完善的工具链支持。其提示模板支持动态变量插入,输出解析器能够自动提取关键数据,并将其组织为预定义的格式化结构。这些特性显著提升了开发效率和代码的复用性,同时也减少了出错的可能性。
总的来说,LangChain 通过 Model I/O 实现了从数据输入、模型调用到输出处理的全链路覆盖,为开发者构建复杂的自然语言处理应用提供了强有力的支持,特别适用于需要高效管理提示设计、灵活调用模型和精准解析输出的场景。