LangChain 从入门到实战|结构化输出 Output Parser 彻底搞懂,告别杂乱大模型文本!
前言
我们调用大模型时,默认拿到的是自由自然语言文本,人类阅读很轻松,但程序很难直接处理。 比如从简历提取信息、商品评论情感分析、工单自动分类,如果让代码去正则截取文字,容错极差、极易失效。
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 核心价值:
- 将消息对象统一转为字符串
- 支持 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 通用结构化解析
工作流程
- Pydantic 定义输出结构(字段名、类型、描述)
- 解析器自动生成格式约束提示词
- 将格式要求注入 Prompt 发送给大模型
- 自动解析返回文本,做类型校验
✅ 优势:兼容性极强,适配所有大模型; ⚠️ 风险:依靠提示词引导输出 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))
六、两种结构化方案怎么选择?
-
PydanticOutputParser 依靠 Prompt 引导模型输出 JSON,本地代码解析;兼容全部大模型。 适合学习底层原理、私有化模型不支持原生 JSON 模式场景。
-
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 持续校验失败如何处理?
- 优化 Prompt,强化格式约束;
- try 捕获异常,持久化原始返回文本,分析错误样本;
- 增加重试机制;
- 业务层增加二次规则校验。
九、总结
- 只需要纯文本 → StrOutputParser,适配 LangChain 管道
- 需要结构化数据: ✅ 学习原理、兼容各类模型:
PydanticOutputParser✅ 新项目、模型支持 JSON Mode:with_structured_output - 结构化输出核心价值:消除文本清洗,让大模型输出直接接入业务代码;
- 生产环境强制增加异常捕获,永远不要假设模型 100% 输出规范 JSON。
后续文章将结合 RAG 项目,演示结构化输出如何规范知识库问答结果。 欢迎评论区交流你在结构化输出踩过的坑!
后续文章会结合 RAG 项目,演示结构化输出如何完成知识库问答结果规范化、检索结果过滤。
你们项目中使用结构化输出踩过哪些坑?欢迎评论区交流!
更多推荐


所有评论(0)