07-LangChain中的输出解析器 | 豆包MarsCode AI刷题

88 阅读6分钟

为了实现上节课目标,我们调用了OpenAI模型,并利用了结构化输出解析器和数据处理工具。这节课,我将带你深入研究LangChain中的输出解析器,并用一个新的解析器——Pydantic解析器,来重构第5课中的程序。

LangChain中的输出解析器

语言模型的输出通常是纯文本,适合人类阅读,但在开发中我们经常需要将这些文本转换成计算机可以处理的结构化数据。输出解析器就是为此而生的,它们帮助我们将模型的输出解析成特定的数据格式,确保符合我们的预期。

输出解析器是一种专门用于处理语言模型响应的类,通常需要实现以下两个核心方法:

  1. get_format_instructions:返回一个字符串,用于指导语言模型如何格式化输出。
  2. parse:接收语言模型的输出并将其解析为特定的数据结构或格式。

还有一个可选的方法:

  • parse_with_prompt:接收语言模型的输出和用于生成这个输出的提示,解析成特定的数据结构。这对于在原始提示下修正或重新解析模型的输出非常有用。

在LangChain中,根据不同的使用场景,设计了多种输出解析器:

  1. 列表解析器(List Parser) :用于处理模型生成的列表输出。
  2. 日期时间解析器(Datetime Parser) :用于确保输出为正确的日期或时间格式。
  3. 枚举解析器(Enum Parser) :用于确保模型输出在一组预定义值中。
  4. 结构化输出解析器(Structured Output Parser) :用于处理复杂、结构化的输出。
  5. Pydantic(JSON)解析器:用于处理符合特定JSON格式的输出,使用Pydantic库进行数据验证。
  6. 自动修复解析器(Auto-Fixing Parser) :用于自动修复常见的输出错误。
  7. 重试解析器(RetryWithErrorOutputParser) :在模型的初次输出不符合预期时,尝试重新生成或修复输出。

前三种解析器较为简单易懂,这节课我们重点讨论结构化输出解析器、Pydantic解析器、自动修复解析器和重试解析器。

实战:Pydantic(JSON)解析器

Pydantic(JSON)解析器是最常用的解析器之一。它通过Python的数据验证库Pydantic来构建复杂的数据模型,并确保模型的输出符合我们定义的数据格式。接下来,我们用Pydantic解析器来重构之前的鲜花文案生成程序。

第一步:创建模型实例

首先,设置OpenAI API密钥并创建模型实例。

# 设置OpenAI API密钥
import os
os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key'# 创建模型实例
from langchain import OpenAI
model = OpenAI(model_name='gpt-3.5-turbo-instruct')

第二步:定义输出数据的格式

通过Pydantic创建一个数据格式类 FlowerDescription,用于验证输出数据的结构。

# 创建一个空的DataFrame用于存储结果
import pandas as pd
df = pd.DataFrame(columns=["flower_type", "price", "description", "reason"])
​
# 数据准备
flowers = ["玫瑰", "百合", "康乃馨"]
prices = ["50", "30", "20"]
​
# 定义输出数据格式
from pydantic import BaseModel, Field
class FlowerDescription(BaseModel):
    flower_type: str = Field(description="鲜花的种类")
    price: int = Field(description="鲜花的价格")
    description: str = Field(description="鲜花的描述文案")
    reason: str = Field(description="为什么要这样写这个文案")

Pydantic用于自动验证输入数据,确保输入符合指定的类型。它的特点包括数据验证、数据转换、JSON支持等,非常适合结构化数据的处理。

第三步:创建输出解析器

基于Pydantic的数据格式类 FlowerDescription,创建输出解析器并获取输出格式指示。

# 创建输出解析器
from langchain.output_parsers import PydanticOutputParser
output_parser = PydanticOutputParser(pydantic_object=FlowerDescription)
​
# 获取输出格式指示
format_instructions = output_parser.get_format_instructions()
print("输出格式:", format_instructions)

这个解析器会为模型提供格式指示,确保输出符合我们定义的JSON结构。

第四步:创建提示模板

我们定义一个提示模板,包含需要模型填充的变量和输出格式指示。

# 创建提示模板
from langchain import PromptTemplate
prompt_template = """您是一位专业的鲜花店文案撰写员。
对于售价为 {price} 元的 {flower} ,您能提供一个吸引人的简短中文描述吗?
{format_instructions}"""prompt = PromptTemplate.from_template(prompt_template, 
       partial_variables={"format_instructions": format_instructions})
​
print("提示:", prompt)

第五步:生成提示,传入模型并解析输出

循环处理每种花和它的价格,将输入传入模型,解析输出并存储结果。

for flower, price in zip(flowers, prices):
    # 根据提示准备模型的输入
    input = prompt.format(flower=flower, price=price)
    print("提示:", input)
​
    # 获取模型的输出
    output = model(input)
​
    # 解析模型的输出
    parsed_output = output_parser.parse(output)
    df.loc[len(df)] = parsed_output.dict()
​
# 打印字典
print("输出的数据:", df.to_dict(orient='records'))

模型生成的描述被解析成结构化的数据并存储到DataFrame中,以便进一步处理和分析。

自动修复解析器(OutputFixingParser)

自动修复解析器用于修复模型输出中的小错误,例如格式不正确的问题。我们尝试使用自动修复解析器来修复一个错误的JSON输出。

# 使用OutputFixingParser创建新的解析器
from langchain.output_parsers import OutputFixingParser
from langchain.chat_models import ChatOpenAI
​
misformatted = "{'name': '康乃馨', 'colors': ['粉红色','白色','红色','紫色','黄色']}"
parser = PydanticOutputParser(pydantic_object=Flower)
new_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI())
result = new_parser.parse(misformatted)
print(result)

自动修复解析器调用大模型来修正格式错误,帮助解析不符合预期的输出。

重试解析器(RetryWithErrorOutputParser)

如果输出缺失关键内容,重试解析器可以根据原始提示重新与模型交互,获取完整的输出。

# 初始化重试解析器
from langchain.output_parsers import RetryWithErrorOutputParser
retry_parser = RetryWithErrorOutputParser.from_llm(
    parser=parser, llm=OpenAI(temperature=0)
)
parse_result = retry_parser.parse_with_prompt(bad_response, prompt_value)
print('RetryWithErrorOutputParser的parse结果:', parse_result)

重试解析器通过重新与模型交互,确保输出符合预期,尤其在缺失内容时非常有用。

总结时刻

结构化解析器和Pydantic解析器帮助我们从语言模型中获取结构化的输出。自动修复解析器可以修正简单的格式错误,而重试解析器则能够在输出不完整时重新与模型交互获取正确的内容。选择解析器时,要根据具体场景的需求选择合适的工具。

  • Pydantic解析器:适合复杂数据结构的验证和转换。
  • 自动修复解析器:用于小的格式修复。
  • 重试解析器:适合需要内容完整性的场景,通过重新生成来确保质量。

接下来的课程中,我们会继续深入探索更多LangChain的组件,带你开发更加丰富的AI应用!

思考题

  1. 到目前为止,我们使用了哪些LangChain输出解析器?它们的用法和异同是什么?
  2. 为什么大模型能够返回JSON格式的数据,输出解析器用了什么“魔法”让大模型做到了这一点?
  3. 自动修复解析器的“修复”功能具体是如何实现的?请debug并研究LangChain如何设计