6.输出解析器
输出解析器
一、什么是输出解析器 OutputParser
1. 核心作用
大模型原生返回是统一的 AIMessage 对象,里面只有一段自由文本 content。
实际开发中需要结构化、可直接业务使用的数据(字符串、字典、强类型对象),输出解析器就是专门做「模型输出格式化转换」的工具。
两大核心方法:
invoke(result):接收模型返回对象,转换成目标格式;get_format_instructions():生成标准化格式提示词,告诉大模型必须按照指定结构输出。
2. 主流分类(文档全部示例覆盖)
StrOutputParser:最简单,只提取纯文本字符串;JsonOutputParser:输出标准字典dict,支持简单自定义JSON结构;PydanticOutputParser:强校验结构化输出,基于Pydantic BaseModel,支持字段长度、数值范围等校验;with_structured_output(TypedDict):LangChain新版快捷结构化输出,基于Python原生TypedDict,轻量无运行时校验。
3. 两个关键类型区分(TypedDict / Pydantic BaseModel)
TypedDict + Annotated:仅静态类型提示,运行时不会自动校验数据合法性,仅用于IDE提示、给大模型看字段说明;Pydantic BaseModel + Field:运行时强制校验,数值范围、字符串长度、类型错误都会直接抛异常,适合严谨业务场景。
二、解析器代码
1. StrOutputParser 纯字符串解析器(StrOutputParserDemo.py)
核心特点
LangChain最简单解析器,逻辑只有一步:提取模型返回 AIMessage.content 转为普通字符串,无任何结构化处理。
完整代码流程拆解
# 1. 导入依赖
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
import os
from langchain.chat_models import init_chat_model
from loguru import logger
# 2. 构建提示模板,支持变量插值
chat_prompt = ChatPromptTemplate.from_messages(
[
("system", "你是一个{role},请简短回答我提出的问题"),
("human", "请回答:{question}")
]
)
# 填充变量生成完整prompt
prompt = chat_prompt.invoke({"role": "AI助手", "question": "什么是LangChain,简洁回答100字以内"})
# 3. 初始化通义千问兼容接口模型
model = init_chat_model(
model="qwen-plus",
model_provider="openai",
api_key=os.getenv("aliQwen-api"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
# 4. 调用大模型,返回AIMessage对象
result = model.invoke(prompt)
logger.info(f"模型原始输出:\n{result}") # 原始对象包含id、content等字段
# 5. 字符串解析器转换
parser = StrOutputParser()
response = parser.invoke(result)
logger.info(f"解析后结果:\n{response}")
logger.info(f"结果类型: {type(response)}") # <class 'str'>
使用场景
只需要纯文本回答,不需要解析JSON、结构化数据,日常简单问答场景首选。
2. JsonOutputParser JSON字典解析器(两种用法)
用法1:简易JSON(JsonOutputParserDemo.py)
直接在提示词约束模型返回JSON,无需定义数据模型,解析后直接得到dict。
# 系统提示强制要求返回json,q存问题,a存答案
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个{role},请简短回答,结果返回json格式,q字段表示问题,a字段表示答案。"),
("human", "请回答:{question}")
])
# 模型调用省略,和上文一致
parser = JsonOutputParser()
response = parser.invoke(result)
print(type(response)) # <class 'dict'>
优点:代码极简;缺点:无法约束JSON字段、字段类型,大模型容易漏字段。
用法2:带格式指令自定义JSON(JsonOutputParser_GetFormatInstructions.py)
基于Pydantic模型定义JSON结构,通过get_format_instructions()自动生成格式规则注入提示词,强制模型输出指定字段。
- 先定义数据模板:
from pydantic import BaseModel, Field
class Person(BaseModel):
time: str = Field(description="新闻时间")
person: str = Field(description="新闻人物")
event: str = Field(description="新闻事件")
- 生成格式指令并注入prompt:
parser = JsonOutputParser(pydantic_object=Person)
format_instructions = parser.get_format_instructions() # 自动生成JSON规范文本
# 提示词拼接规范指令
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是AI助手,只能输出结构化JSON。"),
("human", "生成{topic}新闻。{format_instructions}")
])
prompt = chat_prompt.format_messages(topic="小米su7跑车", format_instructions=format_instructions)
- 模型返回后解析为字典,自带基础字段校验。
使用场景
需要结构化数据,但不需要复杂字段校验(长度、数值范围等),大部分业务场景通用。
3. PydanticOutputParser 强校验结构化解析器(StructuredOutput_Pydantic.py)
核心优势
基于BaseModel,支持:
- 字段描述
Field(description="xxx"); - 自定义校验器
@field_validator; - 运行时自动校验,不满足规则直接抛异常;
- 自动生成格式化指令约束大模型输出。
代码关键片段讲解
from pydantic import BaseModel, Field, field_validator
# 1. 定义强约束数据模型
class Product(BaseModel):
name: str = Field(description="产品名称")
category: str = Field(description="产品类别")
description: str = Field(description="产品简介")
# 自定义字段校验:简介长度≥10
@field_validator("description")
def validate_description(cls, value):
if len(value) < 10:
raise ValueError('产品简介长度必须大于等于10')
return value
# 2. 初始化解析器,自动生成格式指令
parser = PydanticOutputParser(pydantic_object=Product)
format_instructions = parser.get_format_instructions()
# 3. 提示词注入规则,调用模型后解析
response = parser.invoke(result)
print(type(response)) # Product对象,可直接response.name取属性
使用场景
对输出数据规范要求极高:表单、商品信息、报表、需要严格字段校验的业务。
4. TypedDict 轻量结构化输出(StructuredOutput_TypedDict.py)
核心特点
Python3.8+原生类型注解,配合llm.with_structured_output()快捷调用,无运行时校验,仅用于给大模型定义输出结构。
from typing import TypedDict, Annotated
# 定义嵌套结构
class Animal(TypedDict):
animal: Annotated[str, "动物名称"]
emoji: Annotated[str, "对应表情"]
class AnimalList(TypedDict):
animals: Annotated[list[Animal], "动物表情列表"]
# 模型直接绑定结构化输出,无需手动拼接format_instructions
llm_with_structured_output = llm.with_structured_output(AnimalList)
resp = llm_with_structured_output.invoke("生成三种动物和对应emoji")
# resp 是原生dict,无校验,即使类型错误也不会报错
Annotated补充说明(AnnotatedTypedDict.py / AnnotatedPydantic.py)
Annotated[基础类型, 元数据]:给字段附加说明文本;- 搭配
TypedDict:仅静态提示,运行时无效; - 搭配
Pydantic Field:元数据+运行时校验双重生效。
例:年龄约束
# TypedDict:只注释,188不会报错
Age = Annotated[int, "年龄0-150"]
# Pydantic:搭配Field,超出范围直接抛异常
Age = Annotated[int, Field(ge=0, le=150, description="年龄0-150")]
三、四大解析器对比总结
| 解析器 | 输出类型 | 运行时校验 | 适用场景 | 优缺点 |
|---|---|---|---|---|
| StrOutputParser | str | 无 | 纯文本问答 | 极简,无结构化能力 |
| JsonOutputParser | dict | 弱校验(字段存在) | 简单结构化数据 | 上手快,不支持复杂校验 |
| PydanticOutputParser | Pydantic对象 | 强自定义校验 | 严谨业务、表单、报表 | 功能最全,代码量稍多 |
| with_structured_output(TypedDict) | dict | 无 | 快速原型、简单嵌套结构 | 调用简洁,无数据校验 |
四、开发选型建议
- 简单问答、只需要文字:
StrOutputParser; - 需要JSON字典,无严格校验:
JsonOutputParser/TypedDict + with_structured_output; - 输出有格式、长度、数值范围强制要求:
PydanticOutputParser; - 快速开发、不想手动拼接format_instructions:优先
llm.with_structured_output()。
五、核心避坑点
TypedDict只有类型提示,运行时不会拦截非法数据,严谨业务不要用;- Pydantic校验会直接抛出
ValidationError,生产环境需要try-except捕获异常; - 使用
get_format_instructions()时,必须把变量注入提示词,否则大模型不会遵守格式; - 所有解析器入参必须是模型返回的
AIMessage对象,不能直接传入字符串。

浙公网安备 33010602011771号