LangChain 结构化输出:用 Pydantic + PydanticOutputParser 驯服 LLM 的“自由发挥”
目录
一、Pydantic
二、PydanticOutputParser
1、为什么需要 PydanticOutputParser?
2、Pydantic和PydanticOutputParser核心区别
3、Pydantic的不足
(1)无法直接解析非结构化文本
(2)缺乏对 LLM 输出的适配性
(3)缺少格式指导生成
(4)错误处理不够场景化
4、PydanticOutputParser核心功能
5、实现结构化输出
三、为什么需要两者结合?
四、总结
先思考一个问题:为什么要使用结构化输出?
在LangChain中,结构化输出就像是让AI“说话有条理”。举个生活中的例子:
假设你让朋友推荐电影,普通回答可能是:“《星际穿越》不错,科幻片,诺兰拍的,有黑洞剧情。” 而结构化输出就像朋友递给你一张卡片:
{"电影名": "星际穿越","类型": "科幻","导演": "克里斯托弗·诺兰","关键词": ["黑洞", "时间膨胀", "亲情"]}
为什么需要这样?
-
机器好处理:就像快递分拣机只认条形码,程序处理这种整齐的数据比从大段文字里“猜”信息容易得多。
-
避免遗漏:提前说好要哪些信息(比如必须包含导演),AI就不会忘记回答。
-
方便对接:直接塞进数据库、生成图表,或者转发给其他系统,都不用人工整理
一、Pydantic
Pydantic 是一个用于 数据验证和设置 的 Python 库
它通过 类型注解 和 数据模型 的方式,简化了数据校验、转换和序列化的过程
Pydantic 的 BaseModel 类允许我们定义数据模型(如 Author、Book、Library),并自动处理数据的验证和转换。这确保了输入和输出的数据符合预期的格式和类型要求
主要用于:
- 确保输入数据符合预定义的结构和约束。
- 将数据转换为标准化的格式(如字典、JSON)。
- 与框架(如 FastAPI)深度集成,简化 API 开发。
核心功能:
- 数据验证:基于 Python 的类型注解自动校验数据。
- 类型转换:将输入数据转换为定义的类型(如
str转int)。 - 结构化输出:将模型转换为字典或 JSON。
- 错误处理:提供清晰的错误信息,便于调试
二、PydanticOutputParser
PydanticOutputParser 是LangChain库中的一个工具,用于语言模型生成输出解析并转换为结构化的Python数据模型
通过PydanticOutputParser,Pydantic 可以直接用于解析来自语言模型的输出,将其转换为预定义的 Pydantic 数据模型。这种集成简化了将自然语言处理结果映射到结构化数据的过程
1、为什么需要 PydanticOutputParser?
既然 Pydantic 已经提供了强大的数据验证和结构化能力,为什么还要引PydanticOutputParser?关键在于 输入源的差异 和 使用场景的特殊性。
2、Pydantic和PydanticOutputParser核心区别
| 维度 | Pydantic | PydanticOutputParser |
|---|---|---|
| 输入类型 | 结构化数据(如字典、JSON) | 非结构化文本(如 LLM 的输出、自然语言) |
| 主要职责 | 数据校验、类型转换、序列化 | 解析自由文本为结构化数据 |
| 适用场景 | API 请求、配置文件加载、数据库交互 | 处理 LLM 输出、外部系统非标准响应 |
| 自动化程度 | 需手动转换输入数据到模型 | 自动提取文本中的结构化信息 |
3、Pydantic的不足
(1)无法直接解析非结构化文本
假设 LLM 输出以下文本:
用户信息:张三,年龄30岁,邮箱zhangsan@example.com。
Pydantic 无法直接将其转换为结构化模型,需手动编写文本提取和格式转换逻辑
(2)缺乏对 LLM 输出的适配性
问题:LLM 的输出具有 不确定性和模糊性,例如:
- 混合自然语言和 JSON(如
答案是:{ "name": "张三" })。 - 字段名称不匹配(如
user_namevsusername)。 - 格式错误(如未闭合的引号、缺少逗号)
LLM 可能返回以下有问题的 JSON:
{ "name": "张三, "age": "30" } // 引号未闭合,age 是字符串
Pydantic 会直接抛出错误,无法自动修复或提取有效部分
(3)缺少格式指导生成
问题:Pydantic 无法生成 针对 LLM 的格式指令,例如在提示(Prompt)中明确要求输出符合特定 JSON 结构。需开发者手动编写格式说明,增加维护成本
而PydanticOutputParser 的 get_format_instructions() 能根据 Pydantic 模型自动生成格式模板,直接嵌入到提示中,确保 LLM 按指定格式输出
(4)错误处理不够场景化
问题:Pydantic 的错误提示面向开发者,但未针对 LLM 输出场景优化。例如:
- 无法区分“字段缺失”和“LLM 未理解指令”。
- 缺少对 LLM 常见输出问题(如多余的解释文本)的容错。
若 LLM 返回以下文本:
回答:我不知道用户年龄,但名字是张三。
Pydantic 会直接报错,而无法提取部分有效信息(如 name)
4、PydanticOutputParser核心功能
(1) 结构化输出
将 非结构化文本(如 LLM 生成的自由格式文本或 JSON 字符串)转换为 结构化的 Pydantic 模型,使其符合预定义的数据格式和规则。
(2) 数据验证
在解析过程中,自动验证输出是否满足 Pydantic 模型定义的约束,例如:
- 类型校验(如
int、float、bool)。 - 范围限制(如数值范围、字符串长度)。
- 格式要求(如日期格式、邮箱格式)。
(3)错误处理
当输出不符合预期时,提供 详细的错误信息,帮助快速定位问题,例如:
- 字段缺失。
- 类型不匹配。
- 值超出范围。
5、实现结构化输出
这是一个 图书馆信息生成与结构化解析 的案例,目标是通过 LangChain 和 Pydantic 实现以下功能:
- 让 LLM 按指定格式生成图书馆信息(包含名称和书籍列表)。
- 将 LLM 的非结构化输出自动转换为强类型的 Python 对象。
- 确保数据格式正确(如作者年龄在 0-120 之间)。
from typing import Listfrom langchain_core.output_parsers import PydanticOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field# 定义作者模型:
class Author(BaseModel):name: str = Field(description='Name of the author')age: int = Field(description='Age of the author',ge=0, le=120)# 定义图书模型:
class Book(BaseModel):title: str = Field(description='python')author: Author = Field(description='echola')# 定义图书馆模型:
class Library(BaseModel):name: str = Field(description='History Library')books: List[Book] = Field(description='List of books')# 使用PydanticOutputParser解析输出,指定模型为Library
parser = PydanticOutputParser(pydantic_object=Library)# 定义提示模版,包含图书馆及图书的信息
prompt = PromptTemplate(# 提示的文本模版template="Provide information about a library an its book,\n{format_instructions}\n{library}",# 输入变量为libraryinput_variables=["library"],# 部分变量为格式说明partial_variables={"format_instructions": parser.get_format_instructions()}
)# 定义LLM
llm = ChatOpenAI(model='deepseek-ai/DeepSeek-R1',openai_api_key="sk-jcuzvtuophtzgkfhhbanhjgqfxviewqwnwyhkihsvwwoufsu",openai_api_base='https://api.siliconflow.cn/v1',temperature=0,max_tokens=1000
)# 格式化提示内容,传入查询内容"请描述图书馆的书籍“
message = prompt.format_prompt(library="请描述图书馆的书籍")
# 获取输出
# 解析模型输出为Library对象
result = llm.invoke(message)# 打印结果
print(result.content)
运行结果输出:
{"name": "History Library","books": [{"title": "python","author": {"name": "echola","age": 40}},{"title": "The Art of Programming","author": {"name": "John Code","age": 45}},{"title": "Data Science Essentials","author": {"name": "Alice Data","age": 38}}]
}
PromptTemplate 定义了一个模板,用于生成传递给 LLM 的输入提示。模板包含两个两个占位符变量部分:用户的查询(library)和格式化指令(format_instructions)
在实例化PromptTemplate类时将format_instructions作为partial_variables的一部分传入,如此便在原有的提示词模版中追加了format_instructions变量,这个变量是输出指令字符串
释义:
- library:是希望模型产生的列表主题
- format_instructions:是从输出解析器中获取的预设的输出指令
此处library变量就是"请描述图书馆的书籍",format_instructions的指令模型就是Library类
PydanticOutputParser用于将模型的文本解析为结构化的Library对象
三、为什么需要两者结合?
1. 场景互补
- Pydantic 解决“数据如何存储和使用”的问题,例如:
- 确保从数据库读取的数据符合模型。
- 验证 API 请求参数的合法性。
- PydanticOutputParser 解决“数据如何从非结构化来源提取”的问题,例如:
- 将用户自然语言指令(如“帮我订明天北京到上海的机票”)解析为结构化的预订请求。
- 处理外部 API 返回的半结构化文本(如混合了文本和 JSON 的响应)。
2、开发效率
- 减少胶水代码:若手动解析 LLM 输出,需编写大量字符串处理、类型转换和错误检查代码。PydanticOutputParser 将这些逻辑封装为通用工具。
- 统一错误处理:Pydantic 的校验错误与 PydanticOutputParser 的解析错误可统一捕获,简化异常处理流程。
3、动态适配
- 灵活应对 LLM 的不确定性:LLM 的输出可能不稳定(如偶尔遗漏字段或格式错误)。PydanticOutputParser 的解析逻辑能动态适配,结合重试机制(如 LangChain 的
RetryOutputParser)提高鲁棒性
四、总结
结构化输出的意义
- 对机器友好:程序无需从自由文本中“猜测”数据,直接按字段提取。
- 对系统友好:数据格式统一,便于跨模块传递(如存入数据库、生成报表、触发后续流程)。
- 对开发者友好:减少数据清洗代码,专注业务逻辑。
Pydantic + PydanticOutputParser 的协同价值
- 从自由到规范:将 LLM 的“自由发挥”转换为严格的结构化数据。
- 端到端校验:从输入解析到业务使用,全程保障数据质量。
- 标准化开发范式:为 NLP 任务提供可复用的数据管理方案。
通过两者的结合,开发者能更高效地构建基于 LLM 的智能应用,确保数据从输入到输出的全链路可控、可靠、可维护。
相关文章:
LangChain 结构化输出:用 Pydantic + PydanticOutputParser 驯服 LLM 的“自由发挥”
目录 一、Pydantic 二、PydanticOutputParser 1、为什么需要 PydanticOutputParser? 2、Pydantic和PydanticOutputParser核心区别 3、Pydantic的不足 (1)无法直接解析非结构化文本 (2)缺乏对 LLM 输出的适配性 …...
快速入手-基于Django-rest-framework的自身组件权限认证(九)
1、在对应的视图函数里增加认证(局部起作用,不全局生效) 导入类: from rest_framework.authentication import ( BasicAuthentication, SessionAuthentication, ) from rest_framework.permissions import IsAuthentica…...
【复活吧,我的爱机!】Ideapad300-15isk拆机升级:加内存条 + 换固态硬盘 + 换电源
写在前面:本博客仅作记录学习之用,部分图片来自网络,如需引用请注明出处,同时如有侵犯您的权益,请联系删除! 文章目录 前言升级成本升级流程电池健康度加内存条和换内存条光驱位加装机械硬盘更换电池重装系…...
基于Spring AI开发本地Jenkins MCP Server服务
前言 首先介绍下MCP是什么? MCP是由开发了 Claude 模型的 Anthropic 公司2024年11月提出并开源的一项开放标准,全称:Model Context Protocol,它是一个开放协议,它使 LLM 应用与外部数据源和工具之间的无缝集成成为可能…...
基于简单神经网络的线性回归
一、概述 本代码实现了一个简单的神经网络进行线性回归任务。通过生成包含噪声的线性数据集,定义一个简单的神经网络类,使用梯度下降算法训练网络以拟合数据,并最终通过可视化展示原始数据、真实线性关系以及模型的预测结果。 二、依赖库 …...
【nvidia】Windows 双 A6000 显卡双显示器驱动更新问题修复
问题描述:windows自动更新nvidia驱动会导致只检测得到一个A6000显卡。 解决方法 下载 A6000 驱动 572.83-quadro-rtx-desktop-notebook-win10-win11-64bit-international-dch-whql.exehttps://download.csdn.net/download/qq_18846849/90554276 不要直接安装。如…...
《SRv6 网络编程:开启IP网络新时代》第2章、第3章:SRv6基本原理和基础协议
背景 根据工作要求、本人掌握的知识情况,仅针对《SRv6 网络编程:开启IP网络新时代》书籍中涉及的部分知识点进行总结梳理,并与工作小组进行分享,不涉及对原作的逐字搬运。 问题 组内同事提出的问题:本文缺扩展头描述…...
如何将AI模型返回的字符串转为html元素?
场景: 接入deepseek模型的api到我们平台,返回的字符串需要做下格式化处理。 返回的数据是这样的: {"role": "assistant","content": "<think>\n嗯,用户问的是“星体是什么”。首先&am…...
Citus源码(1)分布式表行为测试
最近对citus的实现非常好奇,本篇对citus的行为做一些测试。本篇只测行为,不分析源码。后面会继续写一系列文章分析citus源码。 环境:3节点 PG17 with citus。 SELECT citus_set_coordinator_host(127.0.0.1, 3001); SELECT citus_add_node(1…...
装饰器模式与模板方法模式实现MyBatis-Plus QueryWrapper 扩展
pom <dependency><groupId>com.github.yulichang</groupId><artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 --> </dependency>MPJLambdaWrapperX /*** 拓展 MyBatis Plus Join QueryWrapper 类&…...
【PCIE711-214】基于PCIe总线架构的4路HD-SDI/3G-SDI视频图像模拟源
产品概述 PCIE711-214是一款基于PCIE总线架构的4路SDI视频模拟源。该板卡为标准的PCIE插卡,全高尺寸,适合与PCIE总线的工控机或者服务器,板载协议处理器,可以通过PCIE总线将上位机的YUV 422格式视频数据下发通过SDI接口播放出去&…...
突破反爬困境:SDK开发,浏览器模块(七)
声明 本文所讨论的内容及技术均纯属学术交流与技术研究目的,旨在探讨和总结互联网数据流动、前后端技术架构及安全防御中的技术演进。文中提及的各类技术手段和策略均仅供技术人员在合法与合规的前提下进行研究、学习与防御测试之用。 作者不支持亦不鼓励任何未经授…...
rce操作
Linux命令长度突破限制 源码 <?php $param $_REQUEST[param];if ( strlen($param) < 8 ) {echo shell_exec($param); } echo执行函数,$_REQUEST可以接post、get、cookie传参 源码中对参数长度做了限制,小于8位,可以利用临时函数&…...
LabVIEW高效溢流阀测试系统
开发了一种基于LabVIEW软件和PLC硬件的溢流阀测试系统。通过集成神经网络优化的自适应PID控制器,该系统能自动进行压力稳定性、寿命以及动静态性能测试。该设计不仅提升了测试效率,还通过智能化控制提高了数据的精确性和操作的便捷性。 项目背景&…...
Spring Boot 中 JdbcTemplate 处理枚举类型转换 和 减少数据库连接的方法 的详细说明,包含代码示例和关键要点
以下是 Spring Boot 中 JdbcTemplate 处理枚举类型转换 和 减少数据库连接的方法 的详细说明,包含代码示例和关键要点: 一、JdbcTemplate 处理枚举类型转换 1. 场景说明 假设数据库存储的是枚举的 String 或 int 值,但 Java 实体类使用 enu…...
DataGear 5.3.0 制作支持导出表格数据的数据可视化看板
DataGear 内置表格图表底层采用的是DataTable表格组件,默认并未引入导出数据的JS支持库,如果有导出表格数据需求,则可以在看板中引入导出相关JS支持库,制作具有导出CSV、Excel、PDF功能的表格数据看板。 在新发布的5.3.0版本中&a…...
Web网页内嵌 Adobe Pdf Reader 谷歌Chrome在线预览编辑PDF文档
随着数字化办公的普及,PDF文档已成为信息处理的核心载体,虽然桌面端有很多软件可以实现预览编辑PDF文档,而在线在线预览编辑PDF也日益成为一个难题。 作为网页内嵌本地程序的佼佼者——猿大师中间件,之前发布的猿大师办公助手&am…...
歌词json
绽放(4:17) {"lyrics": [{time: 00:00, text: 作词:郑润泽},{time: 00:01, text: 作曲:郑润泽},{time: 00:02, text: 编曲:赵建飞},{time: 00:03, text: 制作人:李淘/赵建飞},{time: 00:09, tex…...
CNG汽车加气站操作工备考真题及答案解析【判断题】
1、燃气经营许可证按照燃气经营规模和类别实行分级审批。(√) 解析:不同规模和类别的燃气经营,其许可证审批级别不同,以确保经营活动的规范和安全。 2、依照《安全生产法》的规定,安全生产监督检查人员对检…...
Sentinel[超详细讲解]-1
定义一系列 规则 👺,对资源进行 保护 👺, 如果违反的了规则,则抛出异常,看是否有fallback兜底处理,如果没有则直接返回异常信息😎 1. 快速入门 1.1 引入 Sentinel 依赖 <depend…...
CUDA专题8—CUDA L2缓存完全指南:从持久化策略到性能优化实战
1. 设备内存L2缓存访问管理 当CUDA内核反复访问全局内存中的某个数据区域时,此类数据访问可视为持久化(persisting)访问。反之,若数据仅被访问一次,则可视为流式(streaming)访问。 从CUDA 11.0开始,计算能力8.0及以上的设备能够调控L2缓存中数据的持久性,从而可能实现更…...
如何让 SQL2API 进化为 Text2API:自然语言生成 API 的深度解析?
在过去的十年里,技术的进步日新月异,尤其是在自动化、人工智能与自然语言处理(NLP)方面。 随着“低代码”平台的崛起,开发者和非技术人员能够更轻松地构建强大而复杂的应用程序。然而,尽管技术门槛降低了&…...
OCCT(2)Windows平台编译OCCT
文章目录 一、Windows平台编译OCCT1、准备环境2、下载源码3、下载第三方库4、使用 CMake 配置5、编译OCCT源码6、运行示例 一、Windows平台编译OCCT 1、准备环境 安装工具: Visual Studio(推荐 VS2019/2022,选择 C 桌面开发 组件࿰…...
【蓝桥杯—单片机】通信总线专项 | 真题整理、解析与拓展 (更新ing...)
通信总线专项 前言SPI第十五届省赛题 UART/RS485/RS232UARTRS485RS232第十三届省赛题小结和拓展:传输方式的分类第十三届省赛 其他相关考点网络传输速率第十五届省赛题第十二届省赛题 前言 在本文中我会把 蓝桥杯单片机赛道 历年真题 中涉及到通信总线的题目整理出…...
【Golang】泛型与类型约束
文章目录 一、环境二、没有泛型的Go三、泛型的优点四、理解泛型(一)定义(二)调用(三)类型约束(Type Constraint)1)接口与约束2)结构体类型约束3)类…...
Uni-app页面信息与元素影响解析
获取窗口信息uni.getWindowInfo {pixelRatio: 3safeArea:{bottom: 778height: 731left: 0right: 375top: 47width: 375}safeAreaInsets: {top: 47, left: 0, right: 0, bottom: 34},screenHeight: 812,screenTop: 0,screenWidth: 375,statusBarHeight: 47,windowBottom: 0,win…...
CentOS(最小化)安装之后,快速搭建Docker环境
本文以VMware虚拟机中安装最小化centos完成后开始。 1. 检查网络 打开网卡/启用网卡 执行命令ip a查看当前的网络连接是否正常: 如果得到的结果和我一样,有ens网卡但是没有ip地址,说明网卡未打开 手动启用: nmcli device sta…...
【身份证证件OCR识别】批量OCR识别身份证照片复印件图片里的文字信息保存表格或改名字,基于QT和腾讯云api_ocr的实现方式
项目背景 在许多业务场景中,需要处理大量身份证照片复印件,手动输入其中的文字信息效率低下且容易出错。利用 OCR(光学字符识别)技术可以自动识别身份证图片中的文字信息,结合 QT 构建图形用户界面,方便用户操作,同时使用腾讯 OCR API 能够保证较高的识别准确率。 界面…...
IP属地和发作品的地址不一样吗
在当今这个数字化时代,互联网已经成为人们日常生活不可或缺的一部分。随着各大社交平台功能的不断完善,一个新功能——IP属地显示,逐渐走进大众视野。这一功能在微博、抖音、快手等各大平台上得到广泛应用,旨在帮助公众识别虚假信…...
Redis - 概述
目录 编辑 一、什么是redis 二、redis能做什么(有什么特点)? 三、redis有什么优势 四、Redis与其他key-value存储有什么不同 五、Redis命令 六、Redis数据结构 1、基础数据结构 2、高级数据结构 一、什么是redis 1、redis&#x…...
