模型 I/O | 豆包MarsCode AI刷题

52 阅读9分钟

模型 I/O | 豆包MarsCode AI刷题

什么是Model I/O

模型,位于LangChain框架的最底层,它是基于语言模型构建的应用的核心元素,是LangChain中的六大核心组件之一。

Model I/O

是语言模型的输入/输出处理的完整流程,由三部分组成:

  1. 输入提示(Format) :设计输入模板,确保结构清晰且动态适配实际内容。
  2. 调用模型(Predict) :通过 LLM 或 Chat 模型处理输入提示并生成输出。
  3. 输出解析(Parse) :将模型的自然语言输出转换为结构化数据。

ffb488f5f695467bb994245df8d947c1tplv-k3u1fbpfcp-jj-mark1890000q75.webp

输入提示

在输入提示(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)

image-20241124203718995转存失败,建议直接上传图片文件

调用模型

在这一部分,我们通过调用大语言模型(LLM)或聊天模型(Chat Model),对输入提示模块生成的内容进行处理,以获得相应的输出。在调用模型之前,首先需要了解LangChain支持的模型类型,包括大语言模型(LLM)、聊天模型(Chat Model)和文本嵌入模型(Embedding Model)。

  • LLM:输入文本后返回文本字符串作为输出。
  • Chat模型:以聊天消息的形式返回输出内容。
  • 文本嵌入模型:对输入进行嵌入处理,返回浮点数表示的向量。

鉴于我们需要模型生成文本回复,这里重点使用LLM和Chat模型。

以下以Chat模型为例,简单介绍调用流程(LLM的使用方法类似,可自行尝试实践):

  1. 定义输入提示:通过模板构造需要传入模型的输入提示信息。
  2. 模型调用:将生成的提示输入传递给Chat模型,并获取响应结果。
  3. 结果处理:对模型返回的内容进行后续处理或直接使用。

这种方式为开发者提供了灵活且高效的调用手段,方便实现多样化的自然语言处理任务。

 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)# 输出文案

image-20241124204446666转存失败,建议直接上传图片文件

输出解析

在LangChain中,输出解析器(Output Parser) 提供了强大的功能,使我们能够从大语言模型(LLM)生成的非结构化文本中提取出结构化数据。这种能力能够显著提升基于语言模型开发应用的效率,尤其在需要处理特定格式或清晰数据结构时。

例如,假设我们希望模型输出两个字段:

  • description:鲜花的说明文本。
  • reason:解释为何写上面的文案。

通常情况下,模型的输出可能是非结构化的,比如:

 让你心动!50元就可以拥有这支充满浪漫气息的玫瑰花束,让TA感受你的真心爱意。为什么这样说呢?因为爱情是无价的,50元对应热恋中的情侣也会觉得值得。

而我们希望将其转换为结构化数据,如下所示:

 {
   "description": "让你心动!50元就可以拥有这支充满浪漫气息的玫瑰花束,让TA感受你的真心爱意。",
   "reason": "因为爱情是无价的,50元对应热恋中的情侣也会觉得值得。"
 }

为了实现这种从非结构化文本到结构化数据的转换,我们可以使用LangChain中的输出解析器。以下是一个基本流程:

  1. 定义输出格式 首先,明确模型输出的目标结构,例如JSON格式的字典。我们可以用一个模板来描述需要的字段及其格式。
  2. 设计解析逻辑 使用LangChain内置的解析器(如OutputParser类)或自定义解析器,根据输出内容提取目标数据。
  3. 集成到工作流中 在生成的非结构化文本基础上,通过解析器将其转换为可直接用于程序处理的结构化数据。

以下是一个完整的实现示例:

 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等)。
    • 统一的接口降低了开发者学习和迁移成本。
  • 结构化输出:

    • 能够轻松定义和提取结构化数据,适合构建复杂的多步骤应用(如自动化报告生成)。

实现鲜花文案生成的流程

  1. 提示模板 (PromptTemplate):

    • 提示模板被定义为格式化的字符串,动态插入变量 flower_nameprice
    • 使用 PromptTemplate.from_template() 方法构建模板。

    代码示例:

     from langchain.prompts import PromptTemplate
     ​
     template = """您是一位专业的鲜花店文案撰写员。
     对于售价为 {price} 元的 {flower_name} ,您能提供一个吸引人的简短描述吗?
     """
     prompt = PromptTemplate.from_template(template)
    
  2. 调用模型:

    • 使用 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)
    
  3. 输出解析:

    • 使用 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 实现了从数据输入、模型调用到输出处理的全链路覆盖,为开发者构建复杂的自然语言处理应用提供了强有力的支持,特别适用于需要高效管理提示设计、灵活调用模型和精准解析输出的场景。