LangChain入门学习笔记(六)—— Model I/O之Output Parsers

news2024/11/25 6:43:40

当大模型产生输出返回后,它的内容更像是一段平铺的文字没有结构。在传给下游节点处理时可能并不能符合输入要求,LangChain提供了一套机制使得模型返回的内容可以按照开发者定义的那样结构化。

在官网文档中可以看到LangChain提供了丰富的输出解析器,涵盖了常用的一些格式。比如CSV、JSON、XML和YAML,也有一些跟模型提供商相关的特定解析工具,比如OpenAI Functions和OpenAI Tools。具体内容可以快速查看这里的表中内容。

快速开始

使用输出解析器的方法很简单,只需要两步:

  • 给出格式指令:给出语言模型输出应如何格式化的说明字符串。
  • 进行解析:对接受的字符串进行解析,成为符合某种结构的输出。

以JSON解析器(其他解析器使用方法类似,可以参看官方文档进行)为例,示例代码如下:

from langchain.output_parsers import PydanticOutputParser
from langchain_core.output_parsers import CommaSeparatedListOutputParser, JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field, validator
from langchain_community.llms import Ollama

model = Ollama(model="llama3", temperature=0.0)


# 定义输出格式的字段属性。
class Joke(BaseModel):
    setup: str = Field(description="question to set up a joke")
    punchline: str = Field(description="answer to resolve the joke")

    # 添加自定义的格式检查。
    @validator("setup")
    def validate_question_mark(cls, field):
        if field[-1] != "?":
            raise ValueError("Badly formed question!")
        return field


# 定义需要的输出解析器。
parser = JsonOutputParser(pydantic_object=Joke)

