【LangChain】P14 LangChain 输出解析器深度解析:Json解析器、XML解析器、字符串及列表、日期解析器
目录
- 前言
- 为什么输出解析器?
- 环境准备
- 常用输出解析器概览
- 1. 字符串解析器(StrOutputParser)
- 功能说明
- 使用示例
- 返回内容
- 快捷方式
- 2. JSON 解析器(JsonOutputParser)
- 功能说明
- 适用场景
- 实现方式一:手动指定 JSON 格式
- 实现方式二:使用 get_format_instructions()
- 使用管道符简化代码
- 3. XML 解析器(XMLOutputParser)
- 功能说明
- 特点
- 实现方式一:手动指定 XML 格式
- 实现方式二:使用 get_format_instructions()
- 4. 列表解析器(CommaSeparatedListOutputParser)
- 功能说明
- 使用示例
- 使用场景
- 5. 日期时间解析器(DatetimeOutputParser)
- 功能说明
- 使用示例
- 使用场景
- 实战建议
- 选择合适的解析器
- 最佳实践
- 总结
在大模型应用开发中,我们常常面临一个问题:语言模型返回的都是纯文本,但我们的应用往往需要结构化的数据来进行后续处理。这就是 LangChain 输出解析器(Output Parser)要解决的核心问题。
本系列博文的前序博文中,已经对 LangChain Model I/O 部分内容中的格式化输入与提示词模板进行了深度的解析。本博文将针对 Model I/O 三个核心组件中的 Parser(解析输出)部分内容,深入学习。
前言
为什么输出解析器?
语言模型返回的是字符串(文本),但在实际开发中,我们往往需要:
- JSON 格式的数据用于 API 调用
- 列表格式的数据用于批量处理
- 日期时间格式用于日程管理
- XML 格式用于系统集成
通过输出解析器,我们可以将 LLM 的文本输出转换为程序可以直接使用的结构化格式。
环境准备
在开始之前,我们先配置好大模型整体开发环境:
import os
import dotenv
from langchain_openai import ChatOpenAI# 加载环境变量
dotenv.load_dotenv()
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
os.environ["OPENAI_BASE_URL"] = os.getenv("OPENAI_BASE_URL")# 初始化模型
chat_model = ChatOpenAI(model=os.getenv("CHAT_MODEL")
)
常用输出解析器概览
LangChain 提供了多种输出解析器,适用于不同场景:
基础解析器:
StrOutputParser
- 字符串解析器,提取纯文本内容JsonOutputParser
- JSON 解析器,确保输出为 JSON 对象XMLOutputParser
- XML 解析器,处理 XML 格式数据CommaSeparatedListOutputParser
- CSV 解析器,返回列表格式DatetimeOutputParser
- 日期时间解析器,处理时间数据
高级解析器:
EnumOutputParser
- 枚举解析器,限定输出为预定义值StructuredOutputParser
- 结构化解析器,转换为字典格式OutputFixingParser
- 修复解析器,自动修正格式错误RetryOutputParser
- 重试解析器,失败时自动重试
本博文不围绕高级内容,将详细介绍最常用的几种解析器。
1. 字符串解析器(StrOutputParser)
功能说明
StrOutputParser
是最基础的解析器,它从模型响应中提取 content 字段,返回纯文本字符串。
使用示例
from langchain_core.output_parsers import StrOutputParser# 调用模型
response = chat_model.invoke("一句话简述什么是大语言模型")# 使用解析器
parser = StrOutputParser()
str_response = parser.invoke(response)
print(str_response)
返回内容
大语言模型是一种利用海量文本数据训练、能够理解和生成人类语言的深度学习模型。
快捷方式
实际上,也可以直接通过代码访问 content
属性:
response = chat_model.invoke("一句话简述什么是大语言模型")
print(response.content) # 效果相同
2. JSON 解析器(JsonOutputParser)
功能说明
JsonOutputParser
将模型的自由文本输出转换为结构化的 JSON 数据,这是开发中最常用的解析器之一。
适用场景
- API 接口返回数据
- 数据库存储前的格式化
- 需要明确字段结构的应用场景
实现方式一:手动指定 JSON 格式
通过提示词明确要求模型返回 JSON 格式:
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate# 创建提示模板
chat_prompt_template = ChatPromptTemplate.from_messages([("system", "你是一个靠谱的{role}"),("human", "{question}")
])# 构造提示
prompt = chat_prompt_template.invoke(input={"role": "人工智能专家","question": "人工智能用英文怎么说?问题用q表示,答案用a表示,返回一个JSON格式的数据"
})# 调用模型和解析
response = chat_model.invoke(prompt)
parser = JsonOutputParser()
json_response = parser.invoke(response)
print(json_response)
# 输出示例: {'q': '人工智能用英文怎么说?', 'a': 'Artificial Intelligence'}
实现方式二:使用 get_format_instructions()
这是更推荐的方式,让解析器自动生成格式说明:
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate# 创建解析器
parser = JsonOutputParser()# 查看自动生成的格式说明
print(parser.get_format_instructions())
# 输出类似: "Return a JSON object. The output should be formatted as a JSON instance..."# 创建包含格式说明的提示模板
prompt_template = PromptTemplate.from_template(template="回答用户的查询\n满足的格式为{format_instructions}\n问题为{question}\n",partial_variables={"format_instructions": parser.get_format_instructions()}
)# 完整调用流程
joke_query = "告诉我一个笑话"
prompt = prompt_template.invoke(input={"question": joke_query})
response = chat_model.invoke(prompt)
json_response = parser.invoke(response)
print(json_response)
使用管道符简化代码
LangChain 支持使用管道符 | 将多个步骤连接成链(Chain):
# 将模板、模型、解析器连接成一条链
chain = prompt_template | chat_model | parser# 一行代码完成所有操作
json_response = chain.invoke(input={"question": joke_query})
print(json_response)
使用 chain 的优势非常明显:代码更简洁,逻辑更清晰,便于维护。关于详细管道符与 chain 的内容,在后续博文阐述。
3. XML 解析器(XMLOutputParser)
功能说明
XML(可扩展标记语言)曾是数据传输的主流格式,至今在许多系统集成场景中仍然广泛使用。XMLOutputParser
可以将模型输出转换为易于处理的 XML 数据结构。
特点
- 使用
<标签>内容</标签>
的格式 - 解析器会将 XML 自动转换为 Python 字典,便于程序处理
- 适合需要层次化数据结构的场景
实现方式一:手动指定 XML 格式
from langchain_core.output_parsers import XMLOutputParseractor = "周星驰"
response = chat_model.invoke(f"请生成{actor}的简短电影记录,将影片名称放在<movie></movie>标签中"
)
print(response.content)
# 输出示例:
# <movie>大话西游</movie>
# <movie>功夫</movie>
# <movie>喜剧之王</movie># 解析XML
parser = XMLOutputParser()
xml_response = parser.invoke(response)
print(xml_response)
# 输出为字典格式,方便程序处理
实现方式二:使用 get_format_instructions()
from langchain_core.prompts import PromptTemplateparser = XMLOutputParser()prompt_template = PromptTemplate.from_template(template="请回答以下问题\n{format_instructions}\n问题:{question}\n",partial_variables={"format_instructions": parser.get_format_instructions()}
)chain = prompt_template | chat_model | parser
result = chain.invoke(input={"question": f"列出{actor}的三部代表作"})
print(result)
4. 列表解析器(CommaSeparatedListOutputParser)
功能说明
CommaSeparatedListOutputParser
将模型输出的逗号分隔文本转换为 Python 列表,非常适合批量数据处理。
使用示例
from langchain_core.output_parsers import CommaSeparatedListOutputParserparser = CommaSeparatedListOutputParser()prompt_template = PromptTemplate.from_template(template="列出五种编程语言\n{format_instructions}\n",partial_variables={"format_instructions": parser.get_format_instructions()}
)chain = prompt_template | chat_model | parser
result = chain.invoke({})
print(result)
# 输出: ['Python', 'JavaScript', 'Java', 'C++', 'Go']
print(type(result)) # <class 'list'>
使用场景
- 生成选项列表
- 关键词提取
- 标签生成
- 任何需要多个独立项目的场景
5. 日期时间解析器(DatetimeOutputParser)
功能说明
DatetimeOutputParser
将模型输出的日期时间文本转换为 Python 的 datetime 对象,便于进行时间计算和格式化。
使用示例
from langchain_core.output_parsers import DatetimeOutputParserparser = DatetimeOutputParser()prompt_template = PromptTemplate.from_template(template="用户的生日是什么时候?\n{format_instructions}\n用户信息:{user_info}\n",partial_variables={"format_instructions": parser.get_format_instructions()}
)chain = prompt_template | chat_model | parser
result = chain.invoke(input={"user_info": "张三,1990年5月20日出生"})
print(result) # 输出: 1990-05-20 00:00:00
print(type(result)) # <class 'datetime.datetime'># 可以直接进行时间计算
from datetime import datetime
age = (datetime.now() - result).days // 365
print(f"年龄: {age}岁")
使用场景
- 日程管理应用
- 时间提醒功能
- 数据分析中的时间维度处理
- 需要进行时间计算的场景
实战建议
选择合适的解析器
- 需要纯文本 →
StrOutputParser
- 需要键值对数据 →
JsonOutputParser
- 系统集成需要 XML →
XMLOutputParser
- 需要列表数据 →
CommaSeparatedListOutputParser
- 需要时间数据 →
DatetimeOutputParser
最佳实践
- 优先使用
get_format_instructions()
:让解析器自动生成格式说明,减少人工错误 - 使用管道符构建链: 使代码更简洁,逻辑更清晰
- 添加错误处理: 模型输出不总是完美,考虑使用
OutputFixingParser
或RetryOutputParser
- 明确提示词: 即使使用解析器,清晰的提示词仍然能大幅提高输出质量
总结
输出解析器是 LangChain 中连接模型输出和应用逻辑的关键桥梁。通过合理使用不同的解析器,我们可以:
- 将自由文本转换为结构化数据
- 减少后续数据处理的复杂度
- 提高应用的可靠性和可维护性
掌握这些解析器的使用方法,将使 AI 应用开发效率大大提升。在后续的文章中,我们将继续探讨 LangChain 的管道符(Pipeline)和重要的链(Chain)机制,敬请期待!
2025.10.07 北京 西直门