【LangChain学习之旅】—(8) 输出解析:用OutputParser生成鲜花推荐列表

【LangChain学习之旅】—(8) 输出解析:用OutputParser生成鲜花推荐列表

  • LangChain 中的输出解析器
  • Pydantic(JSON)解析器实战
    • 第一步:创建模型实例
    • 第二步:定义输出数据的格式
    • 第三步:创建输出解析器
  • 第四步:创建提示模板

Reference:LangChain 实战课

LangChain 中的输出解析器

语言模型输出的是文本,这是给人类阅读的。但很多时候,你可能想要获得的是程序能够处理的结构化信息。这就是输出解析器发挥作用的地方。

输出解析器是一种专用于处理和构建语言模型响应的类。一个基本的输出解析器类通常需要实现两个核心方法。

  • get_format_instructions:这个方法需要返回一个字符串,用于指导如何格式化语言模型的输出,告诉它应该如何组织并构建它的回答。
  • parse:这个方法接收一个字符串(也就是语言模型的输出)并将其解析为特定的数据结构或格式。这一步通常用于确保模型的输出符合我们的预期,并且能够以我们需要的形式进行后续处理。

还有一个可选的方法。

  • parse_with_prompt:这个方法接收一个字符串(也就是语言模型的输出)和一个提示(用于生成这个输出的提示),并将其解析为特定的数据结构。这样,你可以根据原始提示来修正或重新解析模型的输出,确保输出的信息更加准确和贴合要求。

下面是一个基于上述描述的简单伪代码示例:

class OutputParser:def __init__(self):passdef get_format_instructions(self):# 返回一个字符串,指导如何格式化模型的输出passdef parse(self, model_output):# 解析模型的输出,转换为某种数据结构或格式passdef parse_with_prompt(self, model_output, prompt):# 基于原始提示解析模型的输出,转换为某种数据结构或格式pass

在 LangChain 中,通过实现 get_format_instructions、parseparse_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):这个解析器用于在模型的初次输出不符合预期时,尝试修复或重新生成新的输出。例如,如果模型的输出应该是一个日期,但是模型返回了一个字符串,那么重试解析器可以重新提示模型生成正确的日期格式。

上面的各种解析器中,前三种很容易理解,而结构化输出解析器你已经用过了。所以接下来我们重点讲一讲 Pydantic(JSON)解析器、自动修复解析器和重试解析器。

Pydantic(JSON)解析器实战

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

Pydantic 是一个 Python 数据验证和设置管理库,主要基于 Python 类型提示。尽管它不是专为 JSON 设计的,但由于 JSON 是现代 Web 应用和 API 交互中的常见数据格式,Pydantic 在处理和验证 JSON 数据时特别有用。
在这里插入图片描述

第一步:创建模型实例

先通过环境变量设置 OpenAI API 密钥,然后使用 LangChain 库创建了一个 OpenAI 的模型实例。这里我们仍然选择了 text-davinci-003 作为大语言模型。

# ------Part 1
# 设置OpenAI API密钥
import os
os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key'# 创建模型实例
from langchain import OpenAI
model = OpenAI(model_name='text-davinci-003')

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

先创建了一个空的 DataFrame,用于存储从模型生成的描述。接下来,通过一个名为 FlowerDescription 的 Pydantic BaseModel 类,定义了期望的数据格式(也就是数据的结构)。

# ------Part 2
# 创建一个空的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 库来创建带有类型注解的类 FlowerDescription,它可以自动验证输入数据,确保输入数据符合你指定的类型和其他验证条件。

Pydantic 有这样几个特点。

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

第三步:创建输出解析器

在这一步中,我们创建输出解析器并获取输出格式指示。先使用 LangChain 库中的 PydanticOutputParser 创建了输出解析器,该解析器将用于解析模型的输出,以确保其符合 FlowerDescription 的格式。然后,使用解析器的 get_format_instructions 方法获取了输出格式的指示。

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

程序输出如下:

输出格式: The output should be formatted as a JSON instance that conforms to the JSON schema below.As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}}
the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.Here is the output schema:{"properties": {"flower_type": {"title": "Flower Type", "description": "\u9c9c\u82b1\u7684\u79cd\u7c7b", "type": "string"}, "price": {"title": "Price", "description": "\u9c9c\u82b1\u7684\u4ef7\u683c", "type": "integer"}, "description": {"title": "Description", "description": "\u9c9c\u82b1\u7684\u63cf\u8ff0\u6587\u6848", "type": "string"}, "reason": {"title": "Reason", "description": "\u4e3a\u4ec0\u4e48\u8981\u8fd9\u6837\u5199\u8fd9\u4e2a\u6587\u6848", "type": "string"}}, "required": ["flower_type", "price", "description", "reason"]}

