LangChain结构化输出:Pydantic与JSON解析器实战
1. 为什么需要模型返回结构化数据在自然语言处理的实际应用中我们经常会遇到这样的场景模型输出的文本内容需要被后续程序解析和处理。比如你问模型明天北京的天气如何理想的回答可能是{ city: 北京, date: 2023-11-20, weather: 晴, temperature: { high: 15, low: 5 } }而不是一段自由文本明天北京天气晴朗最高气温15度最低气温5度。后者虽然对人类友好但程序需要额外编写复杂的解析逻辑才能提取关键信息。1.1 结构化数据的优势结构化数据相比自由文本有几个显著优势程序可读性JSON/YAML等格式可以直接被各种编程语言解析数据一致性固定字段确保每次返回的数据结构相同接口标准化便于不同系统间的数据交换类型安全可以定义字段的数据类型减少错误1.2 LangChain中的结构化输出LangChain提供了几种实现结构化输出的方式Pydantic输出解析器利用Python的类型提示系统JSON输出解析器直接返回JSON格式自定义解析器针对特定需求定制提示选择哪种方式取决于你的具体需求。Pydantic适合Python项目JSON更通用自定义解析器灵活性最高但开发成本也最高。2. 使用Pydantic实现结构化输出Pydantic是Python中用于数据验证和设置管理的库LangChain内置了对Pydantic的支持。2.1 定义输出模型首先需要定义一个Pydantic模型来描述你期望的数据结构from pydantic import BaseModel, Field class WeatherInfo(BaseModel): city: str Field(description城市名称) date: str Field(description日期格式为YYYY-MM-DD) weather: str Field(description天气状况) temperature: dict Field(description温度信息包含最高和最低温度) class Config: schema_extra { example: { city: 北京, date: 2023-11-20, weather: 晴, temperature: {high: 15, low: 5} } }2.2 创建解析器并绑定到链from langchain.output_parsers import PydanticOutputParser from langchain.prompts import PromptTemplate from langchain.llms import OpenAI # 创建解析器 parser PydanticOutputParser(pydantic_objectWeatherInfo) # 创建提示模板 prompt PromptTemplate( template回答用户问题。\n{format_instructions}\n问题{query}\n, input_variables[query], partial_variables{format_instructions: parser.get_format_instructions()} ) # 创建链 model OpenAI(temperature0) chain prompt | model | parser # 执行查询 result chain.invoke({query: 明天北京的天气如何}) print(result)2.3 关键参数解析temperature0设置为0确保输出确定性高适合结构化数据get_format_instructions()自动生成模型的结构描述partial_variables将格式指令作为固定部分加入提示注意Pydantic模型中的Field描述很重要它们会被转换为模型的结构说明影响LLM的输出。3. JSON输出解析器实战如果你不需要Pydantic的验证功能或者需要与非Python系统交互JSON格式是更好的选择。3.1 基本使用from langchain.output_parsers import StructuredOutputParser, ResponseSchema from langchain.prompts import ChatPromptTemplate # 定义响应模式 response_schemas [ ResponseSchema(namecity, description城市名称), ResponseSchema(namedate, description日期), ResponseSchema(nameweather, description天气状况), ResponseSchema(nametemperature, description温度范围) ] # 创建解析器 parser StructuredOutputParser.from_response_schemas(response_schemas) # 创建提示 prompt ChatPromptTemplate.from_template( 回答关于天气的问题返回JSON格式。 {format_instructions} 问题{query} ) # 创建链 chain prompt | model | parser # 执行 result chain.invoke({ query: 明天上海的天气怎么样, format_instructions: parser.get_format_instructions() })3.2 高级配置# 自定义JSON格式 custom_parser StructuredOutputParser.from_response_schemas( response_schemas, json_pattern{ 回答: { 城市: ..., 日期: ..., 天气: ..., 温度: {最高: xx, 最低: xx} } } )3.3 处理复杂结构对于嵌套结构可以这样定义response_schemas [ ResponseSchema(namecity, description城市名称), ResponseSchema(namedate, description日期), ResponseSchema(nameweather, description天气状况), ResponseSchema( nametemperature, description温度信息, typeobject, schema{ high: {type: number, description: 最高温度}, low: {type: number, description: 最低温度} } ) ]4. 常见问题与解决方案4.1 模型不遵循格式现象返回自由文本而非指定格式解决方案加强提示词中的格式要求在示例中展示正确格式降低temperature值使用更强大的模型如GPT-4改进后的提示模板prompt PromptTemplate( template请严格按照指定格式回答问题。 格式要求 {format_instructions} 示例 问题明天北京的天气如何 回答 {{ city: 北京, date: 2023-11-20, weather: 晴, temperature: {{high: 15, low: 5}} }} 现在请回答 问题{query} 回答, input_variables[query], partial_variables{format_instructions: parser.get_format_instructions()} )4.2 字段缺失或错误现象缺少某些字段或字段值不符合预期解决方案在Pydantic模型中设置必填字段为字段添加更详细的描述使用try-catch处理解析错误from pydantic import validator class WeatherInfo(BaseModel): city: str date: str weather: str temperature: dict validator(date) def date_format(cls, v): if not re.match(r\d{4}-\d{2}-\d{2}, v): raise ValueError(日期格式必须是YYYY-MM-DD) return v4.3 处理多值返回有时一个问题需要返回多个结构化结果class WeatherInfoList(BaseModel): items: List[WeatherInfo] # 提示词中明确说明 prompt 返回以下城市未来三天的天气 {cities} 每个城市每天一个记录共{count}条记录。 {format_instructions}5. 性能优化技巧5.1 批量处理当需要处理多个相似查询时可以使用批量模式queries [北京天气, 上海天气, 广州天气] results chain.batch([{query: q} for q in queries])5.2 缓存结果对相同查询缓存结果from langchain.cache import InMemoryCache from langchain.globals import set_llm_cache set_llm_cache(InMemoryCache())5.3 流式处理对于大结构数据可以分段处理class ChunkedOutputParser(BaseOutputParser): def parse(self, text: str): # 实现分段解析逻辑 pass6. 高级应用场景6.1 动态结构根据输入动态确定输出结构def dynamic_schema(query): if 天气 in query: return WeatherInfo elif 股票 in query: return StockInfo else: return BaseModel parser PydanticOutputParser(pydantic_objectdynamic_schema(query))6.2 多模型协作让一个模型决定结构另一个模型填充内容# 第一步确定结构 schema_chain prompt | model | SchemaParser() # 第二步填充数据 data_chain prompt | model | DataParser()6.3 结合其他LangChain组件from langchain.chains import LLMChain from langchain.agents import Tool weather_tool Tool( nameWeather, funclambda x: chain.run(queryx), description获取天气信息输入格式城市名 天气 )在实际项目中我发现结构化输出特别适合以下场景构建问答系统API数据提取和标准化多步骤工作流中的数据传递需要精确解析的自动化任务一个实用的技巧是先让模型用自由文本回答再让另一个模型将其转换为结构化格式。这种方法结合了两种方式的优点在复杂场景下效果更好。

