【LangChain】 输出解析器(Output Parsers)完全指南

LangChain 输出解析器(Output Parsers)完全指南

2026 年最新版 | 覆盖所有内置解析器 + 完整代码示例


一、什么是输出解析器

输出解析器是 LangChain 中连接"自由文本 LLM"与"结构化程序"的桥梁。LLM 天生输出自然语言,但应用程序需要 JSON、列表、日期等结构化数据。解析器负责将原始文本转换为可直接使用的 Python 对象 。


二、解析器全景图

LangChain 输出解析器(Output Parsers)速查表

类别 解析器 用途 复杂度
基础文本 StrOutputParser 提取纯文本内容
列表 CommaSeparatedListOutputParser 逗号分隔列表
NumberedListOutputParser 编号列表
MarkdownListOutputParser Markdown 列表
结构化 JsonOutputParser 解析为 JSON 字典 ⭐⭐
PydanticOutputParser 解析为 Pydantic 对象(类型安全) ⭐⭐⭐
专用 DatetimeOutputParser 日期时间格式 ⭐⭐
EnumOutputParser 枚举值约束 ⭐⭐
XMLOutputParser XML 格式输出 ⭐⭐
容错 OutputFixingParser 自动修复格式错误 ⭐⭐⭐
RetryOutputParser / RetryWithErrorOutputParser 带上下文的重试修复 ⭐⭐⭐⭐
工具调用 JsonOutputKeyToolsParser 解析 OpenAI 工具调用 ⭐⭐⭐
PydanticToolsParser Pydantic 工具参数解析 ⭐⭐⭐

复杂度说明

复杂度 含义
即拿即用,无需额外配置
⭐⭐ 需要指定格式或少量配置
⭐⭐⭐ 需要定义模型/结构,有一定学习成本
⭐⭐⭐⭐ 涉及重试逻辑和错误处理,复杂度较高

三、基础解析器详解与示例

  1. StrOutputParser --- 字符串解析器

最基础的解析器,从 AIMessage 中提取纯文本内容。

python 复制代码
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

# 构建链:提示 → 模型 → 解析器
prompt = ChatPromptTemplate.from_template("用一句话解释{concept}")
chain = prompt | llm | StrOutputParser()

result = chain.invoke({"concept": "神经网络"})
print(result)
# 输出: "神经网络是一种模拟人脑神经元连接方式的机器学习模型..."
print(type(result))  # <class 'str'>

特点:去除了 AIMessage 包装,直接返回字符串,适合简单问答场景 。


  1. CommaSeparatedListOutputParser --- CSV 列表解析器

要求模型输出逗号分隔的内容,自动转为 Python 列表。

python 复制代码
from langchain_core.output_parsers import CommaSeparatedListOutputParser
from langchain_core.prompts import ChatPromptTemplate

parser = CommaSeparatedListOutputParser()

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个分类助手。{format_instructions}"),
    ("human", "列出{topic}的主要类型,不要编号,用逗号分隔")
]).partial(format_instructions=parser.get_format_instructions())

chain = prompt | llm | parser

result = chain.invoke({"topic": "Python Web 框架"})
print(result)
# 输出: ['Django', 'Flask', 'FastAPI', 'Tornado', 'Bottle']
print(type(result))  # <class 'list'>

get_format_instructions() 自动生成提示:告诉模型"你的输出应该是一个逗号分隔的列表" 。


  1. NumberedListOutputParser --- 编号列表解析器

解析带编号的列表(如 1. xxx 2. xxx)。

python 复制代码
from langchain_core.output_parsers import NumberedListOutputParser

parser = NumberedListOutputParser()

prompt = ChatPromptTemplate.from_template("""
列出{topic}的5个优点,使用编号格式。
{format_instructions}
""")

chain = prompt.partial(format_instructions=parser.get_format_instructions()) | llm | parser

