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

当大模型产生输出返回后,它的内容更像是一段平铺的文字没有结构。在传给下游节点处理时可能并不能符合输入要求,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 Ollamamodel = 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 | parseprint(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。 可选。@propertydef _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.rhkb.cn/news/362346.html

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

相关文章

Ngnix内存池——高并发实现高效内存管理

目录 一、高并发下传统方式的弊端 1、常用的内存操作函数 2、弊端一 3、弊端二 4、弊端三 5、弊端四 二、弊端解决之道 1、内存管理维度分析 2、内存管理组件选型 三、高并发内存管理最佳实践 1、内存池技术 2、内存池如何解决弊端 3、高并发内存池如何实现 四、…

Vue 学习之 axios

目录 执行安装命令:npm install axios 使用的时候导入 axios以data,params,headers传参方式的区别 axios封装 是一个基于 promise 的 网络请求库,作用于浏览器和 node.js 中。使用Axios可以在前端项目中发送各种方式的HTTP请求…

最新AI智能聊天对话问答系统源码(图文搭建部署教程)+AI绘画,文生图,TTS语音识别输入,文档分析

一、人工智能语言模型和AI绘画在多个领域广泛应用 人工智能语言模型和AI绘画在多个领域都有广泛的应用。以下是一些它们的主要用处: 人工智能语言模型 内容生成 写作辅助:帮助撰写文章、博客、报告、剧本等。 代码生成:自动生成或补全代码&…

迭代器模式观察者模式

文章目录 1.引出迭代器模式1.展示院系结构2.传统方式 2.迭代器模式解决院系结构展示问题1.基本介绍2.原理类图3.类图4.代码实现1.Department.java 存储信息的对象2.College.java 被迭代的类型接口3.ComputerCollege.java 被迭代的具体实现类,存储数据并将其在创建迭…

PAL: Program-aided Language Models

PAL: Program-aided Language Models ArXiv:https://arxiv.org/pdf/2211.10435 GitHub:https://reasonwithpal.com/ 一、动机 大模型与Chain-of-Thought可以很好地将一些复杂的问题分解为若干个子问题并进行逐步推理;但是对于一些较为复杂…

JavaScript算法之龟兔赛跑

简介:龟兔赛跑算法,又称弗洛伊德循环检测算法,是一种在链表中非常常用的算法。它基于运动学和直觉的基本定律。本文旨在向您简要介绍该算法,并帮助您了解这个看似神奇的算法。 假设高速公路上有两辆车。其中一辆的速度为 x,另一辆的速度为 2x。它们唯一能相遇的条件是它们…

个人支付系统实现

基础首页: 订单: 智能售卡系统 基于webmanworkerman开发 禁用函数检查 使用这个脚本检查是否有禁用函数。命令行运行curl -Ss https://www.workerman.net/check | php 如果有提示Function 函数名 may be disabled. Please check disable_functions in …

2024年6月17日~2024年6月26日周报

一、前言 在上周主要完成了可变形卷积的学习的部署。 本周,结合前段时间的工作与闵老师的讨论,思考了接下来的一些尝试方向。本周重新在之前的网络上尝试添加可变形卷积v4,或者将可变形卷积v2修改为可变形卷积v4。另外,继续学习了…

java中的Collections工具类

Collections类是java中提供的一个工具类,它和接口Collection乍一看非常相像,但是二者的区别是非常大的,最明显的就是它们一个是类,而另一个是接口了。Collections工具类的作用是对Set 、Map、 List这些容器提供辅助方法来对容器中…

Springboot + Mybatis-Plus代码生成指南

使用 Spring Boot 和 MyBatis-Plus 生成代码&#xff0c;可以大大简化开发流程&#xff0c;可以保持编码的规范性&#xff0c;生成单元测试等。以下是详细步骤&#xff1a; 配置pom.xml <dependency><groupId>com.baomidou</groupId><artifactId>myb…

4.1 四个子空间的正交性

一、四个子空间的正交性 如果两个向量的点积为零&#xff0c;则两个向量正交&#xff1a; v ⋅ w v T w 0 \boldsymbol v\cdot\boldsymbol w\boldsymbol v^T\boldsymbol w0 v⋅wvTw0。本章着眼于正交子空间、正交基和正交矩阵。两个子空间的中的向量&#xff0c;一组基中的向…

Python期末模拟题库[python123题库]

期末模拟题库 一、单项选择题 1、下列关于Python语言的特点的说法中&#xff0c;错误的是()‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪…

使用ESP32开发一款chat机器人

目的&#xff1a;使用语音对话的方式实现和ai机器人对话&#xff0c;核心硬件如下 主板&#xff1a; ESP32S3 语音&#xff08;拾音器-麦克风&#xff09;&#xff1a;INMP441全向麦克风模块 购买记录&#xff1a; https://oshwhub.com/shukkkk/esp32s3_tft_mp3

原创作品—医疗行业软件界面UI、交互设计

在医疗行业大屏UI设计中&#xff0c;首要的是以用户为中心&#xff0c;深入理解医生、护士、管理层等用户群体的具体需求和工作流程。大屏设计应直观展示关键医疗数据、患者信息、设备状态等&#xff0c;确保用户能够迅速、准确地获取所需信息。同时&#xff0c;功能布局应合理…

【6.26更新】Win11 23H2 22631.3810镜像:免费下载!

微软已发布六月最新的可选更新补丁KB5039302&#xff0c;用户安装后&#xff0c;系统版本将升级至22631.3810。此次更新将会逐步推出一些新功能&#xff0c;在“设置”主页上添加了新的Game Pass推荐卡&#xff0c;同时显示桌面按钮再次默认位于任务栏上。接下来小编给大家带来…

flash申请内存失败,导致老化问题解决

背景 在闪光灯初始化阶段客制化了一个buffer&#xff0c;下发到kernel的闪光灯驱动中用于保存读取闪光灯寄存器的值。功能测试都是正常的&#xff0c;但是一旦开始批量跑产线老化测试会有1/4500左右概率的后主摄拍照卡住。定位根因是闪光灯初始化失败&#xff0c;进一步原因就…

SherlockChain:基于高级AI实现的智能合约安全分析框架

关于SherlockChain SherlockChain是一款功能强大的智能合约安全分析框架&#xff0c;该工具整合了Slither工具&#xff08;一款针对智能合约的安全工具&#xff09;的功能&#xff0c;并引入了高级人工智能模型&#xff0c;旨在辅助广大研究人员针对Solidity、Vyper和Plutus智…

第六十九:iview 表格汇总怎么拿到传过来的数据,而不是自动累加,需要自定义方法

话不多少&#xff0c;先看官方解释 我这个简单&#xff0c;所以所有说明都在图上了 handleSummary({ columns, data }){console.log(columns, data)let sums {}columns.forEach((item,index)>{const key item.key;console.log("key",item)if(index 0){console.…

煤安防爆手机为什么能在煤矿井下使用

煤安防爆手机之所以能在煤矿井下使用&#xff0c;是因为它们经过特殊设计&#xff0c;符合严格的防爆安全标准&#xff0c;能够防止电火花引发爆炸&#xff0c;同时具备防尘防水、抗冲击等特性&#xff0c;确保在恶劣的煤矿环境中稳定可靠地运行&#xff0c;为工作人员提供安全…

【FFmpeg】avformat_open_input函数

【FFmpeg】avformat_open_input函数 1.avformat_open_input1.1 初始化输入格式&#xff08;init_input&#xff09;1.1.1 文件路径判断格式&#xff08;av_probe_input_format2&#xff09;1.1.1.1 格式探测&#xff08;read_probe&#xff09;1.1.1.2 扩展匹配检查&#xff08…