上面这个输出,这部分是通过output_parser.get_format_instructions()方法生成的,这是 Pydantic (JSON) 解析器的核心价值,值得你好好研究研究。同时它也算得上是一个很清晰的提示模板,能够为模型提供良好的指导,描述了模型输出应该符合的格式。(其中 description 中的中文被转成了 UTF-8 编码。)

它指示模型输出 JSON Schema 的形式,定义了一个有效的输出应该包含哪些字段,以及这些字段的数据类型。例如,它指定了 "flower_type" 字段应该是字符串类型,"price" 字段应该是整数类型。这个指示中还提供了一个例子,说明了什么是一个格式良好的输出。

下面,我们会把这个内容也传输到模型的提示中,让输入模型的提示和输出解析器的要求相互吻合,前后就呼应得上。

第四步:创建提示模板

# ------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)

输出:

提示: 
input_variables=['flower', 'price'] output_parser=None partial_variables={'format_instructions': 'The output should be formatted as a JSON instance that conforms to the JSON schema below.\n\n
As an example, for the schema {
"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, 
"required": ["foo"]}}\n
the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. 
The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.\n\n
Here is the output schema:\n```\n
{"properties": {
"flower_type": {"title": "Flower Type", "description": "\\u9c9c\\u82b1\\u7684\\u79cd\\u7c7b", "type": "string"}, 
"price": {"title": "Price", "description": "\\u9c9c\\u82b1\\u7684\\u4ef7\\u683c", "type": "integer"}, 
"description": {"title": "Description", "description": "\\u9c9c\\u82b1\\u7684\\u63cf\\u8ff0\\u6587\\u6848", "type": "string"}, 
"reason": {"title": "Reason", "description": "\\u4e3a\\u4ec0\\u4e48\\u8981\\u8fd9\\u6837\\u5199\\u8fd9\\u4e2a\\u6587\\u6848", "type": "string"}}, 
"required": ["flower_type", "price", "description", "reason"]}\n```'} template='您是一位专业的鲜花店文案撰写员。
\n对于售价为 {price} 元的 {flower} ,您能提供一个吸引人的简短中文描述吗?\n
{format_instructions}' template_format='f-string' validate_template=True

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/619948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

运算电路(1)——加法器

一、引言 微处理器是由一片或少数几片大规模集成电路组成的中央处理器。这些电路执行控制部件和算术逻辑部件的功能。微处理器能完成取指令、执行指令,以及与外界存储器和逻辑部件交换信息等操作,是微型计算机的运算控制部分。它可与存储器和外围电路芯片…

Zabbix监控系统及部署

目录 前言 一个完整的项目 业务架构 运维架构 优秀监控软件的好处 1.zabbix概述 zabbix是什么 zabbix监控原理 Zabbix6.0新特性 1.Zabbix server高可用防止硬件故障或计划维护期的停机 2.Zabbix6.0 LTS新增Kubernetes监控功能,可以在Kubernetes系统从多个…

前端工程化相关

工具方法: 知道软件包名,拿到源码或者路径的方法 在浏览器输入以下内容,就可以找到你想要的。。。 unpkg.com/输入包名 一、模块化 ESM特性清单: 自动采取严格模式,忽略“use strict”每个ESM模块都是单独的私有作用…

网络——华为与华三

作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 公众号:网络豆云计算学堂 座右铭:低头赶路,敬事如仪 个人主页: 网络豆的主页​​​​​ 写在前面 大家好,我是网络豆&#xff0…

Elasticsearch:是时候离开了! - 在 Elasticsearch 文档上使用 TTL

作者:来自 Elastic David Pilato 想象一下,圣诞老人必须向世界上所有的孩子们分发礼物。 他有很多工作要做,他需要保持高效。 他有一份所有孩子的名单,并且知道他们住在哪里。 他很可能会将礼物按区域分组,然后再交付。…

docker部署ng实现反向代理

场景 按规定尽可能减少开放到外网的端口,所以需要将多个服务部署到一个ip一个端口上。 方案 使用ng实现请求转发。根据http请求中的host与ng配置文件中的server_name匹配,转发到对应的机器上。 在docker上部署三个容器,每个容器中启动一个…

Java内存模型之可见性

文章目录 1.什么是可见性问题2.为什么会有可见性问题3.JMM的抽象:主内存和本地内存3.1 什么是主内存和本地内存3.2 主内存和本地内存的关系 4.Happens-Before原则4.1 什么是Happens-Before4.2 什么不是Happens-Before4.3 Happens-Before规则有哪些4.4 演示&#xff…