result = chain.invoke({"topic": "微服务架构"})
print(result)
# 输出: ['独立部署', '技术栈灵活', '扩展性强', '故障隔离', '团队自治']

  1. MarkdownListOutputParser --- Markdown 列表解析器

解析 Markdown 格式的无序列表(- item* item)。

python 复制代码
from langchain_core.output_parsers import MarkdownListOutputParser

parser = MarkdownListOutputParser()

prompt = ChatPromptTemplate.from_template("""
用 Markdown 列表格式列出{topic}的核心特性。
{format_instructions}
""")

chain = prompt.partial(format_instructions=parser.get_format_instructions()) | llm | parser

result = chain.invoke({"topic": "Docker"})
print(result)
# 输出: ['容器化', '轻量级', '可移植', '版本控制', '资源隔离']

四、结构化解析器详解与示例

  1. JsonOutputParser --- JSON 解析器

将 LLM 输出解析为 Python 字典。可配合 Pydantic 模型生成格式说明 。

python 复制代码
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field

# 方式一:无 Schema,直接解析为 dict
parser = JsonOutputParser()

prompt = ChatPromptTemplate.from_messages([
    ("system", "提取信息并以 JSON 返回。{format_instructions}"),
    ("human", "介绍一下日本,包含名称、人口、大洲")
]).partial(format_instructions=parser.get_format_instructions())

chain = prompt | llm | parser
result = chain.invoke({})
print(result)
# 输出: {'name': 'Japan', 'population': 125000000, 'continent': 'Asia'}
print(type(result))  # <class 'dict'>

# 方式二:带 Pydantic Schema(仅生成格式说明,返回仍是 dict)
class CountryInfo(BaseModel):
    name: str = Field(description="国家名称")
    population: int = Field(description="人口数量")
    continent: str = Field(description="所在大洲")

parser_with_schema = JsonOutputParser(pydantic_object=CountryInfo)
# 生成的格式说明更详细,但返回仍是 dict 而非 CountryInfo 对象

  1. PydanticOutputParser --- Pydantic 解析器(强烈推荐)

最强大、最安全的解析器。将输出直接转为类型安全的 Pydantic 对象,自动校验字段类型和必填项 。

python 复制代码
from pydantic import BaseModel, Field
from typing import List, Optional
from langchain_core.output_parsers import PydanticOutputParser

# 定义数据结构
class ActionItem(BaseModel):
    task: str = Field(description="任务描述")
    assignee: str = Field(description="负责人")

class MeetingSummary(BaseModel):
    title: str = Field(description="会议标题")
    key_decisions: List[str] = Field(description="关键决策")
    action_items: List[ActionItem] = Field(description="行动项")

parser = PydanticOutputParser(pydantic_object=MeetingSummary)

prompt = ChatPromptTemplate.from_messages([
    ("system", """你是会议纪要助手。从会议记录中提取结构化信息。
{format_instructions}"""),
    ("human", "{transcript}")
]).partial(format_instructions=parser.get_format_instructions())

chain = prompt | llm | parser

meeting_notes = """
3月10日站会。出席:Alice, Bob, Carol。
Alice 说数据管道已完成,待审查。
Bob 提到生产环境 API 速率限制有问题。
决定:API 调用实现指数退避。
Carol 周五前完成重试逻辑代码。
Bob 下周二前搭建监控面板。
Alice 审查 Carol 的 PR。
"""

summary = chain.invoke({"transcript": meeting_notes})

print(type(summary))  # <class '__main__.MeetingSummary'>
print(f"标题: {summary.title}")
print(f"决策: {summary.key_decisions}")
for item in summary.action_items:
    print(f"  任务: {item.task} -> 负责人: {item.assignee}")

输出:

复制代码
标题: 3月10日团队站会
决策: ['API调用实现指数退避']
  任务: 完成重试逻辑代码 -> 负责人: Carol
  任务: 搭建监控面板 -> 负责人: Bob
  任务: 审查Carol的PR -> 负责人: Alice

