小白举手04-青训营ai笔记-输出 | 豆包MarsCode AI 刷题

85 阅读6分钟

一、概念

(一)定义

输出解析器是一种专用于处理和构建语言模型响应的类,能够把语言信息转换成计算机能够理解的结构性语言。一个基本的输出解析器类通常需要实现两个核心方法。

  • get_format_instructions:这个方法需要返回一个字符串,用于指导如何格式化语言模型的输出,告诉它应该如何组织并构建它的回答。
  • parse:这个方法接收一个字符串(也就是语言模型的输出)并将其解析为特定的数据结构或格式。这一步通常用于确保模型的输出符合我们的预期,并且能够以我们需要的形式进行后续处理。
  • parse_with_prompt:这个方法接收一个字符串(也就是语言模型的输出)和一个提示(用于生成这个输出的提示),并将其解析为特定的数据结构。这样,你可以根据原始提示来修正或重新解析模型的输出,确保输出的信息更加准确和贴合要求。

(二)分类

  1. 列表解析器(List Parser):这个解析器用于处理模型生成的输出,当需要模型的输出是一个列表的时候使用。例如,如果你询问模型“列出所有鲜花的库存”,模型的回答应该是一个列表。
  2. 日期时间解析器(Datetime Parser):这个解析器用于处理日期和时间相关的输出,确保模型的输出是正确的日期或时间格式。
  3. 枚举解析器(Enum Parser):这个解析器用于处理预定义的一组值,当模型的输出应该是这组预定义值之一时使用。例如,如果你定义了一个问题的答案只能是“是”或“否”,那么枚举解析器可以确保模型的回答是这两个选项之一。
  4. 结构化输出解析器(Structured Output Parser):这个解析器用于处理复杂的、结构化的输出。如果你的应用需要模型生成具有特定结构的复杂回答(例如一份报告、一篇文章等),那么可以使用结构化输出解析器来实现。
  5. Pydantic(JSON)解析器:这个解析器用于处理模型的输出,当模型的输出应该是一个符合特定格式的JSON对象时使用。它使用Pydantic库,这是一个数据验证库,可以用于构建复杂的数据模型,并确保模型的输出符合预期的数据模型。
  6. 自动修复解析器(Auto-Fixing Parser):这个解析器可以自动修复某些常见的模型输出错误。例如,如果模型的输出应该是一段文本,但是模型返回了一段包含语法或拼写错误的文本,自动修复解析器可以自动纠正这些错误。
  7. 重试解析器(RetryWithErrorOutputParser):这个解析器用于在模型的初次输出不符合预期时,尝试修复或重新生成新的输出。例如,如果模型的输出应该是一个日期,但是模型返回了一个字符串,那么重试解析器可以重新提示模型生成正确的日期格式。

二、json解析

Pydantic (JSON) 解析器应该是最常用也是最重要的解析器,我带着你用它来重构鲜花文案生成程序。

注释:

1、pandas pd包

Pandas 是一个开源的 Python 数据分析和操作库,专门用于处理结构化数据。它提供了高效的数据结构和数据分析工具,使得数据清洗、分析和可视化变得更加简单和快速。Pandas 的核心数据结构包括:

  • Series:一维数组,类似于列表或字典,带有标签。
  • DataFrame:二维表格数据结构,类似于电子表格或 SQL 表格,行和列都有标签。

为什么使用 pd 作为别名?

在 Python 中,使用 import pandas as pd 的方式导入 pandas 库是一个广泛接受的惯例。这种做法的好处包括:

  1. 简化代码:使用 pd 作为别名可以减少代码中的字符数,使得调用库中的函数时更加简洁。例如,使用 pd.DataFrame() 而不是 pandas.DataFrame()
  2. 提高可读性:由于 pd 是一个常见的约定,其他开发者在阅读代码时能够快速理解这是在使用 Pandas 库。
  3. 避免命名冲突:如果在同一代码中使用多个库,使用别名可以避免潜在的命名冲突。

2、pydantic和json

选择 Pydantic:如果你在 Python 环境中工作,需要快速构建和验证数据模型,尤其是在 Web 开发(如 FastAPI)中,Pydantic 是一个非常合适的选择。Pydantic有这样几个特点。

  1. 数据验证:当你向Pydantic类赋值时,它会自动进行数据验证。例如,如果你创建了一个字段需要是整数,但试图向它赋予一个字符串,Pydantic会引发异常。
  2. 数据转换:Pydantic不仅进行数据验证,还可以进行数据转换。例如,如果你有一个需要整数的字段,但你提供了一个可以转换为整数的字符串,如 "42",Pydantic会自动将这个字符串转换为整数42。
  3. 易于使用:创建一个Pydantic类就像定义一个普通的Python类一样简单。只需要使用Python的类型注解功能,即可在类定义中指定每个字段的类型。
  4. JSON支持:Pydantic类可以很容易地从JSON数据创建,并可以将类的数据转换为JSON格式。

选择 JSON Schema:如果你需要与其他编程语言或系统进行数据交换,并且希望使用一种标准化的方法来描述数据结构,那么 JSON Schema 更为合适。

这两者可以结合使用,例如在 Python 中使用 Pydantic 来处理数据,同时生成 JSON Schema 用于与其他系统交互。

3、鲁棒性 robust的音译


# ------Part 1
import os
# os.environ["OPENAI_API_KEY"] = 'Your OpenAI API Key'

# 创建模型实例
from langchain_openai import ChatOpenAI

model = ChatOpenAI(
    model=os.environ.get("LLM_MODELEND"),
)

# ------Part 2
# 创建一个空的DataFrame用于存储结果
import pandas as pd

df = pd.DataFrame(columns=["flower_type", "price", "description", "reason"])

# 数据准备
flowers = ["玫瑰", "百合", "康乃馨"]
prices = ["50", "30", "20"]

# 定义我们想要接收的数据格式
from pydantic.v1 import BaseModel, Field


class FlowerDescription(BaseModel):
    flower_type: str = Field(description="鲜花的种类")
    price: int = Field(description="鲜花的价格")
    description: str = Field(description="鲜花的描述文案")
    reason: str = Field(description="为什么要这样写这个文案")


# ------Part 3
# 创建输出解析器
from langchain.output_parsers import PydanticOutputParser

output_parser = PydanticOutputParser(pydantic_object=FlowerDescription)

# 获取输出格式指示
format_instructions = output_parser.get_format_instructions()
# 打印提示
print("输出格式:", format_instructions)


# ------Part 4
# 创建提示模板
from langchain import PromptTemplate

prompt_template = """您是一位专业的鲜花店文案撰写员。
对于售价为 {price} 元的 {flower} ,您能提供一个吸引人的简短中文描述吗?
{format_instructions}"""

# 根据模板创建提示,同时在提示中加入输出解析器的说明
prompt = PromptTemplate.from_template(
    prompt_template, partial_variables={"format_instructions": format_instructions}
)

# 打印提示
print("提示:", prompt)

# ------Part 5
for flower, price in zip(flowers, prices):
    # 根据提示准备模型的输入
    input = prompt.format(flower=flower, price=price)
    # 打印提示
    print("提示:", input)

    # 获取模型的输出
    output = model.predict(input)
    # 解析模型的输出
    parsed_output = output_parser.parse(output)
    parsed_output_dict = parsed_output.dict()  # 将Pydantic格式转换为字典

    # 将解析后的输出添加到DataFrame中
    df.loc[len(df)] = parsed_output.dict()

# 打印字典
print("输出的数据:", df.to_dict(orient="records"))