【SQL注入】SQLMAP v1.7.11.1 汉化版

下载链接 【SQL注入】SQLMAP v1.7.11.1 汉化版 简介 SQLMAP是一款开源的自动化SQL注入工具,用于扫描和利用Web应用程序中的SQL注入漏洞。它在安全测试领域被广泛应用,可用于检测和利用SQL注入漏洞,以验证应用程序的安全性。 SQL注入是一种…

调试(c语言)

前言: 我们在写程序的时候可能多多少少都会出现一些bug,使我们的程序不能正常运行,所以为了更快更好的找到并修复bug,使这些问题迎刃而解,学习好如何调试代码是每个学习编程的人所必备的技能。 1. 什么是bug&#xf…

Java项目:06 Springboot的进销存管理系统

作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 进销存管理系统 介绍 进销存系统是为了对企业生产经营中进货、出货、批发销售、付款等全程进行(从接获订单合同开 始,进入物料采购、入…

浅析Linux进程地址空间

前言 现代处理器基本都支持虚拟内存管理,在开启虚存管理时,程序只能访问到虚拟地址,处理器的内存管理单元(MMU)会自动完成虚拟地址到物理地址的转换。基于虚拟内存机制,操作系统可以为每个运行中的进程创建…

ros2+gazebo(ign)激光雷达+摄像头模拟

虽然ign不能模拟雷达,但是摄线头是可以模拟的。 好了现在都不用模拟了,ign摄线头也模拟不了。 ros2ign gazebo无法全部模拟摄线头和雷达。 只能有这样2个解决方法: 方法1:使用ros2 gazebo11 方案2:使用ros2买一个实…

【问题探讨】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究

目录 主要内容 模型研究 结果一览 下载链接 主要内容 该模型以环境保护成本和运行成本为双目标构建了微电网优化调度模型,模型目标函数和约束条件复现文献《基于改进粒子群算法的微电网多目标优化调度》,程序的特点是采用非支配排序的蜣螂…

Redis缓存使用问题

数据一致性 只要使用到缓存,无论是本地内存做缓存还是使用 redis 做缓存,那么就会存在数据同步的问题。 以 Tomcat 向 MySQL 中写入和删改数据为例,来解释数据的增删改操作具体是如何进行的。 我们分析一下几种解决方案, 1、先更新缓存,再更新数据库 2、先更新数据库,…

2023年第十四届中国数据库技术大会(DTCC2023):核心内容与学习收获(附大会核心PPT下载)

随着信息化时代的深入发展,数据库技术作为支撑信息化应用的核心技术,其重要性日益凸显。本次大会以“数据价值,驱动未来”为主题,聚焦数据库领域的前沿技术与最新动态,吸引了数千名业界专家、企业代表和数据库技术爱好…

橘子学Spring01之spring的那些工厂和门面使用

一、Spring的工厂体系 我们先来说一下spring的工厂体系(也称之为容器),得益于大佬们对于单一职责模式的坚决贯彻,在十几年以来spring的发展路上,扩展出来大量的工厂类,每一个工厂类都承担着自己的功能(其实就是有对应的方法实现)…

阿里云云服务器u1实例和e实例有什么区别?

阿里云服务器u1和e实例有什么区别?ECS通用算力型u1实例是企业级独享型云服务器,ECS经济型e实例是共享型云服务器,所以相比较e实例,云服务器u1性能更好一些。e实例为共享型云服务器,共享型实例采用非绑定CPU调度模式&am…

监督学习 - 岭回归(Ridge Regression)

什么是机器学习 岭回归(Ridge Regression)是一种线性回归的扩展,它通过在损失函数中添加正则化项(L2范数)来解决线性回归中可能存在的过拟合问题。正则化项有助于限制模型的参数,使其不过分依赖于训练数据…

LeetCode264. 丑数 II(相关话题:多重指针动态规划)

题目描述 给你一个整数 n ,请你找出并返回第 n 个 丑数 。丑数 就是质因子只包含 2、3 和 5 的正整数。 示例 1: 输入:n 10 输出:12 解释:[1, 2, 3, 4, 5, 6, 8, 9, 10, 12] 是由前 10 个丑数组成的序列。示例 2&am…

【Sharding-Sphere 整合SpringBoot】

Sharding-Jdbc在3.0后改名为Sharding-Sphere。Sharding-Sphere相关资料,请自行网上查阅,这里仅仅介绍了实战相关内容,算是抛砖引玉。 Sharding-Sphere 整合SpringBoot 一、项目准备二、项目实战1. pom.xml及application.yml2. OrderInfoCont…