前言

我们调用大模型时,默认拿到的是自由自然语言文本,人类阅读很轻松,但程序很难直接处理。 比如从简历提取信息、商品评论情感分析、工单自动分类,如果让代码去正则截取文字,容错极差、极易失效。

LangChain 提供了 Output Parser(输出解析器) 整套方案,强制大模型输出规范结构,直接转换成对象、JSON,实现「大模型结果无缝接入业务代码」。 本文梳理三种核心输出方案,附带完整实战案例,帮你彻底分清什么时候该用哪一种。

环境依赖安装

Pycharm终端运行:

pip install langchain langchain-openai pydantic python-dotenv

一、为什么必须使用结构化输出?

举个直观例子: 大模型原始自然语言输出:

候选人姓名是张三,工作 3 年,熟悉 Python、FastAPI 和 MySQL,希望应聘后端开发工程师。

程序想要提取姓名、年限、技能,只能写正则、字符串匹配,文本稍有改动代码就崩。

结构化输出(JSON):

json

{
  "name": "张三",
  "years_of_experience": 3,
  "skills": ["Python", "FastAPI", "MySQL"],
  "target_position": "后端开发工程师"
}

程序可以直接读取字段 resume.name、resume.skills,无需复杂文本处理。

✅ 结构化输出典型场景: 信息抽取、文本分类、情感分析、工单分类、内容审核、数据入库、调用业务接口。

二、LangChain 三大输出方案总览

LangChain 日常开发最常用 3 种输出方式:

表格

方式核心作用适用场景
StrOutputParser将模型输出转为普通字符串文案生成、总结、翻译、普通问答
PydanticOutputParser根据 Pydantic 模型,解析文本为结构化对象兼容所有大模型,学习底层原理
with_structured_output原生绑定模型,直接输出结构化对象支持 JSON Mode 的模型(DeepSeek、OpenAI 等),新项目首选

三、StrOutputParser 基础字符串解析

核心知识点

model.invoke() 返回的是 AIMessage 对象,无法直接参与 LangChain 管道 |。 StrOutputParser 核心价值:

  1. 将消息对象统一转为字符串
  2. 支持 Runnable 链式管道 prompt | model | parser

误区:单独调用 response.content 和解析器效果几乎一致;构建链路必须使用解析器。

案例 1:文本总结 01_text_summary.py

python

运行

from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.output_parsers import StrOutputParser

# 初始化模型(DeepSeek OpenAI兼容接口,按需替换)
llm = ChatOpenAI(
    model="deepseek-chat",
    api_key="你的key",
    base_url="https://api.deepseek.com/v1",
    temperature=0
)

# 提示词模板
prompt = PromptTemplate.from_template("请简洁总结下面这段文字:{content}")

# 构建链式管道
chain = prompt | llm | StrOutputParser()

# 执行调用
text = """LangChain是一套大模型应用开发框架,支持提示词管理、链式调用、RAG检索、智能体开发。"""
result = chain.invoke({"content": text})
print(type(result))
print(result)

适合场景:文本摘要、文章翻译、普通问答,只需要纯文本结果,不需要结构化字段。

四、PydanticOutputParser 通用结构化解析

工作流程

  1. Pydantic 定义输出结构(字段名、类型、描述)
  2. 解析器自动生成格式约束提示词
  3. 将格式要求注入 Prompt 发送给大模型
  4. 自动解析返回文本,做类型校验

✅ 优势:兼容性极强,适配所有大模型; ⚠️ 风险:依靠提示词引导输出 JSON,极端情况格式错乱,需要捕获异常

案例 2:简历信息抽取 02_resume_extractor.py

python

运行

from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from typing import List

# 1. 定义输出结构
class ResumeInfo(BaseModel):
    name: str = Field(description="候选人姓名")
    years_of_experience: int = Field(description="工作年限,数字")
    skills: List[str] = Field(description="掌握的技术栈列表")
    target_position: str = Field(description="意向应聘岗位")

# 2. 创建解析器
parser = PydanticOutputParser(pydantic_object=ResumeInfo)

# 3. 组装prompt,注入格式要求
prompt = PromptTemplate(
    template="抽取简历信息,严格按照格式输出。\n{format_instructions}\n简历内容:{resume}",
    input_variables=["resume"],
    partial_variables={"format_instructions": parser.get_format_instructions()}
)

llm = ChatOpenAI(
    model="deepseek-chat",
    api_key="你的key",
    base_url="https://api.deepseek.com/v1",
    temperature=0
)

# 构建链路
chain = prompt | llm | parser

resume_text = "候选人张三,拥有3年Python后端开发经验,熟悉FastAPI、MySQL,希望应聘后端开发工程师。"
output = chain.invoke({"resume": resume_text})

