news 2026/7/24 18:02:38

OH My GOD!让AI直接返回JSON,这个技巧早该学会了(四)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OH My GOD!让AI直接返回JSON,这个技巧早该学会了(四)

——别再让模型说废话了,结构化输出才是生产环境的唯一标准!

一个被低估的真相

前面我们把模型调用和 Prompt 模板都讲完了。但有个问题一直憋着没说——

模型吐出来的永远是自然语言。

比如你让它提取简历信息,它给你一段流畅的中文:

“张伟,拥有 5 年 Python 开发经验,目前担任算法工程师……”

人看着舒服,但程序怎么处理?

写正则去匹配?换份简历格式就全崩。用大模型做 NER?那叫脱裤子放屁。

程序要的是这个:

{ "name": "张伟", "years_of_experience": 5, "skills": ["Python"], "position": "算法工程师" }

直接入库、直接调接口、直接做逻辑判断——这才是程序该处理的数据形态。

今天只说三件事,不绕弯子:

  1. StrOutputParser到底是不是多余的设计

  2. PydanticOutputParser如何把模型的“自由发挥”压到最低

  3. with_structured_output怎么用一行代码搞定结构化输出

第一件事:StrOutputParser,管道里的“隐形螺丝”

很多人觉得这玩意儿多余——model.invoke()返回AIMessage,直接.content拿字符串不就行了?

单次调用确实没区别。

但一旦上了 LangChain 的管道语法|,区别就出来了。

管道要求链上的每一个组件都必须是Runnable——prompt是,model是,但AIMessage不是。你在管道末尾直接挂一个AIMessage,链条当场断掉。

StrOutputParser本身是Runnable,它只做一件事:把AIMessage转成字符串,让管道顺畅跑完。

结论很直白:不用管道,它确实多余;但只要构建链式调用,它就是那个“没它不行”的标配。


第二件事:PydanticOutputParser,结构化输出的核心武器

先定义一个 Pydantic 模型:

from pydantic import BaseModel, Field class ResumeInfo(BaseModel): name: str = Field(description="候选人姓名") years_of_experience: int = Field(description="工作年限") skills: list[str] = Field(description="技能列表")

注意,Field里的description不是装饰性的注释——它会直接拼进 Prompt,告诉模型“你必须按这些字段输出,别自己发挥”。

创建 Parser 并拿到格式指令:

parser = PydanticOutputParser(pydantic_object=ResumeInfo) format_instructions = parser.get_format_instructions()

format_instructions是一段 JSON Schema,精确描述了每个字段的类型、含义和约束。你要把它塞进 Prompt 里,让模型明确知道输出边界。

完整链路长这样:

template = ChatPromptTemplate.from_messages([ ("system", "提取简历信息,{format_instructions}"), ("human", "{resume_text}") ]) prompt = template.invoke({ "resume_text": "张伟,5年Python经验,算法工程师", "format_instructions": parser.get_format_instructions() }) response = model.invoke(prompt) result = parser.invoke(response) print(result.name) # 直接取属性,不用字符串解析 print(result.years_of_experience) # 5

这条链路的精髓在于四步闭环

Parser 生成格式说明 → 注入 Prompt → 模型按格式输出 JSON → Parser 把 JSON 转成 Pydantic 对象

模型的自由发挥空间被压缩到最小,输出质量从“看运气”变成“可预期”。


第三件事:with_structured_output,新版本的一行流

如果你用的是新版 LangChain,且模型本身支持结构化输出,有更狠的方式——

from typing import Literal class ReviewAnalysis(BaseModel): sentiment: Literal["正面", "中性", "负面"] = Field(description="情感倾向") rating: int = Field(description="评分", ge=1, le=5) keywords: list[str] = Field(description="关键词") structured_model = model.with_structured_output(ReviewAnalysis, method="json_mode") result = structured_model.invoke("这手机续航太差了") print(result.sentiment) # "负面" print(result.rating) # 2

⚠️ 特别注意method="json_mode"——如果你用的是 DeepSeek 但不加这个参数,直接报错。这是很多人的踩坑点。

底层发生了什么?

模型输出合法 JSON → LangChain 内部自动解析 → 实例化成 Pydantic 对象。

你拿到手就是类型安全的对象,全程感受不到 JSON 字符串的存在。不需要手动json.loads(),不需要try-except解析,不需要字段名映射——全给你封装好了。


两种方式,怎么选?

方式优势适用场景
PydanticOutputParser链路透明,每一步都可见可干预理解原理、调试排查、老项目维护
with_structured_output代码极简,开发效率高新项目快速落地、模型能力较新

实操建议:先用PydanticOutputParser把逻辑跑通,确认输出结构符合预期,再切换到with_structured_output提升开发效率。两步走,稳且快。


实战:工单分类,输出即路由

class TicketClassification(BaseModel): category: Literal["退货", "换货", "物流", "质量"] = Field(description="问题类别") priority: Literal["高", "中", "低"] = Field(description="优先级") structured_model = model.with_structured_output(TicketClassification, method="json_mode") result = structured_model.invoke("屏幕有划痕,我要退货") print(result.category) # "退货" print(result.priority) # "高" # 输出直接驱动业务逻辑 if result.category == "退货" and result.priority == "高": create_refund_ticket(priority="urgent") elif result.category == "物流": query_logistics(result.order_id)

关键转变:模型的输出不再是“给人看的文本”,而是“给程序用的指令”。不需要人在中间传话,不需要写正则解析,不需要维护脆弱的字符串匹配逻辑。


别把模型当神仙——异常处理必须到位

模型偶尔会抽风,输出不合法格式:

try: result = parser.invoke(response) except OutputParserException as e: print(f"解析失败:{e}") save_failed_output(response.content) # 留存原始数据,人工介入 # 可选:降级到正则兜底,或返回默认值

生产环境三条铁律,写在代码里不如刻在脑子里:

  1. 信息抽取类任务,temperature设为0——不要任何创造性,要的是确定性

  2. 必须捕获OutputParserException——并记录原始输出,否则出问题连排查线索都没有

  3. 重要业务加程序规则兜底——模型是概率系统,永远不要 100% 信任,关键路径上要有 fallback


最后说一句

自然语言给人看,结构化数据给程序用。

这不仅是技术选型,更是工程思维的体现

​​​​​​​
  • StrOutputParser是管道链的“最后一公里”

  • PydanticOutputParser让你掌控输出结构的每一处细节

  • with_structured_output让新项目开发效率翻倍

三种工具,覆盖从理解原理到生产落地的全路径。

别再让模型说废话了——结构化输出,是 AI 应用进入生产环境的底线要求。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/24 18:02:29

显卡驱动彻底清理终极指南:DDU专业工具深度解析与应用

显卡驱动彻底清理终极指南:DDU专业工具深度解析与应用 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-uninstaller …

作者头像 李华
网站建设 2026/7/24 18:01:59

LLaMA-Factory 实战:从零微调 Qwen2.5 大模型的完整指南

LLaMA-Factory 实战:从零微调 Qwen2.5 大模型的完整指南 一、引言 大语言模型(LLM)正在重塑软件开发的面貌。然而,通用模型在面对垂直领域任务时往往力不从心:医疗诊断需要专业术语理解,法律文书需要精确条…

作者头像 李华
网站建设 2026/7/24 18:00:59

边缘端 AI 部署实战:从模型量化到树莓派/手机推理的完整方案

边缘端 AI 部署实战&#xff1a;从模型量化到树莓派/手机推理的完整方案 一、引言 大模型在云端运行成本高、延迟大、隐私风险显著。边缘端部署正在成为趋势——在手机、IoT设备、嵌入式系统上直接运行 AI 模型&#xff0c;实现低延迟&#xff08;<10ms&#xff09;、零网络…

作者头像 李华
网站建设 2026/7/24 18:00:24

网络流量分析,运维团队到底在看什么?

网络流量分析&#xff0c;运维团队到底在看什么&#xff1f; **摘要&#xff1a;**网络流量分析&#xff08;NTA&#xff09;是运维中一项基础但关键的能力。本文从工程师视角解析NTA的核心价值、分析维度与典型应用场景。 网络运维中一个高频问题&#xff1a;“带宽又满了&…

作者头像 李华
网站建设 2026/7/24 18:00:23

浏览器背后的“试验田“:Chromium 究竟是什么?

如果你每天都在用 Chrome 浏览网页&#xff0c;那么你或许应该认识一下它的"亲兄弟"——Chromium。 Chromium 是 Chrome 的实验开发版本。 简单来说&#xff0c;它是 Google 浏览器技术的"前沿阵地"&#xff0c;各种新功能、新特性会率先在这里落地测试&a…

作者头像 李华
网站建设 2026/7/24 17:59:40

2026年AI配音技术选型:从开源TTS到商业API,7款方案横向评测

给开源项目做演示视频、录制技术教程&#xff0c;或者为个人应用接入语音能力——配音往往是“最后一公里”的效率瓶颈。自录受环境、口音、返工成本制约&#xff1b;直接上开源TTS又面临推理耗时、参数盲调、部署成本等问题。过去半年&#xff0c;我陆续测试了十余款TTS方案&a…

作者头像 李华