Pydantic 的优势:

  • 自动类型转换(如字符串 "125000000" → 整数 125000000
  • 必填字段校验(缺少字段会报错)
  • 字段约束(如 ge=1, le=5 限制评分范围)

  1. DatetimeOutputParser --- 日期时间解析器

将 LLM 输出解析为 Python datetime 对象 。

python 复制代码
from langchain.output_parsers import DatetimeOutputParser
from langchain_core.prompts import ChatPromptTemplate

parser = DatetimeOutputParser()

prompt = ChatPromptTemplate.from_messages([
    ("system", "提取日期时间信息。{format_instructions}"),
    ("human", "会议定在下周三下午三点")
]).partial(format_instructions=parser.get_format_instructions())

chain = prompt | llm | parser

result = chain.invoke({})
print(result)
# 输出: 2026-05-20 15:00:00
print(type(result))  # <class 'datetime.datetime'>

  1. EnumOutputParser --- 枚举解析器

强制输出必须是预定义枚举值之一 。

python 复制代码
from langchain.output_parsers import EnumOutputParser
from enum import Enum

class Sentiment(str, Enum):
    POSITIVE = "positive"
    NEGATIVE = "negative"
    NEUTRAL = "neutral"

parser = EnumOutputParser(enum=Sentiment)

prompt = ChatPromptTemplate.from_template("""
分析以下评论的情感倾向。只能从 positive/negative/neutral 中选择。
评论:{review}
""")

chain = prompt | llm | parser

result = chain.invoke({"review": "产品质量非常好,物流也很快!"})
print(result)  # Sentiment.POSITIVE
print(type(result))  # <enum 'Sentiment'>
print(result.value)  # 'positive'

  1. XMLOutputParser --- XML 解析器

解析 XML 格式的输出 。

python 复制代码
from langchain_core.output_parsers import XMLOutputParser

parser = XMLOutputParser()

prompt = ChatPromptTemplate.from_messages([
    ("system", "以 XML 格式返回结果。{format_instructions}"),
    ("human", "提取以下信息:书名《三体》,作者刘慈欣,年份2008")
]).partial(format_instructions=parser.get_format_instructions())

chain = prompt | llm | parser

result = chain.invoke({})
print(result)
# 输出: {'book': {'title': '三体', 'author': '刘慈欣', 'year': '2008'}}

五、容错解析器(生产环境必备)

LLM 有时会输出格式错误的 JSON(缺少逗号、多余注释等)。容错解析器自动修复这些问题 。

  1. OutputFixingParser --- 自动修复解析器

当主解析器失败时,调用另一个 LLM 来修复格式。

python 复制代码
from langchain.output_parsers import OutputFixingParser
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field

class Recipe(BaseModel):
    name: str = Field(description="菜品名称")
    ingredients: List[str] = Field(description="食材列表")
    prep_time: int = Field(description="准备时间(分钟)")

base_parser = PydanticOutputParser(pydantic_object=Recipe)

# 用修复解析器包装基础解析器
fixing_parser = OutputFixingParser.from_llm(
    parser=base_parser,
    llm=ChatOpenAI(model="gpt-4o-mini"),  # 用于修复的 LLM
)

# 模拟一个格式错误的输出
bad_output = '{"name": "宫保鸡丁", "ingredients": ["鸡肉", "花生", "辣椒"] "prep_time": 30}'  # 注意缺少逗号

try:
    result = fixing_parser.parse(bad_output)
    print(f"修复成功: {result}")
except Exception as e:
    print(f"修复失败: {e}")

工作原理:修复解析器收到错误输出后,将其发送给 LLM 并附加指令"请修正这个 JSON 的语法错误" 。


  1. RetryOutputParser / RetryWithErrorOutputParser --- 重试解析器

OutputFixingParser 更强大:不仅发送错误输出,还附带原始提示和错误信息,让 LLM 在完整上下文中重新生成 。

python 复制代码
from langchain_core.output_parsers import (
    PydanticOutputParser, 
    RetryWithErrorOutputParser
)
from langchain_core.prompts import PromptTemplate

class ProductReview(BaseModel):
    product_name: str = Field(description="产品名称")
    rating: int = Field(description="评分 1-5", ge=1, le=5)
    summary: str = Field(description="简短总结")

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
main_parser = PydanticOutputParser(pydantic_object=ProductReview)

# 用重试解析器包装
retry_parser = RetryWithErrorOutputParser.from_llm(
    parser=main_parser,
    llm=llm,
    max_retries=2  # 最多重试 2 次
)

prompt_template = """
分析以下产品评论并提取信息。
{format_instructions}

评论文本:
{review_text}
"""

prompt = PromptTemplate(
    template=prompt_template,
    input_variables=["review_text"],
    partial_variables={"format_instructions": main_parser.get_format_instructions()}
)

# 使用 parse_with_prompt 方法,传入提示对象
review = "不错的手机(4星)。相机很好。希望存储空间更大。"
prompt_value = prompt.format_prompt(review_text=review)
llm_output = llm.invoke(prompt_value)

try:
    result = retry_parser.parse_with_prompt(
        llm_output.content,
        prompt_value
    )
    print(f"产品: {result.product_name}")
    print(f"评分: {result.rating}")
except Exception as e:
    print(f"重试后仍失败: {e}")

RetryWithErrorOutputParser vs OutputFixingParser

  • OutputFixingParser:只给 LLM 错误输出,让它"猜"着修
  • RetryWithErrorOutputParser:给 LLM 原始提示 + 错误输出 + 错误信息,在完整上下文中重新生成,成功率更高 。

六、工具调用解析器

用于解析支持 Function Calling 的模型(如 OpenAI、Claude)的工具调用结果 。

  1. JsonOutputKeyToolsParser
python 复制代码
from langchain_core.output_parsers.openai_tools import JsonOutputKeyToolsParser

# 当模型返回 tool_calls 时,提取指定工具的参数
parser = JsonOutputKeyToolsParser(key_name="get_weather")

# 通常配合 with_structured_output 使用

  1. PydanticToolsParser
python 复制代码
from langchain_core.output_parsers.openai_tools import PydanticToolsParser

# 将工具调用参数直接解析为 Pydantic 对象

七、现代推荐做法:with_structured_output()

2026 年最新趋势:对于支持原生结构化输出的模型(GPT-4o、Claude 3、Gemini),优先使用 .with_structured_output(),而非传统的 Output Parser 。

python 复制代码
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field

class MovieReview(BaseModel):
    title: str = Field(description="电影标题")
    rating: float = Field(description="评分 0-10")
    summary: str = Field(description="一句话总结")
    recommended: bool = Field(description="是否推荐")

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

# 直接绑定结构化输出,无需解析器!
structured_llm = llm.with_structured_output(MovieReview)

result = structured_llm.invoke("评价电影《盗梦空间》")
print(type(result))  # <class '__main__.MovieReview'>
print(result.title)      # "Inception"
print(result.rating)     # 8.8
print(result.recommended)  # True

优势:

  • 使用模型原生的 Function Calling / JSON Mode,可靠性更高
  • 无需在提示中写复杂的格式说明
  • 省去解析步骤,直接返回 Pydantic 对象

何时还用传统 Parser:

  • 使用不支持结构化输出的模型(如本地小模型)
  • 需要复杂的后处理逻辑(如从混合文本中提取 JSON)
  • 需要容错修复机制

八、自定义解析器

继承 BaseOutputParser 实现专属逻辑 。

python 复制代码
from langchain_core.output_parsers import BaseOutputParser
from typing import Any
import re
import json

class MarkdownJsonExtractor(BaseOutputParser):
    """从 Markdown 代码块中提取 JSON"""
    
    def parse(self, text: str) -> Any:
        # 匹配 ```json ... ```块
        match = re.search(r"```json\s*(.*?)\s*```", text, re.DOTALL)
        if not match:
            raise ValueError(f"未找到 JSON 代码块: {text[:100]}...")
        
        json_str = match.group(1)
        try:
            return json.loads(json_str)
        except json.JSONDecodeError as e:
            raise ValueError(f"JSON 解析失败: {e}")
    
    def get_format_instructions(self) -> str:
        return "请将 JSON 输出包裹在 ```json\n...\n```代码块中。"

# 使用
custom_parser = MarkdownJsonExtractor()

llm_output = """
分析完成!以下是结果:
```json
{
  "sentiment": "positive",
  "confidence": 0.95,
  "keywords": ["质量", "服务"]
}

如有疑问请告诉我。

"""

result = custom_parser.parse(llm_output)

print(result)

输出: {'sentiment': 'positive', 'confidence': 0.95, 'keywords': ['质量', '服务']}


九、选型指南

场景 推荐方案 理由
简单文本问答 StrOutputParser 最轻量
逗号分隔标签 CommaSeparatedListOutputParser 一行代码搞定
需要类型安全 PydanticOutputParser 自动校验 + IDE 提示
快速原型 JsonOutputParser 无需定义模型
生产环境高可靠 with_structured_output() + RetryWithErrorOutputParser 双重保障
老旧模型/本地模型 PydanticOutputParser + OutputFixingParser 容错修复
混合格式提取 自定义 BaseOutputParser 完全可控

十、完整对比总结

解析器 输入 输出 自动格式说明 容错能力 2026 推荐度
StrOutputParser AIMessage str ⭐⭐⭐
CommaSeparatedListOutputParser str list ⭐⭐⭐
JsonOutputParser str dict ⭐⭐
PydanticOutputParser str Pydantic 对象 ⭐⭐⭐⭐
DatetimeOutputParser str datetime ⭐⭐
EnumOutputParser str Enum ⭐⭐
XMLOutputParser str dict
OutputFixingParser str 同包装解析器 同包装 ⭐⭐⭐⭐
RetryWithErrorOutputParser str + prompt 同包装解析器 同包装 ✅✅ ⭐⭐⭐⭐⭐
with_structured_output() - Pydantic 对象 原生支持 模型级 ⭐⭐⭐⭐⭐

核心原则 :2026 年的 LangChain 开发,能用 with_structured_output() 就不用传统 Parser ;必须用 Parser 时,生产环境务必加一层容错解析器RetryWithErrorOutputParser)[1][2][5]。