print(f"姓名:{output.name}")
print(f"技能列表:{output.skills}")
print(type(output))  # ResumeInfo 对象,可以直接调用属性

五、with_structured_output 简洁结构化方案

新版本 LangChain 模型内置方法,代码更加简洁。底层调用大模型原生JSON Mode强制输出合法 JSON,LangChain 内部自动完成解析,开发者看不到原始 JSON 字符串。

使用 DeepSeek/OpenAI 兼容接口,建议配置 method="json_mode"

案例 3:商品评论情感分析 03_review_analyzer.py

python

运行

from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
from typing import Literal

# Literal 字面量约束,限定可选值,类似枚举
class ReviewAnalysis(BaseModel):
    sentiment: Literal["正面", "中性", "负面"] = Field(description="评论情感倾向,只能三选一")
    summary: str = Field(description="简短总结评论内容")
    key_problem: str | None = Field(description="负面评价提取核心问题,无则填null")

llm = ChatOpenAI(
    model="deepseek-chat",
    api_key="你的key",
    base_url="https://api.deepseek.com/v1",
    temperature=0
)

# 绑定结构化输出,开启json_mode
analyzer = llm.with_structured_output(ReviewAnalysis, method="json_mode")

review = "商品发货速度很快,材质手感不错,唯一缺点包装有轻微破损。"
result = analyzer.invoke(review)

print(f"情感:{result.sentiment}")
print(f"总结:{result.summary}")
print(type(result))

六、两种结构化方案怎么选择?

  1. PydanticOutputParser 依靠 Prompt 引导模型输出 JSON,本地代码解析;兼容全部大模型。 适合学习底层原理、私有化模型不支持原生 JSON 模式场景。

  2. with_structured_output 调用模型 API 原生结构化能力,代码极简;依赖模型服务商支持。

新项目业务开发优先选择!

一句话区分: PydanticOutputParser = 提示词约定格式 + 本地解析 with_structured_output = 大模型 API 原生支持结构化返回

七、案例 4:工单分类 + 解析异常容错 04_ticket_classifier.py

⚠️重点:生产环境必须捕获 OutputParserException,大模型输出不稳定,一定会出现解析失败!

python

运行

from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
from typing import Literal
from langchain.output_parsers import OutputParserException

class TicketClassify(BaseModel):
    category: Literal["功能故障", "咨询提问", "退款售后", "建议反馈"] = Field(description="工单分类")
    priority: Literal["高", "中", "低"] = Field(description="工单优先级")
    brief: str = Field(description="问题简短概括")

llm = ChatOpenAI(
    model="deepseek-chat",
    api_key="你的key",
    base_url="https://api.deepseek.com/v1",
    temperature=0
)
classifier = llm.with_structured_output(TicketClassify, method="json_mode")

user_question = "软件登录时报错,无法进入系统,影响正常办公!"

try:
    ticket_result = classifier.invoke(user_question)
    print(f"分类:{ticket_result.category},优先级:{ticket_result.priority}")
except OutputParserException as e:
    # 标准容错方案
    print("结构化解析失败!")
    print(f"错误信息:{e}")
    # 1. 保存原始模型输出用于排查
    # 2. 记录日志
    # 3. 可选策略:重试、降级人工处理

八、高频开发问题解答

Q1:信息抽取任务,temperature 为什么设置为 0?

temperature 控制模型随机性。抽取、分类任务要求输出稳定,关闭随机采样,避免模型自由发挥,输出不可控内容。

Q2:已经有 with_structured_output,为什么还要学习 PydanticOutputParser?

学习底层原理,理解「格式提示词如何传递给模型」「解析报错根源」;很多老旧 / 私有化大模型不支持 JSON Mode,Parser 方案是兜底手段。

Q3:Pydantic 持续校验失败如何处理?

  1. 优化 Prompt,强化格式约束;
  2. try 捕获异常,持久化原始返回文本,分析错误样本;
  3. 增加重试机制;
  4. 业务层增加二次规则校验。

九、总结

  1. 只需要纯文本 → StrOutputParser,适配 LangChain 管道
  2. 需要结构化数据: ✅ 学习原理、兼容各类模型:PydanticOutputParser ✅ 新项目、模型支持 JSON Mode:with_structured_output
  3. 结构化输出核心价值:消除文本清洗,让大模型输出直接接入业务代码;
  4. 生产环境强制增加异常捕获,永远不要假设模型 100% 输出规范 JSON。

后续文章将结合 RAG 项目,演示结构化输出如何规范知识库问答结果。 欢迎评论区交流你在结构化输出踩过的坑!

后续文章会结合 RAG 项目,演示结构化输出如何完成知识库问答结果规范化、检索结果过滤。

你们项目中使用结构化输出踩过哪些坑?欢迎评论区交流!

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