相关新闻

Python的包与依赖管理:从模块搜索到项目构建

Python的包与依赖管理:从模块搜索到项目构建

Python项目的规模增长到一定程度后,代码组织就不再是简单的“把文件放在一起”。模块导入、包结构、虚拟环境、依赖管理——这些问题从项目的早期阶段就开始出现,理解它们背后的机制有助于避免工程陷阱。一、模块搜索路径的机制与调试import语句执行时&a…

2026/10/27 3:17:37 阅读更多 →
TMS320VC5509A DSP外设接口时序详解:从MMC/SD到USB的硬件设计与调试

TMS320VC5509A DSP外设接口时序详解:从MMC/SD到USB的硬件设计与调试

1. 项目概述与核心价值 如果你正在基于德州仪器(TI)的TMS320VC5509A这款经典的定点数字信号处理器(DSP)进行嵌入式系统开发,尤其是在设计需要连接外部存储卡(如SD卡)或实现USB设备功能的项目时&…

2026/10/24 19:34:51 阅读更多 →
FastAdmin任意文件读取漏洞深度剖析与立体化防御实战

FastAdmin任意文件读取漏洞深度剖析与立体化防御实战

1. 项目概述:从一次应急响应说起那天晚上,我正打算关电脑,手机突然响了,是客户那边负责运维的老张。电话那头语气有点急,说他们一个面向公众的FastAdmin后台管理界面,好像被人“看”了,系统日志…

2026/10/26 9:54:53 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/25 22:36:10 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/26 4:52:12 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/26 5:00:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/26 3:16:46 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 13:21:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →