【LangChain】输出解析器 Str/Pydantic/JSON 解析器用法详解 告别模型乱输出

文章目录

  • 输出解析器
  • 总结
    • [📚 LangChain 输出解析器](#📚 LangChain 输出解析器)
      • [🎯 一句话搞懂](#🎯 一句话搞懂)
      • [🤔 为什么需要输出解析器?](#🤔 为什么需要输出解析器?)
      • [⚔️ 输出解析器 vs `with_structured_output`](#⚔️ 输出解析器 vs with_structured_output)
      • [🧩 三种常用输出解析器](#🧩 三种常用输出解析器)
        • [1️⃣ `StrOutputParser` ------ 纯文本输出](#1️⃣ StrOutputParser —— 纯文本输出)
        • [2️⃣ `PydanticOutputParser` ------ 结构化对象输出](#2️⃣ PydanticOutputParser —— 结构化对象输出)
        • [3️⃣ `JsonOutputParser` ------ JSON 输出](#3️⃣ JsonOutputParser —— JSON 输出)
      • [💡 核心技巧:`get_format_instructions()`](#💡 核心技巧:get_format_instructions())
      • [⚡ 完整工作流(以 Pydantic 为例)](#⚡ 完整工作流(以 Pydantic 为例))
      • [🧠 总结一句话](#🧠 总结一句话)
      • [📌 记忆口诀](#📌 记忆口诀)

输出解析器

概念

负责获取模型的输出,并将输出转换为更结构化的格式。当使用LLM生成结构化数据或规范化聊天模型和LLM的输出时,这很有用。

大型语言模型(LLM)的输出本质上是非结构化的文本。但在构建应用程序时,我们通常希望得到结构化的、机器可读的数据,这样可以将其转换为更适合下游任务的格式,比如:

  • JSON对象
  • Python字典或列表
  • 一个特定的Pydantic模型实例
  • 一个简单的布尔值或字符串枚举

输出解析器的作用就是架起这座桥梁:它们将LLM的非结构化文本输出转换为结构化格式。这使得与LLM的交互从"模糊的文本对话"变成了"精确的数据API调用",是构建可靠、高效LLM应用不可或缺的组件。

与with_structured_output()的区别

它们都实现了相同的功能,但:

  • 维度不同:输出解析器是LangChain中的一个功能性组件,with_structured_output()是聊天模型的一个方法。

  • 用法不同:输出解析器的工作流程可以是链式的,可以将 Prompt、LLM 和 Parser 像管道一样连接起来:chain = prompt | llm | parser。而 with_structured_output(schema) 却不行,只能手动调用,返回一个新的、具备了结构可以......根据使用场景选择,结果想使用链式就选择输出解析器。

解析文本输出

使用 StrOutputParser 输出解析器输出文本

python 复制代码
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
model = ChatOpenAI(model="gpt-4o-mini")
chain = model | StrOutputParser()
for chunk in chain.stream("写一首夏天的诗词,50字以内。"):
    print(chunk, end="|")
复制代码
|炎|夏|骄|阳|照|,|绿|树|映|蓝|天|。|
|蝉|鸣|声|声|烈|,|荷|塘|映|清|鲜|。|
|微|风|拂|面|过|,|凉|意|透|心|间|。|
|烦|忧|随|汗|去|,|畅|享|此|夏|欢|。|

若是不使用输出解析器,而是直接得到聊天模型返回的 AIMessage,文本内容则需要从消息中的 content 字段获取

解析结构化对象输出Pydantic

要输出结构化对象,需要用到的输出解析器是 PydanticOutputParser。

class langchain_core.output_parsers.pydantic.PydanticOutputParser 类,其参数如下:

  • pydantic_object:要解析的pydantic模型。

内置方法:

  • invoke():将单个输入转换为输出。
  • get_format_instructions() → str:重要!!
    • 作用:生成一个指令字符串,这个字符串会被添加到发送给LLM的提示(Prompt)的末尾。
    • 目的:告诉LLM应该以什么样的格式返回它的响应。例如,"请将你的回复封装在XML标签中"或"请以JSON格式输出,包含'name'和'age'两个字段"。
python 复制代码
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import PydanticOutputParser
from langchain_core.prompts import PromptTemplate
from typing import Optional
from pydantic import BaseModel, Field

# 定义大模型
model = ChatOpenAI(model="gpt-4o-mini")

# 定义输出结构:Pydantic类
class Joke(BaseModel):
    """给用户讲一个笑话。"""
    setup: str = Field(description="这个笑话的开头")
    punchline: str = Field(description="这个笑话的妙语")
    rating: Optional[int] = Field(default=None, description="从1到10分,给这个笑话评分")

# 设置解析器
parser = PydanticOutputParser(pydantic_object=Joke)

# 提示词模板
prompt = PromptTemplate(
    template="Answer the user query.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

chain = prompt | model | parser
for chunk in chain.stream({"query": "给我讲一个关于唱歌的笑话"}):
    print(chunk, end="|")

结果:

复制代码
setup='为什么歌手总是带着铅笔去演出?'punchline='rating=None|setup='为什么歌手总是带着铅笔去演出?'punchline='因为'rating=None|setup='为什么歌手总是带着铅笔去演出?'punchline='因为他们'rating=None|setup='为什么歌手总是带着铅笔去演出?'punchline='因为他们想'rating=None|setup='为什么歌手总是带着铅笔去演出?'punchline='因为他们想要'rating=None|setup='为什么歌手总是带着铅笔去演出?'punchline='因为他们想要不断'rating=None|setup='为什么歌手总是带着铅笔去演出?'punchline='因为他们想要不断调整'rating=None|setup='为什么歌手总是带着铅笔去演出?'punchline='因为他们想要不断调整音'rating=None|setup='为什么歌手总是带着铅笔去演出?'punchline='因为他们想要不断调整音响'rating=None|setup='为什么歌手总是带着铅笔去演出?'punchline='因为他们想要不断调整音响!'rating=None|

解析JSON输出

要输出JSON格式,需要用到的输出解析器是JsonOutputParser。

class langchain_core.output_parsers.json.JSONOutputParser类,其参数如下:

  • pydantic_object:用于验证的Pydantic对象。如果为空,则不执行任何验证。

内置方法:

  • invoke():将单个输入转换为输出。
  • get_format_instructions() → str:重要!!
    • 作用:生成一个指令字符串,这个字符串会被添加到发送给LLM的提示(Prompt)的末尾。
    • 目的:告诉LLM应该以什么样的格式返回它的响应。例如,"请将你的回复封装在XML标签中"或"请以JSON格式输出,包含'name'和'age'两个字段"。
python 复制代码
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate
# 定义大模型
model = ChatOpenAI(model="gpt-4o-mini")
# 设置解析器
parser = JsonOutputParser()
# 提示词模板
prompt = PromptTemplate(
    template="Answer the user query.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)
chain = prompt | model | parser
print(chain.invoke({"query": "给我讲一个关于唱歌的笑话"}))

结果:

复制代码
{'joke': '为什么歌手总是带着梯子?\n因为他们想要在音乐会上达到更高的层次!'}

总结

📚 LangChain 输出解析器

🎯 一句话搞懂

输出解析器 = 把大模型"说的人话"转成"程序能直接用的数据"

比如:把一段文字变成 JSON、Python字典、Pydantic对象等。


🤔 为什么需要输出解析器?

  • 大模型(LLM)只会输出自然语言文本 (字符串),比如:"你好,我叫小智"
  • 但程序想要的是结构化数据 ,比如:{"name": "小智", "message": "你好"}
  • 以前要写正则表达式或手动解析,很麻烦 → 输出解析器帮你自动完成转换。

⚔️ 输出解析器 vs with_structured_output

对比项 输出解析器 with_structured_output()
本质 独立组件(可插拔) 聊天模型自带的方法
用法 链式调用:`prompt llm
灵活性 高,可自由组合不同解析器 局限于模型,不可链式
推荐场景 喜欢链式编程、需要多种输出格式 简单场景、想省事

小白建议:用输出解析器更通用,容易理解,也方便调试。


🧩 三种常用输出解析器

1️⃣ StrOutputParser ------ 纯文本输出

直接返回大模型输出的字符串内容(去掉额外包装)。

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

model = ChatOpenAI(model="gpt-4o-mini")
chain = model | StrOutputParser()

for chunk in chain.stream("写一首夏天的诗词,50字以内"):
    print(chunk, end="|")

效果:逐字输出诗句,就像流式打字效果。


2️⃣ PydanticOutputParser ------ 结构化对象输出

你定义一个 Pydantic 类(类似数据模板),解析器会让模型严格按照这个格式返回数据,并自动转成对象。

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

class Joke(BaseModel):
    setup: str = Field(description="笑话开头")
    punchline: str = Field(description="笑话妙语")
    rating: Optional[int] = Field(None, description="1~10分")

parser = PydanticOutputParser(pydantic_object=Joke)

关键 :调用 parser.get_format_instructions() 生成指令告诉模型要输出什么格式。
好处 :输出直接是 Joke 对象,可以用 joke.setupjoke.punchline 访问属性。


3️⃣ JsonOutputParser ------ JSON 输出

让模型返回一个合法的 JSON 字符串,并自动解析成 Python 字典。

python 复制代码
from langchain_core.output_parsers import JsonOutputParser

parser = JsonOutputParser()
# 同样需要 get_format_instructions() 引导模型输出 JSON

结果示例{'joke': '为什么歌手总是带着梯子?...'}

可以直接用 result['joke'] 取值。


💡 核心技巧:get_format_instructions()

  • 这是最容易被忽视但最重要的方法
  • 它会生成一段人类可读的格式说明,拼接到提示词末尾,告诉模型:"请按这个格式返回结果"。
  • 如果不加这个,模型可能乱输出,解析器会报错。

⚡ 完整工作流(以 Pydantic 为例)

  1. 定义 Pydantic 类(你想要的结构)
  2. 创建解析器:parser = PydanticOutputParser(pydantic_object=MyClass)
  3. 在提示词模板中加入 {format_instructions} 占位符
  4. partial_variablesparser.get_format_instructions() 注入模板
  5. 构建链:prompt | model | parser
  6. 调用链,自动得到结构化对象

🧠 总结一句话

输出解析器 = 让大模型学会"讲程序听得懂的语言"

你想让模型输出 JSON、对象还是纯文本,就选对应的解析器,然后用 | 把它接到模型后面。


📌 记忆口诀

  • 纯文本StrOutputParser
  • 对象PydanticOutputParser
  • JSONJsonOutputParser
  • 别忘了加指令get_format_instructions()

🎉

相关推荐
C137的本贾尼1 小时前
告别硬编码:提示词模板入门
python·langchain
夜影风3 小时前
AI Agent初探:让LLM自己决定该调用什么工具
人工智能·langchain·ai agent
Dovis(誓平步青云)4 小时前
《SQL语义等价性检查:Pivot的CASE WHEN改写策略与限制》
linux·windows·sql·microsoft·oracle·stable diffusion
云天AI实战派4 小时前
2026 实战:用 OpenAI 实时音频模型做门店语音助手,从 Spec 到 API 接入上线全流程
microsoft·音视频·语音识别
热爱学习的小翁同学4 小时前
Power Automate调用Azure Foundry智能体
microsoft·azure
fly_over4 小时前
AI Agent 开发实战教程(二):Prompt 工程与工具调用
开发语言·python·langchain·prompt·ai编程·ai agent
InfinteJustice16 小时前
踩坑分享C 语言文件操作全攻略:从基础读写到随机访问与缓冲区原理
c语言·开发语言·microsoft