相关推荐
薛定猫AI1 小时前
Codex 与 Claude Code 安装配置完整教程(Windows/Mac/Linux)
人工智能
TDengine (老段)1 小时前
TDengine 集群拓扑深度解析 — 节点发现、EP 机制与负载均衡
大数据·数据库·人工智能·重构·负载均衡·时序数据库·tdengine
Kiyra1 小时前
异步任务不用 Kafka 也行:用 Redis Stream 搭一套轻量级 Producer/Consumer 框架
数据库·人工智能·redis·分布式·后端·缓存·kafka
城事漫游Molly1 小时前
定量研究设计清单:问卷、实验与变量操作化怎么做?
大数据·人工智能·算法·ai写作·论文笔记
涤生大数据1 小时前
大数据凉了?速看4月的就业数据新鲜出炉!AI时代岗位不会原地消失,而是岗位的标准会被逐步抬高
大数据·人工智能
七夜zippoe1 小时前
基于 JiuwenClaw AgentTeam 集群模式的年会策划实战:从源码部署到多智能体协作落地
人工智能·agent·openjiuwen·jiuwenclaw·agentteam
Soari1 小时前
科研绘图新纪元:深度拆解 3DCellForge,AI 驱动的交互式 3D 细胞建模神器
人工智能·3d·科研绘图·3dcellforg
new【一个】对象1 小时前
Python 包管理器uv
人工智能·windows·python
智塑未来1 小时前
高精度3D室内定位设备如何赋能机器人科研创新
人工智能·安全