文章目录
- 输出解析器
- 总结
-
- [📚 LangChain 输出解析器](#📚 LangChain 输出解析器)
-
- [🎯 一句话搞懂](#🎯 一句话搞懂)
- [🤔 为什么需要输出解析器?](#🤔 为什么需要输出解析器?)
- [⚔️ 输出解析器 vs `with_structured_output`](#⚔️ 输出解析器 vs
with_structured_output) - [🧩 三种常用输出解析器](#🧩 三种常用输出解析器)
-
- [1️⃣ `StrOutputParser` ------ 纯文本输出](#1️⃣
StrOutputParser—— 纯文本输出) - [2️⃣ `PydanticOutputParser` ------ 结构化对象输出](#2️⃣
PydanticOutputParser—— 结构化对象输出) - [3️⃣ `JsonOutputParser` ------ JSON 输出](#3️⃣
JsonOutputParser—— JSON 输出)
- [1️⃣ `StrOutputParser` ------ 纯文本输出](#1️⃣
- [💡 核心技巧:`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.setup、joke.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 为例)
- 定义 Pydantic 类(你想要的结构)
- 创建解析器:
parser = PydanticOutputParser(pydantic_object=MyClass) - 在提示词模板中加入
{format_instructions}占位符 - 用
partial_variables把parser.get_format_instructions()注入模板 - 构建链:
prompt | model | parser - 调用链,自动得到结构化对象
🧠 总结一句话
输出解析器 = 让大模型学会"讲程序听得懂的语言"
你想让模型输出 JSON、对象还是纯文本,就选对应的解析器,然后用
|把它接到模型后面。
📌 记忆口诀
- 纯文本 →
StrOutputParser - 对象 →
PydanticOutputParser - JSON →
JsonOutputParser - 别忘了加指令 →
get_format_instructions()
🎉