拒绝“胡言乱语”!LangChain 输出解析器全指南:让 LLM 乖乖吐出 JSON/Pydantic 对象

1. 概念
输出解析器(Output Parser)的作用是将 LLM 的非结构化文本输出转换为结构化的格式。
1.1 为什么需要输出解析器?
大型语言模型(LLM)的输出本质上是非结构化的文本,但在构建应用程序时,我们通常希望得到结构化的、机器可读的数据,比如:
- JSON 对象
- Python 字典或列表
- 一个特定的 Pydantic 模型实例
- 一个简单的布尔值或字符串枚举
输出解析器的作用就是架起这座桥梁:它们将 LLM 的"模糊的文本对话"变成了"精确的数据 API 调用",是构建可靠、高效 LLM 应用不可或缺的组件。
1.2 与 with_structured_output() 的区别
虽然它们都实现了相同的功能,但:
-
维度不同:
- 输出解析器是 LangChain 中的一个功能性组件
with_structured_output()是聊天模型的一个方法
-
用法不同:
- 输出解析器的工作流程可以是链式的,可以将 Prompt、LLM 和 Parser 像管道一样连接起来:
chain = prompt | llm | parser with_structured_output(schema)则不行,只能手动调用,返回一个新的、具备了结构化输出能力的 Runnable
- 输出解析器的工作流程可以是链式的,可以将 Prompt、LLM 和 Parser 像管道一样连接起来:
可以根据自己的使用场景选择,如果想使用链式就选择输出解析器。
2. 解析文本输出
对于使用 StrOutputParser 输出解析器输出文本,我们已经使用过多次了。
StrOutputParser 也实现了标准的 Runnable 接口,示例如下:
from langchain_core.output_parsers import StrOutputParser
from langchain_deepseek import ChatDeepSeek
from langchain_core.prompts import PromptTemplate
# 提示词模板
prompt = PromptTemplate(
input_variables=["question"],
template="请回答:{question}"
)
# 大模型
llm = ChatDeepSeek(model="deepseek-chat")
# 输出解析器
parser = StrOutputParser()
# 构建链
chain = prompt | llm | parser
# 调用
result = chain.invoke({"question": "什么是LangChain?"})
print(result) # 输出字符串
3. 解析结构化对象输出
要输出结构化对象,需要用到的输出解析器是 PydanticOutputParser。
3.1 PydanticOutputParser 类
class langchain_core.output_parsers.pydantic.PydanticOutputParser
参数:
pydantic_object:要解析的 pydantic 模型
内置方法:
invoke():将单个输入转换为输出get_format_instructions() → str:重要!!- 作用:生成一个指令字符串,这个字符串会被添加到发送给 LLM 的提示(Prompt)的末尾
- 目的:告诉 LLM 应该以什么样的格式返回它的响应。例如,“请将你的回复封装在 XML 标签中"或"请以 JSON 格式输出,包含 ‘name’ 和 ‘age’ 两个字段”
3.2 使用示例
# pydantic格式的输出解释器的runnable对象
from langchain_core.output_parsers import PydanticOutputParser
from langchain_deepseek import ChatDeepSeek
from pydantic import BaseModel, Field
from langchain_core.prompts import PromptTemplate
# 1. 构造pydantic对象
class Output(BaseModel):
answer: str = Field(description="回答")
reason: str = Field(description="回答的理由")
# 2. 构造输出解析器
parser = PydanticOutputParser(pydantic_object=Output)
# 3. 提示词模版 - 关键:必须包含 format_instructions
prompt_template = PromptTemplate(
input_variables=["input"],
template="请回答问题:{input}\n\n{format_instructions}",
# 关键:使用 partial_variables 自动注入格式说明
partial_variables={"format_instructions": parser.get_format_instructions()}
)
# 4. 大模型
llm = ChatDeepSeek(
model="deepseek-chat",
temperature=0.5,
)
# 5. 构建链
chain = prompt_template | llm | parser
# 6. 调用链
result = chain.invoke({"input": "为什么要学习langchain"})
print(result)
print(f"\n回答: {result.answer}")
print(f"理由: {result.reason}")
输出示例:
answer='学习LangChain是为了高效构建基于大语言模型(LLM)的应用程序'
reason='LangChain提供了标准化组件,简化了与不同LLM的集成、外部数据源连接等'
3.3 get_format_instructions() 生成的内容
print(parser.get_format_instructions())
输出:
Here is the output schema:
{
"properties": {
"answer": {
"description": "回答",
"title": "Answer",
"type": "string"
},
"reason": {
"description": "回答的理由",
"title": "Reason",
"type": "string"
}
},
"required": ["answer", "reason"]
}
4. 解析 JSON 输出
要输出 JSON 格式,需要用到的输出解析器是 JsonOutputParser。
4.1 JsonOutputParser 类
class langchain_core.output_parsers.json.JsonOutputParser
参数:
pydantic_object:用于验证的 Pydantic 对象。如果为空,则不执行任何验证
内置方法:
invoke():将单个输入转换为输出get_format_instructions() → str:重要!!- 作用:生成一个指令字符串,这个字符串会被添加到发送给 LLM 的提示(Prompt)的末尾
- 目的:告诉 LLM 应该以什么样的格式返回它的响应
4.2 使用示例
# json格式的输出解释器的runnable对象
from langchain_core.output_parsers import JsonOutputParser
from langchain_deepseek import ChatDeepSeek
from pydantic import BaseModel, Field
from langchain_core.prompts import PromptTemplate
# 1. 构造pydantic对象,同样是pydantic对象构造json
class Output(BaseModel):
answer: str = Field(description="回答")
reason: str = Field(description="回答的理由")
# 2. 构造输出解析器
parser = JsonOutputParser(pydantic_object=Output) # 转化成json格式
# 3. 提示词模版 - 关键:必须包含 format_instructions
prompt_template = PromptTemplate(
input_variables=["input"],
template="请回答问题:{input}\n\n{format_instructions}",
# 关键:必须包含 format_instructions---按照上面的json格式
partial_variables={"format_instructions": parser.get_format_instructions()}
)
# 4. 大模型
llm = ChatDeepSeek(
model="deepseek-chat",
temperature=0.5,
)
# 5. 构建链
chain = prompt_template | llm | parser
# 6. 调用链
result = chain.invoke({"input": "为什么要学习langchain"})
print(result)
输出示例:
{
'answer': '学习LangChain是为了高效地构建和集成基于大语言模型(LLM)的应用程序。',
'reason': 'LangChain提供了一套标准化的接口、组件和工具链,能够简化LLM应用的开发流程'
}
4.3 PydanticOutputParser 与 JsonOutputParser 的区别
| 特性 | PydanticOutputParser | JsonOutputParser |
|---|---|---|
| 返回类型 | Pydantic 对象实例 | Python 字典 |
| 类型验证 | 严格的类型验证 | 可选验证 |
| 使用场景 | 需要类型安全和数据验证 | 只需要 JSON 格式 |
| 示例 | Output(answer="...", reason="...") |
{"answer": "...", "reason": "..."} |
5. 其他类型的解析器
除了上面讲的文本、对象、JSON解析器,其实 LangChain 官方还提供了更多类型的解析器,如:
- XML 解析器:
XMLOutputParser - Yaml 解析器:
YamlOutputParser - CSV 解析器:
CommaSeparatedListOutputParser - 枚举解析器:
EnumOutputParser - 日期解析器:
DatetimeOutputParser等等
更多类型参考官方文档。
除此之外,LangChain 还支持我们自定义输出解析器,以将模型输出结构化为自定义格式,详细情况参考这里。
6. 完整工作流程
用户输入
↓
PromptTemplate (包含 format_instructions)
↓
LLM (按照格式说明生成结构化输出)
↓
OutputParser (解析为 Python 对象)
↓
结构化数据
8. 常见问题
Q1: 为什么 LLM 没有按格式返回?
A: 检查是否在模板中包含了 {format_instructions}
Q2: PydanticOutputParser 和 JsonOutputParser 选哪个?
A: 需要类型验证选 Pydantic,只需要字典选 Json
Q3: 如何自定义输出格式?
A: 可以继承 BaseOutputParser 实现自定义解析器
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)