# 通过format_instructions输入格式化的指令。
prompt = PromptTemplate(
    template="Answer the user query.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

# LCEL组装带有输出解析器的chain,当chain被调用invoke后,parser最终按照格式解析后输出结果。
prompt_and_model = prompt | model | parser
output = prompt_and_model.invoke({"query": "Tell me a joke about bear."})
print(output)

首先,Joke类定义了输出内容的格式,其中指定了"setup"和"punchline"字段,以及提问时的格式校验。

其次,实例化JSON格式的输出解析器(JsonOutputParser)对象,指定格式为前面定义的Joke。

然后,在定义prompt时候传入format_instructions,指示后续的格式化形式。

最后,定义的chain中使用该parser。

我们可以看到输出为:

自定义输出解析器

如果觉得LangChain 提供的解析器武德不够充沛,可以自己动手打造自己专属的“武器”。LangChain提供了两种方法:

  • 使用RunnableLambda或者RunnableGenerator,这种方法简洁明了,推荐使用。
  • 从解析器基类继承编写新的类,相对比较复杂。

RunnableLambda/RunnableGenerator自定义解析

使用这个方法,我们定义自己的处理方法,接收某个输入,然后将其做对应转换后返回。以RunnableLambda为例如下:

from langchain_community.chat_models import ChatOllama
from langchain_core.messages import AIMessage
# from langchain_core.runnables import RunnableLambda


# 定义自己的解析方法
def parse(ai_message: AIMessage) -> str:
    # 传入AIMessage类型的参数,这是Chat Model的输出
    return ai_message.content.swapcase()


# 定义一个Chat Model
model = ChatOllama(model="llama3")

# LCEL定义一个chain
chain = model | parse

print(chain.invoke("hello"))

# output = model.invoke("hello")
#
# parse = RunnableLambda(parse)
# print(parse.invoke(output))

定义了自己的解析处理方法parse,注意它接受AIMessage类型的输入,这是Chat Model的输出类型,在model定义时我们使用了ChatOllama类型。它的输出给到parse解析得到最终输出,使用LCEL即是:

chain = model | parse

这里的LCEL将parse自动封装为RunnableLambda,可以理解这个操作如下面内容(注释部分):

output = model.invoke("hello")

parse = RunnableLambda(parse)
print(parse.invoke(output))

最终的输出:

将语言模型的输出结果进行了大小写调换。

继承解析基类

可以通过继承一个简单的定制化解析器类BaseOutputParser来自定义自己的解析器类。只需要重写parse方法,加入自己的解析逻辑即可。_type方法返回str类型信息,主要用于日志相关功能。使用自定义的解析器类对象,解析大模型的输出。如下代码所示:

from langchain_community.llms.ollama import Ollama
from langchain_core.output_parsers import BaseOutputParser


# 继承BaseOutputParser,定义parse和_type
class MyCustomOutputParser(BaseOutputParser[str]):

    # 自定义解析方法
    def parse(self, text: str) -> str:
        return text.swapcase()

    # 本自定义解析器类的type属性,用于Log。 可选。
    @property
    def _type(self) -> str:
        return "my_custom_parser"


# 定义一个LLM,返回str
model = Ollama(model="llama3")

# 初始化自定义的解析器对象
parser = MyCustomOutputParser()

# 调用自定义解析器进行解析
print(parser.invoke(model.invoke("hello")))

该自定义解析子类的方法,得到跟前面的RunnableLambda方法一样的结果。

也可以通过继承BaseGenerationOutputParser类来自定义自己的解析类,这样能够更好和更多地控制解析输出结果,比如对模型输出里的metadata内容进行解析。使用方法上和继承BaseOutputParser的方法大致相当,只是重写的方法是parse_result。有兴趣可以参考这里,不再赘述。

通过Model I/O的介绍,大家基本上可以写个简单的LLM应用了。通过prompt输入用户的提示语,经过LLMs/ChatModel处理后,输出结果通过Output Parser解析后最终返回用户一个期望格式的内容。

当然,为了LLM应用更好的结果,我们可能还需要提供更多的内容给到底层的大模型来处理,这就是“Retrieval”相关的内容了。

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

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

相关文章

Solana链,什么是sol跟单机器人、pump跟单机器人、sol狙击机器人、sol夹子机器人、sol聪明钱筛选

Solana Sol跟单机器人🤖 SOL跟单机器人(Copy Trading Bot)是一种自动化交易工具,允许用户复制其他成功交易者的交易行为。这种机器人通常用于加密货币市场、外汇市场等金融市场。以下是SOL跟单机器人的一些关键特性和功能&#xf…

优维“态势感知监控”产品:像“上帝”一样掌控应用系统

什么是态势感知? 态势感知是一种基于环境的、动态、整体地洞悉全网安全风险的能力。它以安全大数据为基础,从全局视角对全网安全威胁进行发现识别、理解分析展示和响应处置,并预测发展趋势,为后续网络安全的相关决策与行动提供数据…

重学java 81.类的加载时机

不破不立,人类最宝贝的品质就是勇敢和过去告别 —— 24.6.21 一、类的加载时机 1.new对象 2.new子类对象(new子类对象先初始化父类) 3.执行main方法 4.调用静态成员 5.反射,创建Class对象 这五种情况就可以让类加载到内存 类加载过程 1.问题:谁将class文件加载到了…

爬虫逆向实战(41)-某花顺登陆(Cookie、MD5、SHA256)

一、数据接口分析 主页地址:某花顺 1、抓包 通过抓包可以发现在登陆时,网站首先请求了pwdRangeCalcRegular.json、getGS两个接口,接着请求dologinreturnjson2进行登陆,但是此接口会返回请先完成滑块验证码校验的响应。然后网站…

U盘容量变0字节:详解原因、恢复方案与预防措施

一、U盘容量变0字节的现象 在日常工作和学习中,U盘作为一种便携式存储设备,被广泛用于数据交换和存储。然而,有时我们可能会遇到一种奇怪的现象:原本容量正常的U盘,在插入电脑后突然显示容量为0字节。这种情况意味着我…

unity-调用讯飞星火语音唤醒-新版windowsSDK

调用讯飞星火语音唤醒-新版windowsSDK 先贴一张在unity中 wins系统下成功调用新版的讯飞windowsSDK的运行截图 为什么要用讯飞的语音唤醒? 项目中需要在unity和win系统下进行语音唤醒开启语音对话,而语音唤醒比较成熟的方案大多都是在linux系统下的&…

CocosCreator 微信小游戏上架流程准备工作

前言 事前准备非常重要,因为有creator的助力,实际上开发小游戏往往很快,但是如果准备不足,上架及审核过程非常慢,往往游戏做好了,还得各种排队等审核,大多数开发者又不是腾讯白名单之内&#x…

甘肃的千层烤馍:传统面点的魅力绽放

千层烤馍,作为甘肃美食文化的重要象征,以其独特的外形和丰富的口感,吸引着众多食客。它的外观犹如一件精美的艺术品,层层叠叠,金黄酥脆,散发着诱人的香气。 在甘肃平凉地区制作千层烤馍&#xff0c…

windows10 编译libevent2.1.12

windows10 编译libevent2.1.12 nmake 编译libevent使用vs命令行工具2.编译命令3.编译出现问题 cmake 编译libevent nmake 编译libevent 使用vs命令行工具 2.编译命令 nmake /f Makefile.nmake3.编译出现问题 cmake 编译libevent cmake -S . -B build32 -A Win32 cd build32…

NXP i.MX8系列平台开发讲解 - 3.15 Linux 之USB子系统(一)

专栏文章目录传送门:返回专栏目录 Hi, 我是你们的老朋友,主要专注于嵌入式软件开发,有兴趣不要忘记点击关注【码思途远】 目录 Linux 之USB子系统(一) 1. USB基础简介 1.1 USB的传输模式 1.2 USB 的设备描述符 1.3 USB 类的定义分类 2…

IK分词器热刷新词库实践分享

目录 前言 什么是分词器? ik分词器简介 ik分词器和默认分词器的对比 ik分词器介绍 ik分词器的分词问题 自定义词库 主配置解说 通过配置文件自定义词库 Step1: 新建自定义分词库 Step2: 将我们的自定义词添加到ik的配置文件中 Step3: 重启es,…

DSP C6000教学实验箱操作教程_数字图像处理:5-3 图像缩放

一、实验目的 学习图像缩放的原理,掌握图像的读取方法,并实现图像缩放。 二、实验原理 图像缩放 在计算机图像处理和计算机图形学中,图像缩放是指对数字图像的大小进行调整的过程。图像缩放是一种非平滑的过程,需要在处理效率以…

通过“BOSS”精通比特币,深入认识私钥、账户和钱包

来源:币界原创 作者:636Marx 无论当今数字货币技术如何发展,认识区块链技术幕后的关键机制至关重要。无论您是新手还是经验丰富的数字货币从业者,掌握钱包地址、公钥和私钥的复杂性都有无可替代重要性。进入 BOSS Wallet,这是一款尖端的 Web…

Kubernates容器化JVM调优笔记(内存篇)

Kubernates容器化JVM调优笔记(内存篇) 先说结论背景思路方案 先说结论 1、首先如果是JDK8,需要使用JDK8_191版本以上,才支持容器化环境和以下参数,否则就更新到JDK10以上,选择对应的镜像构建就行了 2、在容…

day01-anaconda的安装

Anaconda的安装 参考地址: http://t.csdnimg.cn/mUmSp 安装完毕,可以卸载电脑中的其他python版本,在控制面板中进行卸载。 在命令行指令中输入 pythonPython 3.8.3 (default, Jul 2 2020, 17:30:36) [MSC v.1916 64 bit (AMD64)] :: An…

【React 】折叠面板,点击展开时再请求数据

需求背景:使用折叠面板的形式展示数据,面板内部数据需要在打开时请求接口获取。 遇到问题:最开始使用Antd 的折叠面板组件,它对于数据直接渲染是没问题的,但是不好满足打开面板时再动态加载数据的需求,于是…

兴业严选|朝阳、大兴、丰台、等5.9折起总有一套适合你~

近日于上海,出现了一桩令人始料未及之事。一套地处浦东、面积达 245.7 平方米的住宅进行挂网拍卖。 出乎意料的是,此套房子受到众多买家的青睐,历经一番激烈的竞价竞争,最终以 1766 万元的价格成交,折合每平方米 7187…

kakfa发版丢消息事件分析

背景 其他部门同事反馈在项目发版/重启(kill -15)的那段时间,经常会出现导致 C 端业务出现问题,从而产生资损 一听资损,赶紧应答下来,了解了下具体情况,然后立马去排查了 问题分析 结合同事的描述以及对业务的了解&a…

8小时出500杯,投诉三次辞退?Manner逼疯员工…?

一边歇斯底里的咆哮:「你投诉啊」!一边将咖啡粉泼向顾客……一场大战要不是隔着岛台,就真的燃起来了……‍ 好巧不巧,同一天,另一段视频中的顾客就没那么好运了,男店员冲上去就给女顾客一个耳光……‍‍ 想…

【ai】tx2-nx 开通samba

ubutn服务器加入了samba给jetson也加入一个samba 添加root用户 密码与nvidia一样 添加nvidia 到suoders中并添加samba账号 nvidia@tx2-nx:~$ nvidia@tx2-nx:~$ nvidia@tx2-nx:~$ nvidia@tx2-nx:~$ sudo vi /etc/sudoers nvidia@tx2-nx:~$ sudo chm